生成一个自定义的HTML5视频播放器

发布于 大漠

虽然拥有特定的HTML视频元素的想法是在十多年前被提出的,但是我们才刚刚开始看到它取得的成果!忘记"HTML5 2012"那所有的繁文缛节;事实是,现在你可以在你的项目中使用视频元素!你只需要在盲目冒险前注意一些细节。

我们必须要知道的一些事项

该规范不建议提供全屏支持是合情合理的。你可以想象,既然可以用 JavaScript 独自控制视频,我们肯定也能想象到这可能会被各种方式所滥用!说到这,一些浏览器版本(nightlies)确实提供通过单击鼠标右键的方式实现全屏视频的功能。

不幸的是,如果这个时候需要全屏支持,就不可以依赖它。相反,需要使用或生成一个自定义的播放器来提供此功能。

为了强制IE浏览器识别各种新的 HTML5元素,我们不得不采用了一点简单的特事策略——使用 JavaScript 创建元素,即 document.createElement('video') 。奇怪的是,这似乎触发了 IE 的意识。没错,这是很奇怪,但这就是我们IE浏览器所期待的,不是吗?为了加快这一进程,Remy Sharp创建了HTML5 Shiv,顺便说一下,使用HTML5元素时还补救了一些打印的问题。只需下载脚本,并在你文档的 head 部分中引用它即可。

当谈及到浏览器所支持的视频类型时,他们就不能很好地相处了。例如,Firefox喜欢视频编码中的 ogg 格式,而 Webkit 浏览器则偏爱呈现 mp4 视频。事实上,这是过度简化;然而,这样做只是暂时的。但是,我只想说,更多的视频类型应该都支持,包括谷歌最近开源的 V8 编解码器。

我们可以容易地给旧版浏览器提供Flash播放器作为后备支持;所以不要害怕。不过,请记住,至少现在,您需要将您的视频转换成至少两种格式。

为什么要生成一个自定义播放器?

全屏幕支持: 从个人的经验来说,我只可以告诉你,全屏幕支持问题是不容商量的条件。举个例子来说,我不能接受仅在600px大小的Nettuts + 编辑器编写代码!仅仅因为这个原因,生成一个自定义播放器至关重要。

品牌: 每个浏览器都使用自己的视频播放器,只是某一部分有一点差异的视频播放器。生成一个自定义的播放器,我们就可以确保视觉效果在浏览器之间是一致的...,我们的核心部分开始倾向播放器的品牌/外表。作为一个概念验证,本教程将要使用Tuts+商标的播放器。

Webkit的视频播放器

Webkit的视频播放器

Mozilla的视频播放器

Mozilla的视频播放器

Tuts+自定义视频播放器 (兼容所有浏览器)

Tuts+自定义视频播放器

视频元素

与任何项目一样,第一步是为我们的项目创建必要的项目标记。

<!DOCTYPE html> 
  
<html lang="en"> 
<head> 
   <meta charset="utf-8"> 
   <title>Custom HTML5 Video Player</title> 
</head> 
<body> 
  
<div id="container"> 
  
    <h1> HTML5 Video </h1> 
  
    <div id="video_container"> 
        <video> 
            <source src="http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.mp4" type="video/mp4"> 
            <source src="http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.ogg" type="video/ogg"> 
              
            <!-- LINK TO FLASH FALLBACK PLAYER HERE. COULD BE EMBED OR OBJECT ELEMENT -->
        </video> 
    </div> 
  
</div>     
  
</body> 
</html>

首先,要有一些能播放的视频。这里我将要使用源码开放的"Big Bunny Buck"皮克斯式视频。我相信直到现在你依旧可以看见它在网络中的使用。看着现在浏览器中的此标记可能会在你脑海里产生一个大大的问号。

原生视频元素

原生视频元素

嘿?就这些吗?它看起来只是像一张图片。问题是什么?默认情况下,这是我们所要求的一切。之后我们指定是否显示控件,显示预览图等等。让我们现在开始做吧;按照如下所示,修改您的video元素:

