简介
HTML5的<video>标签已经被目前大多数主流浏览器所支持,包括还未正式发布的IE9也声明将支持<video>标签,利用浏览器原生特性嵌入视频有很多好处,所以很多开发者想尽快用上,但是真正使用前还有些问题要考虑,尤其是 Opera/Firefox 和IE/Safari浏览器所支持的视频编码不同的问题,Google几个月前发布的开源视频编码VP8有望能解决这一问题,另外Google还发布了开放网络媒体项目WebM,旨在帮助开发者为开放网络制作出世界级媒体格式,Opera, Firefox,
Chrome和IE9都将支持VP8,而且Flash Player也将可以播放VP8,这就意味着我们很快就可以只制作一个版本的视频然后在所有主流浏览器上播放了。另外一个主要的问题就是如何构建自定义的HTML5<video>播放器,这是目前Flash Player的优势所在,利用Flash的IDE所提供的接口可以很方便的构建一个个性化的视频播放器,那HTML5的<video>标签要怎样才能实现呢?这个问题就是本文所要解决的!我们将开发一个HTML5<video>视频播放器的jQuery插件,并且可以很方便的进行自定义,将分为以下几个部分:
1.视频控制工具条
2.视频控制按钮
3.打包成jQuery插件
4.外观和体验
5.自定义皮肤
视频控制工具条
做为一个专业的web开发人员,我们创建一个视频播放器时一定希望它的外观在各个浏览器中看起来一致(consistent),但是通过下面的图可以看到目前各个浏览器提供的视频控制工具条外观各不相同:

那就没办法了,我们得自己从头来创建这个控制工具条,利用HTML和CSS再加上一些图片实现起来并不算很难,另外通过HTML5多媒体元素提供的API我们可以很方便将创建的任何按钮与播放/暂停等事件进行绑定。

视频控制按钮
基本的视频控制工具条要包含一个播放/暂停按钮,一个进度条,一个计时器和一个音量控制按钮,我们将这些按钮放在<video>元素下面,并用一个div作为父容器:

  1. <div
    class="ghinda-video-controls">
  2. <a class="ghinda-video-play" title="Play/Pause"></a>
  3. <div
    class="ghinda-video-seek"></div>
  4. <div
    class="ghinda-video-timer">00:00</div>
  5. <div class="ghinda-volume-box">
  6. <div
    class="ghinda-volume-slider"></div>
  7. <a
    class="ghinda-volume-button"
    title="Mute/Unmute"></a>
  8. </div>
  9. </div>

复制代码

注意,我们使用元素的class属性来代替ID属性是为了方便在一个页面上使用多个播放器。

