html5制作音乐播放器,html5中audio

  html5制作音乐播放器,html5中audio

  支持的浏览器:

  难度:中等

  注意:本文中讨论的API尚未最终确定,仍在不断变化。请在自己的项目中谨慎使用。

  音频在很大程度上使得多媒体体验非常吸引人。如果你曾经试过关掉声音看电影,你可能会注意到这一点。

  游戏也不例外!我最喜欢的视频游戏的记忆包含音乐和音效。二十年后的今天,在大多数情况下,当玩我最喜欢的游戏时,我仍然无法将近藤浩治和马特的黑暗配乐从我的脑海中驱逐出去。音效也是一样,比如魔兽争霸中单位的实时点击反应,任天堂的经典例子。

  游戏的音频提出了一些有趣的挑战。要创作出引人入胜的游戏音乐,设计师需要调整潜在的不可预测的状态。事实上,一些游戏可以持续未知的时间长度,声音可以与环境交互,并以复杂的方式混合,例如室内效果和相对声音定位。最后,一部剧可能会有很多音效,要求混音效果好,渲染上不损失性能。

  网页上的游戏音频

  对于简单的游戏,使用音频标签可能就足够了。然而,许多浏览器提供的粗糙实现导致音频故障和高延迟的出现。这可能只是一个暂时的问题,因为制造商正在努力改进他们的实现。要了解音频标签的支持,我们可以使用areweplayingyet.org提供的优秀测试工具。

  一旦你深入到音频标签规范中,你就会清楚地明白,有很多东西是用它根本无法实现的。这并不奇怪,因为它主要是为了支持多媒体播放而设计的。这些限制包括:

  您不能对声音信号使用过滤器。

  无法访问原始PCM (Yujie: WAV)数据

  没有来源、受众立场、方向的概念。

  没有精确的时间安排。

  下面我将深入介绍一些关于用WebAudio API编写游戏音频的内容。在入门教程中可以找到这个API的简要介绍。

  游戏里经常有背景音乐播放。例如,背景音轨如下:

  如果你的循环音乐很短,而且为人所知,那就相当讨厌了。当玩家被困在某个区域或关卡时,同样的背景音乐会在同一时间连续播放。我们可能需要逐渐淡出,以防止玩家感到无聊。另一种策略是通过根据游戏中的上下文逐渐淡入和淡出来混合不同的声音强度。

  如果你的玩家处于史诗BOSS级别,可能需要混合几种不同的情绪区间,比如从艺术氛围到心理暗示氛围再到激烈氛围。音乐合成软件通常允许您通过选择一组曲目来导出几个混音(它们具有相同的长度)。这样轨道之间就有了一定的内在一致性,避免了从一个轨道切换到另一个轨道时的不和谐过渡。

  然后,使用WebAudio API,您可以使用BufferLoader等一些类通过XHR导入所有这些声音样本(这在介绍网络音频API的文章中有深入的描述)。加载音效是需要时间的,所以游戏中用到的这些音效应该在每一关开始加载页面的时候同时加载,或者在玩家玩的时候增量加载。

  接下来,您需要为每个节点创建一个源,并为每个源创建一个增益节点。连接图如下:

  完成后,您可以在一个循环中同时播放这些声源,因为它们都具有相同的长度,WebAudio API将确保它们是一致的。由于最终BOSS战时音效风格会变得相似或不同,游戏可以使用类似如下的增量算法来改变链中每个节点对应的增益值:

  在上面的方法中,有两个声源同时播放,我们使用相同功率的曲线(如简介中所述)在它们之间淡入淡出。下面的例子使用了这种策略,演示的背景音乐在魔兽争霸2的主题上逐渐增强:

  完整的源代码

  缺失的一环:网络音频的音频标签

  现在很多游戏开发者使用音频标签作为背景音乐,因为它非常适合流媒体内容。现在,您可以通过audio选项卡将内容引入网络音频的上下文中。

  Audio tag支持流媒体,这是相当有用的,因为它可以让你立即播放背景音乐,而不必等待下载所有内容。网络音频API支持音频流后,就可以进行操作或分析了。以下示例对通过音频标签播放的音乐使用低通滤波器:

  关于音频标签和网络音频API集成的更多讨论,可以看看这篇短文。

  游戏通常会播放声音效果来响应用户输入或游戏状态的变化。但是和背景音乐一样,音效会很快让用户感到疲劳。为了避免这种情况,最好有一个声音池,用于相似但不同的声音效果。这可以从轻微变化到急剧变化一个固定的长度,就像在魔兽系列中点击每个单位时一样。

  游戏音频的另一个重点是可以同时有多个。想象一下,你正在和多个演员拍摄一场枪战。每把机枪每秒触发几次,导致几十种音效同时播放。同时播放多个音源的音效,准确定时音源,才是网络音频API真正的亮点。

  以下示例演示了由多个单独的子弹样本组成的机枪,它创建了多个播放时间交错的声源。

  下面是这段代码的效果:

  如果你觉得太吵了,我很抱歉。我们将在后面的章节中讨论测量和动态压缩。

  现在如果你游戏里的机枪都是这样的声音,那就相当无聊了。当然,它们会根据目标的距离和相对位置而变化(稍后讨论),但即使这样也可能不够。幸运的是,网络音频API提供了一种简单的方法来调整上面的例子。有两种主要类型:

  1.子弹发射时间的微妙变化

  2.更改每个声音效果的回放速率(同时更改音高),以更好地模拟现实世界中的随机性。

  这两种方法的效果如下:

  完整的源代码

  对于这些技术在现实生活中的实际例子,可以看看台球桌的演示,它采用随机采样和改变打球速度的方式来表现球更有趣的碰撞声。

  3D定位音效

  游戏通常以2D或3D世界为背景。在这种情况下,立体声音频可以大大增加沉浸式体验。好在网络音频API带来了内置的硬件加速位置音频特性,可以直接使用。顺便说一下,您应该确保您有立体声扬声器(最好是耳机)来运行以下示例。在下面的示例中,您可以通过在画布上滚动鼠标滚轮来更改声源的角度。

  完整的源代码

  在上面的例子中,画布的中心有一个听众(人的图标),而鼠标控制声源的位置(喇叭的图标)。这是一个使用AudioPannerNode实现这种效果的简单示例。它的基本思想是通过设置音频信号源的位置来响应鼠标的移动,如下所示:

  关于网络音频空间化需要了解的事情:

  监听器默认为原点(0,0,0)。

  网络音频定位API没有单元,所以我引入了一个乘数,让演示听起来更好。

  网络采用Y-直角坐标系(与大多数计算机图形系统相反)。这就是我在上面的代码片段中更改Y轴的原因。

  高级:锥形

  定位模型非常强大,相当先进,主要基于OpenAL。请参考上述规范的第3节和第4节了解详情。

  当有单个AudioListener连接到网络音频API时,它可以按位置和方向配置空间。每个源都可以通过AudioPannerNode对音频输入进行空间化。视听节点有位置和方向,也有距离和方向性模型。

  距离模型指定的增益取决于与源的接近程度,而方向模型可以通过指定内锥和外锥来配置,以确定收听者在内锥、内锥和外锥之间或外锥之外时的增益(通常为负)。

  虽然我的例子是在2D空间,这种模式可以很容易地扩展到三维。例如,对于3D声音空间化的示例,请看这个位置演示。此外,对于位置,网络音频模型还可以选择多普勒频移的速度。这个例子展示了多普勒效应的细节。

  关于这个话题的更多信息,可以阅读混合定位音频和WebGL的详细教程。

  室内效果和滤镜

  实际上,声音被感知的方式很大程度上取决于它所处的房间。同样吱吱作响的门,在地下室里发出的声音,和大开着的大厅相比,完全不一样。高价值的游戏会模仿这些影响,因为为每个环境制作一套独立的音效是相当昂贵的,而且会产生相当多的素材和大量的游戏数据。

  严格来说,描述原声和现实中听到的声音之间差异的音频术语是脉冲响应。可以仔细记录这些脉冲响应。事实上,为了您的方便,有些网站存储了许多这些预先录制的脉冲响应文件(存储为音频)。

  有关如何从给定环境创建脉冲响应的更多信息,您可以通读网络音频API规范卷积部分的“录音设置”一节。

  更重要的是,针对我们的目标,网络音频API提供了一种在我们的语音中应用脉冲响应的简单方法,即通过使用卷积节点。

  下面的例子展示了一些不同脉冲响应下的军事演讲:

  完整的源代码

  你也可以看看网络音频API的规范页面上的房间效果演示,以及这个让你通过一个很棒的爵士乐标准来控制干(原始素材)和湿(卷积处理)的混音的例子。

  最后的倒计时

  现在你已经创建了一个游戏,添加了位置音频,现在你的画面中有大量的AudioNodes同时播放。太棒了,但是还有一件事要考虑:

  当多个声音相互叠加播放时,您可能会发现在某些情况下,声音超过了扬声器的最大容量。就像图像超出画布边界一样,当波形超过最大阈值时,声音会被削波,产生明显的失真。波形看起来像这样:

  这里有一个真实剪辑的例子。波形看起来相当糟糕:

  这听起来也很可怕:

  听到如上这种失真的音乐是很严重的,或者相反,过度混音会迫使听众调大音量。如果你现在有这种情况,真的需要马上解决!

  从技术角度来说,任何一个通道的信号值超过有效范围,也就是-1到1之间,就会发生削波。一旦检测到削波,视觉反馈会非常有用。为了可靠地实现这一点,您可以将JavaScriptAudioNode放在您的图中。音频将设置如下:

  同时,可以通过以下processAudio方法检测削波:

  正常情况下,注意不要因为性能原因过度使用JavaScriptAudioNode。在这种情况下,另一种方法是将RealtimeAnalyserNode添加到getByteFrequencyData的音频图中,并在渲染期间由requestAnimationFrame检测。这种方法更有效,但它会错过大多数信号(包括可能削波的地方),因为渲染最多发生60次,并且音频信号变化更快。

  因为削波的检测非常重要,所以未来我们很可能会在网络音频API节点中看到内置的MeterNode。

  通过调整主AudioGainNode的增益,您可以控制混音的音量以防止削波。但是,在实践中,因为游戏中播放的声音可能取决于许多因素,所以在所有情况下都很难确定主增益值来防止削波。通常情况下,你应该调整增益,做最坏的打算,但这是一门艺术,不是科学。

  要知道这是如何实现的,这里有一个例子,你可以调整主增益。如果增益设置得太高,声音会被削波。监视器将变红,以给出剪辑的视觉反馈。下面的声音生态环境是Disco Dan的混音,原曲是Yasunori Mitsuda的一首很棒的《时空之轮》。

  完整的源代码

  在音乐和游戏制作中,效果设备通常用于平滑信号和控制尖峰信号。这个功能可以通过DynamicsCompressorNode在在线音频的世界里实现,可以为你的音频画面添加更响亮、更丰富、更饱满的音色,也有利于剪辑。直接引用规范,这个节点

  ".降低信号最响亮部分的音量,提高最柔和部分的音量.在游戏和音乐应用程序中播放大量独立声音时,控制信号的整体水平尤为重要,并有助于避免削波。”

  使用动态压缩通常是个好主意,尤其是在游戏设置中。如前所述,您不知道此时和何时会播放什么声音。迪纳莫实验室的Plink就是一个很好的例子,因为声音的回放完全取决于你和其他参与者。效果在大多数情况下都是有用的,除了一些罕见的情况,在这种情况下,您可以使用经过仔细调整、听起来“刚刚好”的轨道。

  它的实现很简单,只需在音频图中的目标之前添加DynamicsCompressorNode作为最后一个节点。

  关于动态压缩的更多细节,维基百科上的这篇文章信息量很大。

  综上所述,仔细检查削波,通过插入主增益节点来防止削波。然后使用动态效应器节点来收紧整个混音。您的音频图表可能如下所示:

  以上内容涵盖了我认为使用网络音频API开发游戏音乐最重要的方面。借助这些技术,您可以在浏览器上构建真正吸引人的音频体验。在我结束这篇文章之前,我给你一个提示:如果你的浏览器标签页使用页面可见性API切换到后台,一定要让声音暂停,否则你会给用户提供一个潜在的无聊体验。

  关于网络音频的其他信息,需要在入门文章中了解更多。如果您有问题,请查看在线音频常见问题解答中是否有回答。最后,如果您有其他问题,可以在堆栈溢出的web-audio选项卡下提问。

  在本文的最后,我现在就给大家展示一下网络音频API在实际游戏中的使用:

  野外跑步者,以及关于一些技术细节的文档。

  愤怒的小鸟,最近改用网络音频API。请转到本文档查看更多信息。

  SkidRacer,用了很多立体声效果。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: