video播放器全屏兼容方案

在Github上有两个video的插件维护的比较积极,在Github里搜索video,排序选择最高star的,关于video播放器的分别是video.jsmediaelement,虽然video.js的数目很多,但我想只是因为它这个项目的名称起得好,所以大家搜索video的内容时,Github总是第一位推荐,而mediaelement却没法出现在Github的那个推荐搜索里。

我们的网站使用的是mediaelement集成的,里面有很多很实用的插件,其中关于video全屏的方案兼容性做得很好,比起video.js那个插件,不支持ios Safari全屏播放,考虑PC方面的比较多,而mediaelement的那个Fullscreen.js就写得比较全了。我提取了里面的一些代码,总结如下:

1.首先检查是否支持浏览器自带的全屏方法。

github上有一个fullscreen.js的api很全,mediaelement就是使用这个类似的方法,当然video.js这个也是使用上面这个。

用法很简单,引入js后,screenfull 就是一个全局变量。我们可以通过定义一个按钮点击后出发这个全屏api.代码如下:

if (screenfull.enabled) {
	screenfull.toggle(target);
	screenfull.on('change', () = >{
		if (screenfull.isFullscreen) {
			$('body').addClass('fullscreen');
		} else {
			$('body').removeClass('fullscreen');
		}
	});
}

还有更多用法可以参考官网:https://github.com/sindresorhus/screenfull.js

2.当不支持上面的用法时,我们还可以继续检测是否支持苹果Safari自带的video全屏api。

var element = $('#video video')[0]; //video DOM
if (element.webkitEnterFullscreen || element.enterFullScreen) {
    element.webkitEnterFullscreen && element.webkitEnterFullscreen();
    element.enterFullScreen && element.enterFullScreen();

}

为什么这个代码有用而且必须加呢?因为iphone上,微信和Safari都不支持第一种的浏览器api,但支持这个全屏api,所以我们使用这个api实现了iphone下面video标签的全屏。

3.当然是以上两种方法都不支持的情况下,我们就只能模拟video全屏了,模拟的意思就是只能实现样式上看起来全屏,但实际浏览器自带的头部和尾部都没法隐藏,不像上面这两种api,当全屏状态下,浏览器的上下导航是会隐藏的。

function mockFullscreen(curEl) {
    var wrapperEl = $('#video .video_wrap');
    var playerEl = $('#video video');
    if (curEl.hasClass('normal')) {
        playerObj.fullscreen = false;
        $('body').removeClass('fullscreen');
        curEl.removeClass('normal');
    } else {
        playerObj.fullscreen = true;
        $('body').addClass('fullscreen');
        curEl.addClass('normal');
    }
}

所以,模拟video控件的全屏,就是上面这三种写法了,结合起来就能实现各个平台的全屏效果了。

完整代码:

<div id="video">
	<button class="fscreen J_play">播放视频</button>
	<button class="fscreen J_fscreen">video全屏</button>
	<div class="video_wrap"><video id="video_js_palyer" preload="auto" autoplay="autoplay" playsinline="true" webkit-playsinline="true" x-webkit-airplay="true" x5-video-player-type="h5" x5-video-player-fullscreen="true" x5-video-orientation="portraint" x5-video-ignore-metadata="true" style="width: 100%; object-fit: contain;" src="//auto.pcvideo.com.cn/pcauto/vpcauto/2018/07/05/1530785606876-vpcauto-78188-1_3.mp4"></video></div>
