2014-09-22 112 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