热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

X5同层播放器应用实践

移动端浏览器中的video元素是比较特别的,早期无论是在iOS还是Android的浏览器中,它都位于页面的最顶层,无法被遮挡。后来

移动端浏览器中的video元素是比较特别的,早期无论是在iOS还是Android的浏览器中,它都位于页面的最顶层,无法被遮挡。后来,这个问题在iOS下得到了解决。但是对Android的大部分浏览器来说,问题仍然存在。X5是腾讯基于Webkit开发的浏览器内核,应用于Android端的微信、QQ、QQ浏览器等应用。它提供了一种名叫「同层播放器」的特殊video元素以解决遮挡问题。

简单使用

只要给普通的video元素加上X5的自定义属性 x5-video-player-type ,就可以调用同层播放器。示例代码如下:

body {margin: 0;background: #000;
}
.video {width: 100%;
}

<div class&#61;"player"><video id&#61;"video" class&#61;"video" controls&#61;"controls" playsinline x5-video-player-type&#61;"h5"><source src&#61;"video.mp4" />video>
div>

点击播放后&#xff0c;页面会瞬间拉伸&#xff08;体验有点差&#xff09;&#xff0c;然后就进入了全屏状态&#xff0c;视频默认在中间位置&#xff1a;

调整位置

在全屏状态下&#xff0c;调整视频位置的通用做法是&#xff1a;把video元素的尺寸设成满屏&#xff0c;再通过 object-position 样式属性控制视频内容的位置。相关代码如下&#xff1a;

.fullscreen .video {object-position: center top;
}

var player &#61; document.getElementById(&#39;video&#39;);
var isFullScreen;// 进入全屏&#xff0c;设置状态
player.addEventListener(&#39;x5videoenterfullscreen&#39;, function() {isFullScreen &#61; true;// 在body上添加样式类以控制全屏状态下的页面布局document.body.classList.add(&#39;fullscreen&#39;);
}, false);// 退出全屏时&#xff0c;清空状态
player.addEventListener(&#39;x5videoexitfullscreen&#39;, function() {isFullScreen &#61; false;document.body.classList.remove(&#39;fullscreen&#39;);player.style.width &#61; player.style.height &#61; &#39;&#39;;
}, false);// 同层播放器进入全屏状态会导致窗口resize&#xff0c;但退出全屏不会
window.addEventListener(&#39;resize&#39;, function() {if (isFullScreen) {// 设为屏幕尺寸player.style.width &#61; window.screen.width &#43; &#39;px&#39;;player.style.height &#61; window.screen.height &#43; &#39;px&#39;;}
}, false);

效果如下方左图所示&#xff0c;可见&#xff0c;此时视频距离顶部尚有一些距离。这个问题与 x5-video-player-fullscreen 属性有关。如果不声明这个属性&#xff0c;原标题栏的占位不会分配给页面&#xff0c;而是平均分成上下两块&#xff0c;分别位于窗口顶部和底部。因此&#xff0c;视频无法顶到最上方。

补充 x5-video-player-fullscreen 属性后&#xff0c;问题就解决了&#xff08;上方右图&#xff09;&#xff1a;

<video id&#61;"video" class&#61;"video" controls&#61;"controls" playsinline x5-video-player-type&#61;"h5" x5-video-player-fullscreen&#61;"true"><source src&#61;"video.mp4" />
video>

大家还可以发现&#xff0c;顶部有一层黑色渐变&#xff08;上图不太明显&#xff0c;可以看下文的图&#xff09;以及两个按钮。据官方文档所述&#xff0c;这些都是无法移除的。

全屏状态下的布局

实际业务中&#xff0c;页面多半不会只有一个视频这么简单&#xff0c;下面就开始添加其他页面元素&#xff08;请行引入rem布局所需的脚本&#xff09;。首先是在视频之前加上标题栏&#xff1a;

.header {width: 100%;height: 1.14rem;line-height: 1.14rem;background: #fff;font-size: 0.36rem;text-align: center;color: #000;
}

