Прямая трансляция Node.js: избегайте буферизации

Я написал небольшой сервер nodeJS, который выводит системный звук, захваченный ffmpeg в Windows (используя DirectShow), в браузер в виде потокового файла MP3. Звук должен быть как можно более живым, с минимальной буферизацией или без нее, а эффект «пропуска» в звуке вполне приемлем.

Когда я воспроизводю звук в Chrome с помощью аудиотега HTML5, возникает задержка около 8-10 секунд при подключении к локальной сети с малой задержкой. Я подозревал, что это буфер на стороне клиента, и использовал Flash MP3-плеер на стороне клиента, что уменьшило задержку до 2-3 секунд.

Теперь буферизация, похоже, происходит на стороне сервера. В документации для NodeJS response.write упоминается, что данные записываются в буферы ядра. Как мне вообще избежать какой-либо буферизации или, по крайней мере, обойти ее, чтобы клиент всегда получал самые последние аудиоданные? Стратегии обработки событий «слива», чтобы всегда отправлять оперативные данные?

В объекте запроса я использовал setNoDelay(true) чтобы избежать использования алгоритма Нэгла. Ниже приведен фрагмент того, как записываются данные, когда порожденный процесс ffmpeg выдает данные.

var clients = []; //List of client connections currently being served
ffmpeg.stdout.on('data', function(data) {
    for(var i = 0; i < clients.length; i++){
        clients[i].res.write(data);
    }
});

person Shirish Kamath    schedule 26.10.2012    source источник


Ответы (1)


Есть несколько мест, где происходит задержка/буферизация:

  1. Захват DirectShow (~ 100 мс или около того)
  2. FFMPEG Буфер кодирования MPEG (1-10 секунд, в зависимости от конфигурации)
  3. Сетевые записи и передача (около 0 в вашей настройке)
  4. Буферизация на стороне клиента (зависит от клиента, как вы видели - большинство клиентов буферизуют ~ 2 секунды для декодирования)

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

Как только вы это сделаете, вы обнаружите, что ваша задержка составляет секунду или две. По крайней мере, это то, что я получаю с аналогичной настройкой.

person Brad    schedule 27.10.2012
comment
ffmpeg не кажется серьезным узким местом в моей настройке. Текущая задержка по локальной сети составляет около 2-3 секунд, и я пытаюсь уменьшить ее еще больше. Я попробую ваше предложение отбросить первые несколько битов. Спасибо. - person Shirish Kamath; 22.11.2012