нужна помощь в решении моей командной строки ffmpeg - PullRequest
0 голосов
/ 03 апреля 2019

я создаю небольшой скрипт bash для кодирования видео 1080p, к видео будет добавлен водяной знак внизу слева, и мне нужно добавить черный отступ сверху и снизу

я пробовал несколько способов, но все равно не повезло, я пробовал -vf и да, это сработало, но я не могу использовать отступы и водяные знаки вместе, и предлагаю использовать filter_complex

если я использую этот код напрямую без bash-скрипта, он будет работать

time ffmpeg -hide_banner -i transformers.mp4 -i transformers.ass -loop 1 -i watermark.png -loop 1 -i logo.png -map 0:0 -map 0:1 -filter_complex "[0:0]scale=(iw*sar)*min(1920/(iw*sar)\,800/ih):ih*min(1920/(iw*sar)\,800/ih), pad=1920:800:(1920-iw*min(1920/iw\,800/ih))/2:(800-ih*min(1920/iw\,800/ih))/2;ass=transformers.ass[FID1];[FID1][2:v]overlay=10:${WATERMARKPOSITION}:repeatlast=0:enable='between(t,300,600)'[FID3];[3:v]fade=in:st=1200:d=1.6:alpha=1,fade=out:st=107998:d=1.6:alpha=1[FID6];[FID3][FID6]overlay=10:5:repeatlast=0:enable='between(t,1200,187922)'" -c:v libx264 -minrate 1800k -maxrate 1800k -bufsize 3600k -profile:v high -c:a aac -b:a 128k -profile:a aac_main -movflags faststart -strict -2 -f mp4 -y "transformers.mp4"

но когда я включаю его в свой bash-скрипт, я получаю эту ошибку,

[libx264 @ 0x2a063e0] height not divisible by 2 (300x39)
Output #0, mp4, to '/movie/Paddy/output/Transformers.Age.of.Extinction.2014.1080p.BluRay.H264.AAC-RARBG.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    comment         : Transformers.Age.of.Extinction.2014.1080p.BluRay.H264.AAC-RARBG
    encoder         : Lavf57.71.100
    title           : Transformers Age of Extinction 2014 1080p BluRay H264 AAC-RARBG - Visit us @ Juraganfilm.COM
    Stream #0:0: Video: h264 (libx264), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], q=-1--1, max. 2300 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc
    Metadata:
      encoder         : Lavc56.60.100 libx264
    Stream #0:1: Video: h264, none, q=2-31, 128 kb/s, SAR 1:1 DAR 0:0, 25 fps
    Metadata:
      encoder         : Lavc56.60.100 libx264
    Stream #0:2(eng): Audio: aac, 0 channels, 128 kb/s (default)
    Metadata:
      creation_time   : 2017-12-19 07:58:39
      handler_name    : SoundHandler
      encoder         : Lavc56.60.100 aac
Stream mapping:
  Stream #0:0 (h264) -> scale (graph 0)
  Stream #0:0 (h264) -> overlay:overlay (graph 0)
  Stream #2:0 (png) -> ass (graph 0)
  Stream #3:0 (png) -> fade (graph 0)
  pad (graph 0) -> Stream #0:0 (libx264)
  overlay (graph 0) -> Stream #0:1 (libx264)
  Stream #0:1 -> #0:2 (aac (native) -> aac (native))
Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height

и ниже скрипт, над которым я работал

output="/movie/output"

FILESDIR=`find $PWD -type f -regex ".*\.\(mp4\|mkv\|avi\)" | sed 's@.*/@@' | sort -n`
for video in $FILESDIR
do

MOVIETITLE=${video%.*}
INFOVID=${MOVIETITLE//./ }
BITRATE="${HEIGHT}"
WIDTH=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 ${video} 2>&1 | sed -e 's|\[.*||g' | sed ':a;N;$!ba;s/\n//g' | sed -e 's|x.*||g')
HEIGHT=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 ${video} | sed -e 's/.*x//')
WATERMARKPOSITION=$(expr $HEIGHT - 50)
VIDEOMAP=$(ffmpeg -i $video 2>&1 | grep "Stream #" | grep Video | sed -e "s|.*\#||g" | sed -e "s|: Video.*||g" | sed -e "s|(.*||g")
AUDIOMAP=$(ffmpeg -i $video 2>&1 | grep "Stream #" | grep Audio | sed -e "s|.*\#||g" | sed -e "s|: Audio.*||g" | sed -e "s|(.*||g")
MAXRATE=$(expr $BITRATE + 500)
BUFFSIZE=$(expr $MAXRATE \* 2)

time ffmpeg -hide_banner -i $video -i $MOVIETITLE.ass -loop 1 -i $WATERMARK -loop 1 -i $LOGO -map ${VIDEOMAP} -map ${AUDIOMAP} -filter_complex "[${VIDEOMAP}]scale=(iw*sar)*min(${WIDTH}/(iw*sar)\,${HEIGHT}/ih):ih*min(${WIDTH}/(iw*sar)\,${HEIGHT}/ih), pad=${WIDTH}:${HEIGHT}:(${WIDTH}-iw*min(${WIDTH}/iw\,${HEIGHT}/ih))/2:(${HEIGHT}-ih*min(${WIDTH}/iw\,${HEIGHT}/ih))/2;ass=$MOVIETITLE.ass[FID1];[FID1][2:v]overlay=10:${WATERMARKPOSITION}:repeatlast=0:enable='between(t,300,600)'[FID3];[3:v]fade=in:st=1200:d=1.6:alpha=1,fade=out:st=107998:d=1.6:alpha=1[FID6];[FID3][FID6]overlay=10:5:repeatlast=0:enable='between(t,1200,187922)'" -c:v libx264 -minrate ${BITRATE}k -maxrate ${MAXRATE}k -bufsize ${BUFFSIZE}k -profile:v high -c:a aac -b:a 128k -profile:a aac_main -movflags faststart -strict -2 -f mp4 -y "${output}/$MOVIETITLE.mp4"
done

