详细讲解HTML 5中视频和音频核心事件_canplaythrough-程序员宅基地

技术标签: Web前端  html5  

【IT168 技术】HTML 5中的视频和音频中有不少核心的事件,其中有的比较容易理解,基本能从字面就解析了,比如“play”事件就很好理解。而其他有的事件则需要花费点心思,特别是“progress”事件。因此,在本文中,将带领读者研究HTML 5视频和音频中重要的事件,探究这些事件是应该在什么时候使用以及其中的重要相关属性。我们也将看下这些事件在当今不同浏览器中的差异。为了本文的测试,使用的浏览器如下:Opera 12、Chrome 28、IE 10、Firefox 22、Safari 5(桌面版)和Mobile Safari 6(iOS版本)。

   播放相关的事件

  我们先来看下视频和音频中的playback事件。plackback事件发生的时机在播放媒体或停止媒体中,这个比较好理解,下面来仔细研究一下。其中“play”和“pause”事件分别在媒体播放和停止的时候触发,但也有一个“ended”事件,该事件是在媒体播放完毕到达最后的时候触发-无论是正常情况下的结束或是用户自己动播放条到媒体文件的最后。

  这两个对应事件的触发很简单,只需要调用play()和pause()方法就可以了。它们也有对应的属性,其中.paused属性默认设置为true,而.ended属性默认是设置为false的,当然当媒体文件播放到最后的时候,.ended属性则变为true。

  然而,在Opera、Safari和IE 10中,请注意有个区别,就是即使媒体播放完毕,其中的.paused属性依然为false(从逻辑上说,媒体已经播放完毕了)。这样一个实际的结果是play/pause按钮的事件都不会触发了,看下面的例子:

  


  button.addEventListener("click", function(e)

  media.play();

  else

  media.pause();

  }, false);

  也就是说,当视频结束后,其pause()事件依然能调用。我们可以通过一个小技巧去修正这个问题,如下代码所示:

  


  media.addEventListener("ended", function(e)

  media.pause();

  }, false);

  也就是在监听ended事件中,主动调用media.pause()方法就可以了。在Firefox和Chrome的最新版本中,已经修正了这个问题。

   关于加载事件

  加载事件总是在媒体加载(或加载失败)的时候发生。加载事件受到加载媒体状态的影响,比如是否使用了preload属性又或者是媒体是否缓存了。下面我们来逐一分析下其中关键的事件,首先是“loadstart”事件,含义是让浏览器刚开始的时候去寻找获得数据。但要注意的是,loadstart并不意味着就任何数据就会马上加载,还要看preload属性的值的设置。如果preload(预装载的值)设置为“none”的话,则“loadstart”事件就是唯一在播放视频前触发的事件。如果preload属性设置为“metadata”或者是“auto”,则会触发“progress”和“loadmetadata”事件(如果没预加载的话,这两个事件也会触发,但不会在播放前发生)。

  在下一节中,我们才学习“progress”事件,由于其比较复杂。我们先来学习比较简单的“loadedmetadata”事件。正如字面的含义,浏览器仅仅加载媒体的元数据信息而已,比如其长度.duration(是一个浮点数而不是默认的NaN)。

  当然,“loadedmetadata”事件只有在确认能加载媒体文件后才能加载,换句话说,如果某个媒体问题文件不能加载(比如404错误),则会直接产生error事件,当然也不可能继续运行相关的播放事件了。

  这里,又要提醒用户有的浏览器中是有差别的。在Mobile Safari中,preload的属性其实是没声明的,就等于设置为“none”一样了。但在IE 10中,又有不同了,其中媒体的元数据默认是自动加载的,所以preload设置为none其实跟设置为metadata的作用是一样的。

  在“loadedmetadata”事件触发后,接下来的重要事件就是“canplay”,这个是浏览器用来确认是否已经装载足够的媒体信息到浏览器中能播放一个事件。如果preload属性设置为“auto”,则在数据装载后大概几秒,“canplay”事件就会触发;如果preload设置为“metadata”或者是“none”,则直到播放开始时才会触发。这个规则对Chrome浏览器来说是例外的,在Chrome中,即使只是加载元数据阶段,“canplay”事件也会触发。

  同时也有仅接着的事件叫“canplaythrough”,这个事件其实是给浏览器根据当前网络状况去判断是否已经加载了足够的媒体片断而支撑基本的播放。所以这个事件要在数据被预加载大概几秒后才会触发。

  在实际情况下,“canplaythrough”事件基本是没啥作用的,因为Safari根本不会触发这个事件,而Opera和Chrome则在“canplay”事件触发后马上就触发这个事件,只有FireFox和IE 10实现了这个事件。

  所以实际上,开发者最应该关心的是监视“progress”事件,以了解媒体到底加载了多少(必要的时候可以计算媒体的下载速度)。

   Progress事件

  接下来我们重点学习下progress事件。该事件在数据正在下载的时候会触发。所以当preload设置为none的时候,progress事件在知道播放事件真正开始前是不会触发的。如果preload设置为“metadata”,则该事件会短暂触发大概几秒,然后停止,直到真正的播放行为开始时才触发;如果preload设置为“auto”,则会触发一直直到整个媒体文件下载完毕。

  无论preload如何设置,一旦用户开始进行播放的行为,则浏览器会开始下载整个媒体文件,则会持续触发progress事件,一直直到整个文件下载完毕,即使视频被暂停。

  当数据下载后,则我们需要了解如何用时间表达这个progress的事件,则对接下来深入了解progress事件是十分重要的。当数据开始加载时,会创建表示媒体播放时间的范围,比如一旦头10秒的数据已经加载,则以数组的方式记录了开始和结束时间,如下的方式表示:

  


  [0,10]


  当然,实际上是会有多个时间范围存在的,比如用户手工使用播放器的进度条去移动到想要的位置,则浏览器会忽略当前的时间范围而加载新的部分而不是象 Flash那样重新加载两个时间点之间的部分。

  比如我们加载10秒的视频后,跳到两分钟后的片断继续播放另外的10秒,则有两个时间范围,用如下的方式表达:


  [0,10],

  [120,130]

  假设用户这个时候又回看旧的片断,则继续又增加一个时间范围的数组,如:

  


  [0,10],

  [60,70],

  [120,130]

  如果从60秒开始看到130秒结束,则最后的时间范围合拼为:

  


  [0,10],

  [60,130]


  上面的例子只是简单说明在播放媒体中,时间的范围是如何运作的,当然实际上的数据保存不是这个样子。实际上媒体都有一个.buffered对象以表示时间范围。.buffered对象有一个.length长度属性表示有多少段时间范围,并且有对应的start()和end()方法,所以我们可以将buffered的数据转换为二维数组,如下代码所示:


  ranges.push([

  media.buffered.start(i),

  media.buffered.end(i)

  ]);

  最后,我们可以自定义progress事件如下:

  


  media.addEventListener("progress", function()

  ranges.push([

  media.buffered.start(i),

  media.buffered.end(i)

  ]);

  }, false);


  有了这个方法,则我们可以针对progress事件进行一些定制开发。比如我们可以实现一个简单的播放视频,并且提供一个额外的进度条,在视频加载过程中能看到其进度。其实际的运行效果请参考:http://jspro.brothercake.com/media-events/progress.html ,下面是一个运行效果截图:
