RSS
 

Конвертируем DVD в mpeg2-ts без пересжатия для IPTV VOD

02 Sep

Некоторое время назад возник вопрос о подготовке видеоконтента для IPTV VOD (видео-по-запросу) серверов. Так как в то время мы ориентировались преимущественно на DLink DIB-120, то вариантов по формату особо небыло – нужен был максимально стандартный mpeg2 transport stream (mpeg2ts). Я почитал всякие форумы и wiki по различным некрупным middleware и был, честно говоря, удивлен тем фактом, что все как один в букварях дают примеры с пережатием видео. Причем особый интерес вызывает то, что нет никакого анализа контента – просто рекомпрессия того-же DVD в mpeg2 с CBR в районе 4-5Мбит/с.

Первая мысль, которая у меня возникла – ограничения приставок по части VBR. Но житейская логика (декодер в приставках ровно такой-же, как и в DVD-плеерах/спутниковых тюнерах) и последующие тесты показали, что приставка совершенно нормально играет mpeg2, ремультиплексированный с обычного DVD. Таким образом, наиболее быстрый способ подготовки vod-контента в mpeg2 следующий:

  1. Берем  DVD, точнее – VIDEO-TS и копируем его на диск для более быстрой последующей обработки.
  2. Анализируем DVD, выбирая chapter с фильмом, как правило, наиболее длительный.
  3. Анализируем chapter, выбираем русскоязычную дорожку в AC3 (к сожалению, приставки не поддерживают декодирование DTS)
  4. Ремультиплексируем DVD (т.е. mpeg2 program stream) в mpe2ts, оставляя только видео и выбранную аудиодорожку.

Оставим пока в сторону другие последующие действия: построение индекса для trick play с использованием RTSP, добавление в vod-каталог и т.п. – эти моменты индивидуальны и более-менее легко автоматизируемые. Поделюсь своим мегаскриптом на bash, которому достаточно на вход дать путь к VIDEO_TS и название результирующего файла – остальное в большинстве случаев делается автоматически.

Из инструментария нам нужны: ffmpeg, vlc, mplayer. Для удобства и красоты я использовал shflags (если использовать freebsd, то обратите внимание на ошибку с expr).  Собственно код:

#!/usr/bin/env bash
# 
. /usr/local/lib/shflags

DEFINE_string 'source' '.' 'Source directory with VOBs' 's'
DEFINE_integer 'title' '0' 'DVD title number. 0 means autodetect' 't'
DEFINE_integer 'audio' '0' 'Audio stream id. 0 means autodetect with lang=RU and type=AC3' 'a'
DEFINE_string 'destination' 'none' 'Destination file. Specify .ts extention' 'd'
DEFINE_string 'tempdir' '/tmp' 'Temp directory' 'T'

FLAGS_HELP="USAGE: $0 [flags]"

FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
echo source = $FLAGS_source
echo  ${FLAGS_tempdir}

TMP=`mktemp ${FLAGS_tempdir}/autots1.XXXXXX` || exit 1
TMP2=`mktemp ${FLAGS_tempdir}/autots2.XXXXXX` || exit 1
TMP3=`mktemp ${FLAGS_tempdir}/autots2-info.XXXXXX` || exit 1

function error_exit()  {
        echo "ERROR: $1"
        rm -f $TMP $TMP2 $TMP3
        exit 1
}

function transcode_to_ts () {
        tempfoo=`basename $0`
        TMPFILE=`mktemp -q /storage1/tmp/${tempfoo}.XXXXXX`
        TMPFILE2=`mktemp -q /storage1/tmp/${tempfoo}.XXXXXXX`

        ffmpeg -i $1 2>&1| grep Audio | grep `printf 0x%x $2` | awk '{print $2}' |sed 's/\[.*$//g' | sed 's/^.//g' > $TMPFILE
        ffmpeg -i $1 -map 0.0 -map `cat $TMPFILE` -vcodec copy -acodec copy -f vob -y $TMPFILE2 || error_exit "Cannot produce VOB with single audio"

        rm -f $TMPFILE

        vlc -I dummy $TMPFILE2 vlc://quit --sout "#std{access=file,mux=ts,dst=$3}" || error_exit "Cannot transcode VOB to TS"
        rm -f $TMPFILE2
}

# check flags
if [ $FLAGS_destination"x" == "nonex" ]; then
        error_exit "Please specify destination"
else
        echo DESTINATION set to $FLAGS_destination
fi


