查看: 165|回复: 0

鸿蒙 ASCF 元服务视频接口开发:选视频播放控制与后台播放避坑

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在鸿蒙元服务里,视频相关需求越来越多:选视频、拍视频、播放控制、倍速、全屏、后台播放、保存到相册等。项目里原有视频 Demo 只有基础播放/暂停,这次把视频 API 过了一遍,补齐功能并记录踩坑。下面按开发流程整理可落地的 API 用法、参数语义和适配注意点。

选择视频:chooseVideo 与 chooseMedia
只选视频时用 has.chooseVideo。sourceType 支持 album 和 camera,同时传两者会让用户选择;maxDuration 用于拍摄,范围 3 到 60 秒,默认 60;camera 可取 back 或 front。返回 tempFilePath、duration、size、width、height。
  1. has.chooseVideo({
  2.     sourceType: ['album', 'camera'],
  3.     maxDuration: 30,
  4.     camera: 'back',
  5.     success: (res) => {
  6.         console.info('临时路径:', res.tempFilePath);
  7.         console.info('时长:', res.duration);
  8.         console.info('大小:', res.size, 'kB');
  9.         console.info('尺寸:', res.width, 'x', res.height);
  10.     }
  11. });
复制代码
需要图片和视频混选,或需要视频缩略图时,用 has.chooseMedia。
  1. has.chooseMedia({
  2.     count: 1,
  3.     mediaType: ['video'],
  4.     sourceType: ['album'],
  5.     maxDuration: 15,
  6.     success: (res) => {
  7.         const file = res.tempFiles[0];
  8.         console.info('类型:', file.fileType);
  9.         console.info('路径:', file.tempFilePath);
  10.         console.info('时长:', file.duration);
  11.         console.info('缩略图:', file.thumbTempFilePath);
  12.     }
  13. });
复制代码
mediaType 可传 ['image']、['video'] 或 ['image', 'video']。chooseMedia 比 chooseVideo 多返回 thumbTempFilePath,展示视频列表时很有用。选择建议:只选视频优先 chooseVideo,参数更直观;需要混合选择或缩略图再用 chooseMedia。

VideoContext 与播放控制
控制视频前先拿上下文。页面里用 has.createVideoContext('myVideo'),在自定义组件里要传第二个参数 this,该能力从 1.0.16 开始支持,不传可能无法找到正确的 video 实例;Page 场景不需要传。
  1. Component({
  2.     onReady() {
  3.         this.videoCtx = has.createVideoContext('myVideo', this);
  4.     }
  5. });
复制代码
基础控制:play() 播放,pause() 暂停在当前位置,stop() 停止并回到起点。seek(秒) 跳转到指定时间,跳转后不会自动播放,需要再调用 play()。
  1. this.videoCtx.seek(10);
  2. this.videoCtx.play();
复制代码
倍速通过 playbackRate 设置,支持 0.125、0.25、0.5、0.75、1、1.25、1.5、1.75、2。项目里常做循环切换按钮,常用序列是 0.5、0.75、1、1.25、1.5、2。
  1. changeRate() {
  2.     const rates = [0.5, 0.75, 1, 1.25, 1.5, 2];
  3.     let index = (this.data.rateIndex + 1) % rates.length;
  4.     const rate = rates[index];
  5.     this.videoCtx.playbackRate(rate);
  6.     this.setData({ currentRate: rate, rateIndex: index });
  7.     has.showToast({ title: `${rate}x 倍速` });
  8. }
复制代码
全屏控制用 requestFullScreen 和 exitFullScreen。direction 为 0 表示竖屏,90 表示逆时针 90 度横屏,-90 表示顺时针 90 度;不传则根据宽高比自动判断。后台播放用 requestBackgroundPlayback 开启,exitBackgroundPlayback 关闭,但需要额外配置,见后文。