<video controls with=1000 preload poster=path/to/poster.jpg>

马上,我们注意到这里的属性并没有引用。事实上,他们不是必要的。然而多年前,这会被认为是不好的做法,会去排除他们。现在已经不是这种情况了。在这一点上,它只归结为个人的偏好。所以,如果你觉得更舒服,可以加入他们,当然之后也可以这样子做。

  • 控件: 向播放器添加标准播放/暂停控件
  • 宽度: 设置播放器的宽度
  • 预加载:是否在页面加载后载入视频。在你盲目添加此属性的时候需要三思而后行。当你启用此功能时,你就会用尽用户所有的带宽。其次,在写这篇文章的时候,还没有浏览器已经应用此功能......,但他们以后可能会使用。
  • 预览图: 并没有在所有浏览器实现,它允许在视频播放前设置一张图片作为视频的开始。

设置属性的视频元素

设置属性的视频元素

自定义控件

很显然我们不想使用浏览器的默认控件。因此,我们必须实现我们自己的控件标记。在我们取得进展之前,你可能会问你自己,"添加controls属性的重要性是什么?" 答案是因为我们必须要考虑到用户者的电脑上可能会禁用JavaScript,所以我们要弥补这一缺陷。在这些情况下,如果我们没有添加controls属性,呈现在用户面前的只会类似一张图片的东西。

应该随时考虑 JavaScript被禁用的可能性。

<div id="video_container"> 
    <video controls width=1000 preload poster=assets/poster.jpg> 
        <source src="http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.mp4" type="video/mp4"> 
        <source src="http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.ogg" type="video/ogg"> 
        <!-- FALLBACK HERE -->
    </video> 
      
    <div id="videoControls"> 
        <button id="play" title="Play"> &#x25BA; </button> 
          
        <div id="progress">  
            <div id="progress_box">  
                <span id="play_progress"></span> 
            </div>  
        </div> 
          
        <button id="fullScreen" title="FullScreen Toggle">  FS </button> 
        <a href="http://www.tutsplus.com"><img src="http://tutsplus.s3.amazonaws.com/tutspremium/web-development/103_html5VideoPlayer/images/tuts_logo.png" alt="Tuts" id="video_tutsLogo" /></a> 
    </div> 
</div>

我们将要在idvideoControlsdiv上,添加必要的按钮和商标。这里有一个小诀窍。就是使用& #x25BA;创建播放按钮。不要太担心idprogressdiv;我们将在本教程后面回顾本节中更多的细节。先简要的回答一下这是存放播放器进度条的容器。最后,我们添加一个控制全屏切换的button按钮,当然还有Tuts+商标。

一次设置两个控件吗?

一次设置两个控件吗

尽管看起来我们现在已经创建了第二组控件 (事实上已经完成),不用担心,我们最终会用JavaScript删除默认控件。如果你一直在跟着做,上面的截图应该达到了你自己期望的那个样子。

JavaScript 代码

控件完成后,现在我们就可以制作最有趣的部分了!创建一个叫js的新文件夹,并添加一个videoPlayer.js的新的文件。接下来,让我们编写一个自我调用形式的匿名函数,以防止产生不必要的全局变量。

(function( window, document) { 
     
}( this, document ))

如果你愿意,你可以分离出参数,这是小小的改进,具有以下两个优点:

  • 通过传递this(Window 全局对象) 和document,我们阻止了 JavaScript 引擎对这些对象的过滤以及追查。对于大型项目,这是极大地便利,但它在性能方面起到的作用却很小。
  • 你可以通过用ab来表示windowdocument这种方式来压缩你的JavaScript代码.

接下来,让我们创建一个包含所有方法的videoPlayer对象来尽可能实现代码的简洁。我们还将创建页面加载时就会被调用的init方法。

(function( window, document) { 
    var videoPlayer = { 
        init : function() { 
         
        } 
    }; 
     
    videoPlayer.init(); 
     
}( this, document ))

