【高级功能】使用多媒体
HTML5 支持直接在浏览器中播放音频和视频文件,不需要使用Abode Flash这样的插件。
1. 使用 video 元素
可以用video 元素在网页里嵌入视频内容。
其基本用法如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用video元素</title> </head> <body> <video width="360" height="240" src="timessquare.webm" autoplay controls preload="none" muted> Video cannot be displayed </video> </body> </html>
此例显示效果如下:
如果浏览器不支持video元素或者无法播放视频那么备用内容(开始和结束标签之内的内容)就会代替它显示。此例中,显示了一段简单的文本消息,但常用的技巧是提供使用费HTML5技术(例如Flash)的视频播放,以支持旧版的浏览器。
video 元素有许多属性,下表列出了它们:
1.1 预先加载视频
preload属性告诉浏览器:当它加载完包含video元素的网页后,是否应该积极地去下载视频。预先加载视频减少了用户播放时的初始延迟,但如果用户不观看视频则会造成网络带宽的浪费。下表介绍了这个属性允许设置的值。
在决定是否预先加载视频时,应当权衡用户想要观看视频的可能性与自动载入视频内容所需要的带宽。自动载入视频会带来更平滑的用户体验,但它可能会大大提升经营成本,如果用户没有观看视频就离开网页,那么这些成本就浪费了。
这个属性的metadata值可以被用来在none和auto值之间建立起适度的平衡。none值的问题在于视频内容会在屏幕上显示为一片空白区域。metadata值会让浏览器获取足够的信息来向用户展示视频的第一帧,而不必下载全部内容。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>将none和metadata值用于preload属性</title> </head> <body> <video width="360" height="240" src="timessquare.webm" controls preload="none" muted> Video cannot be displayed </video> <video width="360" height="240" src="timessquare.webm" controls preload="metadata" muted> Video cannot be displayed </video> </body> </html>
此例展示了在同一个文档里使用none和metadata值,其显示效果如下,可以看到这些值如何影响展示给用户的预览画面。
PS:metadata值向用户提供了漂亮的预览画面,但需要慎重一些。当用网络分析工具测试这个属性,发现尽管只请求了元数据,但是有些浏览器实际上会预先下载整个视频。平心而论,浏览器可以自由选择是否忽略preload属性所表达的偏好。但是,如果需要限制带宽的消耗,poster属性可能更胜一些。
1.2 显示占位图像
可以用poster属性向用户呈现一张占位图像。这张图像会显示在视频的位置,直至用户开始播放。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用poster属性来指定占位图像</title> </head> <body> <video width="360" height="240" src="timessquare.webm" controls preload="none" poster="poster.png"> Video cannot be displayed </video> <img src="poster.png" /> </body> </html>
这里为视频文件的第一帧做了一张屏幕截图,然后在它上面叠加了单词 Poster(海报)。这张图像包括了视频控件,以此提示用户这张海报代表一段视频剪辑。这里还在此例中加入了一个img元素,以演示video元素会不加改动地展示这张海报图像。
1.3 设置视频尺寸
如果省略width和height属性,浏览器就会显示一个很小的占位元素,并在元数据可用时(也就是当用户开始播放,或者preload属性被设为metadata时)把它调整到视频原始尺寸的大小。这可能会产生颤动感,因为页面布局需要调整以容纳视频。
如果指定width和height属性,浏览器会保持视频的长宽比(不必担心视频会向任一方向拉伸)。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>应用width和height属性</title> <style> video {background-color: gray;border: medium double green;} </style> </head> <body> <video width="600" height="240" src="timessquare.webm" controls preload="auto"> Video cannot be displayed </video> </body> </html>
此例中设置的width属性与height属性的比例是失衡的。这里还给video元素应用了一个样式,以凸显浏览器为了保持视频的长宽高,只会使用部分指派给该元素的空间。
1.4 指定视频来源(和格式)
指定视频最简单的方式是使用 src 属性,并提供所需视频文件的URL。
可以看到前面的例子中,用src属性指定了文件 timessquare.webm。这是一个用WebM 格式编码的文件。目前还没有哪一种视频格式被普遍支持,如果想将视频推向各种各样的HTML5用户,就要做好以多种格式编码视频的准备。
一个不幸的事实是,没有哪一种格式能够用于所有的主流浏览器。因此,必须以多种格式编码视频,直到出现同一一种格式为止。可以使用source元素来指定多个格式。
下面例子展示了如何使用 source元素来向浏览器提供备选视频格式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用source元素</title> </head> <body> <video width="360" height="240" controls preload="auto"> <source src="timessquare.webm" /> <source src="timessquare.ogv" /> <source src="timessquare.mp4" /> Video cannot be displayed </video> </body> </html>
浏览器会沿着列表顺序寻找它能够播放的视频文件。这可能会引发多个服务器请求以获得每个文件的额外信息。浏览器判断它是否能播放某个视频的依据之一是服务器返回的MIME类型。可以通过给source元素应用type属性来提示用户,方法是在其中指定文件的MIME类型。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>在source元素上应用type属性</title> </head> <body> <video width="360" height="240" controls preload="auto"> <source src="timessquare.webm" type="video/webm" /> <source src="timessquare.ogv" type="video/ogg" /> <source src="timessquare.mp4" type="video/mp4" /> Video cannot be displayed </video> </body> </html>
PS:media属性向浏览器指明该视频最适合在那种设备上播放。
2. 使用 audio 元素
audio 元素允许在HTML文档里嵌入音频内容。
可以看到audio和video元素有许多共同点。下面的例子展示了audio元素的用法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用audio元素</title> </head> <body> <audio controls src="P!NK - Just Give Me a Reason.mp3" autoplay> Audio content cannot be played </audio> </body> </html>
也可以使用source元素来提供多种格式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用audio元素</title> </head> <body> <audio controls autoplay> <source src="P!NK - Just Give Me a Reason.ogg" /> <source src="P!NK - Just Give Me a Reason.mp3" /> <source src="P!NK - Just Give Me a Reason.wav" /> Audio content cannot be played </audio> </body> </html>
这两个例子都使用了controls属性,这样浏览器就会对用户显示默认的播放控件。它们在不同的浏览器中外观各异,下面是在火狐浏览器中的显示效果:
3. 通过 DOM 操作嵌入式媒体
audio 和 video 元素有着很大的相似性,所以HTMLMediaElement对象在DOM里为它们统一定义了核心功能。audio元素在DOM里由HTMLAudioElement对象所代表,但此对象没有定义不同于HTMLMediaElement的额外功能。video元素由HTMLVideoElement对象所代表,而它定义了一些额外的属性。
PS: audio和video元素的相似度是如此之高,以至于它们唯一区别仅仅是在屏幕上占据的空间大小。audio元素不会占用一大块屏幕空间来显示视频图像。事实上,甚至可以用audio元素来播放视频文件(当然,这么做只能听得到配乐),也可以用video元素来播放音频文件(不过视频显示区域会保持空白)。这看起来很奇怪,但其实是可行的。
3.1 获得媒体信息
HTMLMediaElement 对象定义了许多成员,可以用它们来获取和修改元素及其关联媒体的信息。
对象定义了下表中展示的额外属性:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>获取媒体元素的基本信息</title> <style> table {border: thin solid orange;border-collapse: collapse;} th,td {padding: 2px 4px;} body > * {float: left;margin: 2px;} </style> </head> <body> <video id="media" width="360" height="240" controls preload="metadata"> <source src="timessquare.webm" type="video/webm" /> <source src="timessquare.ogv" type="video/ogg" /> <source src="timessquare.mp4" type="video/mp4" /> Video cannot be displayed </video> <table id="info" border="1"> <tr><th>Property</th><th>Value</th></tr> </table> <script type="application/javascript"> var mediaElem = document.getElementById("media"); var tableElem = document.getElementById("info"); var propertyNames = ["autoplay","currentSrc","controls","loop","muted","preload","src","volume"]; for(var i=0;i<propertyNames.length;i++){ tableElem.innerHTML += "<tr><td>"+propertyNames[i]+"</td><td>"+mediaElem[propertyNames[i]]+"</td></tr>"; } </script> </body> </html>
此例的脚本在一张表格中显示了许多属性的值,位置就在video元素的旁边,展示了如何使用一些HTMLMediaElement属性来获取媒体元素的基本信息。
3.2 评估回放能力
canPlayType 方法用来了解浏览器是否能够播放特定的媒体格式。这个方法会返回下表里列出的其中一个值:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>使用canPlayType方法</title> <style> table {border: thin solid orange;border-collapse: collapse;} th,td {padding: 2px 4px;} body > * {float: left;margin: 2px;} </style> </head> <body> <video id="media" width="360" height="240" controls preload="metadata"> Video cannot be displayed </video> <table id="info" border="1"> <tr><th>Property</th><th>Value</th></tr> </table> <script type="application/javascript"> var mediaElem = document.getElementById("media"); var tableElem = document.getElementById("info"); var mediaFiles = ["timessquare.webm","timessquare.ogv","timessquare.mp4"]; var mediaTypes = ["video/webm","video/ogv","video/mp4"]; for(var i=0;i<mediaTypes.length;i++){ var playable = mediaElem.canPlayType(mediaTypes[i]); if(!playable){ playable = "no"; } tableElem.innerHTML += "<tr><td>" + mediaTypes[i] + "</td><td>"+ playable +"</td></tr>"; if(playable == "probably"){ mediaElem.src = mediaFiles; } } </script> </body> </html>
此例的脚本中,用canPlayType 方法评估了一组媒体类型。如果收到一个 probably 答复,就会设置video元素的src属性值。通过这种方式,此例在一张表格里记录了三种媒体类型的答复。
用这种方式选择媒体时需要多加小心,因为浏览器评估自身格式播放能力的方法各不相同。
很难评论浏览器在答复中所表现出的不一致性。有太多因素使它们无法给出明确的答案,但它们在评估支持时使用不同方式这一点意味着应当非常谨慎的使用canPlayType方法。
3.3 控制媒体回放
HTMLMediaElement 对象定义了许多成员,它们能够控制回放和获得回放信息。这些属性和方法如下表所示:
下面的例子展示了如何使用表格中的属性来获取回放信息:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用HTMLMediaElement属性获取媒体回放详情</title> <style> table {border: thin solid black;border-collapse: collapse;} th,td {padding: 2px 4px;} body > * {float: left;margin: 2px;} div {clear: both;} </style> </head> <body> <video id="media" width="360" height="240" controls preload="metadata"> <source src="timessquare.webm" type="video/webm" /> <source src="timessquare.ogv" type="video/ogg" /> <source src="timessquare.mp4" type="video/mp4" /> Video cannot be displayed </video> <table id="info" border="1"> <tr><th>Property</th><th>Value</th></tr> </table> <div> <button id="pressme">Press Me</button> </div> <script type="application/javascript"> var mediaElem = document.getElementById("media"); var tableElem = document.getElementById("info"); document.getElementById("pressme").onclick = function(){ var propertyNames = ["currentTime","duration","paused","ended"]; tableElem.innerHTML = ""; for(var i=0;i<propertyNames.length;i++){ tableElem.innerHTML += "<tr><td>"+propertyNames[i]+"</td><td>"+mediaElem[propertyNames[i]]+"</td></tr>"; } } </script> </body> </html>
此例包含一个button元素,当它被按下后会使表格显示出currentTime、duration、paused 和 ended 属性的当前值。
可以使用回放方法代替默认的媒体空间,演示例子如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>替换默认的媒体控件</title> </head> <body> <video id="media" width="360" height="240" preload="metadata"> <source src="timessquare.webm" type="video/webm" /> <source src="timessquare.ogv" type="video/ogg" /> <source src="timessquare.mp4" type="video/mp4" /> Video cannot be displayed </video> <div> <button>Play</button> <button>Pause</button> </div> <script type="application/javascript"> var mediaElem = document.getElementById("media"); var buttons = document.getElementsByTagName("button"); for (var i=0;i<buttons.length;i++){ buttons[i].onclick = handleButtonPress; } function handleButtonPress(e){ switch(e.target.innerHTML){ case 'Play': mediaElem.play(); break; case 'Pause': mediaElem.pause(); } } </script> </body> </html>
此例中,省略了video元素的controls属性,并用点击button元素触发的play和pause方法来启动和停止媒体回放。