鸿蒙开发进阶(HarmonyOS )基于XComponent的视频播放器高性能体验

  鸿蒙NEXT开发实战往期必看文章:

一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!

“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零基础入门到精通)

HarmonyOS NEXT应用开发案例实践总结合(持续更新......)

HarmonyOS NEXT应用开发性能优化实践总结(持续更新......)


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

方案

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。

核心代码

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

<span style="color:#333333"><span style="background-color:#ffffff"><span style="background-color:#fdfdfd"><span style="color:#000000"><code class="language-plain">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; 
  }); 
}</code></span></span></span></span>

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

<span style="color:#333333"><span style="background-color:#ffffff"><span style="background-color:#fdfdfd"><span style="color:#000000"><code class="language-plain">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; 
      } 
    } 
  } 
};</code></span></span></span></span>

配置AVPlayer的datasrc属性。

<span style="color:#333333"><span style="background-color:#ffffff"><span style="background-color:#fdfdfd"><span style="color:#000000"><code class="language-plain">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;</code></span></span></span></span>

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

如果你想在鸿蒙开发视频播放器中设置返回停止播放按钮,你可以按照以下步骤进行: 1. 在布局文件中添加返回停止播放按钮。 ``` <ohos.agp.components.ComponentGroup ohos:id="$+id:media_control" ohos:height="match_parent" ohos:width="match_parent" ohos:background_element="#80000000"> <ohos.agp.components.Text ohos:id="$+id:back_button" ohos:width="wrap_content" ohos:height="wrap_content" ohos:text="返回" ohos:text_size="20fp" ohos:text_color="#ffffff"/> <ohos.agp.components.Text ohos:id="$+id:stop_button" ohos:width="wrap_content" ohos:height="wrap_content" ohos:text="停止" ohos:text_size="20fp" ohos:text_color="#ffffff"/> </ohos.agp.components.ComponentGroup> ``` 2. 在代码中获取返回停止播放按钮,并为它们设置点击事件。 ``` Component backBtn = findComponentById(ResourceTable.Id_back_button); backBtn.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { // 返回操作 } }); Component stopBtn = findComponentById(ResourceTable.Id_stop_button); stopBtn.setClickedListener(new Component.ClickedListener() { @Override public void onClick(Component component) { // 停止播放操作 } }); ``` 3. 在视频播放的相关方法中,添加返回停止播放的逻辑。 ``` private void playVideo() { // 播放视频操作 } private void stopVideo() { // 停止视频播放操作 } private void back() { // 返回操作 } private void startMedia() { // 启动媒体播放器 playVideo(); } private void stopMedia() { // 关闭媒体播放器 stopVideo(); } @Override public void onStop() { super.onStop(); stopMedia(); } @Override public void onClick(Component component) { switch (component.getId()) { case ResourceTable.Id_back_button: back(); break; case ResourceTable.Id_stop_button: stopMedia(); break; default: break; } } ``` 通过以上步骤,你就可以在鸿蒙开发视频播放器中设置返回停止播放按钮了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值