Improve audio player stability

This commit is contained in:
Nutcake 2023-05-18 15:17:05 +02:00
parent ce98e73f6f
commit b7a27944cf
3 changed files with 32 additions and 9 deletions

View file

@ -175,7 +175,7 @@ class AudioClipContent {
final String id; final String id;
final String assetUri; final String assetUri;
AudioClipContent({required this.id, required this.assetUri}); const AudioClipContent({required this.id, required this.assetUri});
factory AudioClipContent.fromMap(Map map) { factory AudioClipContent.fromMap(Map map) {
return AudioClipContent( return AudioClipContent(
@ -190,7 +190,7 @@ class MarkReadBatch {
final List<String> ids; final List<String> ids;
final DateTime readTime; final DateTime readTime;
MarkReadBatch({required this.senderId, required this.ids, required this.readTime}); const MarkReadBatch({required this.senderId, required this.ids, required this.readTime});
Map toMap() { Map toMap() {
return { return {

View file

@ -17,22 +17,46 @@ class MessageAudioPlayer extends StatefulWidget {
State<MessageAudioPlayer> createState() => _MessageAudioPlayerState(); State<MessageAudioPlayer> createState() => _MessageAudioPlayerState();
} }
class _MessageAudioPlayerState extends State<MessageAudioPlayer> { class _MessageAudioPlayerState extends State<MessageAudioPlayer> with WidgetsBindingObserver {
final AudioPlayer _audioPlayer = AudioPlayer(); final AudioPlayer _audioPlayer = AudioPlayer();
double _sliderValue = 0; double _sliderValue = 0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addObserver(this);
if (Platform.isAndroid) { if (Platform.isAndroid) {
//TODO: Add caching of audio-files
_audioPlayer.setUrl( _audioPlayer.setUrl(
Aux.neosDbToHttp(AudioClipContent Aux.neosDbToHttp(AudioClipContent
.fromMap(jsonDecode(widget.message.content)) .fromMap(jsonDecode(widget.message.content)).assetUri),
.assetUri),
preload: true).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off)); preload: true).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off));
} }
} }
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
_audioPlayer.stop();
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_audioPlayer.setUrl(
Aux.neosDbToHttp(AudioClipContent
.fromMap(jsonDecode(widget.message.content)).assetUri),
preload: true).whenComplete(() => _audioPlayer.setLoopMode(LoopMode.off));
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_audioPlayer.dispose();
super.dispose();
}
Widget _createErrorWidget(String error) { Widget _createErrorWidget(String error) {
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@ -114,8 +138,8 @@ class _MessageAudioPlayerState extends State<MessageAudioPlayer> {
StreamBuilder( StreamBuilder(
stream: _audioPlayer.positionStream, stream: _audioPlayer.positionStream,
builder: (context, snapshot) { builder: (context, snapshot) {
_sliderValue = (_audioPlayer.position.inMilliseconds / _sliderValue = _audioPlayer.duration == null ? 0 : (_audioPlayer.position.inMilliseconds /
(_audioPlayer.duration?.inMilliseconds ?? 0)).clamp(0, 1); (_audioPlayer.duration!.inMilliseconds)).clamp(0, 1);
return StatefulBuilder( // Not sure if this makes sense here... return StatefulBuilder( // Not sure if this makes sense here...
builder: (context, setState) { builder: (context, setState) {
return SliderTheme( return SliderTheme(

View file

@ -29,8 +29,7 @@ class MessageBubble extends StatelessWidget {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: switch (message.type) { child: switch (message.type) {
MessageType.sessionInvite => MessageType.sessionInvite => MessageSessionInvite(message: message, foregroundColor: foregroundColor,),
MessageSessionInvite(message: message, foregroundColor: foregroundColor,),
MessageType.object => MessageAsset(message: message, foregroundColor: foregroundColor,), MessageType.object => MessageAsset(message: message, foregroundColor: foregroundColor,),
MessageType.sound => MessageAudioPlayer(message: message, foregroundColor: foregroundColor,), MessageType.sound => MessageAudioPlayer(message: message, foregroundColor: foregroundColor,),
MessageType.unknown || MessageType.text => MessageText(message: message, foregroundColor: foregroundColor,) MessageType.unknown || MessageType.text => MessageText(message: message, foregroundColor: foregroundColor,)