<header id&#61;"header" class&#61;"header">标题栏header>
<div class&#61;"player"><video id&#61;"video" class&#61;"video" controls&#61;"controls" playsinline x5-video-player-type&#61;"h5" x5-video-player-fullscreen&#61;"true"><source src&#61;"video.mp4" />video>
div>

然而&#xff0c;点击播放进入全屏状态后&#xff0c;标题栏就消失了&#xff0c;其实它是被视频挡住了。既然同层播放器是可以被遮挡的&#xff0c;那可以试试绝对定位&#xff1a;

.fullscreen .header {position: absolute;top: 0;left: 0;z-index: 9999;
}

从下方左图可见&#xff0c;标题栏确实可以挡住视频了。

此时视频内容被遮挡&#xff0c;所以要将其下移&#xff08;上方右图&#xff09;&#xff1a;

.fullscreen .video {object-position: center 1.14rem;
}

接下来在视频之后添加其他页面元素&#xff0c;常规做法是限制视频区域高度&#xff0c;再进行后面的布局。但由于video元素本身在全屏状态下的宽高必须设成满屏&#xff0c;所以只能通过它的父元素&#xff08;div.player&#xff09;限制它的占位&#xff1a;

.player {height: 4.22rem;
}
.fullscreen .player {/* 全屏状态下重设高度&#xff0c;勿忘 */height: 5.36rem; /* 4.22 &#43; 1.14 */
}
.video {width: 100%;height: 100%;
}
.main {box-sizing: border-box;padding: 0.3rem;height: 5rem;background: #fff;
}

<header id&#61;"header" class&#61;"header">...header>
<div class&#61;"player">...div>
<div id&#61;"main" class&#61;"main">这里是其他内容div>

而div.main本身是不需要做任何特殊处理的。然而&#xff0c;此时又出现了一个新问题&#xff1a;进入全屏状态后&#xff0c;视频控制栏不见了。原因是&#xff0c;video元素的高度为屏幕高度&#xff0c;控制栏位于屏幕最底端&#xff0c;而div.player又限制了高度&#xff0c;导致video元素超出的区域被隐藏&#xff0c;自然就看不到控制栏了。幸好&#xff0c;我们还可以通过伪元素选择器修改控制栏的样式&#xff1a;

.fullscreen .player {position: relative;height: 5.36rem;
}
.fullscreen .video::-webkit-media-controls {position: absolute;bottom: 0;
}

通过使控制栏相对于div.player定位&#xff0c;就可以让它回到视频画面的底端了。最终效果如下图所示&#xff1a;

综上所述&#xff0c;在全屏状态下&#xff0c;video元素之前的元素需要做布局调整&#xff0c;而在其后的元素则不需要

页面滚动

如果页面有滚动条&#xff0c;进入全屏状态后&#xff0c;是否还可以滚动呢&#xff1f;

笔者撰写本文第一版&#xff08;2017年中&#xff09;的时候&#xff0c;全屏状态下的页面滚动会变成抖动&#xff0c;效果非常糟糕&#xff0c;而目前则是滚不了了。

所以&#xff0c;如果页面内容确实较多&#xff0c;只能使用元素内滚动了

控制栏的坑

不得不说&#xff0c;原生控制栏的bug非常严重。

Bug 1&#xff1a;播放某些格式的视频时&#xff0c;进度条会出现错乱&#xff0c;即使退出全屏模式也还是错乱。

Bug 2&#xff1a;控制栏的全屏按钮在某些情况&#xff08;具体规律尚未查明&#xff09;下无效。

Bug 3&#xff1a;整个控制栏在某些情况&#xff08;具体规律尚未查明&#xff09;下无法调出。

以上三个bug非必现。但为了躲开这些坑&#xff0c;建议屏蔽原生控制栏&#xff0c;自行开发一个控制栏。

视频全屏的实现

上一节提到&#xff0c;原生控制栏的全屏按钮在某些情况下无效&#xff0c;这样一来就必须想其他方法去实现视频的全屏了&#xff0c;这里面最关键就是video元素的 x5-video-orientation 属性。它决定了同层播放器进入全屏状态后&#xff0c;当前窗口是横屏还是竖屏&#xff08;前文的所有描述中&#xff0c;都是竖屏的情况&#xff09;。并且&#xff0c;它是可以动态设置的。

如果把 x5-video-orientation 设成横屏&#xff0c;再把页面上的其他元素隐藏掉&#xff0c;就跟全屏无异了。具体实现如下&#xff1a;

var isLandscape;// 点击其他内容区域&#xff0c;进入全屏
var main &#61; document.getElementById(&#39;main&#39;);
main.addEventListener(&#39;click&#39;, function() {// 同层播放器进入全屏状态之后&#xff0c;才能让视频全屏if (!isFullScreen) { return; }// 修改 x5-video-orientationplayer.setAttribute(&#39;x5-video-orientation&#39;, &#39;landscape&#39;);isLandscape &#61; true;
}, false);// 检测窗口方向改变&#xff0c;修改布局
window.addEventListener(&#39;orientationchange&#39;, function() {if (isLandscape) {document.body.classList.add(&#39;landscape&#39;);var width &#61; window.screen.width;var height &#61; window.screen.height;player.style.width &#61; width &#43; &#39;px&#39;;player.style.height &#61; height &#43; &#39;px&#39;;}
}, false);

.landscape .header { display: none; }
.landscape .video { object-position: center center; }
.landscape .main { display: none; }

要强调的是&#xff0c;从修改 x5-video-orientation 到窗口方向改变&#xff0c;需要一定的时间才能完成。因此&#xff0c;不要在修改之后马上调整布局&#xff0c;而是要监听 window 的 orientationchange 事件&#xff0c;在事件回调中调整布局。此外&#xff0c;还要在退出全屏时&#xff0c;清空相关状态&#xff1a;

player.addEventListener(&#39;x5videoexitfullscreen&#39;, function() {isFullScreen &#61; false;isLandscape &#61; false;document.body.classList.remove(&#39;fullscreen&#39;, &#39;landscape&#39;);player.style.width &#61; player.style.height &#61; &#39;&#39;;
}, false);

最终效果如下&#xff08;顶部的阴影和两个按钮仍然无法干掉&#xff09;&#xff1a;

后记

本文第一版写于2017年6月&#xff0c;当时刚接触同层播放器&#xff0c;所以文章内容只能算是一份试用报告。经过一年多的项目实践之后&#xff0c;有些旧问题找到了更好的解决方案&#xff0c;还发现并解决了一些新问题&#xff0c;而同层播放器本身也有一些变化&#xff0c;于是在2018年11月进行修订&#xff0c;发布第二版。

本文同时发布于作者个人博客&#xff1a; mrluo.life/article/det…


转载于:https://juejin.im/post/5be553a7e51d450e6f661d67


