Мне нужно прокрутить изображение по вертикали, от верхней части изображения до нижней части изображения, а затем прекратить создание выходного видео, как только последний нижний бит изображения прокручивается за пределы верхней части экрана.
@AlexHall интересно. Вы разобрались, и как эта опция прокрутки соотносится по функциональности с другими перечисленными здесь опциями, включая время выполнения?
Я не понял этого.
Вот решение, которое я нашел;
ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -i "input.png" -filter_complex "[1:v]scale=1920:-2[fg]; [0:v][fg]overlay=y=-'t*h*0.02'[v]" -map "[v]" -t 00:03:00 output.mp4
Обратите внимание, что скорость прокрутки составляет 0,02. Установите его ниже, например, 0,01, чтобы прокручивать медленнее, или выше, например, 0,03, чтобы прокручивать быстрее.
Обратите внимание, что я передал команде максимальное время 3 минуты. Это время, к сожалению, должно быть больше, чем любой вывод прокрутки изображения, который когда-либо мог занять в вашей конкретной настройке.
Для справки: изображение размером 1920x7043 пикселей занимает 49,88 секунды. Вы можете получить высоту изображения программно, используя;
file input.png | sed 's|.*1920 x \([0-9]\+\).*|\1|'
output: 7043
Если у кого-то есть лучший способ «обнаружить конец прокрутки изображения, т.е. последняя строка/нижняя часть изображения, прокручивающаяся за верхнюю часть экрана», и возможность масштабировать время/длительность на основе этого – тогда это будет очень удобно.
На данный момент это лучшее решение, которое у меня есть; просканируйте вывод последней команды ffmpeg выше на предмет чего-то вроде;
[blackdetect @ 0x559298835480] black_start:49.88
Например, с помощью этой команды;
ffmpeg -i output.mp4 -vf blackdetect=d=0.1:pix_th=.1 -f rawvideo -y /dev/null 2>&1 | grep -o "black_start:[\.0-9]\+ "
output: black_start:49.88
И обрезать соответственно;
ffmpeg -i output.mp4 -t 49.88 -c copy finaloutput.mp4
vlc finaloutput.mp4 # Assuming you have vlc installed
Другой способ исправить это — каким-то образом вычислить точное количество секунд/кадров или что-то подобное, необходимое внутри команды ffmpeg, и после этого завершить работу. Я не уверен, поддерживает ли ffmpeg такой (сложный) синтаксис. Приветствуются идеи.
Если вы прокручиваете со скоростью X% от высоты, то время прокрутки нижней части изображения за верхнюю часть составляет 1/X секунд, если вы начинаете с изображения, изначально расположенного на y = 0.
@Roel Еще один способ получить высоту: ffprobe -v error -show_entries stream=height -of csv=p=0 input.png
@Gyan есть способ сделать это программно в ffmpeg?
@Roel Добавлен ответ.
Для этого в одной команде используйте
ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -t 0.08 -i "input.png" -filter_complex "[1:v]scale=1920:-2,setpts=if (eq(N,0),0,1+1/0.02/TB),fps=25[fg]; [0:v][fg]overlay=y=-'t*h*0.02':eof_action=endall[v]" -map "[v]" output.mp4
Обратите внимание, что в некоторых оболочках (например, Баш) запятые необходимо экранировать:
ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -t 0.08 -i "input.png" -filter_complex "[1:v]scale=1920:-2,setpts=if (eq(N\,0)\,0\,1+1/0.02/TB),fps=25[fg]; [0:v][fg]overlay=y=-'t*h*0.02':eof_action=endall[v]" -map "[v]" output.mp4
-t
добавляется к изображению, так что у нас есть поток с 2 кадрами. (25 fps x 0.08 = 2
). setpts устанавливает временную метку для 2-го кадра, обратную скорости прокрутки, которая представляет часть высоты. Фильтр fps заполняет промежутки временных меток с клонированными кадрами.
Наложение останавливается после завершения ввода изображения.
Спасибо. я получаю сообщение об ошибке; [Parsed_setpts_1 @ 0x55b3c88ebd40] [Eval @ 0x7ffcb0ec3bc0] Отсутствует ')' или слишком много аргументов в 'eq(N' [Parsed_setpts_1 @ 0x55b3c88ebd40] Ошибка при синтаксическом анализе выражения 'if (eq(N') [AVFilterGraph @ 0x55b3c07eptfizing] ' with args 'if (eq(N' Ошибка инициализации сложных фильтров. Недопустимый аргумент
Похоже, вашей оболочке нужно, чтобы вы избежали запятых в выражениях, поэтому if (eq(N,0),0,1+1/0.02/TB)
--> if (eq(N\,0)\,0\,1+1/0.02/TB)
Да, это сработало. Спасибо большое. Это использование bash. Он работает отлично! Также добавлена команда в ответ для удобной справки. Бог благословил
дополнительный вопрос - как вставить небольшую 2-секундную паузу перед тем, как изображение начнет прокручиваться?
Вставьте эти настройки после оверлея, setpts=if (eq(N\,0)\,0\,PTS+2/TB)
ты жжешь. Спасибо!
Для справки с 2-секундной паузой при запуске; ffmpeg -f lavfi -i color=s=1920x1080 -loop 1 -t 0.08 -i "6-answer9.png" -filter_complex "[1:v]scale=1920:-2,setpts=if (eq(N\,0)\,0\,1+1/0.02/TB),fps=25[fg]; [0:v][fg]overlay=y=-'t*h*0.02':eof_action=endall,setpts=if (eq(N\,0)\,0\,PTS+2/TB)[v]" -map "[v]" output.mp4
Кстати, чтобы сделать фон белым, когда прокрутка находится на завершающей стадии, используйте; color=s=1920x1080:color=0xffffff
вместо этого.
Эй, ваше решение идеально, однако я совсем новичок в работе с ffmpeg и у меня есть несколько вопросов: 1) как вы увеличиваете частоту кадров? Я попробовал настройки fps = 50 и -t 0,04, чтобы сохранить то же соотношение кадров, которое вы использовали, но это не помогло. 2) как мне добавить 1-секундную паузу в начале и конце видео? Спасибо за всю вашу помощь.
В начале есть двухсекундная пауза, которую легко изменить на одну секунду. Я ожидаю, что пауза в конце будет похожей. Не уверен в FPS, посмотрите документацию ffmpeg.
Поскольку на этот вопрос был дан последний ответ, в ffmpeg был добавлен фильтр прокрутки, но я не могу понять, как, например, установить
v
в этой команде (найден здесь), чтобы изображение прокручивалось один раз в секунду (адаптируя команду для вертикальной прокрутки):ffmpeg -loop 1 -framerate 30 -i input.png -vf "scroll=v=0.001,crop=640:360:0:ih,format=yuv420p" -preset veryslow -crf 18 -t 10 output.mp4
-- Я выяснил, что это будет 0,03333 для изображения, обрезанного по собственной высоте, но если это изображение выше, чем область обрезки, это изменится. ?