#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
поможет.