HarmonyOS 实战开发 —— 基于XComponent的视频播放器高性能体验


📚往期笔录记录🔖:

🔖鸿蒙(HarmonyOS)北向开发知识点记录~
🔖鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
🔖鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
🔖嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
🔖对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
🔖鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
🔖记录一场鸿蒙开发岗位面试经历~
🔖持续更新中……


场景一:视频播放预加载,边下边播

方案

  1. 创建一个沙箱文件,并获取沙箱文件的readFd和writeFd。
  2. 通过.new rcp.Request(DOWNLOAD_URL)创建网络下载请求request,配置request的TracingConfiguration,在onDataReceive回调中通过fs.writeSync传入沙箱文件的writeFd,将下载的数据流写入本地沙箱文件,将fs.writeSync返回写入字节大小作为网络下载大小downloadSize,根据downloadSize和下载大小(默认1024*1024字节,AVPlayer默认缓存为1M)配置request的transferRange属性,控制网络下载的起始字节和结束字节。
  3. 通过RCP的session.fetch传入request下载获取网络视频资源。
  4. 配置AVPlayer的datasrc属性,在datasrc的回调函数中,通过fs.readSync传入沙箱文件的readFd,将沙箱文件的数据写入内存buffer,沙箱文件大小为0时开启网络下载,当pos(表示填写的数据在资源文件中的位置)小于沙箱文件100kb时,再次开启网络下载进而实现分段下载,该回调函数在AVPlayer解析数据时触发,在边下边播的场景中,会不断触发该回调。
  5. 设置AVPlayer播放资源,将datasrc设置给AVPlayer。

核心代码

控制网络下载的起始字节和结束字节。

function download(length: number) {
  console.info('MineRcp download from = ' + downloadSize + 'to =  ' + (downloadSize + length - 1));
  request.transferRange = {
    from: downloadSize,
    to: downloadSize + length - 1,
  };
  downloadStarted = true;
  session.fetch(request).then(() => {
    downloadStarted = false;
  }).catch(() => {
    downloadStarted = false;
  });
}

onDataReceive回调中通过fs.writeSync传入沙箱文件的writeFd,将下载的数据流写入本地沙箱文件。

request.configuration = {
  tracing: {
    httpEventsHandler: {
      onDataReceive: (incomingData: ArrayBuffer) => {
        const writeLength = fs.writeSync(this.writeFd, GetDecodedBuffer(incomingData));
        downloadSize += writeLength;
        console.info('MineRcp recieve Length = ' + writeLength.toString() + " , recieve = " + downloadSize);
        return incomingData.byteLength;
      }
    }
  }
};

配置AVPlayer的datasrc属性。

let src: media.AVDataSrcDescriptor = {
  fileSize: -1,
  callback: (buf: ArrayBuffer, length: number, pos?: number) => {
    // buffer,ArrayBuffer类型,表示被填写的内存,必选。
    //
    // - length,number类型,表示被填写内存的最大长度,必选。
    //
    // - pos,number类型,表示填写的数据在资源文件中的位置,可选,当fileSize设置为-1时,该参数禁止被使用。
    // - 返回值,number类型,返回要填充数据的长度。
    let num = 0;
    if (buf === undefined || length === undefined) {
      return -1;
    }
 
    num = fs.readSync(this.readFd, buf);
    console.info('MineRcp cacheBuffer after checkBuffer Length = ' + num.toString() + ', pos: ' + pos +
      ', downloadSize: ' +
      downloadSize);
    if (num > 0) {
      if (pos != undefined && downloadSize - pos < 100 * 1024) {
        console.info('MineRcp data not enough, download more');
        let downloadLength = 1024 * 1024;
        if (this.fileSize - downloadSize <= downloadLength) {
          downloadLength = this.fileSize - downloadSize;
        }
        if (!downloadStarted) {
          download(downloadLength);
        }
      }
      return num;
    }
 
    if (num === 0) {
      console.info('MineRcp no data read, download more');
      if (!downloadStarted) {
        let downloadLength = 1024 * 1024;
        if (this.fileSize - downloadSize <= downloadLength) {
          downloadLength = this.fileSize - downloadSize;
        }
        download(downloadLength);
      }
      return 0;
    }
 
    return -1;
  }
}
src.fileSize = this.fileSize;
this.isSeek = false; // 支持seek操作
this.player.dataSrc = src;

场景二:同一页面内视频播放横竖屏全屏切换无缝转场

方案

设置竖屏和全屏两个按钮,分别添加点击事件。

  1. 首先设置窗口方向,通过window的setPreferredOrientation接口来设置屏幕方向,接口文档: setPreferredO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值