import 'dart:io'; import 'package:audioplayers/audioplayers.dart'; import 'package:comunic/utils/date_utils.dart'; import 'package:flutter/material.dart'; /// Audio player widget /// /// @author Pierre Hubert class AudioPlayerWidget extends StatefulWidget { final File file; const AudioPlayerWidget(this.file); @override _AudioPlayerWidgetState createState() => _AudioPlayerWidgetState(); } class _AudioPlayerWidgetState extends State { AudioPlayer _player; Duration _mediaDuration; Duration _mediaPosition; double get _max => _mediaDuration?.inMilliseconds?.toDouble() ?? 0.0; double get _value => _mediaPosition?.inMilliseconds?.toDouble() ?? 0.0; bool get _playing => _player != null && _player.state == AudioPlayerState.PLAYING; @override void dispose() { super.dispose(); if (_player != null) _player.dispose(); } @override Widget build(BuildContext context) { return Material( textStyle: TextStyle(color: Colors.white), color: Colors.transparent, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Spacer(), Icon(Icons.audiotrack, color: Colors.white), Spacer(), Slider( value: _value, onChanged: (newValue) => _player.seek(Duration(milliseconds: newValue.toInt())), max: _max, activeColor: Colors.white, min: 0, ), Spacer(), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Spacer(), Text(formatDuration(_mediaPosition ?? Duration())), Spacer(), _AudioButton( icon: Icons.play_arrow, onTap: _play, visible: !_playing), _AudioButton(icon: Icons.pause, onTap: _pause, visible: _playing), _AudioButton(icon: Icons.stop, onTap: _stop, visible: _playing), Spacer(), _playing ? Container() : Text(formatDuration(_mediaDuration ?? Duration())), Spacer(), ], ), Spacer(), ], ), ); } void _play() async { if (_player == null) { _player = AudioPlayer(); _player.onDurationChanged.listen((newDuration) { setState(() => _mediaDuration = newDuration); }); _player.onAudioPositionChanged.listen((newDuration) { setState(() => _mediaPosition = newDuration); }); _player.onPlayerStateChanged.listen((event) => setState(() {})); _player.onSeekComplete.listen((event) => setState(() {})); } if (_player.state != AudioPlayerState.PAUSED) _player.play(widget.file.absolute.path, isLocal: true); else _player.resume(); } void _pause() async { _player.pause(); } void _stop() { _player.stop(); _player.seek(Duration()); } } class _AudioButton extends StatelessWidget { final IconData icon; final void Function() onTap; final bool visible; const _AudioButton({ Key key, @required this.icon, @required this.onTap, @required this.visible, }) : assert(icon != null), assert(onTap != null), assert(visible != null), super(key: key); @override Widget build(BuildContext context) { if (!visible) return Container(); return IconButton(icon: Icon(icon, color: Colors.white), onPressed: onTap); } }