【JS】网页播放器埋坑,看这一篇就搞定!!!

在座的傻 x

本喵来了

今天写的文章一(亿)级棒!

【JS】网页播放器埋坑,看这一篇就搞定!!!

没错,今天要说的对象就是“网页播放器”这个逼,这玩意看起来没什么难度,但实际上有几个坑,下面由本帅气无敌喵逐一解说如何解决在开发中可能会遇到的坑。

  1. 无法自动播放
  2. 全屏问题
  3. 手机端播放器自定义控制条无法显示

01无法自动播放

不就是 video 标签添加一个 autoplay 吗?很遗憾...事情并没有这么简单。

桌面版的 Safari 在 2017 年的 11 版开始禁止了带有声音的视频自动播放,2018 年 4 月份发布的 Chrome 66 也禁止了,随后各个浏览器都跟随着苹果和谷歌两位大佬的脚本逐一禁止了。

请注意,是禁止带有声音的网页视频自动播放,因此,自动播放和声音是有奸情!!!

想要自动播放可以通过以下几种方式解决。

  • video 标签添加一个 muted 属性(静音)

    静音的视频是允许自动播放。

  • 用户在网站上进行了互动

    这个办法在字面上可能很难理解,举个栗子吧。

杰瑞鼠打开了浏览器,访问了黄网“TOM and JERRY”的首页(带有视频),在首页点击某个黄涩视频链接,进入到了这个视频详情。

那么假设首页和这个视频详情的 video 都有 autoplay 这个属性,没有 muted 属性,请问这两个视频是否在网页加载的那一刻起能够自动播放吗?

【JS】网页播放器埋坑,看这一篇就搞定!!!

答案是:首页的 video 不能自动播放,但是视频详情里的 video 可以播放(且有声音),因为在同一个会话里,在进入视频详情前,用户已经打开了同站点下的首页,也就是说,用户已经与网站进行了交互,而用户刚进入首页前,是没有访问过同站点下的其他网页,也即是没有任何交互,因此首页的 video 不能自动播放。

  • 浏览器设置“允许自动播放”

    这种方法就是全面开放自动播放功能,没有“静音”和“交互”的限制了,需要用户自行设置。以 chome 浏览器为例,在地址栏访问 chrome://flags/,搜索“Autoplay”,即可搜索到该设置(不过,高版本的 chrome 已经不是在这里设置了,本喵也找不到设置的地方)。

【JS】网页播放器埋坑,看这一篇就搞定!!!

    再以火狐浏览器为例,在选项里找“自动播放”,即可找到。

【JS】网页播放器埋坑,看这一篇就搞定!!!

  • 浏览器域名白名单(未证实)

    听说浏览器有个域名白名单的东西,只要将域名填入该白名单,访问相关网站就可以自动播放,但目前为止本喵手上没有足够证据证实各个大厂的 py 交易。

上述几种自动播放解决方法各有缺点,为了让用户体验好一点,有时候,我们需要检测网页打开时是否支持自动播放,若不支持,则在视频中间显示播放按钮或者出现其他的样式,下面贴一下检测自动播放代码。

var promise = document.querySelector('video').play()

if (promise !== undefined) {

promise.then(() => {

// 支持自动播放且有声音

}).catch(error => {

// 不支持自动播放且有声音,这个时候可以在视频上面显示一个播放图标,提示用户自己点击播放

})

}

    但不是所有的浏览器的 video.play() 都支持返回 promise。想了解更多,可以到这个网站看看。

https://developer.mozilla.org...

02 全屏问题

废话不说,先贴代码。

<!-- 这里专门用一个 div 包含 video,这样做是有原因的,下面有说明 -->

<div class="video-box">

<video src="https://segmentfault.com/a/1190000038688060/xxx" poster=""></video>

</div>

<script>

// 检测是否全屏(IOS 端无效)

function checkFullScreen() {

var isFull = document.webkitIsFullScreen || document.mozFullScreen ||

document.msFullscreenElement || document.fullscreenElement

if (isFull == null || isFull == undefined) {

isFull = false

}

return isFull

}

// 全屏

