html5用video标签流式加载的实现

所属分类: 网页制作 / html5 阅读数: 469
收藏 0 赞 0 分享

video标签

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

这种方式有什么问题吗?

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

请求video流视频

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

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

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

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

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

video去播“流”

MediaSource

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

使用

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

<div class="a">
        <video id="video" controls preload="auto"></video>
    </div>
    <script>
        $(function() {
            var video = document.querySelector('#video');
            var mediaSource = new MediaSource();
            video.src = URL.createObjectURL(mediaSource);
            mediaSource.addEventListener('sourceopen', sourceOpen);

            function sourceOpen(e) {
                URL.revokeObjectURL(video.src);
                // 设置 媒体的编码类型
                var mime = 'video/webm; codecs="vorbis,vp8"';
                var mediaSource = e.target;
                var sourceBuffer = mediaSource.addSourceBuffer(mime);
                var videoUrl = 'http://localhost:9090/examples/mp4/video.webm';
                fetch(videoUrl).then(function(response) {
                        console.log(response)
                        return response.arrayBuffer();
                    })
                    .then(function(arrayBuffer) {
                        sourceBuffer.addEventListener('updateend', function(e) {
                            if (!sourceBuffer.updating && mediaSource.readyState === 'open') {
                                mediaSource.endOfStream();
                                // 在数据请求完成后,我们需要调用 endOfStream()。它会改变 MediaSource.readyState 为 ended 并且触发 sourceended 事件。
                                video.play().then(function() {}).catch(function(err) {
                                    console.log(err)
                                });
                            }
                        });
                        sourceBuffer.appendBuffer(arrayBuffer);
                    });
            }
        })
</script>

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


 

生成这样的一个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加载视频的新的流,从而进行最快的加载和响应。

到此这篇关于html5用video标签流式加载的实现的文章就介绍到这了,更多相关html5用video标签流式加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

更多精彩内容其他人还在看

突袭HTML5之Javascript API扩展5—其他扩展(应用缓存/服务端消息/桌面通知)

前面已经总结了主要的API扩展(应用缓存/服务端消息/桌面通知),下面的几个只有在特定的场合才能发挥它的潜质,无一例外,IE均不支持,桌面通知目前只有Chrome支持,感兴趣的朋友可以了解下,或许对你有所帮助
收藏 0 赞 0 分享

HTML5之HTML元素扩展(上)—新增加的元素及使用概述

HTML5中加入了全新的结构型元素,例如页眉header,页脚footer,导航nav,内容article,章节section等除了这种整个页面的结构型元素,html5也加入了块级别的语义元素,感兴趣的朋友可以了解下,或许对你有所帮助
收藏 0 赞 0 分享

HTML5之HTML元素扩展(下)—增强的Form表单元素值得关注

在HTML5增强的元素中,最值得关注的就是表单元素;在HTML5中,表单已经做了重大的修整,一些以前需要通过JavaScript编码实现的功能现在无需编码就可轻松实现,感兴趣的朋友可以详细了解下,或许对你有所帮助
收藏 0 赞 0 分享

HTML5之WebGL 3D概述(上)—WebGL原生开发开启网页3D渲染新时代

WebGL开启了网页3D渲染的新时代,它允许在canvas中直接渲染3D的内容,而不借助任何插件,看到此处是不是感觉特别惊讶啊,WebGL有一个很好的中文教程,就是下面使用参考中的第一个链接,所以这里不再班门弄斧,后面的内容只是简单的总结一下学习的内容,感兴趣的朋友可以了
收藏 0 赞 0 分享

HTML5之WebGL 3D概述(下)—借助类库开发及框架介绍

前面我们看到了使用原生的WebGL API开发是多么的累,只因如此大量的WebGL框架被开发出来,这些框架不同程度的封装了创建3D场景的各种要素你可以快速创建需要的3D场景,感兴趣的朋友可以了解下,或许本文对你有所帮助
收藏 0 赞 0 分享

HTML中fieldset标签概述及使用方法

之前HTML没有好好学,导致以前看到控件组样式感觉很新奇,fieldset> 标签将表单内容的一部分打包,生成一组相关表单的字段,接下来对HTML中fieldset标签的使用进行详细解读,感兴趣的朋友可以了解下,或许对你有所帮助
收藏 0 赞 0 分享

HTML5中微数据概述及在搜索引擎中的使用举例

HTML5微数据规范是标记内容的一种方式,用于描述特定的信息类型,例如评论、人物信息或活动。微数据使用 HTML 标记(常为 span>或 div)中的简单属性为项和属性指定简要的描述性名称
收藏 0 赞 0 分享

html5新增的属性和废除的属性简要概述

HTML5中,在新增加和废除很多元素的同时,也增加和废除了很多属性比如表单相关的属性/链接相关属性是新增的而HTML4中一些属性就被废除掉了,感兴趣的你可以了解下,或许对你学习html5有所帮助
收藏 0 赞 0 分享

html5的新增的标签和废除的标签简要概述

HTML5中在新增加和废除很多标签的同时,也增加和废除了很多标签比如新增的结构标签:section元素/video元素等等,感兴趣的朋友可以了解下,希望本文的知识点对你有所帮助
收藏 0 赞 0 分享

html5配合css3实现带提示文字的输入框(摆脱js)

webkit特有的一个css,可以控制里面的文字样式,配合css3的动画效果和伪类,我们就可以很容易做出一个带动画的输入框,在系统登录、搜索等位置很适合,感兴趣的你可以参考下本文或许可以帮助到你
收藏 0 赞 0 分享
查看更多