获取信息与保存相册
getVideoInfo 可返回 type、duration、width、height、size、orientation。orientation 有 up、down、left、right 四个值,视频编辑时可用它判断是否需要旋转。
  1. has.getVideoInfo({
  2.     src: videoPath,
  3.     success: (res) => {
  4.         console.info('格式:', res.type);
  5.         console.info('时长:', res.duration, 's');
  6.         console.info('尺寸:', res.width, 'x', res.height);
  7.         console.info('大小:', res.size, 'kB');
  8.         console.info('方向:', res.orientation);
  9.     }
  10. });
复制代码
注意 duration 单位:ASCF 运行时 2.0.1 之前是毫秒,2.0.1 及之后是秒。跨版本运行时需要兼容。
  1. const duration = res.duration > 10000 ? res.duration / 1000 : res.duration;
复制代码
saveVideoToPhotosAlbum 用于保存到相册,filePath 只能是本地路径,不支持网络路径,网络视频要先下载;保存时会弹出系统确认弹窗。
  1. has.saveVideoToPhotosAlbum({
  2.     filePath: 'internal://tmp/video.mp4',
  3.     success: () => {
  4.         has.showToast({ title: '保存成功' });
  5.     },
  6.     fail: (err) => {
  7.         console.error('保存失败:', err);
  8.     }
  9. });
复制代码
另外,chooseVideo 返回的 tempFilePath 是临时路径,应用重启后可能失效。需要长期保存时,应调用 saveVideoToPhotosAlbum,或用文件 API 拷贝。

典型场景
视频选择、预览、上传:chooseVideo 成功后先设置 videoPath,再调用 getVideoInfo 获取信息,最后上传服务器。自定义播放器控件:维护 isPlaying、currentRate、currentTime,togglePlay 控制播放暂停,seekForward 和 seekBackward 做快进快退,onTimeUpdate 更新当前时间。课程后台播放:onShow 时 requestBackgroundPlayback,onHide 时按业务决定是否继续,onUnload 时 exitBackgroundPlayback。
  1. onReady() {
  2.     this.videoCtx = has.createVideoContext('courseVideo');
  3. },
  4. onShow() {
  5.     this.videoCtx.requestBackgroundPlayback();
  6. },
  7. onUnload() {
  8.     this.videoCtx.exitBackgroundPlayback();
  9. }
复制代码

踩坑与修复
后台播放不是调用 requestBackgroundPlayback 就能生效,需要三步配置,缺一不可。第一步,在 module.json5 的 requestPermissions 中声明 ohos.permission.KEEP_BACKGROUND_RUNNING;第二步,在 module.json5 的 abilities 中增加 backgroundModes,值为 ['audioPlayback'];第三步,在 app.json 中增加 requiredBackgroundModes,值为 ['audio']。只加权限、不配 backgroundModes 时,调用没报错但也没效果。

duration 单位变化是另一个坑:chooseVideo 和 getVideoInfo 返回的 duration 在 ASCF 运行时 2.0.1 前后不同,之前是毫秒,之后是秒,不做兼容可能差 1000 倍。

chooseVideo 返回临时路径、saveVideoToPhotosAlbum 不支持网络路径、createVideoContext 在自定义组件中要传 this、seek 后不会自动播放,这些都是实际开发中容易忽略的点。

Demo 与结论
项目中新建了完整的视频 API Demo,入口在“接口”->“媒体”->“视频API”。Demo 覆盖选择/拍摄视频(chooseVideo 和 chooseMedia)、播放/暂停/停止、跳转指定时间、循环切换倍速(0.5x 到 2x)、进入/退出全屏、开启/关闭后台播放、获取视频详细信息、保存视频到相册。

实际常用的仍是 chooseVideo 选视频、play/pause/seek 控制播放、playbackRate 倍速、requestFullScreen 全屏。后台播放配置较麻烦,但三步都配好即可。chooseMedia 和 chooseVideo 之间,建议优先 chooseVideo,参数和返回值更直接;只有需要图片加视频混合选择时,再用 chooseMedia。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-9-30 11:27 , Processed in 0.022341 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部