2014-09-22 121 views
1

我試圖使用Web音頻API從服務器加載音頻。到目前爲止,我所有使用Node/Express API返回數據的嘗試都未能返回任何可能在我的瀏覽器中播放的內容。從節點API的Web音頻API中加載音頻

我目前的嘗試是將文件的內容存儲到Mongo內的緩衝區中。請求時,音頻轉換爲ArrayBuffer,然後編碼到Base64中。客戶端然後解碼字符串並將其傳遞到Web Audio API緩衝區源。

我確信我是這麼做的,但這是我唯一想到的。我已經在下面發佈了我的代碼。如果你知道更好的方法,我會很感激這個指導。

感謝

數據加載到MongoDB的

var buffer = fs.readFileSync('C4.mp3'); 
Sound.create({ 
    instrument: 'Piano', 
    audio: buffer, 
    note: 'C4' 
}); 

控制器將音頻

var Sound = require('./sound.model'); 
var base64 = require('base64-arraybuffer'); 

// Get list of sounds 
exports.index = function(req, res) { 
    Sound.find(function (err, sounds) { 
    if(err) { return handleError(res, err); } 

    var soundsToReturn = []; 
    for (var i = 0; i < sounds.length; i++) { 
     soundsToReturn.push({instrument: sounds[i].instrument, 
          audio: base64.encode(toArrayBuffer(sounds[i].audio)), 
          note: sounds[i].note}); 
    }; 

    return res.status(200).json(soundsToReturn); 
    }); 
}; 

function toArrayBuffer(buffer) { 
    var ab = new ArrayBuffer(buffer.length); 
    var view = new Uint8Array(ab); 
    for (var i = 0; i < buffer.length; ++i) { 
     view[i] = buffer[i]; 
    } 
    return ab; 
} 

客戶端解碼音頻

$.ajax({ 
     url: url, 
     dataType: 'json', 
     success: function(data) { 
     audioCtx.decodeAudioData(_base64ToArrayBuffer(data[0].audio), function(b){ 
      buffer = b; 
     }) 
     } 
    }); 


function _base64ToArrayBuffer(base64) { 
    var binary_string = window.atob(base64); 
    var len = binary_string.length; 
    var bytes = new Uint8Array(len); 
    for (var i = 0; i < len; i++)  { 
    var ascii = binary_string.charCodeAt(i); 
    bytes[i] = ascii; 
    } 
    return bytes.buffer; 
} 
+1

'sounds [i] .audio'的類型是什麼?它是一個緩衝區(例如'Buffer.isBuffer(聲音[i] .audio)'返回'true')? – mscdex 2014-09-22 03:00:03

+0

是的,它是由fs.readFileSync創建的緩衝區。 – Nael 2014-09-22 03:03:58

回答

2

因爲你的聲音數據已經在緩衝區的格式,你應該能減少你的控制器代碼只是:

var Sound = require('./sound.model'); 

// Get list of sounds 
exports.index = function(req, res) { 
    Sound.find(function (err, sounds) { 
    if (err) 
     return handleError(res, err); 

    var soundsToReturn = []; 
    for (var i = 0; i < sounds.length; i++) { 
     soundsToReturn.push({instrument: sounds[i].instrument, 
          audio: sounds[i].audio.toString('base64'), 
          note: sounds[i].note}); 
    }; 

    return res.status(200).json(soundsToReturn); 
    }); 
}; 

至於客戶端去,對你唯一可能看看有沒有testing base64 decoding performance。除此之外,我認爲其他一切看起來都不錯。

+0

太棒了!當我回家後,我會嘗試它,讓你知道它是如何發生的。謝謝您的幫助。 – Nael 2014-09-22 14:02:08

+0

謝謝!這工作完美。 – Nael 2014-09-23 00:42:06