技术文章 | jswz

如何在HTML5 页面实现播放视频和直播

 

随着网络提速和手机性能的提升,移动端页面中出现视频内容的频率越来越高。HTML5 通过 video 标签来支持嵌入式的媒体文件,使得开发者能够方便的将视频文件嵌入页面中。下面来说说使用 video 标签遇到的问题和解决方案,仅供参考!

一、前端培训班之video 常用属性

video 标签的常用属性包括 src、width、height、controls、autoplay、preload、poster 等,下面依次介绍下各个属性的作用。

src

src 规定要播放的视频 URL,也可以使用标签来设置视频 URL 和格式


目前, video 标签支持三种视频格式,浏览器兼容性如下图所示:
 

width/height

宽/高。通过设定宽高,可以在页面加载时为视频预留出空间。

autoplay

autoplay 规定视频就绪后是否马上播放。然而,在实际开发中发现,iOS 在蜂窝网络和 Safari 浏览器以及部分安卓浏览器并不支持该属性。

preload

preload 属性规定是否在页面加载后载入视频。如果设置了 autoplay 属性,则忽略该属性。

controls

controls 规定浏览器应该为视频提供播放控件,主要包括播放、暂停、定位、音量、全屏等。

poster

poster 属性规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。如果未设置该属性,则使用视频的第一帧来代替。但部分安卓浏览器不支持该属性,设置的 poster 图片在视频预加载之后会消失,视频区域显示为黑色背景,可以设置 preload="none",在用户点击播放之前一直显示 poster 图片。

二、前端培训班视频内联/全屏播放

video 视频播放主要有两种情况,内联播放和全屏播放。 在 iOS 系统中,点击播放视频时,页面会自动弹出一个系统默认原生全屏播放器来播放视频。如果我们希望视频在页面中内联播放,而不是全屏播放,可以通过添加参数 webkit-playsinline playsinline来控制(iOS10+ 支持)。 在 Android 系统中,视频是默认内联播放的。但在开发测试过程中发现一些安卓机在视频播放时,会将 video 的层级提到最高,挡住其他遮罩在视频区域上的元素,而且无法通过设置 z-index 来改变层级。 iOS 下正常效果:
 
Android 下不正常效果:
 
目前,要解决这个问题,只能在展示遮罩层时,隐藏视频区域或者在安卓环境下设置视频全屏播放。在 Android 系统中 X5 内核的浏览器设置全屏播放视频需要再加两个参数:
x5-video-player-type="h5"
x5-video-player-fullscreen="true"
这两个参数可以控制 X5 内核浏览器全屏播放视频,从而规避掉视频遮挡的问题。


三、前端培训班视频地址替换

在我们的单页面应用中,视频数据是从接口中获取,并异步渲染到页面中,当再次请求接口改变数据时,Vue 可以检测到数据的变化,并更新页面的展示。但我们在开发过程中发现,表现并非如此。当我们修改了 video 标签 src 的内容时,可以看到 video 的视频地址已经更新,但是视频无法播放。经研究发现,出现这个现象的原因是当我们直接替换视频地址后,新的视频并未被自动加载,因此无法播放。通过查阅 video 的原生方法,发现可以在更改视频来源后,调用 load() 函数来重新加载视频。 除此之外,利用 Vue 渲染 DOM 的机制,我们也可以通过重新渲染 video 来更新视频地址。
方法一: 当我们在切换视频 url 时,先将 url 置空,然后再赋值新的 url,通过 v-if 条件判断触发 DOM 更新来更新 video 标签
 width="100%"
 controls="controls"
 webkit-playsinline playsinline
 x5-video-player-type="h5"
 x5-video-player-fullscreen="true"
 v-if="videoUrl">
  
  

 
方法二: 利用改变 key 值来触发 video 更新
 width="100%"
 controls="controls"
 webkit-playsinline playsinline
 x5-video-player-type="h5"
 x5-video-player-fullscreen="true"
 :key="videoUrl"
 v-show="videoUrl">
  
  


四、前端培训班直播功能开发

视频直播目前主要支持三种直播协议,分别是 HLS、RTMP 和 HTTP-FLV。

HLS

HLS(HTTP Live Streaming)是苹果公司实现的基于 HTTP 的流媒体传输协议,最初是针对 iPhone、iPod、iPad、iTouch 等移动设备开发的。HLS 将视频文件切分为小的 ts 文件,然后通过 m3u8 索引表进行管理。HLS 采用 HTTP 短连接,延时相对较高(通常大于 10 秒),但兼容性很高,iOS、Android 和 HTML5 页面都支持,适合在微信中做推广。

RTMP

