开启HTML5音频的力量

分享于 

17分钟阅读

Web开发

  繁體

在10天内开发 Windows 8应用程序。

声音构成了我们生活的background。 今天,的HTML5 <音频> 元素使得网络开发人员能够在他们的应用程序中嵌入声音。 平台它的余部分的灵活性可以使用多种方案,从简单的声音效果到 background 音频引擎。

这个博客文章介绍了在你的Web应用程序中使用 <音频> 标签的一些最佳实践,并包括来自真实世界站点的有用提示。

将音频元素添加到页面

第一步是将音频元素添加到页面中。 通过在标记中声明一个 <音频> 标记,通过在JavaScript代码中实例化新的音频元素,可以执行这里操作:


<audio src="audio/sample.mp3" autoplay>



</audio>



运行现场演示程序


var audio = document.createElement("audio");


if (audio!= null && audio.canPlayType && audio.canPlayType("audio/mpeg"))


{


audio.src = "audio/sample.mp3";


audio.play();


}



运行现场演示程序


<audio src="data:audio/mpeg,ID3%02%00%00%00%00%..." autoplay>



</audio>



运行现场演示程序

第一种方法允许你在页面加载期间初始化音频组件。 第二种方法使你更灵活,更好地管理网络流,因为它将音频剪辑的加载延迟到应用程序生命周期。 第三种方法是在页面中嵌入音频文件作为的数据 uri,减少服务器的请求数。

注意,即使没有实际添加到DOM树( 和代码 Fragment 上面 中一样),也可以播放由JavaScript生成的音频元素。 但是,将音频元素添加到页面将允许你显示默认的控件栏。

虽然本文没有介绍,但是你可以支持多个音频文件格式。 另外,如果你在服务器上承载音频文件,请记住在服务器端的register 文件("音频/cfg")。 例如这里是互联网信息服务( IIS )的设置。

播放前先加载音频

有了音频元素后,你可以选择最佳的预加载策略。 HTML5 <音频> 规范描述了一个具有三个可能值的预加载属性:

  • "to":向 User Agent 提示,作者不希望用户需要媒体资源,或者服务器想要最小化不必要的流量。
    如果你的场景是一个播客博客,每个文章都有一个音频文件,这个选项可以减少初始预载带宽。 用户播放文件( 要么通过默认的可视控件,要么使用JavaScript方法( load() ) 或者 play()。) 后,浏览器将开始获取音频流。
  • "元数据"提示给 User Agent,作者不希望用户需要媒体资源,但是提取资源元数据( 维度。持续时间。等等 )。) 是合理的。
    如果你构建音频播放器控件,并且需要有关音频剪辑的基本信息,但不需要播放它,则建议使用这里选项。
  • "自动":向 User Agent 提示,User Agent 可以先将用户的需求放在服务器上,并且包括优秀的下载资源。
    如果你构建游戏,这种方法可以能是最好的,因为它允许你在实际启动游戏体验之前预加载所有音频。

要注意,在设置音频元素 src属性时,如果场景需要另一个值,请在设置 src 之前在一行中设置预加载preload属性- unless。

你可以在这三个选项中预览对网络的影响,方法是使用F12开发工具( 网络选项卡) 调试目的,可以通过检查"总是从服务器刷新"菜单来模拟新的调用并禁用本地缓存。

preload=none:

preload=metadata:

preload=auto:

这里属性对于初始化阶段非常有用,你可能还需要知道浏览器什么时候实际下载了音频剪辑,并准备好播放它。 可以通过听"canplaythrough"事件获得这里信息;User Agent 估计如果现在启动回放,则可以在不进行进一步缓冲的情况下。


var audio = document.createElement("audio");


audio.src = "audio/sample.mp3";


audio.addEventListener("canplaythrough", function () {


alert('The file is loaded and ready to play!');


}, false);



运行现场演示程序

循环

对于带有音频的场景,另一个常见的要求是能够循环播放声音剪辑。 有了 HTML5 <音频> ;可以使用"循环"属性进行这里操作;这个设置将永远循环你的剪辑,或者直到用户激活 pause() 音频控件。


<audio src="audio/sample.mp3" autoplay loop>



</audio>



运行现场演示程序

另一种循环音频文件的方法是在音频剪辑结束时编程调用 play() 方法;这样做最终可以管理一个循环之间的延迟,而另一个循环则是这样。


var audio = document.createElement("audio");


audio.src = "piano/3C.mp3";


