2014-11-06 2 views
0

У меня возникла проблема, когда всякий раз, когда я перекодирую аудиофайл и отправляю аудио-буфер клиенту через 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); 
} 

ответ

2

В этом примере вы обращаетесь source.buffer.getChannelData перед установкой source.Buffer = AudioBuffer , Может, переверните порядок этих двух строк?

+0

На самом деле это проблема двух частей. То, что вы упомянули, и audioStack = Int16Array (данные); должен быть audioStack = новый Int16Array (data) ;. Это странно, потому что у меня есть оба из тех, что установлены с FF29, и все работает отлично. –