什么是hivideo?

最近一段时间在使用PhoneGap开发一个App应用,App需要播放视频,本想直接使用html5的video,但使用它在全屏播放时不支持横屏播放,只能放弃。最终决定还是自己封装一个播放器算了,免得以后要扩展功能麻烦。

最近迷上hi这个单词,所以我给这个播放器取名叫做:hivideo。

hivideo是一款基于html5的视频播放器,摒弃video原有的播放控制条样式,自己重写了一次。支持暂停、播放进度控制、声音控制、全屏播放。如果是要在手机端使用hivideo,全屏播放时还支持横屏播放。

hivideo最终实现的效果如下:

如何使用hivideo?

hivideo目录结构:

assets

----images

----hivideo.css

hivideo.js

要想使用hivideo,首先得在主界面引入样式hivideo.css文件。

<link rel="stylesheet" href="assets/hivideo.css" />

hivideo.js文件可在主页面直接引用,同时也支持CommonJs、AMD规范。

在需要转换为hivideo播放器的video标签上添加属性:

<video ishivideo="true"></video>

hivideo会自动把上面的video元素转换为hivideo播放器。我们还可以在video标签上设置播放属性:

1.autoplay: 自动播放。

2.isrotate:全屏是否横屏播放,如果在手机端使用hivideo,我们可以设置该属性为true,表示全屏播放时横屏显示。

3.autoHide:播放视频时自动隐藏控制条。

使用方式:

<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元素,可通过如下方式把video转换为hivideo播放器:

hivideo(document.getElementById("player"));

在线演示Demo:https://heavis.github.io/hivideo/index.html

开源地址:https://github.com/heavis/hivideo

如何隐藏浏览器的播放器样式

目前大多数浏览器都支持video元素,并且不同浏览器实现的video样式也不尽相同。

chrome实现的播放器样式:

Firefox实现的播放器样式:

IE实现的播放器样式:

为了让播放器在各个浏览器下样式统一,首先要隐藏各个浏览器实现的样式。但一般我们通过浏览器开发工具查看不到播放器下的元素,因为这些元素都是阴影元素,它们是通过文档片段附加到video上,对于文档流是不可见的。
    如何查看浏览器下的阴影元素?Chrome为开发人员提供了可选项,打开开发者工具->Settings->General页签,我们能看到Elments有一个叫做”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函数都对应多个版本,需要考虑兼容性。

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到100。

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;
// go full-screen
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{
// exit full-screen
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;
})
}

如果本篇内容对大家有帮助,请点击页面右下角的关注。如果觉得不好,也欢迎拍砖。你们的评价就是博主的动力!下篇内容,敬请期待!

分享一个基于HTML5实现的视频播放器的更多相关文章

  1. 分享一个基于HTML5实现的视频播放器【转】

    什么是hivideo? 最近一段时间在使用PhoneGap开发一个App应用,App需要播放视频,本想直接使用html5的video,但使用它在全屏播放时不支持横屏播放,只能放弃.最终决定还是自己封装 ...

  2. HTML5实现的视频播放器01

    HTML5实现的视频播放器   什么是hivideo? 最近一段时间在使用PhoneGap开发一个App应用,App需要播放视频,本想直接使用html5的video,但使用它在全屏播放时不支持横屏播放 ...

  3. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  4. 最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  5. 基于<最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)>的一些个人总结

    最近因为项目接近收尾阶段,所以变的没有之前那么忙了,所以最近重新拿起了之前的一些FFMPEG和SDL的相关流媒体播放器的例子在看. 同时自己也用FFMPEG2.01,SDL2.01结合MFC以及网上罗 ...

  6. 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】

    转自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] ...

  7. 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器

    ===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...

  8. [UWP]分享一个基于HSV色轮的调色板应用

    1. 前言 上一篇文章介绍了HSV色轮,这次分享一个基于HSV色轮的调色板应用,应用地址:ColorfulBox - Microsoft Store 2. 功能 ColorfulBox是Adobe 色 ...

  9. 用JavaCV改写“100行代码实现最简单的基于FFMPEG+SDL的视频播放器 ”

    FFMPEG的文档少,JavaCV的文档就更少了.从网上找到这篇100行代码实现最简单的基于FFMPEG+SDL的视频播放器.地址是http://blog.csdn.net/leixiaohua102 ...

随机推荐

  1. 大家一起Aop

    一.前言 1.在项目中无处不充斥着记录日志的代码,各种try catch,实在是有点看着不爽.这不,果断要想法子偷个懒儿. 二.摘要 鄙人不才,先总结一下个人想到的可实现AOP的几种思路: 1.通过继 ...

  2. 一个哥们看到数据库日志不断增大 [log_reuse_wait_desc]为replication 之后的做法

    一哥们看到数据库日志不断增大 [log_reuse_wait_desc]为replication 之后的做法 一天那个哥们看到数据库日志暴涨,用sys.databases 视图看一下[log_reus ...

  3. CSS3 特效分解一

    先声明下,下面的特效不是我发明的,对CSS3的创造力还不够,只是看了别人demo的源码,一点一点分析出来的.整理出的笔记,分享给大家.因为源码是好,但是一头扎进去半天出不来. 首先看个登陆框,如下,相 ...

  4. 初试ASP.NET Web API/MVC API(附Demo)

    写在前面 HTTP RESTful 创建Web API 调用Web API 运行截图及Demo下载 ASP.NET Web API是​​一个框架,可以很容易构建达成了广泛的HTTP服务客户端,包括浏览 ...

  5. [nRF51822] 8、基础实验代码解析大全 · 实验11 - PPI

    前一篇分析了前十个基础实验的代码,从这里开始分析后十个~ 一.PPI原理: PPI(Programmable Peripheral Interconnect),中文翻译为可编程外设互连. 在nRF51 ...

  6. Tomcat7基于Redis的Session共享实战二

    目前,为了使web能适应大规模的访问,需要实现应用的集群部署.集群最有效的方案就是负载均衡,而实现负载均衡用户每一个请求都有可能被分配到不固定的服务器上,这样我们首先要解决session的统一来保证无 ...

  7. wpf ListView DataTemplate方式的鼠标悬停和选中更改背景色

    今天使用wpf技术弄一个ListView的时候,由于需求需要,需要ListView显示不同的数据模板,很自然的使用了DataTemplate方式来定义多个数据模板,并在ListView中使用ItemT ...

  8. js实用篇之String对象

    概述 String对象是JavaScript原生提供的三个包装对象之一,用来生成字符串的包装对象. var s1 = 'abc'; var s2 = new String('abc'); typeof ...

  9. Java 循环中标签的作用

    continue和break可以改变循环的执行流程,但在多重循环中,这两条语句无法直接从内层循环跳转到外层循环.在C语言中,可以通过goto语句实现多重循环的跳转,但在非循环结构中使用goto语句会使 ...

  10. JQuery插件之Jquery.datatables.js用法及api

    1.DataTables的默认配置 $(document).ready(function() { $('#example').dataTable(); } ); 示例:http://www.guoxk ...