关闭

web视频播放

时间: 2020-12-29阅读: 143标签: 视频

前言

毫无疑问,现在是短视频、直播的时代。视频内容逐渐代替图文形式成为网友们获取新鲜事物以及展现自我的一大媒介。随着5G的到来,2020年属于直播短视频爆发式增长的一年,电商平台也都涌入直播营销的大风口,成为了各自平台引流转化的关键。不管是用户还是开发者,我们处于这个风口中。本文将带你探索浏览器视频播放的奥秘。


视频的构成

一个完整可播放的视频文件是由视频和音频两部分构成。视频和音频又有各自的封装格式(容器)和编码格式。

编码格式

常见的视频编码格式有:MPEG4、H.264、H.265等。
常见的音频编码格式有:MP3、AAC、WAV等。

封装格式

常见的视频封装格式有:MP4、FLV、mov、AVI、RMVB等。


先理解几个名词

就是影像动画中的最小单位的影像画面。一帧就是一张静止的图像。视频中的动画就是由多幅连续的帧画面构成。

帧率

帧率是以帧为单位的图像在显示器上出现的频率,也叫帧速率,单位:赫兹(Hz)。简单理解为每秒播放图片的数量。

码率

码率是比特率的俗称,是指每秒传送的比特数。

FFmpeg

FFmpeg是可以用来记录、转换数字视频和音频的一套计算机程序。FFmpeg是在linux下开发,所以天生跨平台。它对音视频编码格式的支持比较全面,能对视频的各个组成部分进行编码。

H264

通常被称之为H.264/AVC;是由国际标准化阻止和国际电信联盟共同提出的继MPEG4之后的新一代数字视频压缩格式。采用H.264压缩后的数据具有低码率、高质量图像、容错能力强、网络适应性强等优点。

MP4

MP4是一中标准的数字多媒体容器格式;用于音频、视频的压缩编码,也可以存储字幕和静止图像,同时能以流的方式进行网络传输。

fMP4(Fragmented MP4)

fMP4是基于MPEG-4 Part 12的流媒体格式,与MP4很相似。简单来说fMP4区别与MP4最大的区别就是它能很好地适应流式播放。


浏览器播放视频

video标签播放

在浏览器播放视频,可以使用html5原生的video标签。但其播放的格式使用一定限制的,目前video只支持三种格式WebM、Ogg、MP4。

  • WebM:WebM 文件使用 VP8 视频编解码器和 Vorbis 音频编解码器
  • Ogg :Ogg 文件使用 Theora 视频编解码器和 Vorbis音频编解码器
  • MP4:MPEG 4文件使用 H264 视频编解码器和AAC音频编解码器

上面三种可以直接使用video播放:

<video id="video-box" src="//cloud.video.taobao.com/play/u/755731755/p/1/e/6/t/1/283631891407.mp4" controls width="400px" heigt="400px"></video>

在页面初始化完成后,video标签会将整个mp4文件下载到浏览器,完成后即可播放。但是当mp4文件较大时,缓存时间就比较长,播放体验不好。当然也可以使用video.js 来播放,这里就不赘述了。

播放HLS流

HLSHTTP Live Streaming)是一个由Apple公司提出的基于HTTP的流媒体传输协议。视频的封装格式是TS,编码格式是H.264/ACC,除了定义TS视频文件本身,还定义了用来控制播放的m3u8文本文件。移动端大部分浏览器都支持,也就是说,你可以在移动端浏览器直接使用vedio标签直接加载一个m3u8文件播放视频或者直播。但在PC端只支持苹果的safari浏览器,其他浏览器想播放需要引入第三方库,如:hls.js

<script src="https://cdn.jsdelivr.net/npm/hls.js"></script>
<video id="video"></video>
<script>
  var video = document.getElementById('video');
  var videoSrc = 'https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8';
  if (Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource(videoSrc);
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, function() {
      video.play();
    });
  }
</script>

