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

Автоматическое конвертирование видео с помощью BASH-скрипта
Метки:    

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *