最新文章
泰课在线 | 微信拼团成功后如何获取课程?
08-09 17:57
Unity教程 | 使用ARKit为iOS开发AR应用
07-31 17:23
Unity Pro专业版7折订阅四选一工具包之VR开发与艺术设计
07-28 11:47
网友使用虚幻UE4实现CAVE 多通道立体渲染的沉浸式环境
07-27 11:57
VR晕动症调查:未来5年内大部分VR晕动症将得到解决
07-27 11:26
AMD CEO:未来3-5年最重要 希望5年达1亿VR用户
07-27 10:44
基于HTML5实现的视频播放器
关于hivideo
近期,我在使用PhoneGap开发一款App应用,该应用需要具备视频播放功能。起初,我打算直接采用HTML5的<video>标签来实现,但在实际使用中发现,其在全屏播放时不支持横屏,因此只能放弃这一方案。为了便于后续功能扩展,我决定自行封装一个视频播放器,并将其命名为“hivideo”。
hivideo是一款基于HTML5的视频播放器,它摒弃了原生<video>标签的播放控制条样式,重新进行了设计。该播放器支持暂停、播放进度控制、声音控制以及全屏播放等功能。若在手机端使用,全屏播放时还支持横屏显示。
hivideo最终实现的效果如下:
如何使用hivideo
hivideo目录结构
assets
----images
----hivideo.css
hivideo.js
引入文件
要使用hivideo,首先需要在主界面引入样式文件hivideo.css:
<link rel="stylesheet" href="assets/hivideo.css" />
hivideo.js文件既可以在主页面直接引用,也支持CommonJS和AMD规范。
转换为hivideo播放器
在需要转换为hivideo播放器的<video>标签上添加ishivideo="true"属性,hivideo会自动将该<video>元素转换为hivideo播放器。示例如下:
<video ishivideo="true"></video>
同时,我们还可以在<video>标签上设置以下播放属性:
autoplay:设置为true时,视频将自动播放。isrotate:若在手机端使用hivideo,将该属性设置为true,表示全屏播放时横屏显示。autoHide:设置为true时,播放视频时将自动隐藏控制条。
使用示例:
<video ishivideo="true" autoplay="true" isrotate="false" autoHide="true">
<source src="http://www.html5videoplayer.net/videos/madagascar3.mp4" type="video/mp4">
</video>
动态加载
如果是后期动态添加的<video>元素,也可以通过hivideo进行动态加载。例如,页面动态添加了一个id为player的<video>元素,可通过以下方式将其转换为hivideo播放器:
hivideo(document.getElementById("player"));
如何隐藏浏览器的播放器样式
目前,大多数浏览器都支持<video>元素,但不同浏览器实现的<video>样式存在差异。为了让播放器在各个浏览器下样式统一,需要先隐藏各个浏览器自带的样式。
然而,一般通过浏览器开发工具无法直接查看播放器下的元素,因为这些元素属于阴影元素(Shadow DOM),它们是通过文档片段附加到<video>上的,对于文档流是不可见的。
在Chrome浏览器中,我们可以通过以下步骤查看阴影元素:打开开发者工具 -> Settings -> General页签,在Elements中找到“Show user agent shadow DOM”选项并勾选。勾选后,通过开发工具即可查看到<video>下的播放元素。
其中,<div pseudo="-webkit-media-controls">元素是控制条的容器,我们只需将其display属性设置为none,即可隐藏控制条。不过,需要兼容各个浏览器,具体样式代码如下:
video[ishivideo="true"]::-webkit-media-controls {
display: none !important;
}
video[ishivideo="true"]::-moz-media-controls {
display: none !important;
}
video[ishivideo="true"]::-o-media-controls {
display: none !important;
}
video[ishivideo="true"]::media-controls {
display: none !important;
}
需要注意的是,将上述样式通过合并的方式书写是无效的,以下写法不能隐藏阴影元素:
video[ishivideo="true"]::-webkit-media-controls,
video[ishivideo="true"]::-moz-media-controls,
video[ishivideo="true"]::-o-media-controls,
video[ishivideo="true"]::media-controls {
display: none !important;
}
隐藏浏览器阴影元素后,就可以开始实现自定义控制条了。在实现之前,我们需要了解<video>标签提供的API。
播放器常用API
各个浏览器操作播放器提供的API名称通常带有厂商前缀,因此基本上每个API函数都对应多个版本,需要考虑兼容性。以下是一些常用的API:
1. 全屏事件
["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"].forEach(function(eventType) {
document.addEventListener(eventType, function(event) {
// 处理全屏状态变化事件
});
});
当播放器全屏状态发生变化时,上述事件会被触发。但仅通过该事件,我们只能知道全屏状态发生了改变,无法确定当前是进入全屏还是退出全屏,还需要结合全屏状态API进行判断。
2. 当前是否全屏状态
hivideo.prototype.isFullScreen = function() {
return document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement;
};
上述代码是hivideo封装的判断是否全屏的函数。
3. 进入全屏模式
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen();
} else if (video.msRequestFullscreen) {
video.msRequestFullscreen();
}
4. 退出全屏模式
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
5. 播放状态
video.paused属性用于判断视频的播放状态,true表示未播放,false表示正在播放。
6. 播放视频
video.play();
7. 暂停播放
video.pause();
8. 是否静音
video.muted = true; // 静音
video.muted = false; // 不静音
9. 声音控制
通过设置video.volume属性来控制声音大小,其值的范围为0到1。
10. 当前播放时间
video.currentTime属性可读可写,单位为秒。可以通过<input type='range'>的值来显示播放进度。
11. 视频总时长
video.duration属性表示视频的总时长,单位为秒。
12. 播放时间更新事件
video.addEventListener("timeupdate", function() {
// 处理播放时间更新事件
});
13. 视频元数据加载完成事件
一般在播放视频时会显示视频总时长,当触发loadedmetadata事件时,视频元数据已经加载完成,因此可以在该事件中设置总时长的显示。
video.addEventListener("loadedmetadata", function() {
// 处理视频元数据加载完成事件
});
14. 视频播放结束事件
video.addEventListener("ended", function() {
// 处理视频播放结束事件
});
有了上述API,实现自定义播放器就相对容易了,在实现过程中,只需在相应位置调用对应的API即可。
如何实现横屏播放
实现横屏播放的原理较为简单,在全屏时,播放器容器会占据整个屏幕。我们可以为容器添加一个自定义样式,使其旋转90度。示例样式如下:
.rotate90 {
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
}
旋转后的容器宽度和高度需要进行调整,将屏幕的高度screen.height赋值给容器的宽度,将屏幕的宽度赋值给容器的高度,这样就能实现全屏横屏播放效果。以下是全屏播放控制的完整代码:
hivideo.prototype.bindFullEvent = function() {
var self = this;
var origWidth = origHeight = 0;
["fullscreenchange", "webkitfullscreenchange", "mozfullscreenchange", "MSFullscreenChange"].forEach(function(eventType) {
var curFullhivideoId = null;
document.addEventListener(eventType, function(event) {
if ((curFullhivideoId = document.body.getAttribute("curfullHivideo")) && curFullhivideoId !== self.videoId_) {
return;
}
var isRotate = self.options.isrotate;
if (self.isFullScreen()) {
var cltHeight = isRotate ? window.screen.width : window.screen.height;
var cltWidth = isRotate ? window.screen.height : window.screen.width;
if (isRotate && !hivideo.hasClass(self.videoParent, "rotate90")) {
hivideo.addClass(self.videoParent, "rotate90");
}
self.videoParent.style.height = cltHeight + "px";
self.videoParent.style.width = cltWidth + "px";
} else {
if (isRotate) {
self.videoParent.className = self.videoParent.className.replace("rotate90", "").trim();
}
self.videoParent.style.height = origHeight + "px";
self.videoParent.style.width = origWidth + "px";
}
});
});
self.fullBtn && self.fullBtn.addEventListener("click", function() {
if (!self.isFullScreen()) {
document.body.setAttribute("curfullHivideo", self.videoId_);
origWidth = self.videoParent.offsetWidth;
origHeight = self.videoParent.offsetHeight;
// 进入全屏
if (self.videoParent.requestFullscreen) {
self.videoParent.requestFullscreen();
} else if (self.videoParent.webkitRequestFullscreen) {
self.videoParent.webkitRequestFullscreen();
} else if (self.videoParent.mozRequestFullScreen) {
self.videoParent.mozRequestFullScreen();
} else if (self.videoParent.msRequestFullscreen) {
self.videoParent.msRequestFullscreen();
}
self.exchangeBtnStatus(this, false);
} else {
// 退出全屏
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
self.exchangeBtnStatus(this, true);
}
});
return self;
};
支持CommonJS、AMD规范
1. CommonJS支持
(function(global, factory) {
"use strict";
// 支持CommonJS规范
if (typeof module === "object" && typeof module.exports === "object") {
module.exports = factory(global);
} else {
factory(global);
}
}(typeof window !== "undefined" ? window : this, function(window) {
// 具体实现代码
}));
2. AMD支持
// 支持AMD规范
if (typeof define === "function" && define.amd) {
define("hivideo", [], function() {
return hivideo;
});
}
大家觉得有帮助请关注“泰斗社区”了解更多相关资讯。