鸿蒙 音视频边播放边缓存

MediaCache for HarmonyOS

用于支持鸿蒙平台的音视频边播放边缓存(mp3、mp4、m3u8等); 旨在代理媒体数据请求并优先提供缓存数据, 从而减少网络流量并提高播放流畅度.


主要特性
  • 边播放边缓存支持以下两种类型的远程资源:
    • 基于文件的媒体,例如 MP3、AAC、WAV、FLAC、OGG、MP4 和 MOV 等常见格式;
    • HTTP Live Streaming 或者叫 m3u8; 在播放时通常会自动代理播放列表中的各个媒体片段;
  • 支持预缓存/预加载, 可缓存指定大小的数据或全部数据;
  • 支持数据加解密, 保存数据时加密, 读取数据时解密;
  • 支持导出, 将媒体数据导出到指定的目录;

安装
shell 复制代码
ohpm i @sj/mediacache

在项目中引用

请在需要依赖的模块找到 oh-package.json5 文件, 新增如下依赖, 执行同步后等待安装完成;

json 复制代码
{
  "dependencies": {
    "@sj/mediacache": "^1.0.8"
  }
}

初始化

在开始代理请求之前, 请通过以下方法进行初始化工作以启动代理服务器等;

ts 复制代码
await MCMediaCache.prepare(getContext());

播放

播放时需要通过代理地址进行播放; 所以在播放之前请使用该方法生成代理地址, 然后设置给播放器播放即可实现边播放边缓存:

ts 复制代码
// 原始地址
const resUrl = 'http://www.example.com/video.mp4';
// 代理地址
const proxyUrl = await MCMediaCache.proxy(resUrl);

// 设置播放; 这里以 AVPlayer 为例, 直接设置代理地址播放即可实现边播放边缓存;
const player: media.AVPlayer;
player.url = proxyUrl;

预缓存
  • 预先缓存指定大小的数据:

    ts 复制代码
    // 直接使用原始地址进行预缓存即可;
    MCMediaCache.prefetch(resUrl, {
      prefetchSize: 5 * 1024 * 1024, // 假设预缓存5M
      onProgress: (progress) => console.log(`[progress] ${progress}`)
    });
  • 预先缓存指定数量的媒体片段: 这个配置主要用于流媒体(HLS), 因为它的播放列表(playlist)中通常包含多个段(ts)文件, 通过以下配置来指定需要预缓存的文件数;

    ts 复制代码
    // 直接使用原始地址进行预缓存即可;
    MCMediaCache.prefetch(resUrl, {
      prefetchSegmentCount: 1, // 假设预缓存1个片段
      onProgress: (progress) => console.log(`[progress] ${progress}`)
    });

导出数据
  • 导出: 导出媒体数据到指定目录, 导出过程中如果媒体数据仅存在部分缓存, 则会发起网络请求获取剩余数据, 如果缓存都已存在, 则不会请求网络;

    ts 复制代码
    const ctx = this.getUIContext().getHostContext()!;
    const targetDir = ctx.filesDir + '/my_exports/video1'; // 导出目录
    const resUrl = 'http://www.example.com/video.mp4'; // 要导出的视频
    
    // 开始导出
    MCMediaCache.exportToDirectory(resUrl, targetDir, {
      conflictStrategy: MCCopyFileConflictStrategy.Overwrite,
      onProgress: (progress) => {
        console.log(`[export progress] ${progress}`);
      }
    }).then(() => {
        console.log(`导出成功`);
    }).catch((e: Error) => {
      console.log(`导出失败: ${e.message}`);
    });
  • 播放: 播放导出的媒体数据, 通过代理指定目录使用返回的代理地址进行播放;

    ts 复制代码
    // 代理指定目录进行播放, 返回代理地址;
    // 当通过 exportToDirectory 导出媒体数据后, 可使用该接口生成代理地址进行播放;
    const ctx = this.getUIContext().getHostContext()!;
    const targetDir = ctx.filesDir + '/my_exports/video1'; // 导出目录
    
    // 获取代理地址
    const proxyUrl = await MCMediaCache.proxyDir(targetDir);
    
    // 设置播放; 这里以 AVPlayer 为例, 直接设置代理地址播放即可;
    const player: media.AVPlayer;
    player.url = proxyUrl;

