media 提供 audio 对象可以使用的一系列丰富事件。可利用一组事件来获取可用于在播放音频文件时跟踪进度的状态数据。
使用状态事件
HTML5 media 对象提供了许多与 audio 和 Sideo 对象共享的方法、属性和事件。在本主题中,你将了解如何注册多个 media 事件以跟踪当前处于播放模式下的音频文件的进度。
通过基于 使用 JavaScript 控制 Audio 对象中的示例进行构建,可以使用事件来显示文件的状态,一个事件用来驱动进度栏,另一个事件用来在加载完网页时加载事件。
下面的示例演示在播放文件和暂停文件时引发的事件。这些事件用于切换“播放”按钮上的标签。在播放音频文件时,按钮标签将显示为“Pause”;在暂停音频文件时,按钮标签将显示为“Play”。
注意 如果你是在 Intranet 上进行开发并且有 HTML5 的呈现问题,则可以向网页的 <head> 块中添加 <meta http-equiv-“X-UA-Compatible” content=”IE=9″/> 以强制 Windows Internet Explorer 9 使用最新标准。如果愿意,可以将 Web 开发服务器配置为发送带 IE=9 的元 http-equiv-“X-UA-Compatible” 标头。
1 2 3 4 5 6 7 8 9 10 11 |
var oAudio = document.getElementById('myaudio'); //set up event to toggle play button to pause when playing oAudio.addEventListener("playing", function() { document.getElementById("play").textContent = "Pause"; }, true); //set up event to toggle play button to play when paused oAudio.addEventListener("pause", function() { document.getElementById("play").textContent = "Play"; }, true); |
除状态事件之外,首次加载脚本时还将注册 DOMContentLoaded 事件。该事件是 Internet Explorer 9 的一个新事件,它会在加载完所有文档对象模型 (DOM) 和脚本内容时引发。通过使用该事件,可以确保加载所需元素,而不用等到加载图像和内容后进行此操作。 当引发该事件时,它会调用加载其他事件的函数。
1 2 |
//this event gets fired when a page has loaded window.addEventListener("DOMContentLoaded", initEvents, false); |
使用 JavaScript 控制 Audio 对象中描述了名为“快进”和“快退”的功能。
添加进度栏
如 使用 JavaScript 控制 Audio 对象主题中所示, audio 对象使用 currentTime 属性来跟踪当前的播放位置。你可以通过重置 currentTime 属性来搜索整个currentTime 音频文件。通过使用 timeupdate 事件,可在时间发生更改时获取并显示时间。 还可使用 currentTime 属性更新进度栏。
在播放音频文件时,每当 currentTime 发生更改,即发生 timeupdate 事件。以下示例注册 timeupdate 事件,将在 currentTime 发生更改时引发该事件。
1 2 |
//set up event to update the progress bar oAudio.addEventListener("timeupdate", progressBar, true); |
在引发 timeupdate 事件时,该事件将调用 progressBar 函数,然后此函数会更新进度栏。
progressBar 函数首先获取 elapsedTime 的值,方法是获取 currentTime 并通过 Math.round 方法将其四舍五入为最接近的整数。虽然无需为进度栏对此值进行四舍五入,但建议在打印时执行此操作以避免出现问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function progressBar() { var oAudio = document.getElementById('myaudio'); //get current time in seconds var elapsedTime = Math.round(oAudio.currentTime); //update the progress bar if (canvas.getContext) { var ctx = canvas.getContext("2d"); //clear canvas before painting ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight); ctx.fillStyle = "rgb(255,0,0)"; var fWidth = (elapsedTime / oAudio.duration) * (canvas.clientWidth); if (fWidth > 0) { ctx.fillRect(0, 0, fWidth, canvas.clientHeight); } } } |
进度栏使用 canvas 元素创建一个矩形区域,该区域将逐渐填充以显示音频文件中的当前位置。Canvas 是 HTML5 元素,它提供一个富图形区域,你可以使用它的方法和属性绘制图形或显示图像。在使用 canvas 元素时,建议你在使用该功能前先进行测试。canvas 元素与 audio 元素相同,让你可以将故障转移文本或代码放入页面的 HTML 部分。
1 2 3 4 5 6 7 |
<audio id="myaudio"> HTML5 audio not supported </audio> <canvas id="canvas" width="500" height="20"> canvas not supported </canvas> |
在示例的 JavaScript 部分,代码对 canvas 对象(由 document.getElementById() 返回)进行测试。如果支持 canvas 标记,将获取一个对象;否则,它将返回 undefined。然后,JavaScript 代码将检查 getContext 方法支持,并调用它以将 contextRenderingContext2D 对象返回到 “ctx” 变量。当前在 Internet Explorer 9 中仅支持二维上下文,但是 W3C 已允许其他类型的上下文。
contextRenderingContext2D 对象包含大部分绘图和图形方法以及属性,可用它们在 canvas 元素上创建图形并显示图像。每次调用 progressBar 函数时,都会清除 canvas 以防止用户在文件中向后移动时出现错误显示。填充的宽度通过将 currentTime 值除以 audio 对象的 duration 属性计算而出。然后,将结果乘以canvas 的 clientWidth 以获取占 canvas 宽度的百分比。然后在 fillRect 方法中使用该值来填充 canvas。
除非 canvas 上包含一些图形,否则将不设置颜色。在下面的示例中,你将使用级联样式表 (CSS) 样式来勾勒 canvas 进度栏的轮廓。如果没有轮廓,则在开始播放文件之前,你将看不到进度栏。
进度栏还可用于在音频文件内部进行移动。向更新 currentTime 的函数中注册一个鼠标 click 事件,该函数将相对于你所单击的位置更新位置的当前时间。在单击进度栏时,它将基于 canvas 中光标的相对 X 位置计算并设置 currentTime,如以下示例所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//set up mouse click to control position of audio canvas.addEventListener("click", function(e) { //this might seem redundant, but this these are needed later - make global to remove these var oAudio = document.getElementById('myaudio'); var canvas = document.getElementById('canvas'); if (!e) { e = window.event; } //get the latest windows event if it isn't set try { //calculate the current time based on position of mouse cursor in canvas box oAudio.currentTime = oAudio.duration * (e.offsetX / canvas.clientWidth); } catch (err) { // Fail silently but show in F12 developer tools console if (window.console && console.error("Error:" + err)); } }, true); } |
前面的函数和代码示例演示了有关如何在网页上播放音频文件、显示进度栏和控制音频文件的播放位置的基础知识。下面的示例将使用单独的调用,每次在需要时获取 canvas 和 audio 对象。在你自己的代码中,你可能需要创建全局变量,或者将播放器封装到自己的全局对象中。
可对播放器进行扩展,以使用播放列表、在播放音乐时显示不断变化的图像、使用多个 audio 元素或使用采样音频创建虚拟乐器。
下面的示例包含本主题中的所有代码示例,并将这些代码示例进行组合以显示完整过程。将其复制并粘贴到一个 HTML 文件中,然后开始体验。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
<!DOCTYPE html> <html> <head> <title>Using media events to add a progress bar to an audio player</title> <!-- Uncomment the following meta tag if you have issues rendering this page on an intranet site. --> <!-- <meta http-equiv="X-UA-Compatible" content="IE=9"/> --> <style id="inlinecss" type="text/css"> /* put a border around the canvas element */ #canvas { margin-top:10px; border-style:solid; border-width:1px; padding:3px; } </style> <script type="text/javascript"> //Global variable to track current file name var currentFile = ""; //display and update progress bar function progressBar() { var oAudio = document.getElementById('myaudio'); //get current time in seconds var elapsedTime = Math.round(oAudio.currentTime); //update the progress bar if (canvas.getContext) { var ctx = canvas.getContext("2d"); //clear canvas before painting ctx.clearRect(0, 0, canvas.clientWidth, canvas.clientHeight); ctx.fillStyle = "rgb(255,0,0)"; var fWidth = (elapsedTime / oAudio.duration) * (canvas.clientWidth); if (fWidth > 0) { ctx.fillRect(0, 0, fWidth, canvas.clientHeight); } } } //Play and pause function function playAudio() { try { //return objects we need to work with var oAudio = document.getElementById('myaudio'); var btn = document.getElementById('play'); var audioURL = document.getElementById('audiofile'); //Skip loading if current file hasn't changed. if (audioURL.value !== currentFile) { oAudio.src = audioURL.value; currentFile = audioURL.value; } //Tests the paused attribute and set state. if (oAudio.paused) { oAudio.play(); btn.textContent = "Pause"; } else { oAudio.pause(); btn.textContent = "Play"; } } catch (e) { // Fail silently but show in F12 developer tools console if (window.console && console.error("Error:" + e)); } } //Rewinds the audio file by 30 seconds. function rewindAudio() { try { var oAudio = document.getElementById('myaudio'); oAudio.currentTime -= 30.0; } catch (e) { // Fail silently but show in F12 developer tools console if (window.console && console.error("Error:" + e)); } } //Fast forwards the audio file by 30 seconds. function forwardAudio() { try { var oAudio = document.getElementById('myaudio'); oAudio.currentTime += 30.0; } catch (e) { // Fail silently but show in F12 developer tools console if (window.console && console.error("Error:" + e)); } } //Restart the audio file to the beginning. function restartAudio() { try { var oAudio = document.getElementById('myaudio'); oAudio.currentTime = 0; } catch (e) { // Fail silently but show in F12 developer tools console if (window.console && console.error("Error:" + e)); } } //added events function initEvents() { var canvas = document.getElementById('canvas'); var oAudio = document.getElementById('myaudio'); //set up event to toggle play button to pause when playing oAudio.addEventListener("playing", function() { document.getElementById("play").textContent = "Pause"; }, true); //set up event to toggle play button to play when paused oAudio.addEventListener("pause", function() { document.getElementById("play").textContent = "Play"; }, true); //set up event to update the progress bar oAudio.addEventListener("timeupdate", progressBar, true); //set up mouse click to control position of audio canvas.addEventListener("click", function(e) { //this might seem redundant, but this these are needed later - make global to remove these var oAudio = document.getElementById('myaudio'); var canvas = document.getElementById('canvas'); if (!e) { e = window.event; } //get the latest windows event if it isn't set try { //calculate the current time based on position of mouse cursor in canvas box oAudio.currentTime = oAudio.duration * (e.offsetX / canvas.clientWidth); } catch (err) { // Fail silently but show in F12 developer tools console if (window.console && console.error("Error:" + err)); } }, true); } //this event gets fired when a page has loaded window.addEventListener("DOMContentLoaded", initEvents, false); </script> </head> <body> <h1>HTML5 audio player with progress bar</h1> <p> <input type="text" id="audiofile" size="80" value="demo.mp3" /> </p> <audio id="myaudio"> HTML5 audio not supported </audio> <p> <button id="play" onclick="playAudio();" disabled> Play </button> <button id="rewind" onclick="rewindAudio();" disabled> Rewind </button> <button id="forward" onclick="forwardAudio();" disabled> Fast forward </button> <button id="restart" onclick="restartAudio();" disabled> Restart </button> </p> <p> <canvas id="canvas" width="500" height="20"> canvas not supported </canvas> </p> <script type="text/javascript"> //Check for support and enable buttons if (window.HTMLAudioElement) { document.getElementById("play").disabled = false; document.getElementById("rewind").disabled = false; document.getElementById("forward").disabled = false; document.getElementById("restart").disabled = false; } </script> </body> </html> |
本系列内容
- HTML5 audio 元素入门:你可使用 audio 元素向你的网页中添加基本音频播放器,而无需脚本或加载项控件。
- 使用 JavaScript 控制 Audio 对象:HTML5 中的 audio 对象提供可用于通过 JavaScript 控制播放的方法、属性以及事件。
- 使用 Media 事件添加进度栏:media 提供 audio 对象可以使用的一系列丰富事件。可利用一组事件来获取可用于在播放音频文件时跟踪进度的状态数据。
- 支持多个音频文件格式:通过使用 audio 元素或对象支持多个音频格式,你可以将更多的听众从多个浏览器吸引到你的网页上。
赞,收藏了慢慢看
好厉害,就是不太会js,没看太懂, 能不能用jquery实现啊
可以的啊,之前有写过video的,可以看看https://github.com/xuanfeng/MV-show-html5。更多http://labs.music.baidu.com/demo/audiolab/
404错误呀,能否再发一遍
谢谢了
哪个404错误呢?