2014-07-03 110 views
4

我目前正在尝试制作网络编辑器,允许用户轻松地调整其音频文件的基本设置,因为我已经整合了waveurfer.js的插件,因为它具有非常整洁和跨浏览器的解决方案,它的波形。使用网络音频api和wavesururfer.js剪切和粘贴音频

在为功能编制了一个必须列表之后,我决定剪切和粘贴对于本产品的工作是必不可少的,但是花费数小时试图弄清楚如何在现有库中实现这一功能后,甚至开始从头开始重建waveurfer.js功能,以了解我尚未成功的逻辑。

我的问题是,如果任何人都可以给我一些关于如何开始构建剪切和粘贴功能的指针,或者甚至是一个非常感谢的例子。

在此先感谢!

WaveSurfer示波器插件: http://wavesurfer-js.org

弹拨网页编辑器 http://plucked.de

编辑解决方案(例如是WaveSurfer示波器的对象。):

function cut(instance){ 
    var selection = instance.getSelection(); 
    if(selection){ 
    var original_buffer = instance.backend.buffer; 
    var new_buffer  = instance.backend.ac.createBuffer(original_buffer.numberOfChannels, original_buffer.length, original_buffer.sampleRate); 

    var first_list_index  = (selection.startPosition * original_buffer.sampleRate); 
    var second_list_index  = (selection.endPosition * original_buffer.sampleRate); 
    var second_list_mem_alloc = (original_buffer.length - (selection.endPosition * original_buffer.sampleRate)); 

    var new_list  = new Float32Array(parseInt(first_list_index)); 
    var second_list  = new Float32Array(parseInt(second_list_mem_alloc)); 
    var combined  = new Float32Array(original_buffer.length); 

    original_buffer.copyFromChannel(new_list, 0); 
    original_buffer.copyFromChannel(second_list, 0, second_list_index) 

    combined.set(new_list) 
    combined.set(second_list, first_list_index) 

    new_buffer.copyToChannel(combined, 0); 

    instance.loadDecodedBuffer(new_buffer); 
    }else{ 
    console.log('did not find selection') 
    } 
} 

回答

6

读该answer表明可以创建要复制的音频段的大小的空AudioBuffer(大小=以秒⨉采样率的长度),然后用来自该段的数据填充其信道的数据。

因此,代码可能这样的:

var originalBuffer = wavesurfer.backend.buffer; 
var emptySegment = wavesurfer.backend.ac.createBuffer(
    originalBuffer.numberOfChannels, 
    segmentDuration * originalBuffer.sampleRate, 
    originalBuffer.sampleRate 
); 
for (var i = 0; i < originalBuffer.numberOfChannels; i++) { 
    var chanData = originalBuffer.getChannelData(i); 
    var segmentChanData = emptySegment.getChannelData(i); 
    for (var j = 0, len = chanData.length; j < len; j++) { 
     segmentChanData[j] = chanData[j]; 
    } 
} 

emptySegment; // Here you go! 
       // Not empty anymore, contains a copy of the segment! 
+1

非常感谢katspaugh!这很棒!当我将新段粘贴到原始缓冲区时,是否还有一种重新绘制波形的方法。 – dennis

+2

@dennis,是的,有'wavesurur.loadDecodedBuffer'方法,它需要一个AudioBuffer。见https://github.com/katspaugh/wavesurfer.js/blob/a8772b8b5148c58c231d4ad7c1d8b62f37409efb/src/wavesurfer.js#L514 – katspaugh

3

有趣的问题。首先想到的词是ffmpeg。我无法从经验谈话,但如果我试图达到这一点,我会接近它,如:

让我们假设你选择你的音轨的一个区域,你想复制它,并创建一个新的轨道(稍后也许只是将它附加到现有的轨道)。

  1. 使用由漂亮wavesurfer.js库提供的getSelection()方法。这会给你startPosition()endPosition() [以秒为单位]。
  2. 鉴于这些要点,您现在可以在后端使用ffmpeg来选择区域并将其保存为新文件(最终将其上传到S3等)。请参阅thread以了解如何从ruby应用程序调用ffmpeg(其中显示的命令行参数也可能有帮助)。

请注意,如果您打算复制并粘贴很多区域以创建新的曲目,则在后端进行此操作可能会毫无意义,我想我会尝试查找客户端侧JS方法。

我希望这是有帮助的,至少一个简单的使用情况,并让你开始为休息;)

更新 这可能是值得一读。

  • Web Audio API,教程here
  • HTML5音频 - 播放状态。 here(不要错过TimeRanges的部分,看起来像一个合理的选择尝试)。
  • This one(过时,但值得一看,有趣的链接)。
+1

喜VINT-I-vuit,非常感谢你为你的输入。我现在有一个方向,我可以设置这个方向,我将采用客户端方法,因为后端方法可能太重了。在成功之后,我将确保返还该优惠并发布我的解决方案。 – dennis

+1

@dennis:我很高兴听到你现在对这个挑战有了更多的概述:)另外,再看看我更新的答案,我添加了一些链接,可以帮助你开始使用基于JS的做法。 – lllllll

+0

很多很多很多谢谢!事实上,TimeRanges的文章看起来非常有前途,我目前正在研究一个Javascript库,以涵盖这些功能,并结合waveurferjs的波形,一旦它处于测试阶段,它将托管在github上。 – dennis