好的,我花了两天时间对不同的解决方案进行原型设计,我终于弄清楚了如何在不将资源存储在服务器上的情况下做到这一点。有一些博客对此进行了详细说明,但我无法在一个地方找到完整的解决方案,因此我将其添加到此处。经验丰富的程序员可能会认为这有点 hacky,但这是我看到这个工作的唯一方法,所以如果有人有更优雅的解决方案,我很想听听。
解决方案是将我的声音文件存储为 Base64 编码字符串。声音文件相对较小(小于 30kb),所以我希望性能不会成为太大问题。请注意,我将“xxx”放在一些超链接的前面,因为我的 n00b 状态意味着我不能发布两个以上的链接。
步骤 1:创建 Base 64 声音字体
首先,我需要将我的 mp3 转换为 Base64 编码的字符串并将其存储为 JSON。我在这里找到了一个为我进行此转换的网站 - xxxhttp://www.mobilefish.com/services/base64/base64.php 您可能需要使用文本编辑器删除返回字符,但对于任何需要示例的人,我找到了一些这里的钢琴音 - xxxhttps://raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js 请注意,为了使用我的示例,您需要删除标题部分数据:音频/mpeg;base64,
第 2 步:将声音字体解码为 ArrayBuffer
你可以自己实现它,但我找到了一个完美的 API(为什么要重新发明轮子,对吧?) - https://github.com/danguer/blog-examples/blob/master/js/base64-binary。 js
资源取自 -这里
第 3 步:添加其余代码
非常坦率的
var cNote = acoustic_grand_piano.C2;
var byteArray = Base64Binary.decodeArrayBuffer(cNote);
var context = new webkitAudioContext();
context.decodeAudioData(byteArray, function(buffer) {
var source = context.createBufferSource(); // creates a sound source
source.buffer = buffer;
source.connect(context.destination); // connect the source to the context's destination (the speakers)
source.noteOn(0);
}, function(err) { console.log("err(decodeAudioData): "+err); });
就是这样!我通过我的桌面版 Chrome 和移动版 Safari 运行(当然仅限 iOS 6,因为旧版本不支持 Web 音频)。在移动版 Safari 上加载需要几秒钟(在桌面版 Chrome 上加载不到 1 秒),但这可能是因为它需要花费时间下载声音字体。也可能是因为 iOS 在用户交互事件发生之前会阻止任何声音播放。我需要做更多的工作来看看它的表现。
希望这能拯救别人我所经历的悲伤。