работал весь день, но до сих пор не могу заставить его работать.

Может ли кто-нибудь наставить меня, какая часть неправильна?

Ответы [ 2 ]

0 голосов
/ 03 апреля 2019

Что касается вашего сценария:

Упростите ваши ffprobe команды

Это исключит четыре случая sed.

Изменение:

WIDTH=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 ${video} 2>&1 | sed -e 's|\[.*||g' | sed ':a;N;$!ba;s/\n//g' | sed -e 's|x.*||g')
HEIGHT=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 ${video} | sed -e 's/.*x//')

Кому:

WIDTH=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of csv=p=0 ${video})
HEIGHT=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=p=0 ${video})

Использовать ffprobe вместо ffmpeg для анализа информации

Вывод stderr из ffmpeg не предназначен для синтаксического анализа машины.Вместо этого используйте ffprobe.Вот для чего это.

Так что вместо:

VIDEOMAP=$(ffmpeg -i $video 2>&1 | grep "Stream #" | grep Video | sed -e "s|.*\#||g" | sed -e "s|: Video.*||g" | sed -e "s|(.*||g")

Это хрупко и даст несколько результатов, если вход имеет более одного видеопотока.

ВместоВы можете сделать:

VIDEOMAP=$(ffprobe -v error -select_streams v:0 -show_entries stream=index -of csv=p=0 $video)

Для аудио просто измените спецификатор потока в -select_streams (измените v на a).

Однако этот конкретный пример является спорным, потому что ...

Просто используйте спецификаторы потока

Нет необходимости в VIDEOMAP и AUDIOMAP.

Вместоиз:

VIDEOMAP=$(ffmpeg -i $video 2>&1 | grep "Stream #" | grep Video | sed -e "s|.*\#||g" | sed -e "s|: Video.*||g" | sed -e "s|(.*||g")
AUDIOMAP=$(ffmpeg -i $video 2>&1 | grep "Stream #" | grep Audio | sed -e "s|.*\#||g" | sed -e "s|: Audio.*||g" | sed -e "s|(.*||g")

В вашем -filter_complex используйте:

  • 0:v:0 для обозначения первого видеопотока
  • 0:a:0 для обозначенияпервый аудиопоток

ffmpeg

Нет необходимости использования культового груза -strict -2.Это требовалось, когда кодировщик AF FFmpeg считался экспериментальным.Это не было экспериментальным в течение многих лет, но пользователи продолжают добавлять его из старых, гнилых примеров и использовать копирование и вставку наизусть.

Не используйте -profile:v high.Если вам не нужно ограничивать меньший профиль (основной или базовый) для совместимости со старыми или ограниченными устройствами / плеерами, просто позвольте кодировщику выбрать профиль.

Вам не нужно -f mp4, если только вы не выводитеИмя файла неоднозначно (например, отсутствует расширение).

Используйте shellcheck.net для проверки вашего скрипта

shellcheck.net поможет вам очистить ваш скрипт и предотвратитьвопросы: в нем много предложений относительно вашего сценария.

0 голосов
/ 03 апреля 2019

1) Удалите отображение.Выход без метки filter_complex автоматически сопоставляется, поэтому -map 0:0 отобразит необработанный видеопоток.Без каких-либо карт.один аудиопоток будет выбран , и среди ваших входов будет только один.

2) После вашего пэда есть точка с запятой, что делает его выходом без метки filter_complex, которыйнапрямую отправляется на вывод

pad (graph 0) -> Stream #0:0 (libx264)

Итак, у фильтра задницы нет входных данных, и он заканчивается использованием watermark.png.Наложение и другие фильтры применяются к этому потоку.И его размер не делится на 2.

overlay (graph 0) -> Stream #0:1 (libx264)

Точка с запятой должна быть запятой.

3) Фильтр задницы напрямую читает файл субтитров.Его не нужно подавать как обычный вход.

time ffmpeg -hide_banner -i transformers.mp4 -loop 1 -i watermark.png -loop 1 -i logo.png -filter_complex "[0:0]scale=(iw*sar)*min(1920/(iw*sar)\,800/ih):ih*min(1920/(iw*sar)\,800/ih), pad=1920:800:(1920-iw*min(1920/iw\,800/ih))/2:(800-ih*min(1920/iw\,800/ih))/2, ass=transformers.ass[FID1];[FID1][2:v]overlay=10:${WATERMARKPOSITION}:repeatlast=0:enable='between(t,300,600)'[FID3];[3:v]fade=in:st=1200:d=1.6:alpha=1,fade=out:st=107998:d=1.6:alpha=1[FID6];[FID3][FID6]overlay=10:5:repeatlast=0:enable='between(t,1200,187922)'" -c:v libx264 -minrate 1800k -maxrate 1800k -bufsize 3600k -profile:v high -c:a aac -b:a 128k -profile:a aac_main -movflags faststart -strict -2 -f mp4 -y "transformers.mp4"

Кроме того, ваши цифры для затухания и последнего наложения выглядят неправильно.st=107998 повторений 107888 секунд т.е. 30 часов .То же самое касается between(t,1200,187922)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...