media_player_plugin 0.0.1
media_player_plugin: ^0.0.1 copied to clipboard
media_player_plugin
media_player_plugin #
一个支持 ios/android 音频、视频播放的 flutter 插件,支持普通的网络流、dash、hls
安装 #
dependencies:
media_player_plugin: ^0.0.1
开发与测试 #
运行 example 请使用 fvm
平台 | 开发语言 | 组件库 | 开发环境 | 测试机 |
---|---|---|---|---|
android | kotlin | media3/exoplay | android Studio 2024.2.2 | 模拟器 android12 |
ios | Switf | AVAudioEngine AVAudioPlayerNode VideoPlayer |
xcode 14 | se2 ios 13.6 |
效果展示 #
-
IOS
-
Android
Audio 使用 #
-
创建播放实例
import 'package:media_player_plugin/media_player_plugin.dart'; const frequencys = [31.0,62.0,125.0,250.0,500.0,1000.0,2000.0,4000.0,8000.0,16000.0]; final controller = MediaAudioPlayer(frequencys: frequencys); await controller.init();
-
销毁
controller.destroy();
-
播放设置
await controller.init(); await controller.setUrl({ // file://xxx , asset://xxx , http://xxx required String url, bool? enableIosHttpRange, Map<String, String>? urlHeader, String? title, String? artist, // file://xxx , asset://xxx , http://xxx String? cover, Map<String, String>? coverHeader, bool? enableIosHttpRange, }); await controller.prepare();
enableIosHttpRange 只对 ios 的音频资源起作用,主要用于开启是否 http range 来快速 seek , 否则渐进式加载资源到 seek 的位置,考虑到兼容问题,不建议开启,测试正常支持 http range 的格式 flac\mp3\wav
-
控制
await controller.play(); await controller.pause(); // second 秒 await controller.seek(2); // replay await controller.seek(0); await controller.play();
-
播放事件监听
await controller.init(); List<StreamSubscription> _removes = []; _removes.add( controller.playStateStream!.listen((data) { setState(() { isPlaying = data.isPlaying; isBuffering = data.isBuffering; isPlayCompleted = data.isPlayCompleted; }); }), ); _removes.add( controller.durationStream!.listen((data) { setState(() { position = Duration(milliseconds: (data.position * 1000).round()); duration = Duration(milliseconds: (data.duration * 1000).round()); bufferd = Duration(milliseconds: (data.cacheDuration * 1000).round()); }); }), ); @override dispose() { super.dispose(); for (var item in _removes) { item.cancel(); } }
-
均衡器
await controller.init(); // 开启 await controller.enableEq(); // 关闭 await controller.disableEq(); // 均衡器信息 await controller.getEqBands(); // 设置均衡器 await updateBand( int index, { double? frequency, double? gain, // bypass为true时 跳过 bool? bypass, })
-
音频可视化 FFT
// 开启 await controller.enableFFT(); // 关闭 await controller.disableFFT(); // 监听 var _subscription = controller.fftStream!.listen((data) { var lefts = data.lefts; var rights = data.rights; print([lefts,rights]) }); _subscription.cancle();
controller.fftStream 每 100ms 回调一次返回 audio pcm 长度为 sampleRate/10 也就是 4800 或 4410, pcm 范围为[-1,1],需要将其转为 rms, 可参考 FFtView 组件
-
后台播放通知
// 开启后台播放通知 await controller.enablePlayback(); // 关闭后台播放通知 await controller.disablePlayback(); // 监听 controller.registerPlayBackEvent({ required Function() onPlayBackPrevious, required Function() onPlayBackNext, }) // 移除 controller.removePlayBackEvent();
enablePlayback 时,如果其他实例有开启则会被关闭,需要自己处理歌曲切换逻辑。 setUrl 如果没提供 title、cover 这些信息时会尝试读取歌曲提供的信息
-
可访问属性
position duration cacheDuration isPlaying isBuffering isPlayCompleted isPlaybackActive isFFTActive isEqActive
-
效果视图组件
FFtView 音频可视化
FFtView( controller: controller, width: 340, indicatorWidth: 2, indicatorHeight: 60, spaceWidth: 1, )
均衡器设置组件
IconButton( onPressed: () async { var bands = await controller.getEqBands(); EqualizerView.show( context: context, bands: bands, height: 300, enableEq: controller.isEqActive, onEqSwitchChanged: (value) { if (value) { controller.enableEq(); } else { controller.disableEq(); } }, onChanged: (index, value) { controller.updateBand(index, gain: value); }, onReset: () { for (var i = 0; i < bands.length; i++) { controller.updateBand(i, gain: 0); } }, ); }, icon: Icon(Icons.equalizer_rounded), ),
Video 使用 #
-
创建播放实例
import 'package:media_player_plugin/media_player_plugin.dart'; final controller = MediaVideoPlayer(); await controller.init();
-
销毁
controller.destroy();
-
播放设置
await controller.init(); await controller.setUrl({ // file://xxx , asset://xxx , http://xxx required String url, bool? enableIosHttpRange, Map<String, String>? urlHeader, String? title, String? artist, // file://xxx , asset://xxx , http://xxx String? cover, Map<String, String>? coverHeader, }); await controller.prepare();
-
播放视图
SizedBox( width: double.infinity, child: MediaVideoView(controller: controller,fit: BoxFit.contain), )
-
播放控件
MediaVideoControls( controller: controller, child: SizedBox( width: double.infinity, child: MediaVideoView(controller: controller,fit: BoxFit.contain), ), onFullScreen: () { // 参考example }, ),
-
控制
await controller.play(); await controller.pause(); // second 秒 await controller.seek(2); // replay await controller.seek(0); await controller.play();
-
播放事件监听
await controller.init(); List<StreamSubscription> _removes = []; _removes.add( controller.playStateStream!.listen((data) { setState(() { isPlaying = data.isPlaying; isBuffering = data.isBuffering; isPlayCompleted = data.isPlayCompleted; }); }), ); _removes.add( controller.durationStream!.listen((data) { setState(() { position = Duration(milliseconds: (data.position * 1000).round()); duration = Duration(milliseconds: (data.duration * 1000).round()); bufferd = Duration(milliseconds: (data.cacheDuration * 1000).round()); }); }), ); @override dispose() { super.dispose(); for (var item in _removes) { item.cancel(); } }
-
读取设置轨道资源
// 读取视频轨道 var video = await controller.readVideoTrack() // 设置视频轨道 await controller.selectVideoTrack("1080p") // 读取音频轨道 var audio = await = controller.readAudioTrack(); // 设置音频轨道 await controller.selectAudioTrack("audio_id");
-
事件监听
获取播放视频的宽高
var off = controller.registerPresentationSize(( width, height, ) { setState(() { videoWidth = width; videoHeight = height; }); }); // 注销 off()
视频是否可播放
var off = controller.registerReadyToPlay((){ }); // 注销 off()
-
后台播放通知
// 开启后台播放通知 await controller.enablePlayback(); // 关闭后台播放通知 await controller.disablePlayback(); // 监听 controller.registerPlayBackEvent({ required Function() onPlayBackPrevious, required Function() onPlayBackNext, }) // 移除 controller.removePlayBackEvent();
-
可访问属性
width height position duration cacheDuration isPlaying isBuffering isPlayCompleted isPlaybackActive
后期计划 #
- 提供字幕选择
- debug 日志输出
- 提供缓存接口