详细讲解HTML 5中视频和音频核心事件
1

  下面选取其中的代码片断讲解其核心原理:

  


  function onprogress()

  //获得buffered数据

  ranges.push([

  media.buffered.start(i),

  media.buffered.end(i)

  ]);

  //获得在容器中的当前进度

  //如果还没有加载完毕则继续加载

  while(spans.length media.buffered.length)

  while(spans.length > media.buffered.length)

  progress.removeChild(progress.lastChild);

  spans[i].style.left = Math.round

  (100 / media.duration) *

  ranges[i][0]

  + "%";

  spans[i].style. width = Math.round

  (100 / media.duration) *

  (ranges[i][1] - ranges[i][0])

  + "%";

  在上面的代码段中,使用的是设置的宽度去代表进度条的每一个格的宽度,首先获得buffered数据,存放到数据ranges中,然后判断媒体文件是否加载完毕,如果还没加载完毕,则继续往DOM中添加标签,而这个span标签的宽度和样式则是通过上面的代码按百分比计算出来。

  最后,用户可以通过http://jspro.brothercake.com/media-events/events.html的例子,学习到本文中提到的在媒体加载前、加载中和加载后浏览器的相关事件,在这个例子中会输出相关的日志
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013267266/article/details/52154914

智能推荐

python中.py和.pyw文件的区别_python. pyw-程序员宅基地

文章浏览阅读589次。 严格来说,它们之间的不同就只有一个:视窗运行它们的时候调用不同的执行档案。视窗用 python.exe 运行 .py ,用 pythonw.exe 运行 .pyw 。这纯粹是因为安装视窗版 Python 时,扩展名 .py 自动被登记为用 python.exe 运行的文件,而 .pyw 则被登记为用 pythonw.exe 运行。.py 和 .pyw 之间的“其它差别”全都是 ..._python. pyw

DHCP的原理与配置_dhcp广播-程序员宅基地

文章浏览阅读1.3k次。DHCP服务是用来进行动态主机分配的,可以有效的避免了因手动设置IP地址所产生的错误,同时也避免了把-一个IP地址分配给多台工作站所造成的地址冲突。DHCP 提供了安全、可靠且简单的TCP/IP 网络设置,降低了配置IP地址的负担。_dhcp广播