其他配置
  • 配置请求头: 发起请求前回调, 可以在回调中修改请求, 添加请求头, cookies等;

    ts 复制代码
    MCMediaCache.setRequestHandler((request) => {
      request.setHeader('key', 'value');
    });
  • 数据加密: 保存数据时加密; 缓存数据写入到文件时回调, 你可以对数据进行一些加密处理;

    ts 复制代码
    MCMediaCache.setDataEncryptHandler(async (resUrl, dataOffset, data) => {
      // xxx
    });
  • 数据解密: 读取数据时解密; 读取数据时回调, 如果原数据被加密但是播放时需要解密, 你可以在该回调中进行解密处理;

    ts 复制代码
    MCMediaCache.setDataDecryptHandler(async (resUrl, dataOffset, data) => {
      // xxx
    });
  • 缓存标识处理: 由于相同的标识将引用同一份缓存, 当出现多个地址指向同一个视频, 例如 url 可能带有鉴权之类的参数, 这部分很容易发生变化, 但这些地址都指向同一个视频, 为了确保只缓存一份视频, 你可以在这里将这些会变化的参数移除;

    ts 复制代码
    MCMediaCache.setAssetIdentifierPreprocessor(async (resUrl) => {
      const resUrl = 'http://www.example.com/video.mp4?token=xxx';
      const index = resUrl.indexOf('?');
      return index !== -1 ? resUrl.slice(0, index) : resUrl;
    });
  • 缓存管理:

    • 个数限制: 可以配置缓存个数, 超过限制时将会自动删除旧的缓存:

      ts 复制代码
      // 缓存个数限制: 0 表示不限制;
      MCMediaCache.cacheConfig.countLimit = 0;
    • 保存时长限制(单位: 毫秒): 超过限制自动删除;

      ts 复制代码
      // 保存时长限制(单位: 毫秒): 0 表示不限制;
      MCMediaCache.cacheConfig.maxAge = 0;
    • 所有缓存能够占用的磁盘大小(单位: 字节): 超过限制时将会自动删除旧的缓存;

      ts 复制代码
      // 磁盘空间限制(单位: 字节): 0 表示不限制;
      MCMediaCache.cacheConfig.maxDiskSize = 0;
    • 磁盘空间预警阈值(单位: 字节): 当磁盘剩余空间不足小于预警阈值时将会自动删除旧的缓存:

      ts 复制代码
      // 磁盘空间预警阈值(单位: 字节): 0 表示不限制;
      MCMediaCache.cacheConfig.diskSpaceWarningThreshold = 0;
  • 配置控制台日志:

    ts 复制代码
    MCMediaCache.setLogEnabled(BuildProfile.DEBUG); // 是否开启日志;
    MCMediaCache.setLogLevel(MCLogLevel.DEBUG); // 设置日志等级;
    MCMediaCache.setLogWhiteModules([MCLogModule.MCHttpConnectionHandler, MCLogModule.MCHttpResponse]) // 允许打印哪些模块的日志;

项目地址

问题反馈

Q群: 1053841673

相关推荐
奶糖不太甜28 分钟前
鸿蒙图片资源加载全攻略:从基础到性能优化
harmonyos·图片资源
小小小小小星33 分钟前
鸿蒙多端适配开发指南:从入门到实战
harmonyos
鸿蒙小灰1 小时前
鸿蒙开发之仿抖音APP教程:方法论与技术探索
harmonyos
CC__xy1 小时前
04 类型别名type + 检测数据类型(typeof+instanceof) + 空安全+剩余和展开(运算符 ...)简单类型和复杂类型 + 模块化
开发语言·javascript·harmonyos·鸿蒙
鸿蒙先行者1 小时前
鸿蒙开发ArkUI框架布局与适配难题丛生之响应式布局实现艰难
harmonyos·arkui
ajassi20002 小时前
开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载
华为·开源·harmonyos
前端世界2 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
网络·华为·harmonyos
Georgewu6 小时前
【HarmonyOS】应用调用相机功能(扫码,自定义相机,人脸活体检测等)显示黑屏
harmonyos
文博知浅7 小时前
时隔4个月,500+star,鸿蒙ArkTS vscode插件1.x已发布🎉完全重构,补全、类型提示、SDK下载管理切换一应俱全,更多新功能正在规划中...
前端·javascript·harmonyos