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

摘要:
最近,我正在使用PhoneGap开发一个应用程序。应用程序需要播放视频。我想直接使用html5视频,但在全屏播放时它不支持水平播放,所以我不得不放弃。最后,我决定自己打包一个播放器,以避免将来扩展功能的麻烦。最近,我被hi这个词迷住了,所以我把这个玩家命名为hivideo。Hivideo是一款基于html5的视频播放器。它抛弃了视频的原始播放控制栏样式,并自行重写。在实现之前,我们需要了解视频提供的API。

什么是hivideo?

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

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

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

    hivideo最终实现的效果如下:

image

如何使用hivideo?

    hivideo目录结构:

复制代码
assets

----images

----hivideo.css

hivideo.js
复制代码

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

<link rel="stylesheet" href="http://t.zoukankan.com/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实现的播放器样式:

image

    Firefox实现的播放器样式:

image

    IE实现的播放器样式:

image

   

    为了让播放器在各个浏览器下样式统一,首先要隐藏各个浏览器实现的样式。但一般我们通过浏览器开发工具查看不到播放器下的元素,因为这些元素都是阴影元素,它们是通过文档片段附加到video上,对于文档流是不可见的。
    如何查看浏览器下的阴影元素?Chrome为开发人员提供了可选项,打开开发者工具->Settings->General页签,我们能看到Elments有一个叫做”Show user agent shadow DOM”的选项:

image

    勾选上该选项,现在我们通过开发工具可以查看到video下的播放元素:

image

    上图中<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实现的视频播放器【转】》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇angular1.5 组件学习 -- 4.1、组件的其他属性 requireInfluxDB学习(三):InfluxDB数据库series、points下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

一文学会conda基本使用

Conda 简介 Conda 是一个开源的包管理系统和环境管理系统,可在 Windows、macOS 和 Linux 上运行。 Conda 可快速安装、运行和更新包及其依赖项。 Conda 可以轻松地在计算机上创建、保存、加载和切换环境。 它是为 Python 程序而创造的,但它可以打包和分发任何语言的软件。 简单来说,conda可以让我们一行命令安装更新...

基于React Native的58 APP开发实践

React Native在iOS界早就炒的火热了,随着2015年底Android端推出后,一套代码能运行于双平台上,真正拥有了Hybrid框架的所有优势。再加上Native的优秀性能,让越来越多的公司在实际项目中一探究竟。58同城APP发布模块年代久远,一直计划进行重构以适应日益苛刻的用户体验,这个需求与我们在React Native上一探究竟的意愿一碰撞...

移动APP 微信支付完整过程(wxPay 方案一)

前两天开始做移动端APP的微信支付,过程中遇到了一些问题,比如支付的过程中返回值总是:-1 {status:false},这些问题已经得到了解决。前人栽树,后人尽管乘凉,那么分享一下整个支付过程(wxPay 方案一): 1、申请微信开发平台的账号、创建移动应用、申请开发者资质认证(整个过程APICLOUD官方网站已经给出了相当明确的操作步骤,与实际操作没有...

详细设计文档

详细设计文档 1.引言 随着广大在校大学生生活水平的提高,在假期选择外出旅游的学生愈加增多,针对大学生群体的旅游APP就显得很有市场价值。 1.1编写目的 本节描述软件详细设计文档的目的是: 定义软件总体要求,作为用户和软件开发人员之间互相了解的基础; 作为软件总体测试和系统结构设计的依据; 本文档的预期读者包括:软件设计人员、模块开发人员、管理人员、测试...

自动写文章的智能软件(基于AI写作)

今天,我们想和你分享一个可以自动写原创文章的软件,理论是基于人工智能科学家乔姆斯基变换生成语法,我是基于这个AI写作进行封装的。发展的原则其实很简单。它与互联网上人工智能平台的应用编程接口接口,实现了自动写文章的功能! 软件使用的文章渲染算法也是基于:乔姆斯基变换生成语法,效果还是不错的!通过这个软件,你每天可以生成数万篇文章,这些文章应该是超越文字和原创...

HTML5安全风险详析之一:CORS攻击

CORS-CrossOrigin Resources Sharing,也即跨源资源共享,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。 一、从SOP到CORS SOP就是Same Origin Polic...