Bash-скрипт + FFmpeg

Здравствуйте. Недавно возникла необходимость конвертирования видео/аудио файлов. Выбор пал на ffmpeg, потому что данная утилита имеет довольно широкие возможности + распространяется бесплатно. Стоит отметить, что ffmpeg следует собирать из исходников, поскольку версия в репозитории довольно стара и может не удовлетворить всех потребностей. Для тех кто еще не знает, что это такое ознакомьтесь с данной статьей, а также с синтаксисом утилиты здесь. Мануалы по компиляции смотрите здесь и здесь. Итак приступим.

Bash-скрипт

#!/bin/bash
#  О найденных ошибках и дополнениях пожалуйста сообщайте на мыло citizen228@gmail.com
#+ с пометкой "[Bash-скрипт. FFmpeg]" в теме письма
GREEN="\033[1;32m"
RED="\033[0;31m"
YELLOW="\033[1;33m"
ENDCOLOR="\033[0m"
LOG="/home/citizen/errors_convert.log"
 
# Переписываем лог датой
echo "------------------------------------------------------------------------------" > $LOG
date >> $LOG
echo "------------------------------------------------------------------------------" >> $LOG
 
# Проверяет наличие файла.
# В случае успеха вернет - 0
FileValidation ()
{
  if [ -f "$1" ]; then
    return 0
    else
      return 1
  fi
}
 
# Проверяет наличие пути.
# В случае успеха вернет - 0
PathValidation ()
{
  if cd "$1" &> /dev/null; then
    cd - &> /dev/null
    return 0
    else
      cd - &> /dev/null
      return 1
  fi
}
 
# Проверяет пуста ли переменная, если да вернет 1, иначе 0
Empty ()
{
  if [ -z $1 ]; then
    return 1
    else
      return 0
  fi
}
 
#  Выходит из скрипта с заданным кодом, если предыдущая команда завершилась с
#+ ошибкой
Exit ()
{
  if [ $? -ne 0 ]; then
    echo -e "$2"
    exit $1
  fi
}
 
# Переходит на следующий шаг цикла, если предыдущая команда завершилась с
#+ ошибкой
Continue ()
{
  if [ $? -ne 0 ]; then
    echo -e "$1"
    continue
  fi
}
 
# Проверяет, чем завершилась предыдущая команда и выводит сообщение.
# Первое - успех; второе - провал
Message ()
{
  if [ $? -eq 0 ]; then
    echo -e "$1"
    else
      echo -e "$2"
  fi
}
 
# Первый параметр - полный путь + имя файла на входе
# Второй параметр - полный путь к файлу на выходе (слеш на конце)
# Третий параметр - расширение файла на выходе
# Четвертый параметр - опции конвертирования
# Функция заодно проверяет наличие входного файла
Convert ()
{
  FileValidation "$1"
  Message "" "$REDФайла $INPUT не существует!$ENDCOLOR"
  # Выделяем имя файла без расширения
  INPUT="${INPUT##*/}"
  OUTPUT="${INPUT%.*}"
  # Путь у файлу на выходе
  # Если нет слеша в конце пути, то добавим его
  SLASH="$(expr match "$2" '.*\(.\)')"
  if [ $SLASH != / ]; then
    PATH_FILE="$2/"
    else
      PATH_FILE="$2"
  fi
  OUTPUT="$PATH_FILE$OUTPUT.$3"
  ffmpeg -i "$1" $4 "$OUTPUT"
  echo "ffmpeg -i" "$1" "$4" "$OUTPUT"
}
 
 
################# Данные функции представлены в качестве примеров, Вы можете создать свой набор предустановок #################
PSP ()
{
  Convert "$1" "$2" "mp4" "-strict experimental -threads 2 -y -s 368x208 -ab 64k -b 300k -ac 2 -acodec aac -vcodec libxvid"
}
 
NokiaC3 ()
{
  Convert "$1" "$2" "3gp" "-strict experimental -threads 2 -y -s 320x240 -ab 64k -b 300k -ac 2 -acodec aac -vcodec libxvid"
}
#################
 
Help ()
{
  echo -e $GREEN"------------------------------------------------------------------------------"$ENDCOLOR
  echo -e $RED"ВНИМАНИЕ:"$ENDCOLOR
  echo -e $RED"          *$ENDCOLOR Формат: $0 <опции>"
  echo -e "$RED          * -p $ENDCOLOR: Путь к каталогу для выходных файлов"
  echo -e "$RED               $ENDCOLOR  Обязательно слеш на конце!"
  echo -e "$RED          * -s $ENDCOLOR: Как конвертировать файлы (preset)"
  echo -e "$RED          * -i $ENDCOLOR: Входной файл для конвертирования"
  echo -e "$RED          * -f $ENDCOLOR: Указать файл из папки. Все файлы с аналогичным раcши"
  echo -e "$RED               $ENDCOLOR  рением также будут переконвертированы"
  echo -e $GREEN"------------------------------------------------------------------------------"$ENDCOLOR
  echo -e "$RED * $ENDCOLOR: Если не указан путь, то выходные файлы помещаются в папку с исходными файлами$ENDCOLOR"
  echo -e "$RED * $ENDCOLOR: Опции желательно указывать в порядке перечисленном выше$ENDCOLOR"
  echo -e "$RED * $ENDCOLOR: Опции можно указывать несколько раз$ENDCOLOR"
  echo -e $GREEN"------------------------------------------------------------------------------"$ENDCOLOR
  echo -e "$RED Presets: $ENDCOLOR"
  echo -e "$RED         * $ENDCOLOR PSP  : видео для консоли (368x208)"
  echo -e "$RED         * $ENDCOLOR Nokia: видео для телефона (320x240)"
  echo -e $GREEN"------------------------------------------------------------------------------"$ENDCOLOR
  exit 0
}
 