播放HLS流的逻辑很简单,首先根据提供的m3u8地址源通过HTTP请求获取到一级index文件内容如:

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=64000
500kbps.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=774000
1000kbps.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=887000
500kbps.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7692000
1000kbps.m3u8

bandwidth 指定视频流的码率,每一个 #EXT-X-STEAM-INF 的下一行是二级index文件的路径,可以是相对路径或者是绝对路径。请求到的二级文件内容如:

#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:10
#EXTINF:10,
1000kbps-00001.ts
#EXTINF:10,
1000kbps-00002.ts
#EXTINF:10,
1000kbps-00003.ts
#EXTINF:10,
1000kbps-00004.ts
#EXTINF:10,

... ...
#EXT-X-ENDLIST

可以从二级文件中读取到ts文件的路径,同样可以是相对路径或者绝对路径。 #EXTINF 表示每个ts切片的时长。 #EXT-X-ENDLIST 是视频结束标志,如果有这个标志也表明该流不是一个直播流。
HLS播放的优势:

  • 可以使用http协议请求数据
  • 可以切换不同的码率,实现无缝播放

劣势:

  • 延迟较高,实时性差,一般延迟在10s以上,不适合做直播
  • ts文件切片小且多,对存储和缓存都有一定的要求

播放FLV流

FLV(Flash Video)是一种网络视频格式,FLV只能基于flash播放,但是由于flash存在很多安全问题已经被众多厂商抛弃,现在我们如果要在H5中播放flv格式的视频流可以使用Blibli的开源库:Flv.js,flv.js 原理是解析视频的flv流并实时转换为fmp4格式,再通过 Media Source Extension 喂给浏览器的 video 标签。

<script src="flv.min.js"></script>
<video id="videoElement"></video>
<script>
    if (flvjs.isSupported()) {
        var videoElement = document.getElementById('videoElement');
        var flvPlayer = flvjs.createPlayer({
            type: 'flv',
            url: 'http://example.com/flv/video.flv'
        });
        flvPlayer.attachMediaElement(videoElement);
        flvPlayer.load();
        flvPlayer.play();
    }
</script>

基于Media Source Extensions播放视频流

我们经常在很多直播网站去看视频,你有没有注意到他们是用的什么流?我们去B站随便找一个直播或者视频打开控制台查看播放器,你会发现 video 标签的 src 居然是 blob 开头的一个 url 。在前面讲FLV播放时,我们提到了Media Source Extension ,本节将介绍这种基于MSE的直播方案。

Media Source Extensions 是什么

媒体源扩展(Media Source Extensions,缩写MSE)是一项W3C规范,MSE允许JavaScript为audio标签和video标签动态地构造媒体源。

借助MSE的能力,我们可以将接收到的实时流通过 blob url 往video标签中灌入二进制数据(如fmp4格式流),或者使用 canvas 来实现直播。

简单实现

首先,判断浏览器是否支持MediaSource:

const supportMediaSource = window.MediaSource &&
            typeof window.MediaSource.isTypeSupported === 'function' &&
            window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42c01f,mp4a.40.2"');

MediaSource支持情况:

接下来新建 MediaSource 实例,并使用生成blob url 加到video标签。并且监听 sourceOpen 事件来判断初始化完成。

const mediaSource = new MediaSource();
const video = document.querySelector('#video-box');
video.src = URL.createObjectURL(mediaSource);

mediaSource.addEventListener('sourceopen',function(){
    // TODO
})

接下来我们通过websocket获取原始视频流,处理后通过 SourceBuffer 喂给 mediaSource

const sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
const ws = new WebSocket("wss://xxx.websocket.com");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("fetch Data");
};

ws.onmessage = function(evt) {
  // 可以在灌入数据前进行转码等操作
  sourceBuffer.appendBuffer(evt.data);
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};

通过MSE的方式我们可以将接收到的视频或者音频流进行端处理,配合WebWorker技术实现快速转码、支持多播,给我们无限的想象空间。

H.265视频播放

