1、问题一:因为百度等浏览器会挟持原生video标签,给它设置默认的、无法更改的样式和功能等,如果有别的需求的话,没办法改变video标签,因此需要使用一些不同的办法在微信内置浏览器、百度等其他浏览器上实现自定义视频样式的播放?
解决办法 :目前使用了三种办法来播放视频,分别针对微信内置浏览器(不分ios和android)、ios系统下的其他浏览器和安卓系统下的其他浏览器。
1、微信内置浏览器
微信浏览器可以直接使用video标签来播放视频,ios端和安卓端都可以适配。主要是通过微信内置的h5同层播放器来拜托浏览器对video标签的挟持,从而实现自定义video标签。代码如下:
<video class="video" poster="@/static/poster.jpg" :enable-progress-gesture="false" @ended="next" preload :controls="false" x-webkit-airplay="allow" :show-center-play-btn="false" x5-video-player-type="h5" x5-playsinline webkit-playsinline playsinline :src="videoSource" type="video/mp4">
2、ios系统
ios系统下的其他浏览器,需要使用canvas来不断绘制出video视频,再放到页面中去,这样就可以避免video标签被浏览器挟持的问题。
代码:
//ios设置视频的方法 iosPlay() { //创建Video标签 this.video = document.createElement('video'); this.video.src = 'https://jieshibang.oss-accelerate.aliyuncs.com/wait.mp4'; const container = document.getElementsByClassName("container"); this.canvas = document.createElement("canvas"); container[0].appendChild(this.canvas); // 初始化(创建)canvas if (this.canvas.getContext) { this.ctx = this.canvas.getContext('2d'); } this.video.width = 750; this.video.height = 1624; // 设置canvas的宽度,这个设置的越大,画面越清晰,最好是视频大小(相当于绘制的图像大,然后被css缩小) this.canvas.width = 750; this.canvas.height = 1624; //设置canvas宽高 this.canvas.style.width = '100vw'; this.canvas.style.height = 'auto'; this.render(); this.video.addEventListener('play', this.playCallBack); }, // 绘制视频 render() { //隐藏填充白屏的背景图 this.hidden(); //填充ios黑屏的背景 this.ctx.fillStyle = '#0fb1df'; // 绘制背景 this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height); if (this.video.paused) { this.video.play() } else { this.video.pause() } }, playCallBack() { if (this.video.paused) { return; } this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height); setTimeout(this.playCallBack, 16.7); },
3、安卓系统
安卓端播放视频需要使用jsmpeg.min.js这个库来实现,引入这个库之后,需要把视频的地址和canvas标签赋给实例,然后再配置一些需要的参数(如:自动播放、结束时跳转的方法等等),需要注意的是,视频的地址需要和项目的地址是同源的,不然会产生跨域的问题,这是由JSMpeg内部的请求导致的,没办法改变。
代码:
androidPlay() { //这里必须使用同一个域名下的视频文件,不然会跨域,这是由JSMpeg内部的请求导致的 const url = "https://jieshibang.jdpes.cn/video/wait.ts"; const container = document.getElementsByClassName("container"); this.canvas = document.createElement("canvas"); container[0].appendChild(this.canvas); // 设置canvas的宽度,这个设置的越大,画面越清晰,最好是视频大小(相当于绘制的图像大,然后被css缩小) this.canvas.width = 750; this.canvas.height = 1624; //设置canvas宽高、裁剪视频,避免拉伸 this.canvas.style.width = "100vw"; this.canvas.style.height = "auto"; this.player = new JSMpeg.Player(url, { canvas: this.canvas, loop: false, autoplay: true, disableGl: false, onEnded: () => { this.next(); //视频结束时跳转 }, }); },
2、问题二:在视频开始播放时出现了短暂黑屏的现象?
解决办法:当第一次播放视频的时候ios端,如果网络慢,视频从开始播到能展现画面会有短暂的黑屏(处理视频源数据的时间),为了避免这个黑屏,可以在视频上加个div浮层(可以是视频的第一帧),然后用timeupdate方法监听,视频播放及有画面的时候再移除浮层。
代码:
this.videoNode.addEventListener('timeupdate', () => { // 当视频的currentTime大于0.1时表示黑屏时间已过,已有视频画面,可以移除浮层 if (this.videoNode.currentTime > 0.1 && !this.playing) { this.playing = true } }, false)
3、问题三:视频自动播放?
解决办法:在微信浏览器端,android始终不能自动播放;ios的话,微信提供了一个事件WeixinJSBridgeReady,在微信嵌入webview全局的这个事件触发后,视频仍可以自动播放(因为微信浏览器的限制,目前ios端也不能自动播放了,建议使用点击/触屏等操作实现视频播放)。至于其他浏览器,建议引导用户去触屏的行为操作比较好(比如添加一个按钮立即播放,引导用户点击操作)。
4、问题四:视频变形的问题?
解决办法:在设置好视频的大小和canvans的大小之后,为避免不同手机出现视频拉伸变形的现象。可以使用object-fit: cover,它可以对视频进行裁剪,解决拉伸问题。object-fit属性可以解决视频出现上下黑边,不能全屏的问题。