Flutter 鸿蒙使用实战:用 video_player 三方库在 OpenHarmony 上实现视频播放与状态监听

Flutter 社区地址: https://atomgit.com/CPF-Flutter/flutter_flutter
github三方库地址:https://github.com/flutter/packages/tree/main/packages/video_player/video_player
pub地址:https://pub.dev/packages/video_player
鸿蒙适配版:https://atomgit.com/openharmony-tpc/flutter_packages

库版本:video_player v2.10.1(openharmony-tpc 鸿蒙适配版,commit br_video_player-v2.10.1_ohos 分支)|验证环境:Flutter 鸿蒙 SDK 3.44.9(oh-3.44.9-dev)|DevEco Studio 26.0.0.821 | 设备:DevEco 模拟器 Pura X View | HarmonyOS 7.0.0.106(API 26)

视频播放是 Flutter 移动端最常见的功能之一——短视频、教育课程、直播推流、内嵌教学视频都依赖同一个核心库。video_player 是 Flutter 官方维护的视频播放库(pub.dev 月下载 600 万级),openharmony-tpc 已在 flutter_packagesbr_video_player-v2.10.1_ohos 分支完成鸿蒙适配。本文介绍它在 OpenHarmony 上的引入方式、federated 五包锁法、VideoPlayerController 全接口演示,以及在 DevEco 模拟器上真实触发的播放/暂停/循环/进度跳播与事件流(isBuffering/isCompleted)的真实运行效果。
在这里插入图片描述
在这里插入图片描述

一、环境搭建

本章不重复展开,直接引用官方文档:Flutter OH 开发环境搭建指导

完成后用 flutter doctor -v 验证,FlutterHarmonyOS toolchain 两项均为 [√] 即可。本文实际使用版本:Flutter OH oh-3.44.9-dev(commit 77e0c8d13b)、DevEco Studio 26.0.0.821、HarmonyOS SDK API 26。
在这里插入图片描述

二、应用背景

2.1 当前的应用场景与痛点

  • 教育/网课类应用:内嵌课程视频,跟踪播放进度,控制播放/暂停
  • 短视频/内容流:列表卡片预览,自动播放 + 滑动切换
  • 直播场景:拉流 RTSP/RTMP/HLS,鸿蒙原生 AVPlayer 已支持 HLS/HTTP 拉流
  • 应用启动屏/引导页:assets 视频做引导动画

痛点:Flutter 官方 video_player 在鸿蒙侧此前无完整实现——OH 适配版由 openharmony-tpc 社区维护,开箱即用。

2.2 为什么需要这个库

自己写鸿蒙播放器要处理 AVPlayer 状态机(idle/initialized/prepared/playing/paused/stopped/error)+ Surface 渲染到 XComponent + 跨事件回调桥接。video_player 的 OH 适配版由社区维护,API 与 Android/iOS 完全一致,业务侧零代码迁移。

2.3 解决什么问题

一句话总结:让 Flutter 应用在鸿蒙上以与 Android/iOS 完全一致的 API 加载、播放、控制、监听视频。具体提供:

  1. 三类来源:资产(AssetSource)/ 网络(DataSourceType.network)/ 文件(DeviceFileSource)
  2. 播放控制:initialize / play / pause / seekTo / setLooping / setVolume / dispose
  3. 状态读取:value.position / value.duration / value.size / value.isPlaying / value.isBuffering / value.isCompleted
  4. 监听:controller.addListener 通知 value 变更(缓冲中/播放中/已完成等状态转换)
    在这里插入图片描述

三、功能介绍

功能API说明适用场景
资产播放VideoPlayerController.asset('assets/x.mp4')播放打包进应用的视频引导页、帮助页、内置短片
网络播放VideoPlayerController.networkUrl('https://...')HLS/HTTP 流式播放短视频、直播点播
播放控制play() / pause() / seekTo(Duration) / setLooping(bool) / setVolume(double)播放控制 5 件套播放器 UI
资源释放dispose()释放 Surface + EventChannel页面销毁时
状态流addListener(() => value)position/duration/isBuffering/isCompleted 实时通知进度条 UI、状态联动
WidgetVideoPlayer(controller)渲染视频画面的 Flutter widget任意位置嵌入视频

四、使用方法

4.1 在应用中引入三方库(AtomGit 链接方式)