function toggleFullScreen() {

var videoBox = document.querySelector('.video-box')

// video 是 video-player 里面的 video 标签,这个用于 ios 端全屏

var video = document.querySelector('.video-box video')

var isFull = checkFullScreen()

//W3C

if (videoBox.requestFullscreen) {

isFull ? document.exitFullscreen() : videoBox.requestFullscreen()

}

//FireFox

else if (videoBox.mozRequestFullScreen) {

isFull ? document.mozCancelFullScreen() : videoBox.mozRequestFullScreen()

}

//Chrome

else if (videoBox.webkitRequestFullScreen) {

isFull ? document.webkitCancelFullScreen() : videoBox.webkitRequestFullScreen()

}

//IE11

else if (videoBox.msRequestFullscreen) {

isFull ? document.msExitFullscreen() : videoBox.msRequestFullscreen()

}

// IOS(特例)

else if (video.webkitEnterFullscreen) {

video.webkitEnterFullscreen()

}

// 这里可以做一些判断,更换缩放图标(对 IOS 端没效果)

if (isFull) {

} else {

}

}

</script>

    上面的全屏代码适用于 pc(Windows和Mac)、移动端(安卓和IOS),主要使用到了 requestFullscreen API,该 API 适用于 PC 和安卓,但很遗憾,IOS 不适用,IOS 端就是个另类,只能用 webkitEnterFullscreen API 进入全屏,而且没有退出全屏的 API,进入全屏后,只能用 iphone 的手势或自带控件进行退出全屏。

如果你发现 requestFullscreen API 失效,以下网站有说明 requestFullscreen API 失效的原因。

https://stackoverflow.com/que...

But 事情没有这么简单,在开发过程中依旧会遇到很多问题,下面逐一说明。

  • PC 端全屏后无法监听 ESC 键

    在 PC 端里,有时候需要退出全屏后做一些操作,点击退出全屏按钮跑逻辑是没问题的,但是不要忘记,按 ESC 键也是退出全屏操作,也需要进行跑逻辑。而当元素使用了 requestFullscreen API 进行全屏时,不需要写任何代码,ESC 键就会默认用来退出全屏,我们自然会想到用 onkeydown 事件来监听 ESC,虽然 onkeydown 事件是可监听,但是唯独 ESC 键是无法监听。

document.onkeydown = function () {

if (event.keyCode == 27) {

// 退出全屏

}

}

    也即是说,上面的代码,按 ESC 是不走的。那咋办?别担心,我们可以利用 onresize 曲线救国,当用户按下 ESC 时,全屏就会失效,windows 的宽高会变小,即会触发 onresize,这个时候再检测是不是非全屏情况,再跑逻辑。

window.onresize = function () {

if (!checkFullScreen()) {

// 按 esc 退出全屏需要执行的代码

}

}

  • IOS端全屏无法自定义控制条

    由于 IOS 端的全屏只能调用 webkitEnterFullscreen 将 video 标签进行全屏(其实就是 IOS 端内置的全屏,注意:是只能针对 video 标签全屏),全屏时是不能显示自定义的控制条。

    But 我们可以用样式写一个“假全屏”的代码。

<script>

// 为了方便,下面用了 jq

// 判断是否是 IOS 端

var isIOS = !(navigator.userAgent.indexOf("Android") > -1) && (/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))

function toggleFullscreen() {

if ($('.video-box').hasClass('fullscreen')) {

// 这里设死高度 210 了,可以自己更改

$('.video-box').removeClass('fullscreen').removeClass('transform').width('100%').height(210).css('margin', '0')

} else {

$('.video-box').addClass('fullscreen')

if ($(window).width() < $(window).height() && isIOS) {

$('.video-box').width($(window).height()).height($(window).width()).css('margin', '-' + $(window).width() / 2 + 'px 0 0 -' + $(window).height() / 2 + 'px').addClass('transform')

} else {

$('.video-box').width($(window).width()).height($(window).height()).css('margin', '-' + $(window).height() / 2 + 'px 0 0 -' + $(window).width() / 2 + 'px')

}

}

}

// 重力感应,改变屏幕方向,如果是全屏时,也进行相应的改变

window.onresize = function () {

if ($('.video-box').hasClass('fullscreen')) {

if ($(window).width() < $(window).height() && isIOS) {

$('.video-box').width($(window).height()).height($(window).width()).css('margin', '-' + $(window).width() / 2 + 'px 0 0 -' + $(window).height() / 2 + 'px').addClass('transform')

} else {

$('.video-box').width($(window).width()).height($(window).height()).css('margin', '-' + $(window).height() / 2 + 'px 0 0 -' + $(window).width() / 2 + 'px').removeClass('transform')

}

}

}

</script>

<style>

/* 屏幕旋转的样式 */

