为Web Audio API加载音频以最节省内存的方式使用

时间:2014-05-14 14:26:20

标签: out-of-memory html5-audio audio-streaming webrtc web-audio

我有一个应用程序可以加载大约15个1 + MB的AAC音频文件,然后根据需要重复播放它们。在桌面浏览器上它工作正常,但在Mobile Safari上,由于内存问题,它可靠地崩溃:

Hardware Model:      iPhone5,2
OS Version:          iPhone OS 7.1 (11D167)
Kernel Version:      Darwin Kernel Version 14.0.0: Fri Feb 21 19:33:46 PST 2014; root:xnu-2423.10.67~1/RELEASE_ARM_S5L8950X
Date:                2014-05-14 09:36:33 -0400
Time since snapshot: 263 ms

Free pages:                              2299
Active pages:                            10722
Inactive pages:                          4853
Speculative pages:                       804
Throttled pages:                         215798
Purgeable pages:                         0
Wired pages:                             25998
File-backed pages:                       11493
Anonymous pages:                         4886
Compressions:                            3160361
Decompressions:                          1482836
Compressor Size:                         181
Uncompressed Pages in Compressor:        310
Largest process:   MobileSafari

Processes
     Name                    <UUID>                       rpages       recent_max   fds      [reason]          (state)

      librariand <uuid>          369              369  200   [vm-pageshortage]  (daemon)
     MobilePhone <uuid>         5793             5793  200   [vm-pageshortage]  (continuous)
    MobileSafari <uuid>       163511           163511  200   [vm-pageshortage]  (audio) (frontmost) (resume)
    ...

目前我正在使用示例BufferLoader.js脚本加载音频文件,该脚本通过AJAX将它们加载到ArrayBuffer中,然后创建AudioBufferSourceNode s:

var source = context.createBufferSource();
source.buffer = bufferList[0];

这显然不会对多个文件表现良好,特别是当我保留原始缓冲区来创建和播放源代码时。

我看到几个类似的替代方案。我可以:

  • 创建audio元素,然后从中创建MediaElementAudioSourceNode
  • 创建audio元素,然后从中创建MediaStream,最后从这些元素创建MediaStreamAudioSourceNode
  • 以某种方式获取FileReader对文件的引用,然后将其转换为MediaStreamAudioSourceNode

这些是我选择的准确摘要吗?哪个让我能够以最少的时间下载音频文件,但在任何时候都将最少量的数据保存在内存中(与Mobile Safari的文件缓存相比)?

谢谢!

1 个答案:

答案 0 :(得分:1)

将我的评论放在答案中:

使用Audio元素时,您可以轻松地将src用于存储在服务器上的文件。现在您可能不希望客户端每次都下载文件。在这种情况下,请将清单文件位置添加到html标记:

<html manifest="link/to/file">

浏览器第一次加载页面时,会识别它并下载清单文件。然后我读取文件,以确定每次都必须下载和存储文件或重新下载文件。每次加载页面时,浏览器都会检查本地清单文件和服务器清单文件之间是否存在任何差异。如果是,用户必须重新加载页面,但您也可以使用简单的脚本手动执行此操作(建议将其添加到html文档而不是它必须加载的任何脚本文件):

applicationCache.addEventListener('updateready', function(e) {if(applicationCache.status == 4) location.reload();});

现在清单文件本身的内容。在顶部添加CACHE MANIFEST,您可以在其下方转储需要加载的所有网址。如果你想添加文件,它应该每次都显式加载,你需要声明更多的东西。添加CACHE:以及要缓存的所有文件,NETWORK:让页面知道每次都要重新下载文件。

使用此系统,您不仅可以保证速度和减少网络负载,还可以保证脱机使用的网页。如果每次都需要加载页面(如某些更新文档),您可以在文档中添加FALLBACK:。只要指定的文件不可用,它就会使用您选择的另一个文件:

FALLBACK:
/file/to/load /path/to/file/if/other/file/is/unavailable

您可以找到更多信息here