毫无疑问,接下来我们就会利用变量来对这些元素进行操作。只需要在我们声明videoPlayer变量的前面追加如下代码:

var video = document.getElementsByTagName('video')[0], 
    videoControls = document.getElementById('videoControls'),    
    play = document.getElementById('play'), 
     
    progressContainer = document.getElementById("progress"), 
    progressHolder = document.getElementById("progress_box"), 
    playProgressBar = document.getElementById("play_progress"), 
     
    fullScreenToggleButton = document.getElementById("fullScreen");

如果你一直在跟着学习(我希望你是),留出来一些时间来了解这些变量真正引用的是什么。如果有必要回到标记制作阶段。我们获取了视频元素、 视频控件容器、 播放按钮,全屏切换按钮和三个进度条容器。为了避免我们每次访问这些元素的时候都要遍历DOM,现在我们对这些元素的位置进行"缓存"!

Init方法

让我们开始编写一些实际的代码。在init方法中,粘贴如下代码片断:

init : function() { 
    // this is equal to the videoPlayer object. 
    var that = this; 
     
    // Helpful CSS trigger for JS.  
    document.documentElement.className = 'js'; 
     
    // Get rid of the default controls, because we'll use our own. 
    video.removeAttribute('controls'); 
     
    // When meta data is ready, show the controls 
    video.addEventListener('loadeddata', this.initializeControls, false); 
}

通过创建一个js的类名来引用documentElementhtml元素,无疑不是一个很巧妙的方法。

// Helpful CSS trigger for JS.  
document.documentElement.className = 'js';

这样我们就可以书写如下CSS代码:

.js #container { 
    /* this styling only renders if JS is enabled */
}

还记得设置两个视频控件的问题吗?让我们现在开始采取措施进行解决。这是一个简单的问题;我们只需要简单地调用removeAttribute方法,就可以解决controls问题.

// Get rid of the default controls, because we'll use our own. 
video.removeAttribute('controls');

现在我们添加第一个 HTML5 事件: loadeddata。当浏览器当前帧的数据加载完成且还没有足够的数据播放视频/音频的下一帧时触发。这在执行任何初始化的程序,如显示自定义控件,是很有意义的。

// When meta data is ready, show the controls 
video.addEventListener('loadeddata', this.initializeControls, false);

如果你接触过JavaScript,你可能会担心,我们不能很好地让IE浏览器得到兼容。是的,IE8并不能识别addEventListener事件。与之代替的,IE已经习惯使用它自己的attachEvent事件。但是,在浏览器的第九版本正在有所改变。因为IE8以及IE8以下的版本不能识别video的元素,我们可以完全忽略attachEvent事件这个问题。

当触发loadeddata事件时,我们调用尚未创建的initializeControls方法。在对象方法中,我们不能通过自身引用initializeControls方法。我们必须首先引用对象本身: 如: this.initializeControls.

initializeControls: 我们的自定义控件

让我们现在开始创建该方法。

initializeControls : function() { 
    // When all meta information has loaded, show controls 
    videoPlayer.showHideControls(); 
}

正如前面提到的,如果编写您自己的自定义播放器,请使用此方法来执行任何额外的初始程序。现在,这种方法将调用另一个方法showHideControls。当用户悬停在视频上时,这种方法可以实现控件的显示以及隐藏功能。

ShowHideControls 方法

showHideControls : function() { 
    // Shows and hides the video player. 
    video.addEventListener('mouseover', function() { 
        videoControls.style.opacity = 1; 
    }, false); 
     
    videoControls.addEventListener('mouseover', function() { 
        videoControls.style.opacity = 1; 
    }, false); 
     
    video.addEventListener('mouseout', function() { 
        videoControls.style.opacity = 0; 
    }, false); 
     
    videoControls.addEventListener('mouseout', function() { 
        videoControls.style.opacity = 0; 
    }, false); 
}