</div>
<script type="text/javascript" src="https://js.3conline.com/pcvideo/2017/wap/live/v2/fullscreen.js" charset="gbk"></script>
<script src="https://js.3conline.com/min/temp/v1/lib-jquery1.10.2.js"></script>
<script type="text/javascript">
	var Features = {};
	var target = $('#video')[0]; // Get DOM element from jQuery collection
	var element = $('#video video')[0];
	var NAV = window.navigator;
	var UA = NAV.userAgent.toLowerCase();
	Features.IS_IOS = /ipad|iphone|ipod/i.test(UA) && !window.MSStream;
	// iOS
	Features.hasiOSFullScreen = (element.webkitEnterFullscreen !== undefined);

	// W3C
	Features.hasNativeFullscreen = (element.requestFullscreen !== undefined);
	// OS X 10.5 can't do this even if it says it can :(
	if (Features.hasiOSFullScreen && /mac os x 10_5/i.test(UA)) {
		Features.hasNativeFullscreen = false;
		Features.hasiOSFullScreen = false;
	}
	var IS_CHROME = /chrome/i.test(UA);

	if (IS_CHROME) {
		Features.hasiOSFullScreen = false;
	}
	var playerObj = {};
	$('.J_play').on('click',function(){
		var self = $(this);
		if(!self.hasClass('playing')){
			element.play();
			self.addClass('playing');
		}else{
			element.pause();
			self.removeClass('playing');
		}
		
	});
	element.addEventListener('play',function(){
		if(!$('.J_play').hasClass('playing')){
			$('.J_play').addClass('playing');
		}
	});
	element.addEventListener('pause',function(){
		if($('.J_play').hasClass('playing')){
			$('.J_play').removeClass('playing');
		}
	});
	element.addEventListener('ended',function(){
		if($('.J_play').hasClass('playing')){
			$('.J_play').removeClass('playing');
		}
	})
	$(document).on('click','.J_fscreen',function(){
		var curEl = $(this);
		curEl.html('触发全屏');
		if(!$('.J_play').hasClass('playing')){
			$('.J_play').trigger('click');
		}
		enterFullScreen();
		
		function enterFullScreen(){
			if(Features.IS_IOS && Features.hasiOSFullScreen && typeof element.webkitEnterFullscreen === 'function' && element.canPlayType('video/mp4')){
				// alert(2);
				Features.isiOSFullScreen = true;
				console.log('ios全屏');
				setTimeout(function(){
					element.webkitEnterFullscreen();
				},0);
				
				return;
			}
			fakeFullScreen();
		}
		function fakeFullScreen(){
			if(Features.isiOSFullScreen) return;
			if (screenfull.enabled) {
				console.log('浏览器全屏');
				screenfull.toggle(target);
				screenfull.on('change', () => {
					if(screenfull.isFullscreen){
						playerObj.isFullScreen = true;
						$('body').addClass('body_fullscreen');
					}else{
						playerObj.isFullScreen = false;
						$('body').removeClass('body_fullscreen');
					}
				});
			}else{
				console.log('伪全屏');
				_mockFullscreen();
			}
		}
		function exitFullscreen(){
			fakeFullScreen();
		}
		function _mockFullscreen() {
			var wrapperEl = $('#video .video_wrap');
			var playerEl = $('#video video');
			if (curEl.hasClass('fullscreen_on')) {
				playerObj.isFullScreen = false;
				$('body').removeClass('body_fullscreen');
				curEl.removeClass('fullscreen_on');
			} else {
				playerObj.isFullScreen = true;
				$('body').addClass('body_fullscreen');
				curEl.addClass('fullscreen_on');
			}
		}

	})
</script>

演示:https://qdkfweb.cn/demo/2018/8/video-fullscreen.html


关注我

我的微信公众号:前端开发博客,在后台回复以下关键字可以获取资源。

  • 回复「小抄」,领取Vue、JavaScript 和 WebComponent 小抄 PDF
  • 回复「Vue脑图」获取 Vue 相关脑图
  • 回复「思维图」获取 JavaScript 相关思维图
  • 回复「简历」获取简历制作建议
  • 回复「简历模板」获取精选的简历模板
  • 回复「加群」进入500人前端精英群
  • 回复「电子书」下载我整理的大量前端资源,含面试、Vue实战项目、CSS和JavaScript电子书等。
  • 回复「知识点」下载高清JavaScript知识点图谱

每日分享有用的前端开发知识,加我微信:caibaojian89 交流