以前、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フラグを指定してはいけないらしいので修正。
番組情報が取得できなくなっていた。。。