if [ $# -eq 0 ]
then
  echo -e $RED"Вызовите сценарий с одним или более параметром"$ENDCOLOR
  Help
fi
 
OPTIND=0
while getopts ":i:p:s:f:" option
do
  case $option in
    i ) # Проверка наличия переменной
        # Название preset должно совпадать с именем функции его вызывающей
        Empty "$PARAM" 2>> $LOG
        Continue "$REDВы не указали preset!$ENDCOLOR" 2>> $LOG
        INPUT="$OPTARG" >> $LOG
        # Делаем выборку из предварительных настроек
        "$PARAM" "$INPUT" "$PATH_TO_OUT" 2>>$LOG;;
    f ) Empty "$PARAM" 2>> $LOG
        Continue "$REDВы не указали preset!$ENDCOLOR" 2>> $LOG
        INPUT="$OPTARG" 2>> $LOG
        FileValidation "$INPUT" 2>> $LOG
        Continue "$RED Файла $INPUT не существует!$ENDCOLOR" 2>> $LOG
        # Выделяем расширение переданного файла
        EXTENSION="${INPUT##*.}" 2>> $LOG
        # Переходим в заданную дирректорию
        cd "${INPUT%/*}"
        for COUNT in *."$EXTENSION"
        do
          "$PARAM" "$COUNT" "$PATH_TO_OUT" 2>>$LOG
        done;;
    p ) PATH_TO_OUT="$OPTARG" 2>> $LOG
        PathValidation "$PATH_TO_OUT" 2>> $LOG
        Continue "$REDНеверный выходной каталог!$ENDCOLOR" 2>> $LOG;;
    s ) PARAM="$OPTARG" 2>> $LOG;;
    * ) Continue $RED"$PARAM: Такой опции не существует!$ENDCOLOR" 2>> $LOG;;
  esac
done
Empty "$INPUT" 2>> $LOG
Exit 1 "$REDВы не указали входной файл!$ENDCOLOR" 2>> $LOG
echo -e $GREEN"------------------------------------------------------------------------------"$ENDCOLOR
cat $LOG | more
echo -e $GREEN"------------------------------------------------------------------------------"$ENDCOLOR
exit 0

Для того, чтобы запустить у себя скрипт достаточно:

  • Скопировать текст приведенный выше в Ваш любимый текстовый редактор
  • Сохранить файл с любым именем
  • Сделать файл исполняемым
    chmod +x Путь_к_Вашему_файлу

  • Отредактировать файл .bashrc добавив строку

    alias Convert='Путь_к_Вашему_файлу'

  • Этой командой в консоли и будет вызываться скрипт

    Convert

Использование

Попробуйте ввести в консоли Convert и нажать Enter. Вы увидите справку по ключам скрипта:

Вызовите сценарий с одним или более параметром
------------------------------------------------------------------------------
ВНИМАНИЕ:
          * Формат: ./a.sh <опции>
          * -p : Путь к каталогу для выходных файлов
                 Обязательно слеш на конце!
          * -s : Как конвертировать файлы (preset)
          * -i : Входной файл для конвертирования
          * -f : Указать файл из папки. Все файлы с аналогичным раcши
                 рением также будут переконвертированы
------------------------------------------------------------------------------
 * : Если не указан путь, то выходные файлы помещаются в папку с исходными файлами
 * : Опции желательно указывать в порядке перечисленном выше
 * : Опции можно указывать несколько раз
------------------------------------------------------------------------------
 Presets: 
         *  PSP  : видео для консоли (368x208)
         *  Nokia: видео для телефона (320x240)
------------------------------------------------------------------------------

Остановимся поподробнее на каждой опции:

  • -p: Каталог для конвертированных файлов. Если данный ключ отсутствует, то будет использована папка, где находится исходный файл. Данную опцию следут указывать до указания входного файла
  • -s: Как конвертировать файлы. Опция является обязательной. Здесь указывается имя функции-настройки из скрипта. В данном случае PSP или NokiaC3. Данную опцию следут указывать до указания входного файла
  • -i: Один файл для конвертирования.
  • -f: Множество входных файлов для конвертирования. В данном случае указывается один файл из папки, и все файлы с аналогичным расширением будут переконвертированы

Предустановки

Чтобы расширить возможности скрипта добавьте свои функции с предустановками:

  • Найдите строку
################# Данные функции представлены
  • Создайте функцию по образу и подобию, стандартных.
  • Например:
ConvertToMP3 ()
{
  Convert "$1" "$2" "mp3" "-vn -acodec libmp3lame -ab 192 -f mp3"
}
  • Третий параметр расширение выходного файла, а четвертый Ваши опции конвертирования

Примеры использования

  • Будет переконвертирован один файл и помещен в /home/citizen
Convert -s PSP -p /home/citizen -i /home/rTorrent/example.avi
  • Будет переконвертированы файлы с одним расширением и помещены в /home/citizen/Scrubs
Convert -s PSP -p /home/citizen/Scrubs -f /home/rTorrent/Scrubs/example.avi
  • Аналогично двум командам выше
Convert -s PSP -p /home/citizen -i /home/rTorrent/example.avi -p /home/citizen/Scrubs/ -f /home/rTorrent/Scrubs/example.avi