Как передавать данные MP3 через WebSockets с помощью node.js и socket.io? - PullRequest
18 голосов
/ 06 января 2012

У меня проблемы с потоковой передачей данных MP3 через WebSocket с помощью node.js и socket.io.Кажется, все работает, но decodeAudioData не работает со мной честно.

Это мой игрушечный сервер:

var app = require('http').createServer(handler)
  , io = require('socket.io').listen(app)
  , fs = require('fs')

app.listen(8081);

function handler (req, res) {
    res.writeHead(200, {
        'Content-Type': 'text/html',
    });
    res.end('Hello, world!');
}

io.configure('development', function() {
  io.set('log level', 1);

  io.set('transports', [ 'websocket' ]);
});

io.sockets.on('connection', function (socket) {
    console.log('connection established');

    var readStream = fs.createReadStream("test.mp3", 
                                         {'flags': 'r',
                                          'encoding': 'binary', 
                                          'mode': 0666, 
                                          'bufferSize': 64 * 1024});
    readStream.on('data', function(data) {
        console.log(typeof data);
        console.log('sending chunk of data')
        socket.send(data);
    });

    socket.on('disconnect', function () {
        console.log('connection droped');
    });
});

console.log('Server running at http://127.0.0.1:8081/');

Клиент получает данные в виде строки типа, но я хочу передать данныедекодировать AudioData, и кажется, что он не любит строки.Вызов decodeAudioData приводит к следующему сообщению об ошибке:

Uncaught Error: SYNTAX_ERR: DOM Exception 12

Я думаю, что decodeAudioData нуждается в данных, хранящихся в ArrayBuffer.Есть ли способ конвертировать данные?

Это код клиента:

<script src="http://127.0.0.1:8081/socket.io/socket.io.js"></script>
<script>
    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');
        }
    }

    function decodeHandler(buffer) {
        console.log(data);
    }

    var socket = io.connect('http://127.0.0.1:8081');
    socket.on('message', function (data) {
            // HERE IS THE PROBLEM
        context.decodeAudioData(data, decodeHandler, function(e) { console.log(e); });
    });
</script>

Ответы [ 3 ]

11 голосов
/ 10 января 2012

Я нашел способ потоковой передачи данных MP3 через Websockets.

Одной из проблем был размер фрагмента данных MP3.Похоже, что API-интерфейс Web Audio должен быть снабжен действительными порциями MP3, чтобы иметь возможность декодировать данные.Наверное, не удивительно.В моем демонстрационном приложении я предоставляю набор файлов чанков MP3.

Кроме того, качество звука не идеальное.У меня есть некоторые тонкие глюки.Я смог улучшить это, отправив большие фрагменты данных MP3, но все еще есть крошечные трещины.

РЕДАКТИРОВАТЬ: Мне удалось улучшить качество звука.Похоже, что метод Web Audio decodeAudioData не предназначен для декодирования непрерывных фрагментов данных MP3.

3 голосов
/ 06 января 2012

В вашем случае context.decodeAudioData ожидает ArrayBuffer двоичных данных, я бы предложил преобразовать ваш чанк в строку base64, а затем в клиентскую часть ArrayBuffer для наиболее предсказуемых результатов. Этот сценарий должен стать хорошей отправной точкой для декодирования на стороне клиента из base64 фрагментированных данных.

Добавление строки с data = Base64Binary.decodeArrayBuffer(data); сразу после получения данных (строка в кодировке base-64) поможет ...

0 голосов
/ 27 июня 2012

Похоже, что socket.io по-прежнему не поддерживает двоичную передачу.Так что websocket.io можно использовать здесь.

  1. https://github.com/LearnBoost/socket.io/issues/511#issuecomment-2370129
  2. https://github.com/LearnBoost/socket.io/issues/680#issuecomment-3083490
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...