我遇到了一个问题,每当我对音频文件进行转码并通过socket.io将音频缓冲区发送到客户端以便通过网络音频播放时,我的连接会在我执行时立即死亡
source.buffer.getChannelData(0).set(audio);
我假设这不是Socket.IO问题而且我只是因为真正的问题而看到了Socket.IO问题。在客户端我将音频文件传送到ffmpeg的stdin并监听ffmpeg的stderr以确定何时发送缓冲区是安全的。客户端正在接收缓冲区并正在正确地执行所有操作,直到上述行。以下是一些重现问题的示例测试代码。
服务器端:
var express = require('express');
var http = require('http');
var spawn = require('child_process').spawn;
var app = express();
var webServer = http.createServer(app);
var io = require('socket.io').listen(webServer, {log: false});
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.send(
"<script src='/socket.io/socket.io.js'></script>\n"+
"<script>var socket=io.connect('http://127.0.0.1:3000');</script>\n"+
"<script src='/webaudio_file_cli.js'></script>"
);
});
webServer.listen(3000);
io.sockets.on('connection', function(webSocket) {
var disconnect = '0';
var count = 0;
var audBuf = new Buffer([]);
if (disconnect == '0') {
console.log('new connection...');
var inputStream = spawn('wget', ['-O','-','http://www.noiseaddicts.com/samples/4353.mp3']);
var ffmpeg = spawn('ffmpeg', [
'-i', 'pipe:0', // Input on stdin
'-acodec', 'pcm_s16le', // PCM 16bits, little-endian
'-ar', '24000', // Sampling rate
'-ac', 1, // Mono
'-f', 'wav',
'pipe:1' // Output on stdout
], {stdio: ['pipe','pipe','pipe']});
inputStream.stdout.pipe(ffmpeg.stdin);
ffmpeg.stdout.on('data', function(data) {
audBuf = Buffer.concat([audBuf,data]);
});
ffmpeg.stderr.on('data', function(data) {
var _line = data.toString('utf8');
if (_line.substring(0,5) == 'size=' && _line.indexOf('headers:') > -1) {
console.log('completed...');
webSocket.emit('audio',audBuf);
}
});
}
webSocket.on('disconnect', function() {
console.log('disconnecting...');
disconnect=1;
});
});
客户端(webaudio_file_cli.js):
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var source = context.createBufferSource();
var audioStack = [], audio = [];
socket.on('audio', function(data) {
playAudio(data);
});
function playAudio(data) {
// playback starting...
audioStack = Int16Array(data);
for (var i = 0; i < audioStack.length; i++) {
audio[i] = (audioStack[i]>0)?audioStack[i]/32767:audioStack[i]/32768; // convert buffer to within the range -1.0 -> +1.0
}
var audioBuffer = context.createBuffer(1, audio.length, 24000);
source.buffer.getChannelData(0).set(audio);
source.buffer = audioBuffer;
source.connect(context.destination);
source.start(0);
}
答案 0 :(得分:2)
在此示例中,您在设置source.Buffer = audioBuffer之前访问source.buffer.getChannelData。翻转这两行的顺序,可能吗?