千呼万唤始进去,在OpenHarmony最新公布的3.1版本中终于反对了surface+videoplayer实现视频播放的性能。

  1. surface+videoplayer视频播放与传统的video组件比照
    大家可能感觉不是很早就反对一个video组件就能够实现视频播放吗?是的,video组件也就简简单单能做个视频播放,而你认真去查阅下,video组件反对的api性能太少了,很多定制化性能都无奈实现。上面是3.1版本上video组件所具备的api:

    OpenHarmony3.1新个性-surface+videoplayer实现视频播放-开源根底软件社区
    而在3.1中增加了一个要害组件就是xcomponent,它能够设置一个type为surface,而我更关怀的就是这个surface,在讲surface之前我先讲讲videoplayer。

3.1版本中同时还新增了视频播放的媒体服务videoplayer,它为咱们提供了视频播放服务相干的各种api,video组件所具备的性能它全副具备,同时还具备视频首帧送显上报事件、监听视频播放宽高变动事件、监听视频缓存更新事件等等高级性能,这样就能够帮忙咱们自定义出十分高级的视频播放器进去了。

而videoplayer它只是个做视频播放的媒体服务,它并不能间接项video组件那样输入视频显示在显示器上,这个时候就须要借助surface了。Surface能够简略的了解为绘制时用的画布,在hml布局文件中增加一个xcomponent组件并设置type为surface,就相当于搁置了一块画布。而surface在程序中能够形象为一块内存,在js代码中xcomponent组件通过调用getXComponentSurfaceId()办法能够申请这块内存,而后就能够随便的绘制,videoplayer在实现视频的编解码服务之后,能够通过调用setDisplaySurface这个办法将视频内容输入到之前的surface内存中,从而达到最终视频在窗口上显示的性能。下图是根本架构图

OpenHarmony3.1新个性-surface+videoplayer实现视频播放-开源根底软件社区

  1. surface+videoplayer视频播放代码实现
    上面只实现一个最根底的视频播放性能。

首先是编写hml布局文件,代码如下:

<div class="container">    <xcomponent id="Xcomponent" type='surface' onload='LoadXcomponent'                style="width : 400px; height : 200px; border-color : red; border-width : 5px;"></xcomponent></div>

而后编写js文件,代码如下:

import media from '@ohos.multimedia.media'import fileIO from '@ohos.fileio'let videoPlayer = undefined;let surfaceID = undefined; // 用于保留Xcomponent接口返回的surfaceIDexport default {    data: {        title: ""    },    onInit() {    },    // 调用Xcomponent的接口用于获取surfaceID,并保留在surfaceID变量中,该接口由XComponent组件默认加载,非被动调用    async LoadXcomponent() {        surfaceID = this.$element('Xcomponent').getXComponentSurfaceId();        console.info('LoadXcomponent surfaceID is' + surfaceID);        // 用户抉择视频设置fd(本地播放)        let fdPath = 'fd://';        // path门路的码流可通过"hdc file send D:\xxx\01.mp3 /data/accounts/account_0/appdata" 命令,将其推送到设施上        let path = '/data/accounts/account_0/appdata/1.mp4';        await fileIO.open(path).then(fdNumber => {            fdPath = fdPath + '' + fdNumber;            console.info('open fd sucess fd is' + fdPath);        }, err => {            console.info('open fd failed err is' + err);        });        await media.createVideoPlayer().then((video) => {            if (typeof (video) != 'undefined') {                videoPlayer = video;                console.info('video createVideoPlayer success');            } else {                console.info('video createVideoPlayer fail');            }        }).catch((error) => {            console.info(`video catchCallback, error:${error.message}`);        });        videoPlayer.url = fdPath;        console.info('video url success');        // 设置surfaceID用于显示视频画面        await videoPlayer.setDisplaySurface(surfaceID).then(() => {            console.info('setDisplaySurface success');        }).catch((error) => {            console.info(`video catchCallback, error:${error.message}`);        });        // 调用prepare实现播放前筹备工作        await videoPlayer.prepare().then(() => {            console.info('prepare success');        }).catch((error) => {            console.info(`video catchCallback, error:${error.message}`);        });        // 调用play开始播放        await videoPlayer.play().then(() => {            console.info('play success');        }).catch((error) => {            console.info(`video catchCallback, error:${error.message}`);        });    },}