这个方法由videovideoControls两个变量,分别代表四个有关视频播放器和控件元素的事件处理程序。这段代码很简单: 当你的鼠标悬停视频上时,将视频控件的透明度更改为 1。相反,移开鼠标时,隐藏该控件。此代码还假定,默认情况下,在我们的样式表内, 视频控制的opacity属性设置为 none

请记住: 如果可能的话,尽可能在CSS文件中设置样式,而不是通过JavaScript来进行添加。除了性能优势和回流/重绘的减少,这种做法真正实现了样式和内容的分离。然而,有些情况下你不得不在JavaScript文件中进行样式添加,这种情况下没有关系。*

按键

我们现在已经成功地隐藏了默认控件,但我们还没有附加任何逻辑到这些不同的自定义按钮上。这就是我们接下来我们要做的事情了。

返回到init方法中,并添加调用一个新的方法。

// When play, pause buttons are pressed. 
this.handleButtonPresses();

当然,你可以自由的对这些方法进行命名,但是至少这个名字可以很容易的让别人知道这个方法的功能。

handleButtonPresses

handleButtonPresses : function() { 
    // When the video or play button is clicked, play/pause the video. 
    video.addEventListener('click', this.playPause, false); 
    play.addEventListener('click', this.playPause, false); 
     
    // When the play button is pressed,  
    // switch to the "Pause" symbol. 
    video.addEventListener('play', function() { 
        play.title = 'Pause'; 
        play.innerHTML = '<span id="pauseButton">&#x2590;&#x2590;</span>';           
    }, false); 
     
     
    // When the pause button is pressed,  
    // switch to the "Play" symbol. 
    video.addEventListener('pause', function() { 
        play.title = 'Play'; 
        play.innerHTML = '&#x25BA;'; 
    }, false); 
     
     
    // When the video has concluded, pause it. 
    video.addEventListener('ended', function() { 
        this.currentTime = 0; 
        this.pause(); 
    }, false); 
}

在此方法中,我们又添加了几个新的并且可用的事件到video元素上:playpauseended.

  • 播放: 视频开始播放时触发。
  • 暂停: 视频暂停时触发。
  • 结束: 视频结束时触发。这个事件监听器可以用来将视频重置回起点。

请记住,例如,我们创建的play事件当你点击播放按钮时不会被触发。相反,当视频本身开始播放时就会被触发。这是要记住的一个重要的区别。*

为了触发上面列出的事件,我们在播放按钮上又添加了一个事件监听,用来监听用户点击。

// When the video or play button is clicked, play/pause the video. 
play.addEventListener('click', this.playPause, false);

The playPause Method

playPause: function() { 
    if ( video.paused || video.ended ) {                 
        if ( video.ended ) { video.currentTime = 0; } 
        video.play(); 
    } 
    else { video.pause(); } 
}

让我们先来谈一下对上面代码的理解。当这种方法被调用时——在我们的事例中,当播放按钮被第一次点击时—— 它是不是已经暂停或者是在视频结束的部分?如果是后者,我们需要将视频的时间重置为 0,以便它可以一次又一次的播放。接下来,我们就要播放视频了: video.play().

现在如果视频没有被暂停或结束——意味着点击了播放按钮后视频正在播放,我们就要做相反的事情了,暂停视频: video.pause().

切换播放/暂停按钮

上面我们详细的的介绍了playPause方法,处理播放或暂停视频的过程。但是,我们当然也需要通过按钮给用户提供一些反馈,不是吗?答案是肯定的;我们要这样做,当用户点击时,我们会切换"play"和"pause"的HTML 字符代码。从根本上说,这是一个处理播放和暂停的按钮。

如果你要提及刚才提到的事件监听,这里我们已经添加了这个功能。

// When the play button is pressed,  
// switch to the "Pause" symbol. 
video.addEventListener('play', function() { 
    play.title = 'Pause'; 
    play.innerHTML = '<span id="pauseButton">&#x2590;&#x2590;</span>';           
}, false); 
 
 
// When the pause button is pressed,  
// switch to the "Play" symbol. 
video.addEventListener('pause', function() { 
    play.title = 'Play'; 
    play.innerHTML = '&#x25BA;'; 
}, false);

