V7投稿 |【杨宗宝】微信小游戏如何将视频显示在3D/2D节点上

写在前边

share
宗宝的独立游戏【穿越奇迹】现已上线:

  • Cocos插件,
  • 微信小游戏,
  • 抖音小游戏,
  • 头条小游戏,
  • TapTap平台。

    大家可以搜索游戏名称:穿越奇迹 进行游戏体验。欢迎大家为游戏提出宝贵的意见

正文

1111

1.重要API

VideoDecoder

VideoDecoder 视频解码器,可以进行视频解码相关操作,逐帧获取解码数据

在微信小游戏中,我们如果想实时获取视频内容,并将其进行渲染显示,我们使用最重要的一个API就是微信提供的视频解码器,使用此接口对视频进行播放,并且通过实时刷新获取每帧的视频数据,再使用Cocos的接口将视频数据渲染到指定的Texture2D上。

MediaAudioPlayer

媒体音频播放器对象 MediaAudioPlayer 对象,可用于播放视频解码器 VideoDecoder 输出的音频。

在使用视频解码器进行视频播放的时候,其只对视频的画面内容进行了输出,并不包含音频输出,所以我们需要使用MediaAudioPlayer去单独播放音频,并与视频的内容保持同步。

2.实现原理

1.创建texture

  • 首先我们通过Cocos API创建一个用于纹理,用来作为视频内容渲染的载体
protected resetTexture(): void {
  if (this._texture) {
      this._texture.destroy();
  }
  const numChannels = 4;
  const view = new Uint8Array(this._size.width * this._size.height * numChannels);
  const imageSource = {
      width: this._size.width,
      height: this._size.height,
      _data: view,
      _compressed: false,
      format: Texture2D.PixelFormat.RGBA8888,
  };
  const texture = new Texture2D();
  const imgAsset = new ImageAsset(imageSource);
  texture.image = imgAsset;
  texture._uuid = 'black-texture';
  this._texture = texture;
}

2.获取本地视频路径

  • 在Cocos中,视频默认是以VideoClip类型存在,所以我们可以通过VideoClip的nativeUrl 来获取视频资源的本地路径
this._url=this._videoClip ? this._videoClip.nativeUrl : null

3.创建视频解码器,进行视频播放

this._video = wx.createVideoDecoder();
this._video.start({ source: this._url, mode: 0 }).then((data: any) => {
  this._video.seek(0).then((arg: any) => {
    console.log('seek then', arg);
  }).catch((err: any) => {
    console.log('seek catch', err);
  });
  }).catch((err: any) => {
  console.log('start catch', err);
});

4.帧刷新获取视频内容,显示到Texture2D上

  • 固定帧率获取视频播放数据
public updateTexture(): void {
  let data = this._video.getFrameData();
  if (data) {
      // console.log(data);
      this._time = data.pts;  //视频播放当前进度 ms
      let imageDataArray = new Uint8ClampedArray(data.data);
      this.texture.uploadData(imageDataArray);
  }
}

自此我们就已经实现了基础的视频播放,并且将其显示到Texture纹理上

5.同步音频播放

  • 创建音频播放器对象
this._audio = wx.createMediaAudioPlayer();
  • 同步音频播放
this._video.start({ source: this._url, mode: 0 }).then((data: any) => {
  this.size = new Size(data.width, data.height);
  this.resetTexture();
   this._audio.start().then(() => {
        //将视频解码器实例。作为音频源添加到音频播放器中
        this._audio.addAudioSource(this._video).then(() => {
        });
    });
    this._video.seek(0).then((arg: any) => {
        console.log('seek then', arg);
    }).catch((err: any) => {
        console.log('seek catch', err);
    });
}).catch((err: any) => {
    console.log('start catch', err);
});

3.项目使用

在实际项目中,视频的播放并不会这么单一,我们会需要常规播放器都含有的功能,

public play(): void {
    ....
}
public pause(): void {
    ....
}
public stop(): void {
    ....
}
public replay(): void {
    ....
}

有了上边实现原理,更加复杂的功能封装大家都可以更具自己的理解自行封装。

写在最后

当前除了微信小游戏,宗宝的游戏:【穿越奇迹】还兼容了抖音小游戏,以及android原生平台的视频播放功能,感兴趣的可以到商城入手咱们游戏源码进行了解,现已开启限时优惠

4赞

大佬牛啊,沙发

1赞

大佬高产啊

文章写好好长时间了,只是一直没来得及发 :joy: