2014-07-03 180 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