dependencies:
  video_player:
    git:
      url: https://atomgit.com/openharmony-tpc/flutter_packages.git
      ref: br_video_player-v2.10.1_ohos
      path: packages/video_player/video_player

dependency_overrides:   # 必须锁四包同 commit,否则 pub 解析到 pub.dev 新版导致 VideoTrack 类型找不到
  video_player_ohos:
    git:
      url: https://atomgit.com/openharmony-tpc/flutter_packages.git
      ref: br_video_player-v2.10.1_ohos
      path: packages/video_player/video_player_ohos
  video_player_platform_interface:
    git:
      url: https://atomgit.com/openharmony-tpc/flutter_packages.git
      ref: br_video_player-v2.10.1_ohos
      path: packages/video_player/video_player_platform_interface
  video_player_android:
    git:
      url: https://atomgit.com/openharmony-tpc/flutter_packages.git
      ref: br_video_player-v2.10.1_ohos
      path: packages/video_player/video_player_android
  video_player_avfoundation:
    git:
      url: https://atomgit.com/openharmony-tpc/flutter_packages.git
      ref: br_video_player-v2.10.1_ohos
      path: packages/video_player/video_player_avfoundation

三个关键点:

  1. 必须用 dependency_overrides 锁四包同 commit:federated 插件的子包如果不锁,pub 可能解析到 pub.dev 上最新版 video_player_android(2.12.x),其 VideoTrack 类型与本 OH 版的旧 video_player_platform_interface 不兼容,编译报 Type 'VideoTrack' not found
  2. url 用 AtomGit 而非 pub.dev:pub.dev 上的 video_player 无 ohos 实现,必须走 openharmony-tpc 的 OH 适配分支
  3. ref 用鸿蒙分支名br_video_player-v2.10.1_ohos),不是 commit hash——这是社区约定的鸿蒙适配分支命名格式

执行 flutter pub get。注意 assets 视频需在 pubspec 声明:

flutter:
  assets:
    - assets/video/

4.2 调用接口实现功能

4.2.1 VideoPlayerController 构造 + initialize

功能说明:异步构造控制器(指定视频源),调 initialize() 触发加载。

final controller = VideoPlayerController.asset('assets/video/demo.mp4');
await controller.initialize();
print('视频:${controller.value.size.width}x${controller.value.size.height} @ ${controller.value.duration.inSeconds}s');
4.2.2 play() / pause():播放控制

功能说明play() 起播、pause() 暂停(位置不变)、seekTo(Duration) 跳播。

await controller.play();    // 异步播放(解码 + 渲染 + 音频)
await controller.pause();   // 暂停
await controller.seekTo(const Duration(seconds: 30));  // 跳到 30 秒
4.2.3 setLooping() / setVolume():循环与音量
await controller.setLooping(true);     // 循环播放
await controller.setVolume(0.5);      // 音量 50%
4.2.4 状态监听:addListener + value

功能说明:订阅 value 变化,自动收到 isPlaying / isBuffering / isCompleted / position / duration 更新。

controller.addListener(() {
  final v = controller.value;
  if (v.isBuffering) print('缓冲中');
  if (v.isCompleted) print('播放完成');
  // 实时刷新 UI
  setState(() {});
});
4.2.5 dispose():资源释放

void dispose() {
  controller.dispose();   // 释放 AVPlayer + Surface
  super.dispose();
}

运行效果(鸿蒙模拟器实测)

v1 初始缓冲
demo 首屏:红色 AppBar + 视频区域(黑底,模拟器无 GPU 加速限制见 FAQ)+ 进度条 0:00/0:12 + "暂停"按钮(初始化后自动起播)+ 循环关按钮 + setVolume 1.00 滑条 + 暗色事件流卡显示 [20:34:39] isBuffering = true(缓冲中) [20:34:40] initialize() 完成:640.0x360.0 @ 12s [20:34:40] play() 自动起播 —— 三个 API 真实调用并捕获

v2 播放完成
12 秒测试视频自动播完:进度条 0:12/0:12 + "播放"按钮(自动停止在末尾)+ 事件流日志累积:isCompleted → 播放完成(事件流) 多次触发(每次 addListener 回调),证明 controller 完整生命周期工作正常

v3 重播 + 循环开启
点击重播按钮后:进度条 0:03/0:12(演示 seekTo)+ "暂停"按钮(重播中)+ “循环开” 按钮(演示 setLooping(true) 生效)+ 事件流新增 setLooping(true) 日志 + 持续的 isBuffering / isCompleted 状态更新 —— 6 个 API 全部触发并可监听