cd "${FLAGS_source}" || error_exit "Cannot change dir"
if [ $FLAGS_title == 0 ]; then
                echo "Detecting chapter..."
                mplayer -frames 0 -msglevel identify=6:all=-1 -really-quiet -vo null -ao null dvd://1 \
                         -dvd-device . > $TMP3  2>/dev/null
                CHAPTER=`cat $TMP3 |  grep ID_DVD_TITLE_ | sort -n -t "=" -k 2n|tail -n 1 | awk -F'_' '{print $4}'`
                rm -f $TMP3
        else
                CHAPTER=$FLAGS_title
        fi;
        echo Chapter set to $CHAPTER

mplayer -identify -dvd-device . -frames 0   -vo null -ao null \
        dvd://$CHAPTER | grep '^audio stream:' > $TMP2 2>/dev/null || error_exit "Cannot check audio streams. Probably DVD title incorrect"

if [ $FLAGS_audio == 0 ]; then
        AUDIO_ID=`cat $TMP2  | grep ac3 | grep 'language: ru' | awk 'BEGIN {FS=": "}{print $5}' | sed 's/\.$//g'| head -1`
        if [ $AUDIO_ID"x" == "x" ]; then
                echo Problem with sound, please specify audio id in command line
                echo Audio streams:
                cat $TMP2 | grep ac3
                rm $TMP2
                error_exit "Cannot continue."
        fi
        else
                AUDIO_ID=$FLAGS_audio
fi

echo 'Using parameters'
echo            CHAPER  $CHAPTER
echo            AUDIO   $AUDIO_ID
echo 'Check audio info:'
cat $TMP2

mplayer -identify -dvd-device .  -dumpstream -dumpfile $TMP dvd://$CHAPTER > /dev/null 2> /dev/null || error_exit "Dumpstream failed"
ls -l $TMP

transcode_to_ts $TMP $AUDIO_ID $FLAGS_destination

ffmpeg -i $FLAGS_destination
ls -l $FLAGS_destination
rm -f $TMP $TMP2

Обратите внимание, что код не “чист” на 100% (мягко говоря – этот код писался “на коленке”), но в большинстве случаев мне его хватает. Есть несколько моментов, на которые следует обратить внимание:

  1. Не всегда ffmpeg и VLC мультиплексируют корректно – можно на выходе получить файл без аудио. Всегда нужно проверять результат
  2. Для подготовки mpeg2ts можно и нужно использовать не VLC, а более гибкий TSMuxeR, но я это (еще) не реализовал
  3. Обратите внимание, что скорость работы скрипта зависит от скорости работы файловой системы. Если есть возможность – временные файлы лучше хранить на отдельном диске, а если есть raid-контроллер со stripe и большим кэшом, то все будет просто летать :)
 

Leave a Reply

You must be logged in to post a comment.

  1. @aidmax

    сентября 2, 2010 at 19:56

    А зачем из DVD дисков контент делать ? Это ж все в серую будет или я ошибаюсь ?

     
  2. Дмитрий

    сентября 2, 2010 at 20:09

    Что касается "серости" – я не уверен, что правообладатель выдаст mpeg2ts :)

    Ну а с технической стороны – DIB-120 прогнозируемо работает с mpeg2, а вот с h.264 дикие чудеса и большое повышение температуры корпуса :) Соответственно, быстрее и качественнее сделать mpeg2ts с DVD простым ремультиплексированием, нежели транскодить из AVI/H264/etc.

     
  3. Владимир

    ноября 21, 2010 at 16:25

    А как быть с HD? Источник – BluRay диски :)

     
    • Дмитрий

      ноября 21, 2010 at 18:18

      только пережимать, если производительность серверов и сети не является бесконечной. Если на бесплатных решениях, то я бы посмотрел на handbrake, а потом в ts собрать можно чем угодно, включая tsmuxer.

       
  4. Travel Deals

    января 15, 2011 at 01:49

    Man I love your post and it is so good and I am definetly going to save it. One thing to say the Indepth analysis you have done is trully remarkable.No one goes that extra mile these days? Well Done.. Just another suggestion you shouldinstall a Translator Application for your Worldwide Audience …

     
  5. Владимир

    марта 24, 2011 at 17:28

    Некоторые фильмы идут "плавно", некоторые "тормозят". Может есть какой-нибудь другой универсальный способ подготовки фильмов для live555?

     
    • Дмитрий

      марта 25, 2011 at 16:28

      есть еще вариант – использовать более другой rtsp-сервер.