audio.addEventListener('ended', function () {


// Wait 500 milliseconds before next loop


setTimeout(function () { audio.play(); }, 500);


}, false);


audio.play();



运行现场演示程序

注意,在声音实际结束之前在音频元素上执行的任何 play() 调用都不会产生任何影响。 如果对当前声音感兴趣,则需要重置 currentTime。


var audio = null;


audio = document.createElement("audio");


audio.src = "piano/3C.mp3";


audio.addEventListener('ended', function () {


audio.play();


}, false);


function play() {


audio.play();


}


function restart() {


audio.currentTime = 0;


audio.play();


}



运行现场演示程序

多个音频标签

如果场景需要同一个音频文件多次播放( 就是用重叠的声音),那么可以通过创建指向同一个文件的多个音频标记来实现这个结果。 同样,如果同时使用不同的音频文件,同样的方法也同样适用。 就像我们在本文前面所解释的,你可以编程方式添加它们,或者通过在标记中实例化它们。

下面的代码Fragment演示如何使用标记加载和播放多个音频文件。 音频样本都具有相同的长度;在执行结束时,它们将从开始处开始循环。 在 IE 9中播放它们时,你会注意到它们在各个循环中自动同步。 注意,这些 5声音组合将像之前演示("示例中使用的音频文件一样播放。


<body>


<audio src="audio/Bass.mp3" autoplay loop>


</audio>


<audio src="audio/Drum.mp3" autoplay loop>


</audio>


<audio src="audio/Crunch.mp3" autoplay loop>


</audio>


<audio src="audio/Guitar.mp3" autoplay loop>


</audio>


<audio src="audio/Pizzicato.mp3" autoplay loop>


</audio>


</body>



运行现场演示程序

虽然这种方法非常简单,但在大多数情况下,开发人员更喜欢以编程方式创建音频剪辑。 下面的代码Fragment演示如何使用代码动态添加 3个音频剪辑。 当你们一起演奏时,你们会得到C 大调和弦 !





AddNote("3C");


AddNote("3E");


AddNote("3G");


function AddNote(name) {


var audio = document.createElement("audio");


audio.src = "piano/" + name + ".mp3";


audio.autoplay = true;


}



运行现场演示程序

这里代码 Pattern 适用于任何浏览器,并允许你构建非常引人注目的场景 !

重要的是要记住,当你的应用程序或者游戏变得更复杂时,你最终可能会达到两个限制: 可以在同一页面上预加载的音频元素数和可以同时播放的音频元素数。

这些数字取决于浏览器和你的电脑的功能。 根据我的经验,IE 9可以同时处理数十个并发音频元素,没有问题。 其他浏览器也不做同样好的事情- 你可能会在循环中播放多个文件时遇到明显明显的延迟和失真。

同步策略

根据网络的特点,你应该始终考虑添加标记之间的延迟,获取内容并准备播放。 特别是,在处理多个文件时,每个文件都可以在前面或者以后播放。 例如这里是以前使用的3文件的捕获,从本地主机加载。

就像你在时间列中看到的,不同的文件可能在不同的时间准备好。

一个非常常见的同步策略是先预加载所有文件。 准备好之后,可以快速循环遍历循环并开始播放它们。


var audios = [];


var loading = 0;


AddNote("2C");


AddNote("2E");


AddNote("2G");


AddNote("3C");


AddNote("3E");


AddNote("3G");


AddNote("4C");


function AddNote(name) {


loading++;


var audio = document.createElement("audio");


audio.loop = true;


audio.addEventListener("canplaythrough", function () {


loading--;


if (loading == 0) // All files are preloaded


StartPlayingAll();


}, false);


audio.src = "piano/" + name + ".mp3";


audios.push(audio);


}


function StartPlayingAll() {


for (var i = 0; i < audios.length; i++)


audios[i].play();


}



运行现场演示程序

现在让我们一起来吧 ! 下面的演示模拟了一个弹 Frère ( 也叫兄弟约翰 peter。或者 Fra Martino )的钢琴。 页面开始获取所有记录,显示在客户机上加载时的进度。 一旦他们准备就绪,歌曲就开始播放并继续播放。

运行现场演示程序

真实世界中的音频

现在我们已经看到了处理多个音频文件的常见模式,我将把几个网站作为最佳实践使用音频> 标签的例子。

Pirates Pirates:

中,我发表了另一个博客帖子,我谈到了海盗喜爱 Daises,这是由 Grant Skinner构建的一个非常棒的HTML5游戏。 除了优秀的游戏和吸引人的视觉效果,that还开发了一个复杂的音频库,在整个游戏中播放。 主要逻辑封装在 AudioManager 类中。 就像前面所提,在开始游戏之前,站点预先加载所有音频剪辑并在初始加载屏幕中显示累积的进度。 网站还考虑到网络超时的情况,或者在下载音频文件时发生错误。


addAudioChannel:function(b,a,f){


var h=document.createElement("audio");


if(f!=true){


this.currAsset=h;


this.timeoutId=setTimeout($.proxy(this,"handleAudioTimeout"),e.AUDIO_TIMEOUT);


h.addEventListener("canplaythrough",$.proxy(this,"handleAudioComplete"),false);


h.addEventListener("error",$.proxy(this,"handleAudioError"),false)


}


h.setAttribute("id",a);


h.setAttribute("preload","auto");


$("<source>").attr("src",b).appendTo(h);


$("<source>").attr("src",b.split(".mp3")[0]+".ogg").appendTo(h);


document.body.appendChild(h)


}


,handleAudioComplete:function(b){


if(LoadedAssets.getAsset(b.target.id)!=true){


LoadedAssets.addAsset(b.target.id,true);


clearTimeout(this.timeoutId);


this.calculatePercentLoaded(true)


}


}


,handleAudioError:function(b){


trace("Error Loading Audio:",b.target.id);


LoadedAssets.addAsset(b.target.id,true);


clearTimeout(this.timeoutId);


this.calculatePercentLoaded(true)


}


,handleAudioTimeout:function(){


trace("Audio Timed Out:",this.currAsset.id);


LoadedAssets.addAsset(this.currAsset.id,true);


this.calculatePercentLoaded(true)


}



运行现场演示程序

Grant目前开发一个声音库项目,允许开发人员将它的声音逻辑与任何其他应用程序一起使用。 期待着 !

烟花( 由 Mike Tompkins ):www.beautyoftheweb.com/firework

这款收费为的Firework演示特别有趣,因为它允许你同时与几个音轨互动,动态改变每个曲目的音量。 此外,当你与音频通道交互时,接口会动态响应不同的输入或者设置。

这一次,在HTML标记( 只有 6条轨道) 中声明了音频标记。 通过侦听 canplaythrough 事件以编程方式跟踪进程。 一旦所有音频文件准备就绪,循环就会经过列表并开始播放。


video.addEventListener('canplaythrough', onCanPlayAudio, false);


for (var i = 0; i < 5; i++) {


var aud = document.getElementById("aud" + i); 


targetVolumes.push(0);


aud.volume = 0;


audioTags.push({


"tag": aud,


"ready": false


});


aud.addEventListener('canplaythrough', onCanPlayAudio, false);


}


// Set audio/video tracks


document.getElementById("tompkins").src = MediaHelper.GetVideoUrl("Firework_3");


for (var i = 0; i < audioTracks.length; i++) {


document.getElementById("aud" + i).src = MediaHelper.GetAudioUrl(audioTracks[i]);


}



运行现场演示程序

这种情况下开发人员还决定从卷设置为 0,并在经验准备好以后将它的动态增加到 1. 根据音频卡和驱动程序的质量,这个小技巧减少了音频启动时听到初始"敲打"噪声的可以能性。

BeatKeep:www.beatkeep.net。

在最后一个场景 可能是这里所示的最为复杂的例子。 在这个例子中,你可以使用一个节拍机构建自己的歌曲,并在一个循环中播放几个音频剪辑。 应用中,音频通道和灵活的缓冲系统之间的同步是非常关键的,需要花费的时间来加载多个 Fragment。

节拍机能够完全控制节奏和时间签名;使用复杂的定时器逻辑和绑定模型是一个非常平滑的体验。

结语

我鼓励你尝试使用 IE 9或者其他浏览器尝试所有的示例和应用程序,并让我们知道你的体验是什么。 你可以下载本文中使用的所有示例代码

If audio audio audio audio recommend recommend,i watch MSDN MSDN MSDN MSDN MSDN MSDN MSDN MSDN recommend watch watch watch watch

感谢 DoubleDominant 在这篇博客文章中使用的音频剪辑, Grant Grant Skinner Skinner Skinner Skinner HTML5 HTML5 HTML5.


POW  Html5  音频  解锁  Html5音频