このブログを検索

2012-01-26

tsをmp4に変換する(pt2編)

以前、ts->mp4をwindowsで変換する方法を紹介しましたが、
今回はそれをUbuntuで、しかもpt2で録画したあとそのまま変換する方法です。

例によってpt2絡みはシミュレーションにつき、間違いがあったらすみません。
ffmpegの使い方は大丈夫だと思いますが。


変換の流れはこうです。

1. do-record.sh(epgrec)によってpt2が録画を行う
2. do-record.shがそのままffmpegで録画ファイルを変換する

1.で一旦tsファイルが作成されるので、リアルタイムにmp4に変換できるわけではありません。
今回は圧縮率をあまり考慮せず、とにかくそのままmp4へ変換することを主眼においたのですが、ウチの環境で30分番組が変換に2時間以上ってところでしょうか。

録画と変換が同時に走るとあまりよくないかなと思い、時間はあまりかけない方針です。
高性能なマシンであればもっと画質を上げ、圧縮率もあげられると思います。

参考:

ffmpegをインストール
mp4変換にはffmpegを使います。
これについてはmediatombで書いた記事を参照
http://xelalko.blogspot.com/2011/08/ubuntudlna3.html

ffmpegの設定ファイルを作成
ts->m4の変換に使う設定ファイルを作成します。
もともといくつか用意されてあり、それらが
/usr/share/ffmpeg/* に格納されています。
今回は「時間優先」「サイズは30分1G未満であればとりあえず」ということで
一番画質が悪くて速そうなlibx264-fastfirstpass.ffpresetを使います。
※ libx264-lossless_fast.ffpreset も速そうな感じだからまた試そう

高画質なものならhqや下記サイトを参考
http://d.hatena.ne.jp/munepi/20091227/1261941397


カスタマイズする場合は下記サイトなど、色々検索しないと情報見つからない・・・
http://mobilehackerz.jp/archive/wiki/index.php?%BA%C7%BF%B7ffmpeg%2F%A5%D3%A5%C7%A5%AA%A5%AA%A5%D7%A5%B7%A5%E7%A5%F3
http://mobilehackerz.jp/archive/wiki/index.php?%BA%C7%BF%B7ffmpeg%2F%B9%E2%C5%D9%A4%CA%A5%AA%A5%D7%A5%B7%A5%E7%A5%F3

ts->mp4スクリプトを作成
ffmpegを呼び出して変換を行うスクリプトを作成します。
変換には引数が多いのでほぼ必須。
$ sudo touch /usr/local/bin/ts2mp4.sh
$ sudo vim /usr/local/bin/ts2mp4.sh
$ sudo chmod 755 /usr/local/bin/ts2mp4.sh
中身は次のとおりにする
#!/bin/bash

TS=$1 
FFPRESET=/usr/share/ffmpeg/libx264-fastfirstpass.ffpreset
#FFPRESET=/usr/share/ffmpeg/libx264-hq.ffpreset
#FFPRESET=/usr/share/ffmpeg/libx264-hq-ts.ffpreset
#FFPRESET=/usr/share/ffmpeg/libx264-lossless_fast.ffpreset

#RESIZE=1440x1080
#RESIZE=960x540
#RESIZE=720x480
RESIZE=512x288
ASPECT=16:9
#ASPECT=3:2

FILEDIR=${TS%/*}
FILENAME=${TS##*/}
FILENAMEBODY=${FILENAME%.*}
FILENAMEEXTENTION=${FILENAME##*.}

#BASE=$(basename ${TS} .ts)
#[ "${FILENAMEBODY}.ts" = "${FILENAME}" ] || exit 1

#CPU_CORES=0
CPU_CORES=$(/usr/bin/getconf _NPROCESSORS_ONLN)

X264_HIGH_HDTV="-f mp4 -vcodec libx264 \
    -vpre ${FFPRESET} -flags +ilme+ildct -top -1 \
    -r 30000/1001 -aspect ${ASPECT} -s ${RESIZE} -bufsize 20000k -maxrate 25000k \
    -acodec libfaac -ac 2 -ar 48000 -ab 128k -threads ${CPU_CORES} \
    -cqp 25 -vsync 1"

ffmpeg -y -i $TS ${X264_HIGH_HDTV} ${FILEDIR}/${FILENAMEBODY}.mp4

exit
あんまりよくわかってないのですが、とりあえずこれで使えています。
bashスクリプトのチェック
$ /bin/bash -n ts2mp4.sh
場合によってはUTF8にしたらエラーがなくなったケースもあります

試しに変換してみる
$ ts4mp4.sh ~/test.ts
これで~/test.mp4ができているはず。ちゃんと再生できるかも要チェック。

ffmpeg引数の-sと-aspectについては
http://aquaspread.g.ribbon.to/index.phpの映像サイズ(アスペクト比)という欄の数値を入れればよさそう?
とりあえずKindle Fireでうまく表示できる設定で示します。
Kindle FIreとGOM Playerが同じみたい。
VLCは違うっぽい?VLCの時だけ手動でアスペクト比を調整して下さい。


do-record.shを複数録画モード対応にする
do-record.shをカスタマイズし、通常のTS録画以外に圧縮録画モードを追加します。
今回は更に圧縮&録画フォルダ変更モードも追加します。
※録画一覧からの録画ファイル削除には恐らく対応しません

$ sudo vim /var/www/epgrec/do-record.sh
中身を次のようにする

#!/bin/bash
# $ OUTPUT=test.ts CHANNEL=22 DURATION=30 TUNER=0 MODE=0 TYPE=GR /var/www/epgrec/do-record.sh
# define tools
RECORDER=/usr/local/bin/recpt1
B25=/usr/local/bin/b25
TS2MP4=/usr/local/bin/ts2mp4.sh
# echo arguments
echo "CHANNEL : $CHANNEL"
echo "DURATION: $DURATION"
echo "OUTPUT  : $OUTPUT"
echo "TUNER : $TUNER"
echo "TYPE : $TYPE"
echo "MODE : $MODE"
# check path
RECDIR=${OUTPUT%/*}
RECNAME=${OUTPUT##*/}
RECNAMEB=${RECNAME%.*}
RECNAMEE=${RECNAME##*.}
# fix directory
if [ "${RECDIR}" = "${RECNAME}" ]; then
    RECDIR=`pwd`
    OUTPUT=${RECDIR}/${RECNAME}
fi
# set recording directory of each mode
OUTPUTDIR0=${RECDIR}
OUTPUTDIR1=${RECDIR}
OUTPUTDIR2=/var/www/epgrec/video/mode2
#    case ${TYPE} in
#        BS)
#        ;;
#        GR)
#        ;;
#    esac
## do-record [output]
do-record ()
{
    local output=$1
    $RECORDER --b25 --strip $CHANNEL $DURATION --sid hd "${output}" >/dev/null 2>&1
    return 0
}
## move-file [beforepath] [afterpath]
move-file ()
{
    local beforepath=$1
    local afterpath=$2
    mv "${beforepath}" "${afterpath}"
    echo "${afterpath}"
    return 0
}
## conv-mp4 [ts2path]
conv-mp4(){
    local ts2=$1
    local ts2path=${ts2%/*}
    local ts2name=${ts2##*/}
    local ts2nameb=${ts2name%.*}
    local mp4="${ts2path}/${ts2nameb}.mp4"
    "${TS2MP4}" "${ts2}" >/dev/null 2>&1
#    if [ -s "${mp4}" ]; then
#        rm "${ts2}"
#    else
#        # failed to convert mp4
#    fi
    echo "${mp4}"
    return 0
}
## main
case ${MODE} in
    0)
        $RECORDER --b25 --strip $CHANNEL $DURATION "${OUTPUT}" >/dev/null 2>&1
    ;;
    1)
        do-record "${OUTPUT}"
    ;;
    2)
        do-record "${OUTPUT}"