.video-box.fullScreen.transform {

transform: rotate(90deg);

-ms-transform: rotate(90deg);

-webkit-transform: rotate(90deg);

-o-transform: rotate(90deg);

-moz-transform: rotate(90deg);

transform-origin: 50%;

-ms-transform-origin: 50%;

-webkit-transform-origin: 50%;

-moz-transform-origin: 50%;

-o-transform-origin: 50%;

}

/* 屏幕改变方向时,播放器控制条,需要固定 */

.video-box.fullScreen.transform .control {

position: fixed;

}

/* 全屏需要更改位置 */

.video-box.fullScreen {

position: fixed;

top: 50%;

left: 50%;

z-index: 10000;

}

</style>

上面的代码也兼容安卓端

    不过这种方式存在一些体验问题,比如:使用重力感应横屏时,浏览器的地址栏会浮在上面,这个地址栏是无法去掉的。

【JS】网页播放器埋坑,看这一篇就搞定!!!

  • 视频全屏时也需要将控制条进行全屏

    估计没有傻 x 产品会用播放器自带的丑陋控制条吧......既然我们要自定义控制条的样式,那就不会在 video 标签添加 controls 属性,而是在 video-box 的 div 下添加一个控制条相关的 div。

<div class="video-box">

<video poster=""></video>

<!-- 控制条 -->

<div class="ctrl-box"></div>

</div>

    那么全屏时,我们不应该只考虑将 video 进行全屏,同时也要将控制条进行全屏,实现很简单,只要将 video-box 这个父类标签进行全屏即可。这也是为什么全屏代码里是将 video-box 进行全屏,而不是单独将 video 全屏,以及为什么要有个父类 div 包住 video。

  • iframe 里面的元素全屏失败

    如果 video 标签是在 iframe 里,iframe 必须声明允许全屏。

<iframe allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen"></iframe>

03 手机端播放器自定义控制条无法显示

如今,手机端主要分为两大阵容:安卓和 IOS,在这两个端里,我们自定义的播放器控制条都会出现各种问题,下面一一列举。

  • 安卓

    在安卓端里,因为比较开放,浏览器可以说是百花齐放,有各种各样的功能,其中,有个对开发者不友好的情况就是某些浏览器(例如:QQ 浏览器)会去掉我们自定义的播放器控制条,改用浏览器内置的默认控制条。

    解决方法如下:

...

...

...

【JS】网页播放器埋坑,看这一篇就搞定!!!

无解!!!

先等等,别急着抓本喵猫尾。这个确实是无解的,有些浏览器厂商就是不愿意开发者可以自定义控制条,你可能会说为什么像虎牙直播这种大厂在手机上的 QQ 浏览器可以使用自定义控制条,那是因为......嗯......他们有 py 交易,没错,就是 py 交易!

例如:QQ 浏览器就有一个域名白名单的东西,而虎牙直播的域名就在这个白名单里,所以我们访问虎牙直播网站时,可以发现虎牙直播是可以显示自定义控制条。

不信?你试下在电脑使用 Fiddler 软件在本地做下代理,让手机和电脑连接同一个局域网,配置这个代理,然后再在电脑上做一下 hosts,将虎牙的域名映射到本地 IP,你就可以在手机里的 QQ 浏览器通过虎牙的域名访问到自己的网站,看看是不是自定义控制条显示出来了。

有关这个问题,本喵还特地在思否提问了。

https://segmentfault.com/q/10...

没错,就是无解,所以哪个傻 x 产品问你为什么这个功能无法实现,你就回答他,“你在教我做事?”

  • IOS

    大家都清楚 IOS 系统是封闭的,封闭到规定 IOS 端里的所有厂商的浏览器都不能支持 requestFullscreen API,只能支持独有的 webkitEnterFullscreen API,全屏时只能显示苹果的那一套控件,导致全屏是没任何办法显示自定义控制条的,不过在非全屏情况下,是可以显示自定义进度条,当然你也可以用上文那里的“假全屏”代码。

好了好了

这期干货就到这里了

本喵要捉杰瑞鼠了

溜了溜了

【JS】网页播放器埋坑,看这一篇就搞定!!!

共同进步

本喵专注于前端技术,不定期更新优质前端文章。
喜欢本喵,请点击下方“关注作者”,亲们还可以关注微信公众号“技术汤姆喵”哦~
若文章有误,欢迎大家指出。
【JS】网页播放器埋坑,看这一篇就搞定!!!

以上是 【JS】网页播放器埋坑,看这一篇就搞定!!! 的全部内容, 来源链接: utcz.com/a/88683.html

回到顶部