Как передавать данные MP3 через WebSockets с помощью node.js и socket.io?

18

У меня проблемы с потоковой передачей данных 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/');

Клиент получает данные как строку типа, но я хочу передать данные для decodeAudioData, и кажется, что строки не нужны. При вызове 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>
    
задан Jan Deinhard 06.01.2012 в 16:04
источник
  • вы нашли решение этой проблемы? –  codeAnand 02.03.2012 в 17:24
  • Я не нашел решение, использующее socket.io. См. Мой собственный ответ для решения без socket.io. –  Jan Deinhard 03.03.2012 в 19:35
  • Socket.io 1.0 поддерживает двоичный файл, я пробовал его, но не работает. Также я пытаюсь использовать websocket, но с той же ошибкой. У вас есть пример того, как вы это решаете? –  cmarrero01 28.02.2015 в 02:11
  • @ cmarrero01 Мое решение в то время использовало ws вместо Socket.io. Но я знаю, что он работает с текущей версией Socket.io. На стороне сервера я должен был явно указать ws на отправку двоичных данных, например ws.send (array, {binary: true, mask: true}); Не уверен, что я устанавливаю маску в true или false. НТН –  Jan Deinhard 28.02.2015 в 06:04
  • Попробуйте удалить 'encoding': 'binary', из createReadStream –  worker11811 23.10.2016 в 17:45

3 ответа

10

Я нашел способ передавать данные MP3 через Websockets самостоятельно.

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

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

EDIT: мне удалось улучшить качество звука. Похоже, метод Web Audio decodeAudioData не предназначен для декодирования непрерывных фрагментов данных MP3.

    
ответ дан Jan Deinhard 10.01.2012 в 09:12
  • Эта ссылка не работает. –  ma11hew28 15.09.2012 в 04:19
  • См. stackoverflow.com/a/13315068/612262 относительно «допустимых кусков mp3». –  biril 09.11.2012 в 21:00
  • Можете ли вы разместить свое решение? Я также пытаюсь передать данные MP3 в websocket. –  Light 02.06.2013 в 16:15
  • Пожалуйста, поставьте свое решение. –  Brad.Smith 15.11.2013 в 17:02
  • Для тех, кто все еще ищет, решение находится на его странице Github: github.com/polaris/audio-demo –  Casey Chow 22.07.2014 в 19:31
Показать остальные комментарии
3

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

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

    
ответ дан Tracker1 06.01.2012 в 20:01
  • Спасибо за ваш ответ, но я не могу заставить его работать со сценарием. Полученный массив ArrayBuffer длиннее, чем он должен быть. Хотелось бы избежать Base64 в любом случае из-за накладных расходов. Кажется, я нашел решение самостоятельно. Я собираюсь опубликовать его здесь в ближайшее время. –  Jan Deinhard 10.01.2012 в 08:52
  • @Fair Dinkum Thinkum Я хотел бы знать ваше решение. –  fyasar 08.12.2012 в 23:12
  • @fyasar Моим решением было использовать модуль ws вместо socket.io. В то время socket.io не мог обрабатывать двоичные данные. Не уверен, что это все еще так. –  Jan Deinhard 10.12.2012 в 16:14
  • @Fair Dinkum Thinkum Вы можете оставить сообщение? –  Light 13.06.2013 в 06:43
  • @FairDinkumThinkum Socket.io 1.0 поддерживает двоичные данные, но я не могу заставить его работать. socket.io/blog/introducing-socket-io-1-0/#binary вы можете поделиться своим решением? –  cmarrero01 28.02.2015 в 02:27
0

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

  1. Ссылка
  2. Ссылка
ответ дан Anant Gupta 27.06.2012 в 06:48