1.原生 H5 video 标签 1 2 3 4 <video id="mse" play=true playsinline controls="controls" > <source src ="实机视频地址" type ="video/mp4" > 你的浏览器不支持Video标签 </video >
2.第三方插件 video.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 _this.player = videojs( _this.videoNode, { play : true , bigPlayButton : false , controls : true , preload : '' , poster : poster, notSupportedMessage : '视频加载失败,请刷新再试试' , sources : [ { src : videoUrl, type : 'video/mp4' , }, ], }, function onPlayerReady ( ) { this .play(); } ) <video ref={(node ) => (this .videoNode = node)} className="video-js vjs-big-play-centered" preload="" play="play" playsinline='true' webkit-playsinline='true' x5-video-player-type='h5' x5-video-player-fullscreen='false' x5-video-orientation='portraint' ></video>
2.1 支持原生 H5 video 标签的所有配置参数,并且更加丰富的配置。 2.2 多环境兼容性 2.3 源码结构
2.4 样式可定制,便于修改 3.业务开发中的场景 目前基本表现良好
3.1 自动播放实现 3.1.1 非微信端 目前主要方法是在 videojs 的 onPlayerReady 回调中调用 play 方法,以及特殊环境下需要用户手动触发
3.1.2 微信端 微信端(特别是 ios)为了能够实现自动播放功能,目前主要通过增加微信 WeixinJSBridgeReady 事件回调的方式来触发
1 2 3 4 5 6 7 document .addEventListener( 'WeixinJSBridgeReady' , function ( ) { this .player.play() }, false )
4.播放过程 image-20200721141051863
一次播放多次请求
请求头信息
image-20200721141223269
响应信息
image-20200721141320415
range: bytes=0-
首部信息,该信息用于检测服务端是否支持 Range 请求
Accept-Ranges
首部(并且它的值不为 “none”),那么表示该服务器支持范围请求
Content-Length
也是有效信息,因为它提供了要下载的视频的完整大小
Content-Range
响应首部则表示这一部分内容在整个资源中所处的位置
range - 可以分片段请求,此时的 Content-Range 则返回的对应请求区间的大小
5.其他场景 5.1 如何实现视频本地预览 视频本地预览的功能主要利用 URL.createObjectURL()
方法来实现。URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <!DOCTYPE html > <html > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > 视频本地预览示例</title > </head > <body > <input type ="file" accept ="video/*" onchange ="loadFile(event)" /> <video id ="previewContainer" controls width ="480" height ="270" style ="display: none;" > </video > <script > const loadFile = function (event ) { const reader = new FileReader() reader.onload = function ( ) { const output = document .querySelector('#previewContainer' ) output.style.display = 'block' output.src = URL.createObjectURL(new Blob([reader.result])) } reader.readAsArrayBuffer(event.target.files[0 ]) } </script > </body > </html >
5.2 如何实现播放器截图 播放器截图功能主要利用 CanvasRenderingContext2D.drawImage()
API 来实现。Canvas 2D API 中的 CanvasRenderingContext2D.drawImage() 方法提供了多种方式在 Canvas 上绘制图像。
drawImage API 的语法如下:
1 2 3 void ctx.drawImage(image, dx, dy)void ctx.drawImage(image, dx, dy, dWidth, dHeight)void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > 播放器截图示例</title > </head > <body > <video id ="video" controls ="controls" width ="460" height ="270" crossorigin ="anonymous" > <source src ="请替换为实际视频地址" /> </video > <button onclick ="captureVideo()" > 截图</button > <script > let video = document .querySelector('#video' ) let canvas = document .createElement('canvas' ) let img = document .createElement('img' ) img.crossOrigin = '' let ctx = canvas.getContext('2d' ) function captureVideo ( ) { canvas.width = video.videoWidth canvas.height = video.videoHeight ctx.drawImage(video, 0 , 0 , canvas.width, canvas.height) img.src = canvas.toDataURL() document .body.append(img) } </script > </body > </html >
5.3 如何实现 Canvas 播放视频 使用 Canvas 播放视频主要是利用 ctx.drawImage(video, x, y, width, height)
来对视频当前帧的图像进行绘制,其中 video 参数就是页面中的 video 对象。所以如果我们按照特定的频率不断获取 video 当前画面,并渲染到 Canvas 画布上,就可以实现使用 Canvas 播放视频的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <!DOCTYPE html > <html > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > 使用 Canvas 播放视频</title > </head > <body > <video id ="video" controls ="controls" style ="display: none;" > <source src ="请替换为实际视频地址" /> </video > <canvas id ="myCanvas" width ="460" height ="270" style ="border: 1px solid blue;" > </canvas > <div > <button id ="playBtn" > 播放</button > <button id ="pauseBtn" > 暂停</button > </div > <script > const video = document .querySelector('#video' ) const canvas = document .querySelector('#myCanvas' ) const playBtn = document .querySelector('#playBtn' ) const pauseBtn = document .querySelector('#pauseBtn' ) const context = canvas.getContext('2d' ) let timerId = null function draw ( ) { if (video.paused || video.ended) return context.clearRect(0 , 0 , canvas.width, canvas.height) context.drawImage(video, 0 , 0 , canvas.width, canvas.height) timerId = setTimeout (draw, 0 ) } playBtn.addEventListener('click' , () => { if (!video.paused) return video.play() draw() }) pauseBtn.addEventListener('click' , () => { if (video.paused) return video.pause() clearTimeout (timerId) }) </script > </body > </html >