Я делаю экранные записи игрового процесса (Dota2), используя мою видеокарту NVIDIA GeForce для аппаратной записи (NVEC Encoder).Это создает видео с переменной частотой кадров.Мои настройки NVIDIA 60 кадров в секунду 15000 кбит / с.Я заплатил одному парню за создание программы, которая генерирует сценарии с заданными моментами запуска / остановки, которые могут извлекать клипы из видео и объединять их с перекрестным затуханием.Смотрите пример кода ниже.Сценарий работает для многих входных записей, но часто дает сбой: аудио и видео десинхронизируются (обычно задержка звука) во многих клипах, около 0,5 секунд.Я думаю, что это больше не работает, когда частота кадров падает больше во время записи.Он не знает, как решить проблему, и мне интересно, кто-нибудь мог бы указать, можно ли что-то исправить в скрипте (пример ниже)?
Скорость обработки данных очень важна (теперь мы выделяем 10 минут)видео занимает около 7-10 минут).Решения, увеличивающие это количество намного больше, к сожалению, не слишком интересны.Его подход состоял в том, чтобы работать отдельно с аудио и видео и объединяться в конце.У него уже есть программа для создания кода ffmpeg для работы с различными сценариями (также с добавлением оверлеев, добавлением музыки, вступления / выхода), поэтому было бы предпочтительнее с некоторыми простыми исправлениями в его коде, а не драматическим изменением логики.Но если ничто иное не может решить проблему, перепроектирование в логике в порядке.Использование других инструментов, кроме ffmpeg, также нормально, но должно быть автоматизируемым (scripts / cli) и не увеличивать время обработки слишком сильно.
Запуск программы «mediainfo» на входном видео показывает, что частота кадров для этого достаточно низкаявходное видео:
Режим частоты кадров: переменный
Частота кадров: 60 000 FPS
Минимальная частота кадров: 3,059 FPS
Максимальная частота кадров: 63,739 FPS
Полный отчет здесь: https://pastebin.com/TX061Wih
Входное видео можно скачать из Dropbox здесь (6 ГБ): https://www.dropbox.com/s/ftwdgapazbi62pr/fullgame.mp4?dl=0
Вот пример сценария, когда его просятизвлеките два клипа из входного видео в 9:57 (длина 41 с) и 15:45 (длина 28 с) и объедините их с затуханием 0,5 с временем затухания 0,5.Там могут быть некоторые остатки кода из опций, которые не используются в этом примере (оверлеи, музыка, вступление / выход).Используя приведенное выше видео, создается десинхронизация аудио / видео.
6 команд выполняются последовательно:
ffmpeg.exe -loglevel warning -ss 00:09:57 -i fullgame.mp4 -t 00:00:41 -filter_complex "[0:a]afade=t=out:st=40.5:d=0.5[a1]" -map "[a1]" -y out_temp_00.mp4.wav
ffmpeg.exe -loglevel warning -i fullgame.mp4 -ss 00:09:57 -t 00:00:41 -an -vcodec copy -f mpegts -avoid_negative_ts make_zero -y out_temp_00.mp4.ts
ffmpeg.exe -loglevel warning -ss 00:15:45 -i fullgame.mp4 -t 00:00:28 -filter_complex "[0:a]afade=t=in:st=0:d=0.5[a1]" -map "[a1]" -y out_temp_01.mp4.wav
ffmpeg.exe -loglevel warning -i fullgame.mp4 -ss 00:15:45 -t 00:00:28 -an -vcodec copy -f mpegts -avoid_negative_ts make_zero -y out_temp_01.mp4.ts
ffmpeg.exe -loglevel warning -i out_temp_00.mp4.wav -i out_temp_01.mp4.wav -y -filter_complex "[0:a]adelay=0|0[a0];[1:a]adelay=40500|40500[a1];[a0][a1]amix=inputs=2:dropout_transition=68.5,atrim=duration=68.5[outa0];[outa0]loudnorm[outa]" -map "[outa]" -ar 48000 -acodec aac -strict -2 fullgame_Output.mp4.aac
ffmpeg.exe -loglevel warning -i out_temp_00.mp4.ts -i out_temp_01.mp4.ts -y -i fullgame_Output.mp4.aac -filter_complex "[0:v]trim=start=0.5,setpts=PTS-STARTPTS[0c];[1:v]trim=start=0.5,setpts=PTS-STARTPTS[1c];[0:v]trim=40.5:41,setpts=PTS-STARTPTS[fo];[1:v]trim=0:0.5[fi];[fi]format=pix_fmts=yuva420p,fade=t=in:st=0:d=0.5:alpha=1[z];[fo]format=pix_fmts=yuva420p,fade=t=out:st=0:d=0.5:alpha=1[x];[z]fifo[w];[x]fifo[q];[q][w]overlay[r];[0c][r][1c]concat=n=3[outv]" -map "[outv]" -map 2:a -shortest -acodec copy -vcodec libx264 -preset ultrafast -b 15000k -aspect 1920:1080 fullgame_Output.mp4
PS
Я уже обратился за помощью в чат-комнату ffmpeg.Один парень сказал, что знает, в чем проблема, но не знает, как ее исправить (?):
[00:10] <kepstin> oh, wait, you're using -vcodec copy
[00:10] <kepstin> that explains everything.
[00:10] <kepstin> when you're using -vcodec copy, the start time (set with -ss) is rounded to the nearest keyframe
[00:10] <kepstin> it's not exact
[00:11] <kepstin> depending on the keyframe interval, this will result in possibly quite large shifts
[00:11] <kepstin> (also, your commands are applying audio filters on commands with -an, which is confusing/contradictory)
[00:12] <birdboy88> so the problem is that the audio temporary clips are not being extracted from the same excat timepoints?
[00:13] <kepstin> birdboy88: yeah, your audio is being re-encoded to wav so it's being cut sample-accurate, but the video's not being precisely cut.
[00:16] <birdboy88> kepstin: so I need to use slow seek (?) to extract video accurately? Or somehow extract audio only where there are video keyframes?
[00:17] <kepstin> birdboy88: i don't know how to extract audio starting at video keyframes with ffmpeg cli. You're already doing slow seek, which doesn't help (you should move the -ss option to before the -i option to speed it up)
[00:17] <kepstin> if you want accurate video cutting when saving to a file, you have to re-encode the video
[00:18] <kepstin> (doing this in a single ffmpeg command means you don't have to save to a file, so you can avoid the issue)
[00:18] * kepstin is off for a bit now
РЕДАКТИРОВАТЬ: Все сделано с последней версией ffmpeg.
Я не смогчтобы заставить код Гаяна работать.Он всегда проигрывает звук (аудио 40.5 или 27.5, поэтому используется только один звук).Это единственное, что работает для меня (изменения были adelay = 40500 | 40500 и amix = input = 2 [a0]; [a0] loudnorm):
ffmpeg -i fullgame.mp4 -filter_complex "[0]split=2[vpre][vpost];
[0]asplit=2[apre][apost];
[vpre]trim=start='00:09:57':duration='00:00:41',setpts=PTS-STARTPTS[vpre-t];
[apre]atrim=start='00:09:57':duration='00:00:41',asetpts=PTS-STARTPTS,afade=t=out:st=40.5:d=0.5[apre-t];
[vpost]trim=start='00:15:45':duration='00:00:28',setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5:alpha=1,setpts=PTS+40.5/TB[vpost-t];
[apost]atrim=start='00:15:45':duration='00:00:28',asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5,adelay=40500|40500[apost-t];
[vpre-t][vpost-t]overlay[v];
[apre-t][apost-t]amix=inputs=2[a0];[a0]loudnorm[a]" -map "[v]" -map "[a]" -y -c:v libx264 -preset ultrafast -b:v 15000k -aspect 1920:1080 -c:a aac fullgame_Output.mp4
Затем я попытался использовать аналогичную настройку, но с3 клипа, но на одной машине я получил ошибку: «Ошибка при фильтрации: невозможно выделить память».А у моей 16 ГБ памяти скорость обработки составляет 0,02х!Есть ли способ избежать этого?Это код, который я пробовал:
ffmpeg -i fullgame.mp4 -filter_complex "[0]split=3[vpre][vpost][v3];
[0]asplit=3[apre][apost][a3];
[vpre]trim=start=357:duration=41,setpts=PTS-STARTPTS[vpre-t];
[apre]atrim=start=357:duration=41,asetpts=PTS-STARTPTS,afade=t=out:st=40.5:d=0.5[apre-t];
[vpost]trim=start=795:duration=28,setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5:alpha=1,fade=t=out:st=40.5:d=0.5:alpha=1,setpts=PTS+40.5/TB[vpost-t];
[apost]atrim=start=795:duration=28,asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5,afade=t=out:st=27.5:d=0.5,adelay=40500|40500[apost-t];
[v3]trim=start=95:duration=30,setpts=PTS-STARTPTS,format=yuva420p,fade=t=in:st=0:d=0.5,setpts=PTS+41+28-0.5/TB[v3-t];
[a3]atrim=start=95:duration=30,asetpts=PTS-STARTPTS,afade=t=in:st=0:d=0.5,adelay=68500|68500[a3-t];
[vpre-t][vpost-t]overlay[v1];
[v1][v3-t]overlay[v];
[apre-t][apost-t][a3-t]amix=inputs=3[a0];
[a0]loudnorm[a]" -map "[v]" -map "[a]" -y -c:v libx264 -preset ultrafast -b:v 15000k -aspect 1920:1080 -c:a aac fullgame_Output.mp4