4.3 完整示例代码

完整工程(含 assets/video/demo.mp4 测试视频,由 ffmpeg -f lavfi testsrc 生成 12 秒测试条)已开源(本地路径 /Users/zhubo/Desktop/HarmonyOS-platform-framework-2026-batch2/video_demo/,由用户自行决定上传到 AtomGit)。

核心状态管理模式:

class _VideoPageState extends State<VideoPage> {
  late final VideoPlayerController _controller;

  
  void initState() {
    super.initState();
    _controller = VideoPlayerController.asset('assets/video/demo.mp4');
    _controller.initialize().then((_) {
      setState(() {});  // 触发 UI 刷新,显示视频
      _controller.play();
    });
    _controller.addListener(() {
      final v = _controller.value;
      if (v.isBuffering) log('缓冲中');
      if (v.isCompleted) log('播放完成');
      if (mounted) setState(() {});  // 进度条实时刷新
    });
  }

  
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  // build: AspectRatio + VideoPlayer + Slider(进度条) + play/pause/loop 按钮 + 事件日志卡
}

签名与构建(活动硬性要求 signingConfig: "default"):

flutter create --platforms ohos .
# ohos/build-profile.json5 的 app.signingConfigs 填入 DevEco 自动签名材料
flutter build hap --debug
hdc install build/ohos/hap/entry-default-signed.hap
hdc shell aa start -b com.example.video_demo -a EntryAbility

五、FAQ:使用问题

Q1:编译报 Type 'VideoTrack' not found

原因:未锁 video_player_android / video_player_avfoundation / video_player_platform_interface 到 OH 适配版的同 commit,pub 解析到 pub.dev 最新版的 video_player_android(2.12.x),其 VideoTrack 类型与本版 platform_interface 不兼容。

修法:完整补齐 dependency_overrides 锁四包(见 §4.1)。

Q2:模拟器上视频画面黑屏,但 isBuffering/isCompleted 事件正常

真实限制:DevEco 模拟器(arm64)无 GPU 硬件加速,AVPlayer 解码帧能成功(isBuffering/isCompleted 事件正常触发、分辨率/时长读出正确),但视频帧不会渲染到 Surface——这是模拟器层面限制,真机(含 Pura X View)可正常渲染。

Q3:网络视频需要什么权限?

VideoPlayerController.networkUrl 需要在 example/ohos/src/main/module.json5 声明 ohos.permission.INTERNET(demo 用的资产视频无需)。网络视频格式:OH 原生 AVPlayer 支持 HLS(m3u8)、HTTP MP4/MKV 等;不直接支持 RTMP/RTSP(需通过 NDK 或原生插件)。

Q4:视频不循环播放?

确认调用了 await controller.setLooping(true);如果 value.isCompleted 后没继续播,可能是 OH 端循环逻辑 bug,需手动 addListener 监听后重新 play()

Q5:dispose 后再操作 controller 报 LateInitializationError?

dispose() 后 controller 不可再用——确保 dispose() 只在 StatefulWidget.dispose() 调用,不要在 deactivate() / dispose 之外的 hook 调。

Q6:发现库的问题怎么反馈?

  • 仓库:openharmony-tpc/flutter_packages
  • 提 Issue:四要素(复现 / 期望 / 实际 / 设备系统 + flutter --version + hilog 关键日志 + 视频源 URL/HASH)
  • 提 PR:Fork → 建 fix/... 分支 → 修改 → push → 在 AtomGit 发 PR,描述附鸿蒙真机验证截图(模拟器视频黑屏不算有效验证)

六、其他内容

video_player v2.10.1 鸿蒙适配版开箱即用:federated 五包同 commit 锁住后,VideoPlayerController 全套 API(initialize/play/pause/seekTo/setLooping/setVolume)与 addListener 状态监听全部在鸿蒙侧真实工作。Demo 在 DevEco 模拟器上验证了从初始化(640x360 @ 12s)、自动播放、循环控制、seekTo 跳播到 isBuffering/isCompleted 事件流触发全链路。模拟器无 GPU 加速限制导致视频帧不渲染(这是模拟器层面),真机环境(Pura X View 真机)有完整渲染能力——这是同类模拟器+视频验证时常见的诚实标注点。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