bluetooth.btcommon.BluetoothError: (2, 'No such file or directory')-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏4次。报错: bluetooth.btcommon.BluetoothError: (2, ‘No such file or directory’) or Failed to connect to SDP server on FF:FF:FF:00:00:00: No such file or directorysudo vim /lib/systemd/system/bluetooth....

C语言中将变量类型转化成字符串类型(sprintf)_c语言 变量转字符串-程序员宅基地

文章浏览阅读1.4w次,点赞5次,收藏25次。sprintf函数的用法1、该函数包含在stdio.h的头文件中。2、sprintf和平时我们常用的printf函数的功能很相似。sprintf函数打印到字符串中,而printf函数打印输出到屏幕上。sprintf函数在我们完成其他数据类型转换成字符串类型的操作中应用广泛。3、sprintf函数的格式:int sprintf( char *buffer, const char *forma..._c语言 变量转字符串

为了防老板偷窥,程序员开源了这个神器-程序员宅基地

文章浏览阅读1.6k次。有些人,在公司上班总想打开网页刷个微博,玩个游戏放松一下,但又怕老板发现,心想假如窗口能隐藏就好了。其实,只要你手眼速度跟得上,按“Alt+Tab”切换屏幕,还是十分适用..._老板键底层原理 csdn

如何制作空心文字_qt 镂空字体-程序员宅基地

文章浏览阅读709次。  条码标签软件在设计制作标签时,虽然没有制图软件那样功能强大,但是基本的设计还是可以做到的,有了这些功能就可以把标签设计得美美哒。本篇文章会给大家介绍空心文字的制作,空心文字和描边文字还是有一些区别的,空心文字的中间都是空的,将其放在带有色彩的背景上时,文字中空的部分就会显示背景色。下面我们就看看制作方法。  打开软件,新建一个标签并设置标签的尺寸。在软件右侧点击“选择其它背景图片”,在文件夹中选择一个图片作为标签的背景。  点击软件左侧的“单行文字”按钮,输入文字。在软件右侧设置字体、字号等_qt 镂空字体

随便推点

Oracle RAC 到单机 OGG 配置测试_rac和单实例启动ogg区别-程序员宅基地

文章浏览阅读8.5k次,点赞2次,收藏12次。RAC OGG RAC到单机 ACFS OGG 创建ACFS fbo_ggs_Linux_x64_shiphome.zip RAC OGG 单实例Rac与单实例不同之处在于rac上的goldengate 需要安装在共享存储上asmca 创建ACFS chekpointtable add extract E_RAC,tranlog,threads 3 begin nowadd exttrail /ogg/install/dirdat/extlt/rac/lt,extract E_RAC add_rac和单实例启动ogg区别

二阶响应曲面分析-程序员宅基地

文章浏览阅读612次,点赞30次,收藏18次。二阶响应曲面分析

【CV】第 10 章:目标检测和分割的应用_cv 目标分割-程序员宅基地

文章浏览阅读441次,点赞6次,收藏10次。此外,我们将学习如何计算图像中人群中的人数,然后学习如何利用分割技术来执行图像着色 . 最后,我们将了解 YOLO 的修改版本,通过使用从 LIDAR 传感器获得的点云来预测对象周围的 3D 边界框。你将如何解决这个问题?我们正在调整 ground truth 的大小,因为我们的网络的输出将缩小到原始大小的 1/8 ,因此我们将地图乘以 64,以便图像像素的总和将按比例缩小到原始人群数数。在本节中,我们将学习如何检测图像中的多个人,以及使用 Detectron2 检测图像中存在的人的各个身体部位的关键点。_cv 目标分割

vs2019将打印信息输出到控制台窗口(黑框)_vs打印到输出窗口-程序员宅基地

文章浏览阅读1.4k次。OUTDIR。_vs打印到输出窗口

Windows和Linux内存检测工具:Valgrind,Visual Leak Detector,CppCheck, Cpplint_valgrind windows安装-程序员宅基地

文章浏览阅读4.7k次。1 Linux内存泄漏检测工具ValgrindValgrind简介Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存..._valgrind windows安装

[转帖]BIOS问答,非常实用 -程序员宅基地

文章浏览阅读2.3k次。BIOS问答1 (注:转自IT168) Q:什么是BIOS ? A:BIOS(Basic Input/Output System)即基本输入输出系统,通常是固化在只读存储器(ROM)中,所以又称为ROM-BIOS。它直接对计算机系统中的输入、输出设备进行设备级、硬件级的控制,是连接软件程序和硬件设备之间的枢纽。ROM-BIOS是计算机系统中用来提供最低级、最直接的硬件控制的程序。就PC而言,BIO

推荐文章

热门文章

相关标签