效果图
单曲播放
1.png列表播放
2.png底部TipsView
3.png详情页
4.pngFlutter音频播放器来了!!!需要Flutter视频播放器的,看这里 :Flutter视频播放器,简洁!。
重点:思路同视频播放器及其雷同!!!
环境:Flutter 2.8.1 channel stable ;Dart 2.15.1
小技巧 :获取网易云的音乐mp3链接,
右击选中的音乐分享或复制链接:
https://music.163.com/song?id=468176711&userid=218388655
复制id固定格式替换:
http://music.163.com/song/media/outer/url?id=468176711.mp3
可以关注下这首《城南花已开》以及背后的故事!
第三方插件
# 推荐使用
just_audio: ^0.9.20
# 也不错
audioplayers: ^0.20.1
以上两个插件都可以,使用方法也相似。只是 just_audio
是 Flutter Favorite,个人也是比较推荐使用just_audio
,迷信官方。。。。但是上述功能笔者却是使用 audioplayers
完成的,怎么样?出乎意料吧!其实笔者后续也是用 just_audio
封装了下,同样Easy!
项目结构
5.png感觉也没啥好说的,就是很普通的。重点提下 AudioPlayerUtil
。
AudioPlayerUtil
同样的,AudioPlayerUtil
专门且只用来处理播放器的所有业务。包括暂停、单曲播放、列表播放、切换曲目、各种事件监听等操作。在所有的widget中不会引用关于第三方插件的任何信息,AudioPlayerUtil
负责widget与播放器之间的所有操作交互。后续优化迭代或更换播放器插件时,只需针对这个工具类进行修改,对所有widget不会有任何的影响,大大的解耦合了。
打个比方:前期使用了 audioplayers
插件,后续因为业务需求要替换成 just_audio
,只需简单修改 AudioPlayerUtil
一个文件即可,方便、简单,代码也很健壮。
public 属性
static MusicModel? get musicModel => _instance._musicModel; // 当前播放的音频模型
static AudioPlayerState get state => _instance._state; // 当前播放状态
static Duration get position => _instance._position; // 当前音频播放进度
static bool get isListPlayer => _instance._isListPlayer; // 当前是否是列表播放
其中 AudioPlayerState
:
/// 播放状态枚举
enum AudioPlayerState{
stopped, // 初始状态,已停止或发生错误
playing, // 正在播放
paused, // 暂停
completed // 播放结束
}
提供以上的公共属性,可以通过 AudioPlayerUtil
来获取对应的值,使用 get
只读,使外界不会误修改这些属性,以保证数值的安全性。开发者可根据自身需要自行添加属性。
public 方法
// 单曲播放
static void playerHandle({required MusicModel model}){...}
// 列表播放,musicModel参数不为null,即为指定列表某一曲目播放
static void listPlayerHandle({required List<MusicModel> musicModels,MusicModel? musicModel}){...}
// 上一曲,只在列表播放时有效
static void previousMusic(){...}
// 下一曲,只在列表播放时有效
static void nextMusic(){...}
// 跳转到某一时段播放
static void seekTo({required Duration position,required MusicModel model}){...}
// 获取音频总时长
static Future<Duration> getAudioDuration({required String url}) async{...}
// 播放状态监听
static void statusListener({required dynamic key,required Function(AudioPlayerState) listener}){...}
// 移除播放状态监听
static void removeStatusListener(dynamic key){...}
// 播放进度监听
static void positionListener({required dynamic key,required Function(int) listener}){...}
// 移除播放进度监听
static void removePositionListener(dynamic key){...}
// 底部显示tip监听
static void showListener({required dynamic key,required Function listener}){...}
// 移除底部显示tip监听
static void removeShowListener(dynamic key){...}
// 设置音量
static Future<int> setVolume(double volume) async{...}
// 释放资源
static void dispose(){...}
提供以上方法来处理音乐播放器的所有业务,同样的开发者可根据自身需要自行添加或修改。如提供暂停pause、播放play等功能。
playerHandle
这个方法,是整个业务的核心方法,同视频播放器一样,开发者只要遇到播放或暂停是均可调用此方法,具体是播放或暂停,内部根据传入的url
自行判断,开发者不需要关心。
切换新曲目也是使用此方法,传入的url
与上次不一致,自动切换新视频。笔者可根据statusListener
来监听播放状态的改变,以此处理自身逻辑。
其他的也没啥好说的了,都是基本操作!有兴趣的可以对照Demo自行查阅。
RCAudioPlayerDemo
具体的实现监听器的思路,看这里。
网友评论