Скрипт конвертирования видеофайлов для просмотра на КПК

Материал из WikiAdmin
Перейти к: навигация, поиск

С каждым днем мы становимся все мобильнее. Плеер для прослушивания музыки, аудиокниг и подкастов есть практически у каждого. В последнее же время стали распространятся и карманные видеоплееры. В качестве карманного видеоплеера я использую свой КПК. Но для того, чтобы посмотреть на нем какой-либо фильм, требуется сперва перекодировать видеофайл (уменьшить разрешение и битрейт), чтобы файл занимал как можно меньше места и не сильно загружал процессор при декодировании.

Поэтому я написал скрипт для Linux, выполняющий все необходимые для этого действия.

Краткая справка по возможностям скрипта:

$ video2pda -h
Использование: video2pda [-q] [-c] [-W pixels] [-H pixels] [-v bitrate] [-a bitrate] files...

video2pda предназначен для перекодирования видеофайлов для просмотра их на КПК и других карманных устройствах. Видео кодируется кодеком Xvid, аудио - Vorbis. В качестве контейнера используется OGM. Если в одной папке с фильмом будут лежать субтитры, скрипт подхватит их и "вклеит" в видео (предполагается, что субтитры в кодировке cp1251).

Ключи: -h : выводит это сообщение -q : кодировать видео с высоким качеством - при кодировании используется двухпроходное сжатие и другие опции, улучшающие качество изображения (уменьшает скорость кодирования видео, но увеличивает качество) -c : включить автоматическое кадрирование изображения (обрезает лишние пиксели по краям изображения, если таковые существуют) -W : ширина экрана на устройстве (по умолчанию 320) -H : высота экрана на устройстве (по умолчанию 240) -v : битрейт видео (по умолчанию 300) -a : битрейт аудио (по умолчанию 64)

Сам скрипт:

#!/bin/bash
#***************************************************************************
#*   Copyright (C) 2007, Konishchev Dmitry                                 *
#*   http://konishchevdmitry.blogspot.com/                                 *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU General Public License as published by  *
#*   the Free Software Foundation; either version 3 of the License, or     *
#*   (at your option) any later version.                                   *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU General Public License for more details.                          *
#**************************************************************************/

# Значения по умолчанию -->
 screen_width=320
 screen_height=240
 video_bitrate=300
 audio_bitrate=64
 video_quality_settings=
 is_crop=0
# Значения по умолчанию <--

tmp_mplayer_output_file=/tmp/video2pda_mplayer_output_$$
tmp_audio_file=/tmp/video2pda_audio_$$
tmp_vorbis_audio_file=/tmp/video2pda_vorbis_audio_$$
tmp_video_file=/tmp/video2pda_video_$$
tmp_subtitles_file=/tmp/video2pda_subtitles_$$

usage="video2pda -h for help"
usage_describe="Использование: video2pda [-q] [-c] [-W pixels] [-H pixels] [-v bitrate] [-a bitrate] files...

video2pda предназначен для перекодирования видеофайлов для просмотра их на КПК и других карманных устройствах.
Видео кодируется кодеком Xvid, аудио - Vorbis. В качестве контейнера используется OGM. Если в одной папке с фильмом будут лежать субтитры, скрипт подхватит их и \"вклеит\" в видео    (предполагается, что субтитры в кодировке cp1251).

Ключи:
-h : выводит это сообщение
-q : кодировать видео с высоким качеством - при кодировании используется двухпроходное сжатие и другие опции, улучшающие качество изображения (уменьшает скорость кодирования видео,   но увеличивает качество)
-c : включить автоматическое кадрирование изображения (обрезает лишние пиксели по краям изображения, если таковые существуют)
-W : ширина экрана на устройстве (по умолчанию 320)
-H : высота экрана на устройстве (по умолчанию 240)
-v : битрейт видео (по умолчанию 300)
-a : битрейт аудио (по умолчанию 64)"

# Выводит страницу помощи
print_help()
{
 echo -e "$usage_describe"
}

# Удаляет временные файлы
cleanup()
{
 rm $tmp_mplayer_output_file $tmp_audio_file $tmp_vorbis_audio_file $tmp_video_file $tmp_subtitles_file divx2pass.log > /dev/null 2>&1
}

# Выводит ошибку
error()
{
 echo "Ошибка! $1" | grep --color '.' >&2
 if [ "$2" != "" ]
 then
  echo "Вывод $2:" >&2
  echo "$3" | grep --color '.' >&2
 fi
 echo -e "Кодирование файла '$file' завершилось неудачей.\n" >&2 

 cleanup
}