RTMP(Real Time Messaging Protocol)实时消息传送协议是 Adobe 公司开发的用于 Flash 播放器和服务器之间音频、视频和数据传输的协议,目前还没有收入国际标准。RTMP 的优点是基于 TCP 长连接,延时较小 (通常为 1 至 3 秒),但 RTMP 的兼容性较差,HTML5 页面无法直接播放。

HTTP-FLV

HTTP-FLV 是利用 HTTP 请求的 content-length 字段,服务器在回复客户端请求时,不回传 content-length 而是发送 flv 数据,这样客户端就可以一直接收数据。采用 HTTP-FLV 协议的直播流延时较小(和 RTMP 相当),而且相比于 RTMP 协议,HTTP-FLV 的穿墙性更高,很少出现被防火墙拦截的情况。但 HTTP-FLV 在手机浏览器中的兼容性十分有限,通常用于直播 APP 中。
三种协议对比图如下:
 
结合我们的需求以及这三种直播协议的优缺点,我们采用了 RTMP 和 HLS 两种协议。优先使用 RTMP,如果不支持 RTMP,则切换为 HLS。虽然原生 video 标签并不支持直播流的视频格式,但我们可以使用开源的 video.js。 video.js 针对 Vue 开发了一个 vue-video-player 组件,并提供了支持 RTMP 流的 videojs-flash 插件和支持 HLS 流的 videojs-contrib-hls 插件。需要注意的是,如果两个流都需要播放,flash 插件需要安装到 hls 插件之前。
我们可以通过npm安装依赖并引入项目中。
npm install vue-video-player --save
npm install videojs-flash --save
npm install videojs-contrib-hls --save
引用依赖
import 'video.js/dist/video-js.css'
import { videoPlayer } from 'vue-video-player'
import 'videojs-flash'
import 'videojs-contrib-hls'
组件调用


直播参数设置
export default {
    data() {
        return {
            playerOptions: {
                width: 360, // 设置视频宽度
                autoplay: false, // 是否自动播放
                controls: true, // 是否显示控制栏
                techOrder: ['flash', 'html5'], // 兼容顺序
                sourceOrder: true,
                flash: { hls: { withCredentials: false } },
                html5: { hls: { withCredentials: false } },
                sources: [
                    {
                        type: 'rtmp/mp4',
                        src: 'rtmp://xxxx' // RTMP 直播流地址
                    },
                    {
                        withCredentials: false,
                        type: 'application/x-mpegURL',
                        src: 'https://xxxx/xxxx.m3u8' // HLS 直播流地址
                    }
                ],// 直播流配置,会根据兼容顺序自动切换
                poster: "https://xxx.jpg", // 封面图片
            }
        }
    }
}

五、前端培训班APP 内视频播放问题

在开发实践过程中,还遇到两个 APP 内的视频播放问题,具体表现如下:
在页面视频播放时,点击 a 标签跳转到其他页面后,原页面视频依旧在后台播放,出现视频声音。
在页面视频播放时,点击手机 home 键,退出 APP 到手机主页,视频会自动停止播放,但当再次通过其他页面唤起 APP 时,原来播放视频的页面会在新页面之下被触发,并且开始自动继续播放视频,出现视频声音。
究其原因,这两种情况的出现都是因为没有正确检测到当前页面的展示状态,因此,我们可以判断页面显示状态变化时,就手动暂停页面上的视频,防止出现只有声音但没有视频画面的情况。解决方案如下:
document.addEventListener('visibilitychange',function() {
    var $video = document.getElementById('video');
    if ($video) {
        document.getElementById('video').pause();
    }
});

小结

目前 video 标签在 HTML5 页面中的应用已经越来越多,表现形式也越来越丰富,但在 iOS 和 Android 两个不同系统下使用 video 标签开发视频播放功能时,不可避免的会遇到手机兼容性问题,而且有些问题目前还没有最佳的解决方案。因此,在需求设计阶段,就要考虑到不同手机系统下的展示情况,规避掉已知问题。相信随着系统和环境的不断升级优化,一定会提出新的解决方案,做为开发者,我们需要不断尝试新方法、新参数,来找到视频播放问题的最佳实践。



爱创课堂是一家专门做前端培训的机构,由百度高级工程师,《JavaScript设计模式》作者张容铭老师亲自授课,全程20个项目实战。

我们前端课程的五大优势:

1. 名师亲自授课,课程无缝隙对接企业
2. 免费学习一周
3. 签订就业协议,目前学员平均就业薪资12K
4. 采取小班教学模式(一个班20—30人)
5. :与中国石油,中国电信,软通等知名企业合作,进行企业内训,并进行学员就业推荐
 
扫描下方二维码或搜索微信公众号:爱创课堂网络科技 
关注并回复:“H5”  领取 H5视频教程

更多前端学习资料,培训咨询 请添加微信:haomei0452 



访问 www.icketang.com/?zh 获取更多信息.