很简单,对吧?如果播放按钮被按下,调用video.play()方法的click事件就会被触发。然后视频就会被播放,并触发play事件。接着按钮的值变为暂停符号,同时更新标题属性。最后,当这一过程会再次发生,我们就会做相反的操作。

全屏支持

我在本教程的开篇中提到过: 对于我而言,全屏支持是必须的。让我们现在添加该功能。返回到你的init()方法,并且再次将以下代码片段添加到底部。我们需要对我们创建的全屏幕模式切换按钮,进行监听......

<button id="fullScreen" title="FullScreen">FS</button>

...当点击时,我们就会切换到全屏幕的状态,否则不是。

别忘了: fullScreenToggleButton指的是"全屏"按钮。

// When the full screen button is pressed... 
fullScreenToggleButton.addEventListener("click", function(){ 
    isVideoFullScreen ? that.fullScreenOff() : that.fullScreenOn(); 
}, true);

等一下:为什么是that?不应该是this吗?答案是否定的。在click 事件的上下文中,this现在是指fullScreen按钮,不是videoPlayer对象。

为了解决这个问题,我们会先"缓存"this变量,并称之为that。这可以添加到我们的init()方法的头部。

init : function() { 
// this is equal to the videoPlayer object. 
var that = this;
... 

现在,我们可以再引用videoPlayer对象。因此, that.fullScreenOff表示,调用fullScreenOff方法就是videoplayer对象的子对象。

这里还存在一个问题。我们如何确定视频的当前状态?它是全尺寸还是常规尺寸?一个简单的方法就是创建一个称为isVideoFullScreen的变量。你可以像其他人一样将此变量添加到页面的顶部。当然,默认情况下,此值应设置为false.

fullScreenToggleButton = document.getElementById("fullScreen"), 
// Boolean that allows us to "remember" the current size of the video player.  
isVideoFullScreen = false,

当我们点击"全屏"按钮时,这个布尔值可以使我们能够正确地调用相应的函数。

isVideoFullScreen ? that.fullScreenOff() : that.fullScreenOn();

我们使用三元运算符来判断当前是否处于全屏模式?如果是,我们调用fullScreenOff()。否则,我们调用fullScreenOn().

fullScreenOn : function() { 
    isVideoFullScreen = true; 
     
    // Set new width according to window width 
    video.style.cssText = 'position: fixed; width:' + window.innerWidth + 'px; height: ' + window.innerHeight + 'px;'; 
     
    // Apply a classname to the video and controls, if the designer needs it... 
    video.className = 'fullsizeVideo'; 
    videoControls.className = 'fs-control'; 
    fullScreenToggleButton.className = "fs-active control"; 
     
    // Listen for escape key. If pressed, close fullscreen. 
    document.addEventListener('keydown', this.checkKeyCode, false); 
}, 
 
 
fullScreenOff : function() { 
    isVideoFullScreen = false; 
     
    video.style.position = 'static'; 
     
    video.className = ''; 
    fullScreenToggleButton.className = "control"; 
    videoControls.className = ''; 
}

在这两个函数中,我们首先相应地更改isVideoFullScreen的值。接下来,我们调整视频本身的大小。cssText允许我们向元素传递一个字符串样式。这种情况下,我们是不能直接在我们的样式表内完成这项任务的。这是因为所需的值是动态的,并且取决于访问者的浏览器窗口大小。

使用window.innerWidthwindow.innerHeight可检索浏览器窗口的高度和宽度。

向你的元素中添加一个类名也是一种很好的做法。这样一来,你就可以通过获取类名来添加想要的样式。

退出键

除了全屏幕切换按钮,当用户点击 esc 键离开全屏幕状态也是很常见的。这对于我们是十分便利的,我们应该为我们的播放器添加此功能。幸运的是,这是一件很简单的事情!

// Listen for escape key. If pressed, close fullscreen. 
document.addEventListener('keydown', this.checkKeyCode, false);

我们使用keydown事件来进行键盘监听。便于代码重复使用,我们可以将一个匿名函数作为第二个传递参数。当这个实现以后,代码就会调用自己的函数,以便重复使用。我们将要命名它为checkKeyCode.

checkKeyCode

// Determines if the escape key was pressed. 
checkKeyCode : function( e ) { 
    e = e || window.event; 
    if ( (e.keyCode || e.which) === 27 ) videoPlayer.fullScreenOff(); 
}

因为IE浏览器兼容问题,这个函数不幸变得更加令人困惑。我不确定即将推出的IE9 处理该事件对象,所以,我们暂时仍然会处理IE浏览器和其它现代浏览器在处理这个事件对象的兼容性。

先把这些放在一边,此代码检查用于检查被单击的键的键值是否为27。如果是,在这种情况下,我们可以通过videoPlayer.fullScreenOff()pause键按下,退出全屏模式.

跟踪进度

最后,但同样重要的是,我们需要跟踪视频的进度。随着视频的进展,我们需要提供一个"洗涤"进度,这将有助于我们跟踪视频。此外,它还允许用户快速切换到他们所需的视频部分。

我们应该在什么时候开始跟踪?

这很简单: 当视频播放的时候!考虑到这一点,让我们修改play事件代码,并且调用函数来跟踪视频的进度。

// When the play button is pressed,  
// switch to the "Pause" symbol. 
video.addEventListener('play', function() { 
    play.title = 'Pause'; 
    play.innerHTML = '<span id="pauseButton">&#x2590;&#x2590;</span>'; 
 
    // Begin tracking video's progress.  
    videoPlayer.trackPlayProgress();                 
}, false);

trackPlayProgress

// Every 50 milliseconds, update the play progress.  
trackPlayProgress : function(){ 
    (function progressTrack() { 
         videoPlayer.updatePlayProgress(); 
         playProgressInterval = setTimeout(progressTrack, 50); 
     })(); 
}

不要让这段代码吓到你。这仅仅是一个递归函数,使我们能够每隔 50 毫秒就调用不同的 updatePlayProgress()方法。为什么不使用setInterval呢?这是因为setInterval有的时候很让人讨厌。setInterval不管函数内的代码将要运行多长时间,每隔 50 毫秒,就会运行一次(在这种情况下)。这里已经超出了本教程的范围,无需深入太多。

setInterval就像司机在交通高峰时间拒绝踩刹车。

因此,在可能的情况下,结合setTimeout调用递归函数是很聪明的解决方案。请注意,我们分配给setTimeout一个playProgressInterval变量,因此我们以后就需要获取id的方式来进行超时清除。

updatePlayProgress

现在,我们已经指定,每隔 50 毫秒,就调用updatePlayProgress方法一次,让我们现在创建它。

updatePlayProgress : function(){ 
    playProgressBar.style.width = ( (video.currentTime / video.duration) * (progressHolder.offsetWidth) ) + "px"; 
}

首先,尽管上面的代码看起来似乎是超级混乱,其实它不是太糟糕了。我们获取进度条并且进行更新其宽度 (每 50 毫秒)。我们可以通过调用video.duration来获取视频的长度,通过划分当前视频的位置来获取准确的宽度。得到的这个数值应该和总进度相乘。

但是,视频被用户暂停时会发生什么?我们肯定不想继续调用setTimeout。因此,当暂停事件被触发时,我们应该创建另外一种被称为stopPlayProgress的方法。

// We've already added this event. We're only updating it with one new call at the bottom. 
video.addEventListener('pause', function() { 
    play.title = 'Play'; 
    play.innerHTML = '&#x25BA;'; 
     
    // Video was paused, stop tracking progress. 
    videoPlayer.stopTrackingPlayProgress(); 
}, false);
 
// Video was stopped, so stop updating progress. 
stopTrackingPlayProgress : function(){ 
    clearTimeout( playProgressInterval ); 
}

Video Scrubbing

我们将在本教程的最后详细介绍如何"洗涤"视频——意思就是,用户在进度条点击,向前或向后点击视频。我相信以及肯定你已经在多种情况下执行过此操作。好了,好了。这些东西都是自动完成的。我们要去书写该功能的代码了。

快点...屏住呼吸。

videoScrubbing : function() { 
    progressHolder.addEventListener("mousedown", function(){ 
        videoPlayer.stopTrackingPlayProgress(); 
         
        videoPlayer.playPause(); 
         
        document.onmousemove = function(e) { 
          videoPlayer.setPlayProgress( e.pageX ); 
        } 
         
        progressHolder.onmouseup = function(e) { 
            document.onmouseup = null; 
            document.onmousemove = null; 
                                 
            video.play(); 
            videoPlayer.setPlayProgress( e.pageX ); 
            videoPlayer.trackPlayProgress(); 
        } 
    }, true); 
}, 
 
setPlayProgress : function( clickX ) { 
    var newPercent = Math.max( 0, Math.min(1, (clickX - this.findPosX(progressHolder)) / progressHolder.offsetWidth) ); 
    video.currentTime = newPercent * video.duration; 
    playProgressBar.style.width = newPercent * (progressHolder.offsetWidth)  + "px"; 
}, 
 
findPosX : function(progressHolder) { 
    var curleft = progressHolder.offsetLeft; 
    while( progressHolder = progressHolder.offsetParent ) { 
        curleft += progressHolder.offsetLeft; 
    } 
    return curleft; 
}

...现在可以呼出。让我们看看这一行一行的代码。

  • 当用户单击进度条时进行监听。
  • 当他们这样做时,调用videoPlayer.stopTrackingPlayProgress 方法来清除我们上面创建的超时限制。
  • 接下来,调用playPause方法处理,在这种情况下,应该暂停视频。
  • 如果这时鼠标还是处于被按下的状态,观察它什么时候移开。如果情况发生,就调用setPlayProgress方法。
  • 这种复杂的方法很难用文字来解释;你需要自己研究一下。实际上,代码根据你在进度条上点击的位置,然后根据整个进度条的长度来进行划分。下一步,它将更新的视频中的时间,和动态进度条的长度。
  • 当这个函数返回后,接下来我们就该监听用户什么时候从原始点击的地方进行鼠标滑过。当他们这样做时,我们清除任何现有的鼠标事件,并继续播放视频,并且再次跟踪其进展情况。

##结论

有是没有的事;这种东西很困惑,直到你突然听到"单击,"这么说。这通常进行扩展,由"Oooohhhhhh"。如果你还没有到达那里,如果你的眼睛忍不住呆滞这长的教程,这是好。再读一遍,和最重要的是,沿着工作。这是我们成长的唯一途径。其次,大肿块的代码我们诚然难以一下子参加。为了补偿,阅读通过本教程再次在碎片,你提到的最后的源代码通过了。这将有助于你把握到底每个块的代码所在的头脑。

视觉方面,像这样的自定义播放器最美妙的事情是,一旦逻辑被写,它将 100%可视化。只需跟踪您所需要的idclass,和你所有的设置。本教程仅仅提供了一个演示范例,如果你不喜欢这种样式,没有关系;你可以自己设计自己的风格!

自定义视频

接下来是什么?

我们现在有一个简洁实用性的播放器,并且,它还可以被进一步扩展。在下一课中 (免费的给你),我们将要学习如何向我们的视频控件中添加音量控制,以及一个计时器。敬请关注。

本文根据@Jeffrey Way的《Build a Custom HTML5 Video Player》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://code.tutsplus.com/tutorials/build-a-custom-html5-video-player--pre-8905

静子

在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶

如需转载,烦请注明出处:https://www.fedev.cn/html5/build-a-custom-html5-video-player.htmlWmns Air Jordan 1 Retro High OG 'Twist'