#        OUTPUT=`move-file "${OUTPUT}" "${OUTPUTDIR1}/${RECNAME}"`
        OUTPUT="${OUTPUTDIR1}/${RECNAME}"
        OUTPUT=`conv-mp4 "${OUTPUT}"`
        ;;
    3)
        do-record "${OUTPUT}"
        OUTPUT=`move-file "${OUTPUT}" "${OUTPUTDIR2}/${RECNAME}"`
        OUTPUT=`conv-mp4 "${OUTPUT}"`
        ;;
esac

MODE=0は今まで通りTS録画(epgrecとして必須)、MODE=1はHDのみ録画、MODE=2はmp4録画、MODE=3はディレクトリ移動した上でmp4録画。
mp4録画モードは変換後にtsを消してもいいけど、今回は残してある。
※ffmpegは本当に毎回変換できるのか心配・・・

試しに動作させてみる

$ mkdir /var/www/epgrec/video/mode2
※パーミッションはvideoと同じにする
$ OUTPUT=test_0.ts CHANNEL=22 DURATION=5 TUNER=0 MODE=0 TYPE=GR /var/www/epgrec/do-record.sh
$ OUTPUT=test_1.ts CHANNEL=22 DURATION=5 TUNER=0 MODE=1 TYPE=GR /var/www/epgrec/do-record.sh
$ OUTPUT=test_2.ts CHANNEL=22 DURATION=5 TUNER=0 MODE=2 TYPE=GR /var/www/epgrec/do-record.sh
$ OUTPUT=test_2.ts CHANNEL=22 DURATION=5 TUNER=0 MODE=3 TYPE=GR /var/www/epgrec/do-record.sh