# Получаем параметры, заданные пользователем -->
 while getopts "hqcW:H:v:a:" option
 do
  case $option in
   h ) print_help; exit 0;;
   q ) video_quality_settings=':me_quality=6:vhq=4';;
   c ) is_crop=1;;
   W ) screen_width=$OPTARG;;
   H ) screen_height=$OPTARG;;
   v ) video_bitrate=$OPTARG;;
   a ) audio_bitrate=$OPTARG;;
   \? ) echo $usage; exit 1;;
   * ) echo $usage; exit 1;;
  esac
 done

 shift $(($OPTIND - 1))
# Получаем параметры, заданные пользователем <--

# Проверяем, передан ли хотя бы один файл -->
 if [ "$1" == "" ]
 then
  echo $usage
  exit 1
 fi
# Проверяем, передан ли хотя бы один файл <--

# Проверяем, установлены ли у пользователя все необходимые программы -->
 needed_soft=

 which 'mplayer' > /dev/null 2>&1
 if [ $? -ne 0 ]
 then
  needed_soft="$needed_soft mplayer"
 fi
 which 'mencoder' > /dev/null 2>&1
 if [ $? -ne 0 ]
 then
  needed_soft="$needed_soft mencoder"
 fi
 which 'oggenc' > /dev/null 2>&1
 if [ $? -ne 0 ]
 then
  needed_soft="$needed_soft oggenc"
 fi
 which 'ogmmerge' > /dev/null 2>&1
 if [ $? -ne 0 ]
 then
  needed_soft="$needed_soft ogmmerge"
 fi

 if [ "$needed_soft" != "" ]
 then
  echo "Для работы скрипта требуются следующие программы:$needed_soft." >&2
  exit 1
 fi
# Проверяем, установлены ли у пользователя все необходимые программы <--

