omni_player 2.0.0
omni_player: ^2.0.0 copied to clipboard
Flutter媒体播放器插件,在Android/iOS上支持视频和音频播放和后台播放。支持MKV、MP4、HLS等.
OmniPlayer #
Flutter 跨平台媒体播放器插件,基于 media_kit(libmpv/FFmpeg)封装,支持 iOS 与 Android 上的音视频播放、后台音频、锁屏/通知栏控制与磁盘缓存。
特性 #
- 广泛格式支持:MP4、MKV、AVI、MOV、FLV、RMVB、MP3、AAC、FLAC、WAV、OGG、HLS(.m3u8)、DASH(.mpd)、RTSP、RTMP 等 FFmpeg 可解码格式。
- 精确 Seek:libmpv 高精度 seek,任意倍速下 seek 延迟 < 200 ms,无 scaletempo 重初始化问题。
- 后台音频播放:进入后台自动禁用视频轨道(保留音频),iOS 通过 AVAudioSession 维持音频活动,Android 通过前台服务持续播放。
- 锁屏 / 通知栏控制:iOS 使用
MPRemoteCommandCenter+MPNowPlayingInfoCenter,Android 使用MediaSessionCompat+MediaStyle通知栏,支持播放/暂停/上一首/下一首/进度拖动。 - 磁盘缓存:HTTP/HTTPS 点播资源首次播放后台静默缓存,再次播放命中本地文件(秒开),支持最大容量限制与手动清理。
- 倍速播放:支持任意倍速(0.25x ~ 4.0x),倍速状态正确同步到锁屏进度条。
- 单例设计:
OmniPlayer.instance全局唯一实例,自动管理生命周期。
平台支持 #
| 平台 | 播放引擎 | 视频渲染 | 后台 / 控制 |
|---|---|---|---|
| iOS | libmpv (FFmpeg) | Metal Texture | AVAudioSession + MPRemoteCommandCenter |
| Android | libmpv (FFmpeg) | OpenGL Texture | Foreground Service + MediaSessionCompat |
仅支持 iOS 与 Android,不支持 macOS、Windows、Web。
安装 #
dependencies:
omni_player: ^2.0.0
# 消费端 App 必须引入媒体库(包含 FFmpeg 解码器)
media_kit_libs_video: ^1.0.4
运行:
flutter pub get
平台配置 #
iOS — Info.plist #
<!-- 后台音频播放 -->
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
<!-- 播放 HTTP 明文资源时添加(可选) -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Android — AndroidManifest.xml #
插件已在自身 manifest 中声明所需权限和 PlayerService,宿主 App 只需保留网络权限:
<uses-permission android:name="android.permission.INTERNET" />
快速开始 #
1. 初始化(App 启动时调用一次) #
import 'package:omni_player/omni_player.dart';
import 'package:media_kit/media_kit.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
MediaKit.ensureInitialized();
runApp(const MyApp());
}
// 在页面 initState 中:
final player = OmniPlayer.instance;
await player.initialize(
cacheConfig: const CacheConfig(
enabled: true,
maxSize: 500 * 1024 * 1024, // 500 MB
),
);
2. 播放媒体 #
await player.open(
const MediaItem(
url: 'https://example.com/video.mp4',
title: '示例视频',
artist: '作者',
coverUrl: 'https://example.com/cover.jpg',
isVideo: true, // false = 纯音频
headers: { // 可选,HTTP 自定义请求头
'Authorization': 'Bearer token',
},
),
autoPlay: true,
skipCache: false, // true = 跳过缓存强制走网络
);
3. 视频渲染 #
import 'package:omni_player/omni_player.dart';
VideoWidget(
player: OmniPlayer.instance,
fit: BoxFit.contain,
backgroundColor: Colors.black,
)
4. 播放控制 #
final player = OmniPlayer.instance;
await player.play();
await player.pause();
await player.stop();
await player.seek(const Duration(seconds: 30));
await player.setVolume(0.8); // 0.0 ~ 1.0
await player.setSpeed(1.5); // 倍速
await player.setLooping(true); // 循环播放
5. 状态监听 #
// 状态枚举:idle / loading / playing / paused / stopped / completed / error
player.stateStream.listen((state) => print('state: $state'));
player.positionStream.listen((pos) => print('position: $pos'));
player.durationStream.listen((dur) => print('duration: $dur'));
player.bufferedStream.listen((p) => print('buffered: ${(p * 100).toInt()}%'));
player.videoSizeStream.listen((s) => print('size: ${s.width}x${s.height}'));
player.errorStream.listen((e) => print('error: $e'));
// 锁屏 / 通知栏触发的上一首 / 下一首
player.previousTrackStream.listen((_) => playPrev());
player.nextTrackStream.listen((_) => playNext());
6. 缓存管理 #
final size = await player.getCacheSizeString(); // "128.5 MB"
await player.clearCacheItem('https://example.com/video.mp4');
await player.clearCache();
7. 释放资源 #
await player.dispose();
API 参考 #
OmniPlayer #
| 方法 / 属性 | 说明 |
|---|---|
OmniPlayer.instance |
获取单例 |
initialize({CacheConfig?}) |
初始化播放器与原生后台服务 |
open(MediaItem, {autoPlay, skipCache}) |
打开并播放媒体 |
play() |
播放 |
pause() |
暂停 |
stop() |
停止并清除当前媒体 |
seek(Duration) |
精确跳转 |
setVolume(double) |
设置音量 0.0 ~ 1.0 |
setSpeed(double) |
设置倍速 |
setLooping(bool) |
设置循环 |
state |
当前播放状态 |
position |
当前播放位置 |
duration |
媒体总时长 |
buffered |
缓冲进度 0.0 ~ 1.0 |
currentItem |
当前 MediaItem |
videoController |
media_kit VideoController(供 VideoWidget 使用) |
getCacheSize() |
缓存大小(字节) |
getCacheSizeString() |
缓存大小(可读字符串) |
clearCache() |
清除全部缓存 |
clearCacheItem(url) |
清除指定 URL 缓存 |
dispose() |
释放全部资源 |
MediaItem #
| 参数 | 类型 | 说明 |
|---|---|---|
url |
String |
媒体地址(HTTP/HTTPS/file://) |
title |
String |
标题(显示在锁屏) |
artist |
String? |
艺术家 |
album |
String? |
专辑 |
coverUrl |
String? |
封面图 URL(锁屏大图) |
isVideo |
bool |
是否为视频(默认 false) |
headers |
Map<String,String>? |
HTTP 自定义请求头 |
CacheConfig #
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled |
bool |
true |
是否启用缓存 |
maxSize |
int |
500 MB | 最大缓存空间(字节) |
customDirectory |
String? |
null |
自定义缓存目录(null = 系统缓存目录) |
注意事项 #
media_kit_libs_video必须由消费端 App 引入,插件本身不内嵌 FFmpeg 库(避免重复打包)。- 缓存仅对
http:///https://点播资源生效,HLS(.m3u8)、DASH(.mpd)、RTSP、RTMP 不缓存。 isVideo: true时进入后台会自动禁用视频轨道(保留音频),回到前台自动恢复;isVideo: false无此切换开销。- Android 最低 SDK 21,iOS 最低 12.0。