H.265是ITU-T VCEG继H.264之后所制定的新的视频编码标准。H.265标准围绕着现有的视频编码标准H.264,保留原来的某些技术,同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系,达到最优化设置。
但是由于浏览器不支持H265格式的流,所以我们无法直接播放。这时候可以使用MSE的方式在 sourceBuffer.appendBuffer(evt.data) 前将 evt.data 使用 libde265.js  等转码库转码后给到sourceBuffer。或者使用业界成熟的播放器进行播放,如淘系的@ali/videox播放器。


总结

越来越多的厂商更加偏向于H.265的编码格式,但是浏览器对该格式的支持度不友好的前提下我们不得不进行转码。使用MSE方式在浏览器端转码,则能借助GPU提高效率和降低延迟。但还是无法兼容所有的PC或者移动端浏览器,这条路还需要我们去继续探索。5G给互联网带来的福利不仅仅是在视频、直播的爆发,我相信web端图像视频技术也将突破现有的技术瓶颈,WebAssembly、硬件编码等图像渲染技术也将越来越丰富。

来自:https://segmentfault.com/a/1190000038766516

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/10022

关闭

jsmpeg.js_h5移动端视频自动播放

在移动端使用h5自动的video标签播放视频,设置autoplay属性,在android端部分不支持,全屏播放还存在层级问题,ios10以上版本支持视频自动播放,以下版本不支视频自动播放

video.js切换视频源问题

什么要再重新load一下什么替换一下src,没有啥作用,简单粗暴又有效的方法,video的问题,单单替换source的src是不行的,简单明了重新替换整个video标签,将video用js重新替换一遍,更改src

h5页面自动播放视频、音频_关于媒体文件自动全屏播放的实现方式

在移动端(ios和android)播放视频的时候,我们即使定义了autoplay属性,仍然不能自动播放。这是由于手机浏览器为了防止浪费用户的网络流量,在默认情况下是不允许媒体文件自动播放的,除非用户自己对浏览器进行设置才能支持autoplay。

基于 WebRTC 的 RTSP 视频实时预览

由于项目需要,需要使用摄像头预览功能,设备型号为海康威视。目前已存在的基于 FFmpeg 的方案延迟都太高,所以项目最终选择基于此方案。方案选用为基于 WebRTC 的视频即时通讯,它原生支持对 RTP 协议的解码

Web端直接播放 .ts 视频

最近项目中需要前端播放 .ts 格式视频,捣鼓了几天学习到很多知识,也发掘了一种优秀的解决方案,项目中已存储的 .ts 切片数量众多,已经占用了NAS服务器绝大部分的资源,生成的 .m3u8 索引虽然非常小

JS判断视频Video的播放、暂停、结束完成及获取长度事件监听处理

在日常应用场景中,可能会遇到这么一个情况,需要判断用户是否完整的观看完了一部视频,在这个场景中,和视频相关的事件大体涉及到几个部分,获取视频长度,视频开始播放,暂停播放和播放结束

vue实现自定义H5视频播放器

前段时间基于vue写了一个自定义的video播放器组件,踩了一些小坑, 这里做一下复盘分享出来,避免日后重复踩坑,这里就直接放几张完成后的播放状态图吧,界面布局基本就是flex+vw适配一把梭

Video Renderer:高性能移动 Web 端视频编辑器

Video Renderer 是一款针对移动 Web 应用开发的高性能视频编辑器。在 2019 伦敦全栈工程师大会( Fullstack London 2019 conference )上, Threads Styling 公司的软件开发工程师Forbes Lindesay 分享了 Video Renderer 的开发经验。

Web视频格式

网络视频一直都很火。虽然在页面上嵌入 Instagram 和 Youtube 视频非常简单,但是有越来越多的需求 —— 比如许多电子商务的场景 —— 要求定制的视频传输方法。

使用 multipart/x-mixed-replace 实现 http 实时视频流

关于实时视频传输,业界已经有非常多成熟方案,分别应用在不同需求场景。本文介绍一种基于 HTTP ,非常简单、易理解的方案,实用性不强,但有助于理解 HTTP 协议。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!