# Кодируем каждый файл -->
 while [ "$1" != "" ]
 do
  file="$1"

  echo "Кодируется файл '$file'..."

  # Проверяем, существует ли такой файл -->
   if [ ! -e "$file" ]
   then
    error "Файла '$file' не существует."
    shift
    continue
   fi
  # Проверяем, существует ли такой файл <--

  output_file=`basename "$file".ogm`
  subtitles_file=`echo "$file" | sed 's/\\.avi$/\\.srt/'`

  # Получаем размер исходного изображения -->
   output=`mplayer "$file" -frames 1 -vo null -ao null 2>&1 > $tmp_mplayer_output_file`
   mplayer_source_video_size=`egrep -o 'VO: \[null\] [[:digit:]]+x[[:digit:]]+ =>' $tmp_mplayer_output_file 2>/dev/null | egrep -o '[[:digit:]]+x[[:digit:]]+' 2>/dev/null`
   if [ "$mplayer_source_video_size" == "" ]
   then
    error "Определение размеров исходного изображения завершилось неудачей." "mplayer" "$output"
    shift
    continue
   fi
   video_width=`echo "$mplayer_source_video_size" | sed 's/x/\n/g' | head --lines 1`
   video_height=`echo "$mplayer_source_video_size" | sed 's/x/\n/g' | head --lines 2 | tail --lines 1`
   echo "Размер исходного изображения: ${video_width}x${video_height}"
  # Получаем размер исходного изображения <--


  # Получаем звуковую дорожку и, если нужно, кадрируем изображение -->
   echo "Получаем звуковую дорожку..."

   # Если требуется кадрировать изображение
   if [ $is_crop -ne 0 ]
   then
    output=`mplayer "$file" -vf cropdetect -ao pcm:fast:file=$tmp_audio_file -vo null 2>&1 > $tmp_mplayer_output_file`
   # Если не требуется кадрировать изображение
   else
    output=`mplayer "$file" -ao pcm:fast:file=$tmp_audio_file -vo null 2>&1 > /dev/null`
   fi

   if [ $? -ne 0 ]
   then
    error "При получении звуковой дорожки произошла ошибка." "mplayer" "$output"
    shift
    continue
   fi

   # Дополнительная проверка, т. к. mplayer почему-то не возвращает ошибки даже если
   # запрашиваемого файла не существует
   if [ ! -e $tmp_audio_file ]
   then
    error "При получении звуковой дорожки произошла ошибка." "mplayer" "$output"
    shift
    continue
   fi

   # Если требуется кадрировать изображение
   if [ $is_crop -ne 0 ]
   then
    mplayer_vf_value=`egrep -o 'crop=[[:digit:]]+:[[:digit:]]+:[[:digit:]]+:[[:digit:]]+' $tmp_mplayer_output_file 2>/dev/null | tail --lines=1 2>/dev/null`
    if [ "$mplayer_vf_value" == "" ]
    then
     error "При получении информации об автоматическом кадрировании произошла ошибка." "mplayer" "$output"
     shift
     continue
    fi

    mplayer_vf_value="$mplayer_vf_value,"
    video_width=`echo $mplayer_vf_value | sed 's/=/\\n/g' | sed 's/:/\\n/g' | egrep '[[:digit:]]+' | head --lines 1`
    video_height=`echo $mplayer_vf_value | sed 's/=/\\n/g' | sed 's/:/\\n/g' | egrep '[[:digit:]]+' | head --lines 2 | tail --lines 1`
    echo "Размер кадрированного исходного изображения: ${video_width}x${video_height}"
   fi
  # Получаем звуковую дорожку и, если нужно, кадрируем изображение <--

  # Получаем размер конечного изображения -->
   # Если размер изображения превышает размеры экрана
   if [ $screen_width -lt $video_width -o $screen_height -lt $video_height ]
   then
    (( test_height = video_height * screen_width / video_width ))
    if [ $test_height -le $screen_height ]
    then
     video_width=$screen_width
     video_height=$test_height 
    else
     (( video_width = video_width * screen_height / video_height ))
     video_height=$screen_height 
    fi
   fi

   echo "Размер конечного изображения: ${video_width}x${video_height}"
  # Получаем размер конечного изображения <--

  # Кодируем звуковую дорожку -->
   echo "Кодируем звуковую дорожку..."

   if [ $audio_bitrate -lt 45 ]
   then
    is_mono='--downmix'
   else
    is_mono=
   fi

   output=`oggenc --quiet $is_mono --bitrate=$audio_bitrate -o $tmp_vorbis_audio_file $tmp_audio_file 2>&1`
   if [ $? -ne 0 ]
   then
    error "При кодировании звуковой дорожки произошла ошибка." "oggenc" "$output"
    shift
    continue
   fi
  # Кодируем звуковую дорожку <--

  # Кодируем видео -->
   echo "Кодируем видео..."

   # Определяем, нужно ли вклеивать субтитры в видеофайл -->
   if [ -e "$subtitles_file" ]
   then
    iconv -f cp1251 -t utf8 --silent -c "$subtitles_file" > $tmp_subtitles_file
    subtitles="-sub $tmp_subtitles_file -subfont-text-scale 3 -utf8"
   else
    subtitles=
   fi
   # Определяем, нужно ли вклеивать субтитры в видеофайл <--

   # Если кодируем с обычным качеством
   if [ "$video_quality_settings" == "" ]
   then
    output=`mencoder "$file" $subtitles -vf ${mplayer_vf_value}scale=$video_width:$video_height -oac copy -ovc xvid -xvidencopts bitrate=$video_bitrate -o $tmp_video_file -ffourcc xvid -forceidx 2>&1 >/dev/null`
    if [ $? -ne 0 ]
    then
     error "При кодировании видео произошла ошибка." "mencoder" "$output"
     shift
     continue
    fi
   # Кодирование с повышенным качеством
   else
    for pass in 1 2
    do
     output=`mencoder "$file" $subtitles -vf ${mplayer_vf_value}scale=$video_width:$video_height -oac copy -ovc xvid -xvidencopts pass=$pass:bitrate=$video_bitrate$video_quality_settings -o $tmp_video_file -ffourcc xvid -forceidx 2>&1 >/dev/null`
     if [ $? -ne 0 ]
     then
      error "При кодировании видео произошла ошибка." "mencoder" "$output"
      shift
      continue 2
     fi
    done
   fi
  # Кодируем видео <--

  # Сливаем видео с аудио -->
   echo "Формируем конечный файл..."
   
   output=`ogmmerge -o "$output_file" -A $tmp_video_file $tmp_vorbis_audio_file 2>&1 > /dev/null`
   if [ $? -ne 0 ]
   then
    error "При формировании конечного файла произошла ошибка." "ogmmerge" "$output"
    shift
    continue
   fi
  # Сливаем видео с аудио <--

  cleanup

  echo -e "OK\n"

  shift
 done
# Кодируем каждый файл <--


Beer.jpg

Большая благодарность автору за предоставленную статью!

Источник konishchevdmitry.blogspot.com
Автор Конищев Дмитрий
Если эта страница оказалась для вас полезной, нажмите на кнопку. :)
Личные инструменты
Пространства имён
Варианты
Действия
Навигация
Инструменты