使用FFMPEG进行网络音频接口的直播流传输

7
我正在尝试使用node.js + ffmpeg并利用web audio api仅向连接到局域网的浏览器流式传输音频。不使用<audio>元素,因为它会添加自己的缓冲区(大约8到10秒),而我希望获得最高的低延迟(最多1到2秒)。音频播放成功,但是声音非常杂乱无章。以下是我的node.js(服务器端)文件:
var ws = require('websocket.io'), 
server = ws.listen(3000);
var child_process = require("child_process");
var i = 0;
server.on('connection', function (socket) 
{

console.log('New client connected');

var ffmpeg = child_process.spawn("ffmpeg",[
    "-re","-i",
    "A.mp3","-f",
    "f32le",
    "pipe:1"                     // Output to STDOUT
    ]);

 ffmpeg.stdout.on('data', function(data)
 {
    var buff = new Buffer(data);
    socket.send(buff.toString('base64'));
 });
});

以下是我的HTML代码:

var audioBuffer = null;
var context = null;
window.addEventListener('load', init, false);
function init() {
    try {
        context = new webkitAudioContext();
    } catch(e) {
        alert('Web Audio API is not supported in this browser');
    }
}

var ws = new WebSocket("ws://localhost:3000/");

ws.onmessage = function(message)
{
    var d1 = base64DecToArr(message.data).buffer;
    var d2 = new DataView(d1);

    var data = new Float32Array(d2.byteLength / Float32Array.BYTES_PER_ELEMENT);
    for (var jj = 0; jj < data.length; ++jj)
    {
        data[jj] = d2.getFloat32(jj * Float32Array.BYTES_PER_ELEMENT, true);
    }

    var audioBuffer = context.createBuffer(2, data.length, 44100);
    audioBuffer.getChannelData(0).set(data);

    var source = context.createBufferSource(); // creates a sound source
    source.buffer = audioBuffer;
    source.connect(context.destination); // connect the source to the context's destination (the speakers)
    source.start(0);
};

请问有人能够建议出错的具体原因吗?

谢谢, Nayan


你好Nayan,我正在使用Web音频API,并希望记录通过Web音频API播放的声音。我的问题在这里http://stackoverflow.com/questions/21234902/record-sound-of-a-webaudio-apis-audio-context,请问你能帮我吗? - Jot Dhaliwal
2个回答

6

我搞定了!

我所要做的就是调整通道数。

我将FFMPEG设置为输出单声道音频,效果非常好。这是我的新FFMOEG命令:

var ffmpeg = child_process.spawn("ffmpeg",[
    "-re","-i",
    "A.mp3",
    "-ac","1","-f",
    "f32le",
    "pipe:1"                     // Output to STDOUT
    ]);

1
你正在取数据块,将其创建为单独的节点,并基于网络时间启动它们。要使音频声音正确,必须在没有中断的情况下播放缓冲区,并实现样本精确定时。你需要从根本上改变你的方法。
我处理这个任务的方式是创建一个ScriptProcessorNode,它管理自己的PCM样本缓冲区。在处理过程中,它将样本读入输出缓冲区。这保证了音频平稳播放。

我已经尝试过了,但没有成功,您能否指出具体的示例或编写一段代码? - Nayan
1
这正是应该的做法。愿意用一些代码来演示吗? - olealgo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接