В процессе работы над одним проектом, связанным с обработкой и перекодированием множественных разнородных видео-файлов, возникло желание оптимизировать рабочий процесс. Для чего и был написан небольшой скрипт. После запуска скрипт выбирает все видео-файлы по маске в своей директории, конвертирует их в H.264 и не забывает при этом создавать уменьшенную копию для файлов с большим разрешением.
Что бы уменьшенная копия создалась нормально — задаваемое разрешение должно быть обязательно чётным. Однако ffmpeg этот момент не учитывает и если доверить масштабирование ему (опустив значение ширины), запросто может выйти нечётное число. Как следствие мы получим ошибку, вместо файла. В скрипте данная проверка реализована с помощью нехитрого if. Если что не так — добавляется единица, превращая число в чётное и решая таким образом проблему.
Для получения разрешения видео используется утилита mediainfo, как правило есть в репозиториях, но если вдруг случилось страшное и нету, то можно взять тут — http://mediainfo.sourceforge.net/ru.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/bin/bash #Перебираем файлы в директории по маске for i in *.mkv; do #Получаем разрешение видео с помощью mediainfo WIDTH=`mediainfo -f "$i" | grep -m 1 Width | awk '{print $3}'` HEIGHT=`mediainfo -f "$i" | grep -m 1 Height | awk '{print $3}'` echo $WIDTH x $HEIGHT #Если ширина видео больше 800 пикселей - делаем уменьшенную копию if [ $WIDTH -gt 800 ] then #Считаем ширину для высоты в 360 пикселей let "TOTAL = $WIDTH * 360 / $HEIGHT" #Если при расчетах получается нечетное число - добавляем единицу if [ $TOTAL -eq $((TOTAL/2*2)) ]; then echo "$TOTAL - чётное число"; else let "TOTAL = $TOTAL + 1"; fi #Конвертируем... ffmpeg -i "$i" -threads 0 -acodec aac -strict experimental -ac 2 -ab 128k -vcodec libx264 -preset slow -f mp4 -crf 20 "hd-$i.mp4" ffmpeg -i "$i" -threads 0 -acodec aac -strict experimental -ac 2 -ab 96k -vcodec libx264 -preset slow -f mp4 -crf 20 -vf "scale=$TOTAL:360" "sd-$i.mp4" else #Если видео уже 800 пикселей - конвертируем без лишних телодвижений ffmpeg -i "$i" -threads 0 -acodec aac -strict experimental -ac 2 -ab 96k -vcodec libx264 -preset slow -f mp4 -crf 20 "sd-$i.mp4" fi done |
Если конечное видео планируется раздавать с помощью псевдостриминга, стоит добавить вызов qt-faststart или чего-то аналогичного сразу после конвертации.