zoukankan      html  css  js  c++  java
  • 分享一个基于HTML5实现的视频播放器

    原文:http://www.cnblogs.com/w-wanglei/p/5763103.html

     

    什么是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="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;
        })
    }
  • 相关阅读:
    FEniCS 1.1.0 发布,计算算术模型
    Piwik 1.10 发布,增加社交网站统计
    淘宝褚霸谈做技术的心态
    CyanogenMod 10.1 M1 发布
    Druid 发布 0.2.11 版本,数据库连接池
    GNU Gatekeeper 3.2 发布
    Phalcon 0.9.0 BETA版本发布,新增大量功能
    EUGene 2.6.1 发布,UML 模型操作工具
    CVSps 3.10 发布,CVS 资料库更改收集
    Opera 移动版将采用 WebKit 引擎
  • 原文地址:https://www.cnblogs.com/liangbo-/p/6547298.html
Copyright © 2011-2022 走看看