Как прокрутить изображение по вертикали с помощью ffmpeg и одновременно определить конец изображения (EOI)?

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

Поскольку на этот вопрос был дан последний ответ, в 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 для изображения, обрезанного по собственной высоте, но если это изображение выше, чем область обрезки, это изменится. ?

Alex Hall 04.05.2020 04:28

@AlexHall интересно. Вы разобрались, и как эта опция прокрутки соотносится по функциональности с другими перечисленными здесь опциями, включая время выполнения?

Roel Van de Paar 22.08.2020 03:22

Я не понял этого.

Alex Hall 24.08.2020 23:07
Применение градиента к изображению с помощью CSS
Применение градиента к изображению с помощью CSS
Здравствуйте, братья и сестры, как дела? Недавно я застрял на применении градиента к изображению. Я применял это много раз, но иногда наши требования...
Получение URL-адреса изображения курса в Moodle с помощью PHP
Получение URL-адреса изображения курса в Moodle с помощью PHP
Moodle - это популярная система управления обучением с открытым исходным кодом, используемая многими учебными заведениями и организациями по всему...
4
3
2 497
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот решение, которое я нашел;

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 такой (сложный) синтаксис. Приветствуются идеи.

Roel Van de Paar 24.05.2019 10:13

Если вы прокручиваете со скоростью X% от высоты, то время прокрутки нижней части изображения за верхнюю часть составляет 1/X секунд, если вы начинаете с изображения, изначально расположенного на y = 0.

Gyan 24.05.2019 11:27

@Roel Еще один способ получить высоту: ffprobe -v error -show_entries stream=height -of csv=p=0 input.png

llogan 24.05.2019 19:19

@Gyan есть способ сделать это программно в ffmpeg?

Roel Van de Paar 25.05.2019 02:52

@Roel Добавлен ответ.

Gyan 25.05.2019 07:52
Ответ принят как подходящий

Для этого в одной команде используйте

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' Ошибка инициализации сложных фильтров. Недопустимый аргумент

Roel Van de Paar 28.05.2019 06:54

Похоже, вашей оболочке нужно, чтобы вы избежали запятых в выражениях, поэтому if (eq(N,0),0,1+1/0.02/TB) --> if (eq(N\,0)\,0\,1+1/0.02/TB)

Gyan 28.05.2019 07:25

Да, это сработало. Спасибо большое. Это использование bash. Он работает отлично! Также добавлена ​​​​команда в ответ для удобной справки. Бог благословил

Roel Van de Paar 28.05.2019 07:29

дополнительный вопрос - как вставить небольшую 2-секундную паузу перед тем, как изображение начнет прокручиваться?

Roel Van de Paar 28.05.2019 07:38

Вставьте эти настройки после оверлея, setpts=if (eq(N\,0)\,0\,PTS+2/TB)

Gyan 28.05.2019 08:00

ты жжешь. Спасибо!

Roel Van de Paar 28.05.2019 08:17

Для справки с 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 (e‌​q(N\,0)\,0\,PTS+2/TB‌​)[v]" -map "[v]" output.mp4

Roel Van de Paar 28.05.2019 09:43

Кстати, чтобы сделать фон белым, когда прокрутка находится на завершающей стадии, используйте; color=s=1920x1080:color=0xffffff вместо этого.

Roel Van de Paar 28.05.2019 09:55

Эй, ваше решение идеально, однако я совсем новичок в работе с ffmpeg и у меня есть несколько вопросов: 1) как вы увеличиваете частоту кадров? Я попробовал настройки fps = 50 и -t 0,04, чтобы сохранить то же соотношение кадров, которое вы использовали, но это не помогло. 2) как мне добавить 1-секундную паузу в начале и конце видео? Спасибо за всю вашу помощь.

Julien FEGER 20.04.2020 21:53

В начале есть двухсекундная пауза, которую легко изменить на одну секунду. Я ожидаю, что пауза в конце будет похожей. Не уверен в FPS, посмотрите документацию ffmpeg.

Roel Van de Paar 30.04.2020 09:35

Другие вопросы по теме