推荐阅读
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 深入解析 Vue 中的 Axios 请求库
    本文深入探讨了 Vue 中的 Axios 请求库,详细解析了其核心功能与使用方法。Axios 是一个基于 Promise 的 HTTP 客户端,支持浏览器和 Node.js 环境。文章首先介绍了 Axios 的基本概念,随后通过具体示例展示了如何在 Vue 项目中集成和使用 Axios 进行数据请求。无论你是初学者还是有经验的开发者,本文都能为你解决 Vue.js 相关问题提供有价值的参考。 ... [详细]
  • 在MFC框架中,存在多个全局函数,用于在不同对象间获取信息或创建新对象。其中,`afxGetApp`函数尤为关键,它能够帮助开发者轻松获取当前应用程序的实例指针。本文将详细解析`afxGetApp`函数的内部机制及其在MFC应用程序中的具体应用场景,探讨其在提升代码可维护性和灵活性方面的优势。此外,还将介绍其他常用全局函数如`AfxWinInit()`和`AfxBeginThread()`的功能和使用方法,为开发者提供全面的参考。 ... [详细]
  • FastDFS Nginx 扩展模块的源代码解析与技术剖析
    FastDFS Nginx 扩展模块的源代码解析与技术剖析 ... [详细]
  • Java SE 文件操作类详解与应用
    ### Java SE 文件操作类详解与应用#### 1. File 类##### 1.1 File 类概述File 类是 Java SE 中用于表示文件和目录路径名的对象。它提供了丰富的方法来操作文件和目录,包括创建、删除、重命名文件,以及获取文件属性和信息。通过 File 类,开发者可以轻松地进行文件系统操作,如检查文件是否存在、读取文件内容、列出目录下的文件等。此外,File 类还支持跨平台操作,确保在不同操作系统中的一致性。 ... [详细]
  • 深入解析微信小程序开发中的全局配置文件设置与优化技巧
    本文深入探讨了微信小程序开发中全局配置文件的设置与优化技巧,详细解析了 `app.js`、`app.json`、`app.wxss` 和 `project.config.json` 的功能与最佳实践。通过合理配置这些文件,开发者可以显著提升小程序的性能和用户体验。文章还介绍了如何利用这些配置文件进行模块化开发和调试,帮助开发者更好地管理和维护小程序项目。 ... [详细]
  • 在今天的实践中,我深入学习了网页图像抓取技术,通过编写爬虫程序批量获取网站上的图片资源。具体来说,我选择了一个包含大量高质量图片的网站作为练习对象,并成功实现了将这些图片批量下载到本地存储。这一过程不仅提升了我对爬虫技术的理解,还增强了我的编程能力。 ... [详细]
  • Python爬虫入门:深入解析HTTP协议与Requests库的应用
    Python爬虫入门:深入解析HTTP协议与Requests库的应用 ... [详细]
  • Java中处理NullPointerException:getStackTrace()方法详解与实例代码 ... [详细]
  • React 实现 Post 请求下载 PDF 文件的解决方案
    在 React 应用中实现通过 POST 请求下载 PDF 文件的功能,本文提供了完整的代码示例。具体实现包括设置状态以显示加载提示,并通过控制台日志记录下载索引,确保请求的正确性和用户体验。此外,还详细介绍了如何处理响应流并将其转换为可下载的 PDF 文件,适用于需要安全传输数据的场景。 ... [详细]
  • 地图集成方法与应用 ... [详细]
  • 本次发布的Qt音乐播放器2.0版本在用户界面方面进行了细致优化,提升了整体的视觉效果和用户体验。尽管核心功能与1.0版本保持一致,但界面的改进使得操作更加直观便捷,为用户带来了更为流畅的使用体验。此外,我们还对部分细节进行了微调,以确保软件的稳定性和性能得到进一步提升。 ... [详细]
  • HTTP请求与响应机制:基础概览
    在Web浏览过程中,HTTP协议通过请求和响应报文实现客户端与服务器之间的通信。当用户访问一个网页时,浏览器会发送一个HTTP请求报文至服务器,服务器接收到请求后,会生成并返回一个HTTP响应报文。这两种报文均包含三个主要部分:起始行、头部字段和消息体,确保了数据的有效传输和解析。 ... [详细]
  • 结语 | 《探索二进制世界:软件安全与逆向分析》读书笔记:深入理解二进制代码的逆向工程方法
    结语 | 《探索二进制世界:软件安全与逆向分析》读书笔记:深入理解二进制代码的逆向工程方法 ... [详细]
  • 本文介绍了如何通过掌握 IScroll 技巧来实现流畅的上拉加载和下拉刷新功能。首先,需要按正确的顺序引入相关文件:1. Zepto;2. iScroll.js;3. scroll-probe.js。此外,还提供了完整的代码示例,可在 GitHub 仓库中查看。通过这些步骤,开发者可以轻松实现高效、流畅的滚动效果,提升用户体验。 ... [详细]
author-avatar
小变态徒
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有