【问题标题】:Audio data preprocessing using <audio> tag and Javascript使用 <audio> 标签和 Javascript 进行音频数据预处理
【发布时间】:2012-02-16 19:26:48
【问题描述】:

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

我使用来自Mozilla&lt;audio&gt;.MozAudioAvailable 事件取得了一些进展,以获取每一帧中的数据并将它们绘制在画布上。但是使用 MozAudioAvailable 我只能得到它现在正在播放的帧。

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

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

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

更新:

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

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

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

【问题讨论】:

    标签: javascript html audio mozilla waveform


    【解决方案1】:

    来自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) 使用 php_gd 使用 RAW PCM 绘制波浪的 PNG,并将其缓存(用于播放器背景)

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

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

    如果这完全适用于您,请告诉我,我会发布一些源代码。 一旦我整理了一下,该程序将作为一个开源项目在http://jukenix.org 发布。

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

    【讨论】:

    • 谢谢,1360050。您的回答很有帮助,但没有解决我的问题。请参阅上面的更新,它可能更清楚地描述了我的问题。谢谢。
    • 谢谢克兰西。我相信您的解决方案有效。我已经考虑过一些像你这样的解决方案,但是纯 HTML5 解决方案会更好地满足我的要求。也许我可以找到一些用 Javascript 编写的波形解码器,这可能对我有更多帮助。
    • 是的,但是如果您打算使用 javascript 读取源自二进制音频文件的音频波,那么您将不得不自己将二进制数据转换成更容易理解的东西。据我所知,mozilla 音频数据 API 是唯一接近解决方案的解决方案,它跳过自己创建单独的 RAW 流,正如你所说,它只知道缓冲区的状态。如果你解决了你的问题,我很想知道你的决定。
    猜你喜欢
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 2020-07-22
    相关资源
    最近更新 更多