これで3つのtsと2つのmp4が作成されるはず。


epgrecのモードを増やす
$ sudo vim /var/www/epgrec/config.php
$RECORD_MODE = array(
というところを次のようにする

$RECORD_MODE = array(
        // ※ 0は必須で、変更不可です。
0 => array(
        'name' => 'Full TS',
        'suffix' => '.ts',
),
1 => array(
        'name' => 'hd only',
        'suffix' => '.ts',
),
2 => array(
        'name' => 'mode 2',
        'suffix' => '.ts',
),
3 => array(
        'name' => 'mode 3',
        'suffix' => '.ts',
),
);

念の為apache再起動
$ sudo /etc/init.d/apache2 restart

以上で設定完了。
epgrecで選択できるモードが増え、mp4変換ができるようになっているはず。
うまくいかない場合はパーミッションの問題が多いかも。
shの最初を
#!/bin/bash -x
にしてデバッグモードにしてみたり、 >>を使ってログを吐いたりしてみて確認しましょう。


ちなみにいくつかのffpresetをtsファイルを用意して試してみました。
hq-tsは先に紹介したサイトのffpresetです。

元データ 約30分のアニメ.ts 2.72G

解像度720x480
fastpass 変換時間2:30 変換後455M
hq 変換時間4:00 変換後364M
hq-ts 変換時間3:40 変換後282M


解像度512x288
fastpass 変換時間2:10 変換後261M
hq 変換時間2:40 変換後215M
hq-ts 変換時間2:30 変換後165M


画質についてははっきり言って誤差の範囲でした。
サイズでいうと時間15%増しで40%くらい下がるみたいだから場合によってはいいかも。
とりあえずはfastpassでhq-tsも視野にってかんじで。

問題は、mp4変換中に他番組の録画が来たら負荷がすごそうだということ。場合によっては3,4番組のmp4変換が重なるかも。他の人だと順に処理するような仕組み作ってる人もいるので、後日取り入れてみるかな・・・。

(2012/1/29追記)
do-record.shやconfig.phpについて、mode=0でsidフラグを指定してはいけないらしいので修正。
番組情報が取得できなくなっていた。。。

0 件のコメント:

コメントを投稿