最近在学用flutter写音乐app,音乐播放方面主要用到了两个库:just_audio
和audio_service
,其中
just_audio
负责音乐的播放功能,audio_service
负责音乐的后台、通知栏展示功能。
先说一下为啥选两个,在此之前我也用过其他的,但都存在一些或多或少的问题:
audio_players
:指定播放链接不能使用headers参数,这就意味着需要带headers才能调用的播放链接都不能用(比如某易云),需要下载到本地再进行指定,这样太麻烦了;
assets_audio_player
: 自带后台播放功能,可以用,但是可能是我没正确使用的原因,遇到一些小bug;
audio_background
:后台播放模块,但不支持歌单的整体播放,作者也是建议如果是歌单的话就用audio_service
。
:::
调用逻辑
- 共分为4个层
- UI层,即界面
- logic层,使用GetxController定义的控制器,参数定义在GetxService以保持页面间的持久化
- handler层,基于BaseAudioHandler的处理类,负责和player的交互
- player层,定义的AudioPlayer,具体的音乐播放、切换等是在这里调用的
- 处理流
-
在 handler层 去监听 player层 的数据变化。
上述代码为例,player层通过playbackEventStream
流进行广播,我们在handler层进行监听,然后再由handler层转发广播出去。 -
handler层通过
playbackState
进行广播,我们在logic层进行监听,并记录下来,供UI层展示
-
当 UI层进行播放、切歌等功能时,调用logic层的方法,去调用handler层的方法,再由handler层去调用player层的方法。
参考教程
在pub.dev
中搜索audio_service
库
跟着第一篇文章中的教程做一遍,就会得七七八八了。
我也是在这篇文章的基础上进行开发的,并在其中发现了一些问题,记录下来。
问题
- 问题:文章中只提供了往歌单中添加歌曲的方法,没提供播放新歌单的方法;
解决办法:在往player层添加歌曲之前,先通过await _playlist.clear();
将歌单清空。 - 问题:在进行随机播放时,歌单索引会进行乱序,并同步更新到UI层,如果你还有一个正常顺序的歌单要同时控制播放,那要注意了;
解决办法:正常顺序的歌单通过index = _player.shuffleIndices!.indexOf(index);
获取到随机歌单中正确的索引。 - 异步方法执行都没用
await
,会有执行混乱的情况发生;
解决办法:异步方法都加上await
执行。 - handler层把歌曲时长和当前歌曲的监听都使用
MediaItem
进行传递了,需要区分,不然如果需要更新时长的地方,你更新当前歌曲了,而两首歌又不是同一首的话,那就糟糕了;
解决办法:在MediaItem.extras
中添加字段,更新时长时设MediaItem.extras?['update_duration'] = true;
,更新当前歌曲时设extras?['update_index'] = true;
进行区分。 - 把逻辑在统一一下,除了播放顺序和随机播放,其他需要同步到UI层的数据,均由player层进行传递。