Ожидание буфера записи FFmpeg image2pipe до завершения

#node.js #ffmpeg #child-process

#node.js #ffmpeg #дочерний процесс

Вопрос:

Я извлекаю кадры из внешнего источника и передаю их в качестве буфера в FFMPEG, используя image2pipe и -i -

 const childProcess = spawn(ffmpeg, [
  "-y",
  "-f",
  "image2pipe",
  "-i",
  "-",
  "-vcodec",
  "libx264",
  "-pix_fmt",
  "yuv420p",
  output
]);
 

Затем у меня есть цикл, который выполняет эту работу.

 for (let i = 0; i < 250; i  ) {
  // ...await
}
 

Внутри обещания

 // ... do the job to get buffer

childProcess.stdin.write(frame); // frame === buffer

// frame done
resolve("success!");
 

Проблема в том, что в некоторых видеороликах кадры прыгают и дергаются. Это происходит потому, что FFmpeg не полностью завершает запись в файл перед переходом к следующему кадру.

Есть ли способ записать буфер в файл через FFmpeg и убедиться, что запись фрейма завершена, прежде чем двигаться дальше?

Дополнительная информация

Вот исходный файл https://s3.us-west-2.amazonaws.com/storycreator.v2.uploads/ckigi4kro00160vlfjmt74afp

Вот визуализированный файл https://s3.us-west-2.amazonaws.com/storycreator.testing/607715f0-3ab9-11eb-a139-3bb84618c6c5.mp4?t=1607585343922

Вот журналы

 2020-12-10T07:28:48.942Z    0ae0c435-54d3-416f-9d1a-8ddf595a7e83    INFO    frame=  130 fps= 16 q=-1.0 Lsize=      83kB time=00:00:05.08 bitrate= 133.6kbits/s speed=0.641x    video:80kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.928688%
 
 2020-12-10T07:28:48.942Z    0ae0c435-54d3-416f-9d1a-8ddf595a7e83    INFO    [libx264 @ 0x640d6c0] frame I:1     Avg QP:15.47  size: 68227[libx264 @ 0x640d6c0] frame P:33    Avg QP:15.07  size:   246[libx264 @ 0x640d6c0] frame B:96    Avg QP:18.75  size:    56[libx264 @ 0x640d6c0] consecutive B-frames:  1.5%  0.0%  0.0% 98.5%
 
 2020-12-10T07:28:48.943Z    0ae0c435-54d3-416f-9d1a-8ddf595a7e83    INFO    [libx264 @ 0x640d6c0] mb I  I16..4: 24.6% 60.5% 14.9%[libx264 @ 0x640d6c0] mb P  I16..4:  0.0%  0.2%  0.0%  P16..4:  0.8%  0.0%  0.0%  0.0%  0.0%    skip:98.9%[libx264 @ 0x640d6c0] mb B  I16..4:  0.0%  0.0%  0.0%  B16..8:  0.3%  0.0%  0.0%  direct: 0.0%  skip:99.7%  L0:26.7% L1:73.3% BI: 0.0%[libx264 @ 0x640d6c0] 8x8 transform intra:62.0% inter:83.6%[libx264 @ 0x640d6c0] coded y,uvDC,uvAC intra: 49.2% 44.3% 32.1% inter: 0.0% 0.2% 0.0%[libx264 @ 0x640d6c0] i16 v,h,dc,p: 53% 38%  7%  2%[libx264 @ 0x640d6c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 26% 24% 29%  3%  3%  3%  5%  3%  4%[libx264 @ 0x640d6c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 37% 26% 14%  3%  4%  5%  4%  4%  3%[libx264 @ 0x640d6c0] i8c dc,h,v,p: 57% 27% 13%  3%[libx264 @ 0x640d6c0] Weighted P-Frames: Y:0.0% UV:0.0%[libx264 @ 0x640d6c0] ref P L0: 95.1%  1.2%  3.1%  0.6%[libx264 @ 0x640d6c0] ref B L0: 48.1% 51.3%  0.7%[libx264 @ 0x640d6c0] ref B L1: 97.3%  2.7%[libx264 @ 0x640d6c0] kb/s:125.75
 
 2020-12-10T07:28:48.944Z    0ae0c435-54d3-416f-9d1a-8ddf595a7e83    INFO    [cache @ 0x5f57940] Statistics, cache hits:0 cache misses:3551
 

Комментарии:

1. Попробуйте протокол асинхронности и кэширования, как показано здесь: ffmpeg.org/ffmpeg-protocols.html#async

2. Есть ли более сложный пример использования этого протокола? Я не совсем понимаю, как это реализовать. Не могу найти много в Google, я прочитал верхнюю часть страницы. Должен ли я префиксить свой вывод с async: помощью? Если да, то как мне справиться с этим так, чтобы интерполяция кадров была в порядке

3. Заменить "-" на "async:cache:pipe:0"

4. Я не уверен, что это значит. Поделитесь полным журналом ffmpeg и, возможно, некоторыми скриншотами исходного кода и результата.

5. Ваша система не может кодировать достаточно быстро или кадры поступают недостаточно быстро. Если первое, добавление -preset ultrafast поможет.