2

嗨,我目前正在开发一个用纯 HTML5 和 Javascript 编写的音频波形编辑器。

我使用Mozilla<audio>的.MozAudioAvailable 事件取得了一些进展,以获取每一帧中的数据并将它们绘制在画布上。然而,使用 MozAudioAvailable 我只能得到它现在正在播放的帧。

作为一个波形编辑器,我的程序必须在当前播放之前大约几秒钟寻找和预处理数据,即播放 00:05:00 时,我的程序可能应该显示从 00:04:50 到 00:05 的波形:10,所以我必须在播放之前对 00:05:00 到 00:05:10 之间的数据进行预处理。

我在互联网上搜索了一个解决方案(不限于 Mozilla 方法,也接受 Chrome 或 Opera 方法),但没有得到任何答案。preload 属性和 onprogress 事件没有帮助。现在我正在尝试制作另一个<audio>标签,它播放与原始音乐相同的音乐,但提前几秒钟获取数据。但是,如您所见,该解决方案非常脏。

我想知道 HTML5 小组是否正在研究一些更灵活的方法来处理多媒体对象,或者是否一些浏览器开发团队正在研究这个。如果您对此主题有任何想法或经验,请给我一些指示。谢谢。

更新:

也许我没有清楚地描述我的问题。下面是一张从 Audacity 拍摄的照片,可以证明我的目标。

Audacity 的截图

大约 1:55.10 处的垂直线表示当前正在播放的帧。对于该行左侧的帧,我可以使用我的程序保存的历史帧。但是对于尚未播放的行右侧的帧,我无法在播放之前获得它们。

一个丑陋的解决方案可能是添加另一个<audio>播放速度比原始标签更快的标签(在屏幕截图中应该播放 1:55.90),这样我就可以得到垂直线右侧的帧。但这很丑陋,而且不容易实现,不是吗?

4

1 回答 1

3

来自https://wiki.mozilla.org/Audio_Data_API

您要查找的数据位于传递给侦听器函数的事件对象的 framebuffer 属性中

要访问历史数据的特定部分,只需缓存您自己捕获的先前帧缓冲区

var channels,
    rate,
    frameBufferLength,
    samples;

function audioInfo() {
  var audio = document.getElementById('audio');

  // After loadedmetadata event, following media element attributes are known:
  channels          = audio.mozChannels;
  rate              = audio.mozSampleRate;
  frameBufferLength = audio.mozFrameBufferLength;
}

function audioAvailable(event) {
  var samples = event.frameBuffer;
  var time    = event.time;

  for (var i = 0; i < frameBufferLength; i++) {
    // Do something with the audio data as it is played.
    processSample(samples[i], channels, rate);
  }
}

附录:

好的,所以你需要你的程序来展望未来。据我所知,除非您可以使用某种巧妙的预加载解决方案,否则这是不可行的(尽管我怀疑这也行不通-也许订阅 moz 邮件列表可能使您可以将其作为未来的功能来请求)。

我仍然不知道您到底要做什么,但是我有一个 HTML5 播放器,它使用绘制的波形背景并在播放期间使用我自己从服务器上的音频文件中提取的 RAW 音频数据绘制示波器- 我不使用 mozilla API,因为我希望它可以在所有支持 ogg 的浏览器中工作,所以我完全加载了一个单独的数据 blob。这当然意味着 a) 它不是纯 HTML5 和 Javascript,并且 b) 我的播放器只播放源自我的服务器的文件。无论如何,阶段是:

1) 使用命令行实用程序(我推荐 sox)来提取 RAW 数据 - 我将其缩混为单声道、8 位 1khz PCM,它相对较小但分辨率足够高,可以使用(1kb/秒)。如果您想保留它(在非 mozilla 浏览器中播放期间绘制示波器)将其作为 blob 缓存在数据库中。

2)使用 RAW PCM 使用 php_gd 绘制波浪的 PNG,并将其缓存(用于您的播放器背景)

3) 如果使用 RAW 数据,那么您可以将其作为 base64 编码的字符串加载到 javascript 中

如果您仅将服务器用作提取 RAW 数据的代理,即使使用外部音频文件也不是不可能做到这一点,但是您需要注意引入的安全问题。

如果这完全适用于您,请告诉我,我将发布一些源代码。有问题的程序将在我稍微整理一下后作为开源项目在http://jukenix.org上发布。

此操作的 PS 屏幕截图位于上面链接页面的底部

于 2012-05-27T11:32:29.213 回答