当前位置:   article > 正文

用video标签流式加载

video标签src路径设定后边播放边加载

video标签

浏览器的video标签通常是接收一个src属性,然后浏览器就会根据这个src属性来自动加载视频。
这个过程是浏览器来加载video的。

这种方式有什么问题吗?

  1. mp4文件不能流式加载
  2. webm,flv,hls等格式兼容性问题
  3. 播放器ui太丑,一些常用的功能都没有
  4. 清晰度切换,等一些操作需要重载视频,比较慢而且还会黑屏
  5. 无法对视频加密

请求video流视频

我们可以通过设置responseType为arraybuffer来获取视频流,也可以通过range字段来获取视频流片段。比如

  1. let xhr = new window.XMLHttpRequest();
  2. xhr.responseType = 'arraybuffer'
  3. xhr.open('get', 'http://www.w3school.com.cn/i/movie.mp4')
  4. xhr.responseType = 'arraybuffer';
  5. // xhr.setRequestHeader('Range', `bytes=0-390625`)
  6. xhr.onload = function () {
  7. if (xhr.status === 200 || xhr.status === 206) {
  8. console.log(xhr.response)
  9. }
  10. }
  11. xhr.send();

或者fetch的arrayBuffer方法返回视频流。

  1. fetch(videoUrl).then(function(response) {
  2. return response.arrayBuffer();
  3. })

获取到的数据是什么呢?二进制的视频流。
获取这个有什么用呢?

video去播“流”

MediaSource

MediaSource简称mse,是h5的一个api,它允许通过js生成媒体流,让浏览器播放。

使用

我们通过 URL.createObjectURL来创建一个blob格式的视频文件,来给video标签播。
具体用法就是new MediaSource,然后根据这个MediaSource生成blob文件,然后向MediaSource中添加mime和视频流。

  1. <div class="a">
  2. <video id="video" controls preload="auto"></video>
  3. </div>
  4. <script>
  5. $(function() {
  6. var video = document.querySelector('#video');
  7. var mediaSource = new MediaSource();
  8. video.src = URL.createObjectURL(mediaSource);
  9. mediaSource.addEventListener('sourceopen', sourceOpen);
  10. function sourceOpen(e) {
  11. URL.revokeObjectURL(video.src);
  12. // 设置 媒体的编码类型
  13. var mime = 'video/webm; codecs="vorbis,vp8"';
  14. var mediaSource = e.target;
  15. var sourceBuffer = mediaSource.addSourceBuffer(mime);
  16. var videoUrl = 'http://localhost:9090/examples/mp4/video.webm';
  17. fetch(videoUrl).then(function(response) {
  18. console.log(response)
  19. return response.arrayBuffer();
  20. })
  21. .then(function(arrayBuffer) {
  22. sourceBuffer.addEventListener('updateend', function(e) {
  23. if (!sourceBuffer.updating && mediaSource.readyState === 'open') {
  24. mediaSource.endOfStream();
  25. // 在数据请求完成后,我们需要调用 endOfStream()。它会改变 MediaSource.readyState 为 ended 并且触发 sourceended 事件。
  26. video.play().then(function() {}).catch(function(err) {
  27. console.log(err)
  28. });
  29. }
  30. });
  31. sourceBuffer.appendBuffer(arrayBuffer);
  32. });
  33. }
  34. })
  35. </script>

我们的mine是什么呢?
video/webm是视频格式,codecs后面第一段是一些视频编解码的一些重要信息,诸如编码方式、分辨率、帧率、码率以及对解码器解码能力的要求。
第二段是关于音频部分的信息。

842714-20180702152427204-940013565.jpg
生成这样的一个video标签。我们现在绕过了浏览器直接去请求src这一步,ajax请求视频流,然后我们可以对视频流进行处理,直接操作视频流实现我们需要的各种功能。
但是对于mp4格式,是不支持流式加载的,所以只能通过我们自己操作流来实现流式播放。

播放器

公司同事研发了一款开源播放器,https://github.com/bytedance/xgplayer ,西瓜视频好几千万dau的产品实测。

播放器原理

它是利用了流式处理视频源,不仅仅是简单的请求流然后交给video标签播放,它是请求视频流然后用js解码然后进行一些需要的操作,交给video播放。

为什么要用js解码呢?

公司大部分视频是mp4,怎么让mp4支持流播放呢?我们把mp4的流拿过来,js解析出它的视频信息,然后js转换成支持视频流的fmp4格式的文件。
它的优势是

  1. 解决了chrome不支持hls格式的问题(还有各种不支持格式的问题),因为我们是直接操作二进制视频数据,所以不存在video标签不支持的情况。
  2. 解决了切换清晰度重新刷新视频的问题
  3. 对于mp4文件快进操作进行最小化的请求加载,让它支持流式加载。
  4. 支持直播和弹幕

我们直接操作的视频流,所以在对视频进行清晰度切换,或者快进的时候,我们后计算当前时间的流,然后用js加载视频的新的流,从而进行最快的加载和响应。

转载于:https://www.cnblogs.com/dh-dh/p/9254172.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/195231
推荐阅读
  

闽ICP备14008679号