这种播放内核用于支持h.265编码的视频播放。

目前,浏览器主流支持的还是h.264+AAC的音视频编码,而h.265编码基于专利等方面原因,在不少浏览器不支持,例如市场份额巨大的桌面chrome就不支持。为了解决这一问题。我们在本播放内核中借助webassemblyffmpeg实现了h.265播放。

注意

源于ffmpeg强大的解码和播放能力,本播放内核的full模式实际上也支持全格式播放(市面上各种常见编码和视频容器)

# 必读

需要说明的是,webassembly应用属于前端比较新兴的技术,会带来一些限制。因此wasm内核的使用有以下注意事项:

# 1. 兼容性

wasm内核依赖window.webassemblywindow.SharedArrayBuffer接口,鉴于浏览器的兼容性本内核主要兼容桌面chrome播放h.265编码的视频。safari等原生支持h.265播放的浏览器建议使用原生播放内核。

# 2. 性能:

由于ffmpeg在浏览器完全软解视频的原因,wasm内核播放视频的性能比浏览器原生解码性能要差。不过我们已经将解码性能做到业界最好,而且在持续关注webassembly相关性能优化中。

下表给出了使用wasm内核播放时cpu消耗的参考值,可以看出相对于原生播放需要消耗大量cpu资源进行视频软解。但这不代表播放器播放视频帧率跟不上(画面无卡顿)。

清晰度 cpu消耗 每帧解码
720P 约50% 6ms
1080P 约80% 11ms

测试机器

CPU: Intel i7-8750H (12) @ 2.20GHz
GPU: Intel UHD Graphics 630, Radeon Pro 555X

# 3. 播放https视频

wasm内核的runtime依赖window.SharedArrayBuffer接口,但chrome浏览器基于安全考虑对此接口有一定限制。目前wasm内核在chrome注册了token (opens new window)来解决此问题(并且目前来看chrome给的token期限是2022年7月27日),但仅能使用https域名注册token,因此视频播放所在页面和视频cdn地址也都需要是https的!

# 4. 内核文件大小(gzip后)

播放模式 文件大小
min 约950KB
full 约4.2MB

注意

wasm内核文件做了本地强缓存(indexdb),第一次需要从网络加载内核文件,后面会缓存直接获取二进制文件

# 使用

在thumbplayer-core中,我们可以按如下方式播放h.265视频:

import SuperPlayer from "@tencent/super-player";
import '@tencent/thumbplayer-kernel-wasm';

const player = new SuperPlayer({
  container: '.container',
});

player.play({
  // 播放hls视频
  url: 'https://sec.video.qq.com/p/teststatic.video/static/playtest/hls/hls_definition_source/hls_hevc_480_270.m3u8',
  // 或者是mp4视频
  // url: 'https://sec.video.qq.com/p/teststatic.video/static/playtest/mp4/hevc_heaac_moov_before_1280_720.mp4',
  kernelName: 'wasm',
});

# 配置项(非必须)

const player = KernelFactory.create({
  container: '.container',
  // 增加wasm播放内核配置
  wasmKernelConfig: {
    // 使用wasm播放内核的full模式,支持的视频格式更多,但首次加载的webassembly文件更大
    featType: 'full',
  }, 
});

wasm播放内核常见配置项如下:

字段名 类型 说明
featType 'min'或'full' 使用哪种功能类型,min仅支持hevc播放,full支持全格式
captureEnabled 0或1 是否开启截图功能(基于webgl性能考虑,如无截图需求,请勿打开)
captureType 'dataUrl'或'imageData' 截图返回的数据格式

# 截图demo

wasm播放内核提供了截图功能,下面是简单的调用截图接口并使用canvas展示的demo

// 用于接受截图数据并展示的canvas对象
const capShowCanvas = document.querySelector('.capture-show');
// 点击按钮开始对播放器画面截图
document.querySelector('.capture-btn').addEventListener('click', () => {
  if (typeof player.captureVideo !== 'function') {
    return;
  }
  // 截取播放器画面top=0,left=0,width=100,height=100的区域
  const arr = [0, 0, 100, 100];
  player.captureVideo(...arr)
    .then((data) => {
      console.log('captureVideo, data=', data);
      if (!data.data) {
        return;
      }

      capShowCanvas.width = data.captureWidth;
      capShowCanvas.height = data.captureHeight;
      capShowCanvas.getContext('2d').putImageData(data.data, 0, 0, 0, 0, data.captureWidth, data.captureHeight);
      // 如果需要缩放画面,使用canvas的css属性
      // capShowCanvas.style.width = '500px';
      // capShowCanvas.style.height = '350px';
    })
    .catch((err) => {
      console.log('captureVideo, err=', err);
    });
});
上次更新: 4/13/2022, 2:39:50 PM