У меня возникла проблема, когда всякий раз, когда я перекодирую аудиофайл и отправляю аудио-буфер клиенту через socket.io для воспроизведения через Интернет, мое соединение умирает, как только как я выполнитьНастройка getChannelData, вызывающая сбой socket.io в веб-аудио
source.buffer.getChannelData(0).set(audio);
Я предполагаю, что это не проблема Socket.IO и что я только видел этот вопрос Socket.io в результате реальной проблемы. В клиенте я передаю аудиофайл в stdin ffmpeg и слушаю stderr из ffmpeg, чтобы определить, когда безопасно отправлять буфер. Клиент получает буфер и делает все правильно до указанной выше строки. Вот пример тестового кода для воспроизведения проблемы.
стороне сервера:
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);
}
На самом деле это проблема двух частей. То, что вы упомянули, и audioStack = Int16Array (данные); должен быть audioStack = новый Int16Array (data) ;. Это странно, потому что у меня есть оба из тех, что установлены с FF29, и все работает отлично. –