Некоторое время назад возник вопрос о подготовке видеоконтента для IPTV VOD (видео-по-запросу) серверов. Так как в то время мы ориентировались преимущественно на DLink DIB-120, то вариантов по формату особо небыло – нужен был максимально стандартный mpeg2 transport stream (mpeg2ts). Я почитал всякие форумы и wiki по различным некрупным middleware и был, честно говоря, удивлен тем фактом, что все как один в букварях дают примеры с пережатием видео. Причем особый интерес вызывает то, что нет никакого анализа контента – просто рекомпрессия того-же DVD в mpeg2 с CBR в районе 4-5Мбит/с.
Первая мысль, которая у меня возникла – ограничения приставок по части VBR. Но житейская логика (декодер в приставках ровно такой-же, как и в DVD-плеерах/спутниковых тюнерах) и последующие тесты показали, что приставка совершенно нормально играет mpeg2, ремультиплексированный с обычного DVD. Таким образом, наиболее быстрый способ подготовки vod-контента в mpeg2 следующий:
- Берем DVD, точнее – VIDEO-TS и копируем его на диск для более быстрой последующей обработки.
- Анализируем DVD, выбирая chapter с фильмом, как правило, наиболее длительный.
- Анализируем chapter, выбираем русскоязычную дорожку в AC3 (к сожалению, приставки не поддерживают декодирование DTS)
- Ремультиплексируем 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% (мягко говоря – этот код писался “на коленке”), но в большинстве случаев мне его хватает. Есть несколько моментов, на которые следует обратить внимание:
- Не всегда ffmpeg и VLC мультиплексируют корректно – можно на выходе получить файл без аудио. Всегда нужно проверять результат
- Для подготовки mpeg2ts можно и нужно использовать не VLC, а более гибкий TSMuxeR, но я это (еще) не реализовал
- Обратите внимание, что скорость работы скрипта зависит от скорости работы файловой системы. Если есть возможность – временные файлы лучше хранить на отдельном диске, а если есть raid-контроллер со stripe и большим кэшом, то все будет просто летать
@aidmax
сентября 2, 2010 at 19:56
А зачем из DVD дисков контент делать ? Это ж все в серую будет или я ошибаюсь ?
Дмитрий
сентября 2, 2010 at 20:09
Что касается "серости" – я не уверен, что правообладатель выдаст mpeg2ts
Ну а с технической стороны – DIB-120 прогнозируемо работает с mpeg2, а вот с h.264 дикие чудеса и большое повышение температуры корпуса
Соответственно, быстрее и качественнее сделать mpeg2ts с DVD простым ремультиплексированием, нежели транскодить из AVI/H264/etc.
Владимир
ноября 21, 2010 at 16:25
А как быть с HD? Источник – BluRay диски
Дмитрий
ноября 21, 2010 at 18:18
только пережимать, если производительность серверов и сети не является бесконечной. Если на бесплатных решениях, то я бы посмотрел на handbrake, а потом в ts собрать можно чем угодно, включая tsmuxer.
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 …
Владимир
марта 24, 2011 at 17:28
Некоторые фильмы идут "плавно", некоторые "тормозят". Может есть какой-нибудь другой универсальный способ подготовки фильмов для live555?
Дмитрий
марта 25, 2011 at 16:28
есть еще вариант – использовать более другой rtsp-сервер.