////

/三度も放置したブログ今度こそ/忘却録/プログラミング/

Ubuntu ffmpegでTSファイルの複数音声(2ヶ国語)を処理する

TS抜きしたファイルの処理方法メモ。

 

基本的な方法は以下等を参考に

さくらのVPSで動画を楽しむ – Ffmpeg トランスコード ストリーミング Ts H.264 X264 変換 | お名前.com、さくらVPS等のサーバーでの開発・設定メモ

 

マシンパワーが十分ならh265もついでに入れておくといいでしょう。

[FFmpeg] ffmpeg に libx265 をリンクする - Qiita

 

さて、私は去年から「フィニアスとファーブ」というアニメにはまっています。

Dlifeで放送されているディズニーのアニメで、毎回吉本新喜劇的な「お決まりパターンとお決まりのセリフ」で繰り広げられる物語が癖になります。

 

www.youtube.com

www.disney.co.jp

日本語と英語の2か国語で放送されており、TSファイルの中にも当然2トラックの音声データがあります。

これらの複数音声データをh264やh265のmp4コンテナにぶち込むのが今回の目的です。

 

環境はUbuntu+ffmpeg

 

stream=`ffmpeg -i "${filepath}" 2>&1 | grep "Audio" | grep -o -e 0:[0-9] | sed -e "s/0:/-map 0:/"    ` 

X264=" -f mp4 -vcodec libx264
             -fpre /home/user/.ffmpeg/${ffpre}.ffpreset
             -r 30000/1001 -aspect 16:9 -s ${size}
             -acodec libfaac -ac 2 -ar 48000 -ab 128k -deblock 0:0

             -threads ${CPU_CORES} -vsync 1 -async 1 -map 0:0 $stream "
   

ffmpeg -y -i "${filepath}" ${X264} ${output_dir}"${filename%.ts}".mp4.mp4

 

ffmpeg -iでTSファイルを読み込んで、コーデック情報から音声ファイルがあるか判別、複数音声があった場合ffmpegにmapオプションで追加します。

ffmpeg -iで出力した一部を抜粋すると以下のような感じです。

 

Input #0, mpegts, from './rec/test/test.ts':
  Duration: 00:00:06.42, start: 92991.097367, bitrate: 14148 kb/s
  Program 258
    Metadata:
      service_name    : ?|ǣ???
      service_provider: ?BS?|ǣ???
    Stream #0:0[0x1001]: Video: mpeg2video (Main) ([2][0][0][0] / 0x0002), yuv420p(tv, bt709), 1440x1080 [SAR 4:3 DAR 16:9], max. 24000 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0:1[0x1041]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 203 kb/s
    Stream #0:2[0x1051]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 236 kb/s
    Stream #0:3[0x1201]: Data: bin_data ([6][0][0][0] / 0x0006)
    Stream #0:4[0x1c06]: Data: bin_data ([6][0][0][0] / 0x0006)

 

まずストリーム0:0がビデオ、0:1が日本語、0:2が英語です。

ちなみにa:bの意味は、a番目の入力ファイルの、b番目のstreamと言う意味です。

複数ファイルを入力すると、1:0(2個目の入力ファイルの最初のstream)みたいなのが出てきます。

 

さて、音声のmapが分かったら、ffmpegの-mapオプションで

ffmpeg -y -i input.ts -option色々 -map 0:1 -map 0:2

と指定すれば複数音声でエンコードできるのですが、複数音声が存在しないファイルもあるので、grepを使ってオプション指定します。

こんな感じなので、grepにパイプして

grep "Audio" で対象行を抜き出し、

grep -o -e 0:[0-9]で0:?の形式を抜き出し、

sed -e "s/0:/-map 0:/" とすると、最終的に

 

-map 0:1

-map 0:2

 

 と出力されます。

あとはこれをffmpegに渡してエンコードしてもらうだけ。