ribbon image search rewind fast-forward speech-bubble pie-graph star

谷歌开源 H5 流媒体播放器 shaka-player 初探

近些年,随着抖音或者快手大火,视频也成了前端比较热衷的领域,无论是最早的直播,还是现在的短视频,我们都离不开 Video ,我们也需要一个足够健壮的 HTML5 播放器来进行视频内容的播放。

Shaka Player 是 谷歌公司对外开源的一款 JavaScript 类库:

Shaka Player is an open-source JavaScript library for adaptive media. It plays adaptive media formats (such as DASH and HLS) in a browser, without using plugins or Flash. Instead, Shaka Player uses the open web standards MediaSource Extensions and Encrypted Media Extensions.

它支持在浏览器播放 Dash 或者 HLS 协议的媒体服务,它还可以支持离线存储(借助 indexDB)。他是基于 MSE, Media Source Extensions 以及 EME, Encrypted Media Extensions 来实现;

由于这些新特性,国内用户在使用的时候还是需要考虑浏览器的兼容性取舍;

开始使用

我们可以使用 NPM 或者 外链引入 CDN 脚本。

npm install shaka-player --save  

或者借助 cdn.js

<script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/2.3.2/shaka-player.compiled.js"></script>  

编辑我们的 html 页面,引入 cdn 脚本后,在页面中加入 video 元素;

<video id="video"  
           poster="//shaka-player-demo.appspot.com/assets/poster.jpg"
           controls autoplay></video>

接下来我们在 </body> 前添加这段脚本;

var manifestUri = '//storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd';

function initApp() {  
  // Install built-in polyfills to patch browser incompatibilities.
  shaka.polyfill.installAll();

  // Check to see if the browser supports the basic APIs Shaka needs.
  if (shaka.Player.isBrowserSupported()) {
    // Everything looks good!
    initPlayer();
  } else {
    // This browser does not have the minimum set of APIs we need.
    console.error('Browser not supported!');
  }
}

function initPlayer() {  
  // Create a Player instance.
  var video = document.getElementById('video');
  var player = new shaka.Player(video);

  // Attach player to the window to make it easy to access in the JS console.
  window.player = player;

  // Listen for error events.
  player.addEventListener('error', onErrorEvent);

  // Try to load a manifest.
  // This is an asynchronous process.
  player.load(manifestUri).then(function() {
    // This runs if the asynchronous load is successful.
    console.log('The video has now been loaded!');
  }).catch(onError);  // onError is executed if the asynchronous load fails.
}

function onErrorEvent(event) {  
  // Extract the shaka.util.Error object from the event.
  onError(event.detail);
}

function onError(error) {  
  // Log the error.
  console.error('Error code', error.code, 'object', error);
}

document.addEventListener('DOMContentLoaded', initApp);  

在使用过程中也发现了一些问题,如图作者的回复,目前对 HLS 支持还有稍许 bug ,不过这些问题都会被解决掉。

网络配置

shake-player 提供了较为详细的网络配置,因为我们可能在流媒体的使用过程需要对 manifest, license 以及 分片进行请求,不同请求我们的策略或许不一样;框架提供了三组配置:

  • drm.retryParameters(license);
  • manifest.retryParameters (manifest);
  • streaming.retryParameters

我们可以设置 retryParameters 来进行错误重试的配置。

retryParameters: {  
  timeout: 0,       // timeout in ms, after which we abort a request; 0 means never
  maxAttempts: 2,   // the maximum number of requests before we fail
  baseDelay: 1000,  // the base delay in ms between retries
  backoffFactor: 2, // the multiplicative backoff factor between retries
  fuzzFactor: 0.5,  // the fuzz factor to apply to each retry delay
}

架构设计

官方也同步给出了 shaka-player 的架构设计图;

其中第一幅图大概也是现在流行的播放器数据流程,如果你要写自己的播放器,可以参考下图1;

最后,如果你希望使用稳定的播放器和更好的兼容性,我们还是推荐使用 video.js,如果希望支持流媒体比如 dash 或者 m3u8 ,hls.js。如果你希望了解 youtube 的方案,你可以阅读源码。

You Can Speak "Hi" to Me in Those Ways