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('pause',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>

演示:http://caibaojian.com/demo/2018/8/video-fullscreen.html

原创文章:video播放器全屏兼容方案 ,未经许可,禁止转载,©版权所有
原文出处:前端开发博客 (http://caibaojian.com/video-screenfull.html)