Реализация настраиваемого потока записи в Node.js, который останавливает и начинает запись в свой приемник на основе условия - PullRequest
0 голосов
/ 06 января 2019

Вот обзор потока данных в моем приложении:

Поток данных с видеокамеры ----> Записываемый поток -----> DataChannel ------> Web

Некоторые детали:

  • У меня нет контроля над потоком данных видеокамеры.
  • Объект DataChannel отправляет данные веб-клиенту по протоколу UDP и имеет собственный буфер.

Вот соответствующие части моего кода:

...

dataChannel = peerConnection.createDataChannel('dataChannel', dataChannelOptions);

const stream = new Writable({
  highWaterMark: 16384,
  write(chunk, encoding, callback) {
    try {
      console.log('buffered amount: ' + dataChannel.bufferedAmount)
      dataChannel.send(chunk);
      callback();
    } catch (e) {
      callback(e);
    }
  }
});

const command = ffmpeg('udp://192.168.10.1:11111')
    .withNoAudio()
    .inputFormat('h264')
    .fpsOutput(30)
    .outputOptions(['-g 90', '-s 960x720', '-quality realtime', '-speed 5', '-threads 8', '-row-mt 1', '-tile-columns 3', '-frame-parallel 1', '-qmin 4', '-qmax 48', '-b:v 3000k'])
    .videoCodec('libvpx-vp9')
    .outputFormat('webm')
    .output(stream)
    .on('error', (error, stdout, stderr) => {
      console.log('Error: ' + error.message);
      console.log('ffmpeg output:\n' + stdout);
      console.log('ffmpeg stderr:\n' + stderr);
    })
    .on('start', commandLine => console.log('Spawned ffmpeg with command: ' + commandLine))
    .on('end', stdout => console.log('ffmpeg has finished:' + stdout));

  command.run();

...

Мне нужен способ заставить перезаписываемый поток прекратить отправку фрагментов в DataChannel, когда буфер DataChannel заполнен, и начать отправку снова, когда в буфере DataChannel есть место.

1 Ответ

0 голосов
/ 07 января 2019

Не уверен, считается ли это лучшей практикой, но это решило ее для меня:

// prevent datachannel buffer from busting
  setTimeout(function repeat() {
    dataChannel.bufferedAmount > 16000000 ? stream.cork() : stream.uncork();
    setTimeout(repeat);
  });
...