打包成jQuery插件
创建好控制按钮后我们需要配合多媒体元素的API来实现视频控制的目的,正如前面提到的一样我们将我们的播放器打包成jQuery插件,这样可以很好的实现复用,代码如下:

  1. $.fn.gVideo =
    function(options) {
  2. // build main options before element iteration
  3. var defaults = {
  4. theme: 'simpledark',
  5. childtheme: ''
  6. };
  7. var options = $.extend(defaults, options);
  8. // iterate and reformat each matched element
  9. return this.each(function() {
  10. 10.  
                  var $gVideo =
    $(this);
  11. 11.
  12. 12.  
                  //create html
    structure
  13. 13.  
                  //main wrapper
  14. 14.  
                  var $video_wrap =
    $('<div></div>').addClass('ghinda-video-player').addClass(options.theme).addClass(options.childtheme);
  15. 15.  
                  //controls wraper
  16. 16.  
                  var $video_controls
    = $('<div class="ghinda-video-controls"><a
    class="ghinda-video-play"
    title="Play/Pause"></a><div
    class="ghinda-video-seek"></div><div
    class="ghinda-video-timer">00:00</div><div
    class="ghinda-volume-box"><div
    class="ghinda-volume-slider"></div><a
    class="ghinda-volume-button"
    title="Mute/Unmute"></a></div></div>');
  17. 17.  
                 
    $gVideo.wrap($video_wrap);
  18. 18.  
                 
    $gVideo.after($video_controls);

复制代码

这里先假设您了解jQuery并知道如何创建一个jQuery插件,因为这个不在本文的讨论范围之内,在上面这段脚本中我们使用jQuery动态创建视频控制工具条的元素,接下来为了绑定事件我们需要获取对应的元素:

  1. //get newly
    created elements
  2. var $video_container
    = $gVideo.parent('.ghinda-video-player');
  3. var
    $video_controls = $('.ghinda-video-controls', $video_container);
  4. var
    $ghinda_play_btn = $('.ghinda-video-play', $video_container);
  5. var
    $ghinda_video_seek = $('.ghinda-video-seek', $video_container);
  6. var
    $ghinda_video_timer = $('.ghinda-video-timer', $video_container);
  7. var
    $ghinda_volume = $('.ghinda-volume-slider', $video_container);
  8. var
    $ghinda_volume_btn = $('.ghinda-volume-button', $video_container);

10. $video_controls.hide();
// keep the controls hidden

复制代码

这里我们通过className方式获取,先让工具条隐藏直到所有资源加载完成,现在来实现播放/暂停按钮:

  1. var gPlay =
    function() {
  2. if($gVideo.attr('paused') == false) {
  3. $gVideo[0].pause();
  4. } else {
  5. $gVideo[0].play();
  6. }
  7. };
  8. $ghinda_play_btn.click(gPlay);

10. $gVideo.click(gPlay);

  1. 11.

12. $gVideo.bind('play',
function() {

  1. 13.  
          $ghinda_play_btn.addClass('ghinda-paused-button');

14. });

  1. 15.

16. $gVideo.bind('pause',
function() {

  1. 17.  
      
       $ghinda_play_btn.removeClass('ghinda-paused-button');

18. });

  1. 19.

20. $gVideo.bind('ended',
function() {

  1. 21.  
      
       $ghinda_play_btn.removeClass('ghinda-paused-button');

22. });

复制代码

大多数浏览器在右键点击视频时会提供一个独立的菜单,它也提供了视频控制功能,如果用户通过这个右键菜单控制视频那就会跟我们的自定义控件冲突,所以为了避免这一点我们需要绑定视频播放器自身的“播放”,“暂停”和“结束”事件,在事件处理函数中处理播放/暂停按钮,控制按钮的样式。
为了创建进度条的拖动块,我们使用了jQuery UI的Slider组件:

  1. var createSeek =
    function() {
  2. if($gVideo.attr('readyState')) {
  3. var video_duration =
    $gVideo.attr('duration');
  4. $ghinda_video_seek.slider({
  5. value: 0,
  6. step: 0.01,
  7. orientation: "horizontal",
  8. range: "min",
  9. max: video_duration,
  10. 10.  
                     
        animate: true,
  11. 11.  
                     
        slide: function(){
  12. 12.  
                     
                seeksliding = true;
  13. 13.  
                     
        },
  14. 14.  
                     
        stop:function(e,ui){
  15. 15.  
                     
                seeksliding =
    false;
  16. 16.  
                     
                $gVideo.attr("currentTime",ui.value);
  17. 17.  
                     
        }
  18. 18.  
                  });
  19. 19.  
                 
    $video_controls.show();
  20. 20.  
          } else {
  21. 21.  
                 
    setTimeout(createSeek, 150);
  22. 22.  
          }

23. };

  1. 24.

25. createSeek();

复制代码

正如你所看到的,这里我们写了一个递归函数,通过循环比较video的readyState属性来判断视频是否已经准备好,否则我们就不能获得视频的时长也无法创建滑动块,当视频准备好后我们初始化滑动块并显示控制工具条,下一步我们通过绑定video元素的timeupdate事件实现计时器功能:

  1. var
    gTimeFormat=function(seconds){
  2. var
    m=Math.floor(seconds/60)<10?"0"+Math.floor(seconds/60):Math.floor(seconds/60);
  3. var
    s=Math.floor(seconds-(m*60))<10?"0"+Math.floor(seconds-(m*60)):Math.floor(seconds-(m*60));
  4. return m+":"+s;
  5. };
  6. var seekUpdate =
    function() {
  7. var currenttime = $gVideo.attr('currentTime');
  8. if(!seeksliding)
    $ghinda_video_seek.slider('value', currenttime);
  9. 10.  
      
       $ghinda_video_timer.text(gTimeFormat(currenttime));

11. };

  1. 12.

13. $gVideo.bind('timeupdate',
seekUpdate);

复制代码

这里我们用seekUpdate函数获取video的currentTime属性值然后调用gTimeFormat函数进行格式化后得到当前播放的时间点。
至于音量控制控件我们还是利用jQuery UI的Slider组件然后利用自定义函数实现静音和取消静音的功能:

  1. $ghinda_volume.slider({
  2. value: 1,
  3. orientation: "vertical",
  4. range: "min",
  5. max: 1,
  6. step: 0.05,
  7. animate: true,
  8. slide:function(e,ui){
  9. $gVideo.attr('muted',false);
  10. 10.  
                  video_volume =
    ui.value;
  11. 11.  
                 
    $gVideo.attr('volume',ui.value);
  12. 12.  
          }

13. });

  1. 14.

15. var muteVolume =
function() {

  1. 16.  
          if($gVideo.attr('muted')==true) {
  2. 17.  
                 
    $gVideo.attr('muted', false);
  3. 18.  
                 
    $ghinda_volume.slider('value', video_volume);
  4. 19.
  5. 20.  
                 
    $ghinda_volume_btn.removeClass('ghinda-volume-mute');
  6. 21.  
          } else {
  7. 22.  
                 
    $gVideo.attr('muted', true);
  8. 23.  
                 
    $ghinda_volume.slider('value', '0');
  9. 24.
  10. 25.  
                 
    $ghinda_volume_btn.addClass('ghinda-volume-mute');
  11. 26.  
          };

27. };

  1. 28.

29. $ghinda_volume_btn.click(muteVolume);

复制代码

最后当我们自己的自定义视频控制工具条构造完成后需要移除<video>标签的controls属性,这样浏览器默认的工具条就被去掉了。
好了,我们的插件功能已经全部完成了,调用方法:

  1. $('video').gVideo();

复制代码

这会将我们的插件应用到页面上每一个video元素上。

外观和体验
好的,现在到了比较有意思的部分,也就是播放器的外观和体验了。当插件功能已经完成后利用一点CSS就可以很容易地自定义样式了,我们将全部使用CSS3来实现。
首先,我们给播放器主容器加一些样式:

  1. .ghinda-video-player
    {
  2. float: left;
  3. padding: 10px;
  4. border: 5px solid #61625d;
  5. -moz-border-radius: 5px; /* FF1+ */
  6. -ms-border-radius: 5px; /* IE future proofing */
  7. -webkit-border-radius: 5px; /* Saf3+, Chrome */
  8. border-radius: 5px; /* Opera 10.5, IE 9 */
  9. 10.
  10. 11.  
          background: #000000;
  11. 12.  
          background-image: -moz-linear-gradient(top,
    #313131, #000000); /* FF3.6 */
  12. 13.  
          background-image: -webkit-gradient(linear,left
    top,left bottom,color-stop(0, #313131),color-stop(1, #000000)); /* Saf4+,
    Chrome */
  13. 14.
  14. 15.  
          box-shadow: inset 0 15px 35px #535353;

16. }

复制代码

下一步,我们设置视频控制工具条左边浮动使它们水平对齐,利用CSS3的opacity和transitions我们给播放/暂停和静音/取消静音按钮添加了非常不错的悬浮效果:

  1. .ghinda-video-play
    {
  2. display: block;
  3. width: 22px;
  4. height: 22px;
  5. margin-right: 15px;
  6. background: url(../images/play-icon.png)
    no-repeat;
  7. opacity: 0.7;
  8. 10.  
          -moz-transition: all 0.2s ease-in-out; /*
    Firefox */
  9. 11.  
          -ms-transition: all 0.2s ease-in-out; /* IE
    future proofing */
  10. 12.  
          -o-transition: all 0.2s
    ease-in-out;  /* Opera */
  11. 13.  
          -webkit-transition: all 0.2s ease-in-out; /*
    Safari and Chrome */
  12. 14.  
          transition: all 0.2s ease-in-out;

15. }

  1. 16.

17. .ghinda-paused-button
{

  1. 18.  
          background: url(../images/pause-icon.png)
    no-repeat;

19. }

  1. 20.

21. .ghinda-video-play:hover
{

  1. 22.  
          opacity: 1;

23. }

复制代码

如果您仔细看了前面那段根据视频播放状态(Playing/Paused)添加和移除播放/暂停按钮样式的JavaScript代码,就会明白为什么.ghinda-paused-button为什么要重写.ghinda-video-play的背景属性了。
现在轮到滑动块了,我们进度条和音量控制的滑动块的实现都是利用了jQuery UI的Slider组件,这个组件它本身自带了样式,定义在jQuery UI对应的css文件中,但是为了使滑动块和播放器其他控件外观保持一致我们全部重写了它的样式:

  1. .ghinda-video-seek
    .ui-slider-handle {
  2. width: 15px;
  3. height: 15px;
  4. border: 1px solid #333;
  5. top: -4px;
  6. -moz-border-radius:10px;
  7. -ms-border-radius:10px;
  8. -webkit-border-radius:10px;
  9. border-radius:10px;
  10. background: #e6e6e6;
  11. background-image: -moz-linear-gradient(top, #e6e6e6,
    #d5d5d5);
  12. background-image: -webkit-gradient(linear,left
    top,left bottom,color-stop(0, #e6e6e6),color-stop(1, #d5d5d5));
  13. box-shadow: inset 0 -3px 3px #d5d5d5;
  14. }
  15. .ghinda-video-seek
    .ui-slider-handle.ui-state-hover {
  16. background: #fff;
  17. }
  18. .ghinda-video-seek
    .ui-slider-range {
  19. -moz-border-radius:15px;
  20. -ms-border-radius:15px;
  21. -webkit-border-radius:15px;
  22. border-radius:15px;
  23. background: #4cbae8;
  24. background-image: -moz-linear-gradient(top,
    #4cbae8, #39a2ce);
  25. background-image: -webkit-gradient(linear,left
    top,left bottom,color-stop(0, #4cbae8),color-stop(1, #39a2ce));
  26. box-shadow: inset 0 -3px 3px #39a2ce;
  27. }

复制代码

这时候音量控制的滑动块一直显示在音量按钮旁边,我们需要将它改成默认隐藏,当鼠标悬浮在音量按钮上再动态显示出来,使用transitions来实现这个效果会是个不错的的选择:

  1. .ghinda-volume-box
    {
  2. height: 30px;
  3. -moz-transition: all 0.1s ease-in-out; /*
    Firefox */
  4. -ms-transition: all 0.1s ease-in-out; /* IE
    future proofing */
  5. -o-transition: all 0.2s
    ease-in-out;  /* Opera */
  6. -webkit-transition: all 0.1s ease-in-out; /*
    Safari and Chrome */
  7. transition: all 0.1s ease-in-out;
  8. }
  9. .ghinda-volume-box:hover
    {
  10. height: 135px;
  11. padding-top: 5px;
  12. }
  13. .ghinda-volume-slider
    {
  14. visibility: hidden;
  15. opacity: 0;
  16. -moz-transition: all 0.1s ease-in-out; /*
    Firefox */
  17. -ms-transition: all 0.1s
    ease-in-out;  /* IE future proofing */
  18. -o-transition: all 0.1s
    ease-in-out;  /* Opera */
  19. -webkit-transition: all 0.1s ease-in-out; /*
    Safari and Chrome */
  20. transition: all 0.1s ease-in-out;
  21. }
  22. .ghinda-volume-box:hover
    .ghinda-volume-slider {
  23. position: relative;
  24. visibility: visible;
  25. opacity: 1;
  26. }

复制代码

利用一些基础的CSS属性以及CSS3提供的新属性我们打造了一个全新的播放器外观

自定义皮肤
可能您已经注意到,我们在编写插件的时候已经定义了一些默认选项,它们是theme和childtheme,可以在调用插件的时候根据需要方便的应用自定义皮肤。
这里解释下theme就是所有控件的一整套样式定义,childtheme就是在theme基础上重写某些样式,我们在调用插件的时候可以同时指定这两个选项或者其中的一个:

  1. $('video').gVideo({
  2. childtheme:'smalldark'
  3. });

复制代码

我们写了一个示例的皮肤smalldark,它只重写了部分的样式,显示效果是这样的:

总结
利用HTML5 video,JavaScript和CSS3打造自定义的视频播放器真的非常容易,t实现工具条功能用JavaScrip,外观和体验交给CSS3,我们得到了一个功能强大并且易于定制的解决方案!
enjoy!

使用CSS3+JQuery打造自定义视频播放器的更多相关文章

  1. HTML5+CSS3+JQuery打造自定义视频播放器

    来源:http://www.html5china.com/HTML5features/video/201109206_1994.html 简介HTML5的<video>标签已经被目前大多数 ...

  2. 项目源码--IOS自定义视频播放器

    下载源码 技术要点: 1. 视频播放器功能的实现 2. 视频文件的扫描与管理 3. Ipad UI的实现 4.源码详细的中文注释 ……. 详细介绍: 1. 视频播放器功能的实现 源码基于MediaPl ...

  3. HTML5视频(自定义视频播放器源码)

    video对象 兼容情况: safari浏览器不支持webm格式 Chrome浏览器支持webm格式 ie8以及以下不支持video标签 , ie9支持video标签 ,但是支持mp4格式的 Fire ...

  4. HTML5,CSS3 与 Javascript 制作视频播放器

    早一段时间,有一直研究 HTML5 和 CSS3 ,自己也做了不少 Demo ,只是 HTML5 Video 和 Audio 由于自己平时比较喜欢留意不同的播放器,因此特别想做一个自己喜欢的设计,考虑 ...

  5. Swift中使用MPMoviePlayerController实现自定义视频播放器界面

    默认情况下播放器自带各种控制按钮,比如前进后退播放暂停等: var url = NSBundle.mainBundle().URLForResource("1", withExte ...

  6. 你是否有一个梦想?用JavaScript[vue.js、react.js......]开发一款自定义配置视频播放器

    前言沉寂了一周了,打算把这几天的结果呈现给大家.这几天抽空就一直在搞一个自定义视频播放器,为什么会有如此想法?是因为之前看一些学习视频网站时,看到它们做的视频播放器非常Nice!于是,就打算抽空开发一 ...

  7. 从零开始学 Web 之 HTML5(四)拖拽接口,Web存储,自定义播放器

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  8. 打造自己的html5视频播放器

    前段时间重新学习了一下html5的video部分,以前只是停留在标签的使用上,这一次决定深入了解相关的API,并运用这些API打造一个简单的视频播放器.所谓“打造自己的”,就是要自己重写video标签 ...

  9. jQuery和CSS 3定制HTML 5视频播放器

    目前,随着越来越多的浏览器开始支持更多的HTML5新特性,开发者也逐渐关注HTML5的开发.在众多HTML5的新特性中,视频方面的新特性是 很值得开发者和用户关注的.现在,只需要有支持HTML5的浏览 ...

随机推荐

  1. BETA阶段冲刺集合

    冲刺开始: https://www.cnblogs.com/LZTZ/p/9097296.html 第一天: https://www.cnblogs.com/LZTZ/p/9097303.html 第 ...

  2. Notepad++如何多视图(分屏)显示

    Notepad++ v6.6.7 当需要同时查阅或者编辑多个文件时,正是多视图功能大显身手的时候. 可以在你想要在另一边预览操作的文件名字(在工具栏和文件内容之间)上,单击右键,如下图所示,选择移动到 ...

  3. lintcode-411-格雷编码

    411-格雷编码 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个二进制的差异. 给定一个非负整数 n ,表示该代码中所有二进制的总数,请找出其格雷编码顺序.一个格雷编码顺序必须以 0 ...

  4. lintcode-394-硬币排成线

    394-硬币排成线 有 n 个硬币排成一条线.两个参赛者轮流从右边依次拿走 1 或 2 个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是输还是赢? 样例 n = 1, 返回 ...

  5. Spring – 缓存注解

    Spring缓存抽象概述 Spring框架自身并没有实现缓存解决方案,但是从3.1开始定义了org.springframework.cache.Cache和org.springframework.ca ...

  6. 爬虫学习之-git拉取远程错误

    本文讲的是把git在最新2.9.2,合并pull两个不同的项目,出现的问题如何去解决 如果合并了两个不同的开始提交的仓库,在新的 git 会发现这两个仓库可能不是同一个,为了防止开发者上传错误,于是就 ...

  7. 51nod 1532 带可选字符的多字符串匹配(位运算)

    题意: 有一个文本串,它的长度为m (1 <= m <= 2000000),现在想找出其中所有的符合特定模式的子串位置.符合特定模式是指,该子串的长度为n (1 <= n <= ...

  8. CAS单点登录详细流程

    一.CAS简介和整体流程 CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目.CAS ...

  9. Communications link failure;;The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.

    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure::The ...

  10. [IOI2013]Dreaming

    link 一道非常类似的题目(link) 试题大意 给你一棵含有$n$个节点的有边权森林,问每次连边将会用$L$的代价,问你若此图通过加边成为树时的最小直径.$n \leq 5\times 10^5$ ...