BMS2の字幕焼き付けトランスコードをffmpegでやってみた
BEER Media Server 2用Luaスクリプトを相変わらずいじっています。
今回は試行状況を書いてみます。
字幕のソフトサブはまったく目途が無いためハードサブを試します。mencoderを使うと巷に情報がいくらでもありますのでここはあえてffmpegだけを使ってやってみます。
VIERAではDLNA経由で音声ファイルを再生する事ができません。そんな場合は音声ファイルに何かの映像を付けて映像として送ってやれば良いのです。需要もなさそうなので放置してましたが、ffmpegの字幕焼き付けのついでに試してみました。音声ファイル再生中にライフゲームを表示させました。
チャプター時間は読めそうな事が判りましたが時間を指定する良いアイデアが浮かばないので保留中です。
BMS2のトランスコード機能に字幕とチャプターが付けば完璧になるのになぁ、と試行しています。
チャプター情報はなんとか読み出せそうです。MKVファイルのチャプタだと MediainfoのMenuトラックのキーとて保存される事が多いです。BMS2ではminfo変数にて取り出すことになります。しかし、BMS2ではAudioトラックとVideoトラック以外はうまく取り出せない感じです。
bms.ini の[MInfoKeys]に追加したいキーを指定するとMI.exeで読み出した状態を確認できます。たとえば字幕がいくつ保存されているかは"General;TextCount"で字幕の数が表示されます。
個別の字幕の形式は"Text(1).Format"で取得できます。
しかし、BMSからはうまく取得できなかったりします。Mediainfo情報のメモリー展開にミスがある感じです。minfo["General;TextCount"]では日によって読めたり読めなかったする感じ・・・なぜ?
minfo["Text(1).Format"]でも正しく読める時があったり、頭の数文字しか読めない時があったり。
BMS2で字幕をテレビに送りテレビで切り替えるソフトサブ方式は目途が無いため、トランスコード時にビデオへ焼き付けるハードサブ方式で実装してみる事にします。
General;TextCountが実質使えないため字幕の有り無しの判断が難しくなります。そのためText(1).Format と Text(2).Format を読み出し、対応できるフォーマットの文字が返ってきたら字幕ありと判断することにします。対応字幕数は2つまでです。
そして、字幕のフォーマットはグラフィックになっているPGS形式とVobSub形式にしました。ffmpegはテキスト字幕も扱う事ができますが、私が実験できるファイルを持っていないので考慮しません。
さて、これで情報は引き出せましたので後は字幕を焼き付けます。
字幕の焼き付けは、前回の記事でコメント頂いたように、mencoderを使うと簡単にできます。しかし、今回はそれを使いません。mencoderでのやり方はDVD ISOと同じようにすれば良いです。やり方も探せばすぐに見つかります。私があらためて書いても面白くないです。
なにより、mencoderでは複数の音声トラックを送る事ができません。せっかく音声トラックの切り替えをテレビでできるようにしたのに、その機能を実現できないのです。
ffmpegで字幕の焼きこみ方法を検索すると日本語の情報がとても少ないです。明らかにこっちの方が記事的に良いです。
という事でffmpegでやってみる事にします。
ffmpegで字幕を焼きこむにはoverlayフィルタを使います。これは2つのビデオファイルを重ねるフィルターです。字幕のグラフィックをビデオと同じ扱いにするわけです。字幕だけではなくjpgファイルなどももちろん重ねられます。
オプションとしては -vf か -filter_complexで行います。-filter_complexが上位版という感じです。overlayフィルタを使うにはffmpegのストリームという考え方を理解しないとすぐに動かなくなってしまいます。ffmpegのフィルタ機能は何でもできるなぁ、というくらい良くできています。(正しく動くかは別です・・・)
そして、このフィルターの中には変な物もあります。マンデブロ集合を生成したり、ライフゲームを生成したり、音声を波形表示にしたり、音声のスペクトルを表示したり。
この機能を使ってVIERAで音声ファイルを再生できるようにしてみます。VIERAは映像の無い音声をDLNAで再生する事ができません。ダミーの映像を作ってビデオファイル化すれば再生できます。特に面白い事もないので実装しませんでしたが、今回はライフゲームを表示させながら音声を再生するようにしてみます。
この変換をffmpeg1行でやると何かノイズが載った様な音になってしまいます。ほんの短い時間間隔で音が途切れている感じになります。試行錯誤の結果、今のところ事前に音声をwavへ変換しておくと回避できます。そのため、パイプ処理を使います。
DVD ISOの字幕は今回の方法を使っていません!以前のまま未検証です。MKVファイルなどマルチトラックコンテナ内の字幕トラックを想定しています。
高解像度ビデオで字幕の焼きこみに時間がかかるようでトランスコードが間に合いません。この時CPUの使用率は高くないのでCPUの性能不足では無いようです。フィルタグラフではマルチスレッド処理がされないのかもしれません。このためHDビデオでの字幕焼き付けは実用になりません。SD画質なら大丈夫みたいです。
それでは、今回のVIERA GT3用Luaスクリプトです。今回はベータ版です。
【2017/5/26 追記
DLNAサーバー BMS2の最新の設定方法は
BMS2用Luaスクリプト
にまとめています】
QSVを使う場合はUseQSVをtrueにしてください。
QSVEncCをBMSと同じフォルダに置いてください。
common.luaはBeer Media Server 2のレグザ ZP2用スクリプトを修正しメディアの種類を増やしてみた と同じものです。
audioファイルに対応しました。再生中にライフゲームを表示します。
DVD ISOの動作は確かめていません。
MKVファイルの字幕を焼き付け表示します。対応字幕はPGS、VobSubです。
(たぶん)対応ビデオ: mpeg1, mpeg2, h.264, wmv, mpeg4, mp4, flv, mkv
(たぶん)対応オーディオ:wav, wma, mp3, pcm, ac3, aac
下のソースはダブルクリックすると全文選択状態になります。コピーしてテキストエディタへ貼り付けVIERA-GT3.luaと名前を付けて保存してください。
今回は試行状況を書いてみます。
字幕のソフトサブはまったく目途が無いためハードサブを試します。mencoderを使うと巷に情報がいくらでもありますのでここはあえてffmpegだけを使ってやってみます。
VIERAではDLNA経由で音声ファイルを再生する事ができません。そんな場合は音声ファイルに何かの映像を付けて映像として送ってやれば良いのです。需要もなさそうなので放置してましたが、ffmpegの字幕焼き付けのついでに試してみました。音声ファイル再生中にライフゲームを表示させました。
チャプター時間は読めそうな事が判りましたが時間を指定する良いアイデアが浮かばないので保留中です。
BMS2のトランスコード機能に字幕とチャプターが付けば完璧になるのになぁ、と試行しています。
チャプター情報はなんとか読み出せそうです。MKVファイルのチャプタだと MediainfoのMenuトラックのキーとて保存される事が多いです。BMS2ではminfo変数にて取り出すことになります。しかし、BMS2ではAudioトラックとVideoトラック以外はうまく取り出せない感じです。
bms.ini の[MInfoKeys]に追加したいキーを指定するとMI.exeで読み出した状態を確認できます。たとえば字幕がいくつ保存されているかは"General;TextCount"で字幕の数が表示されます。
個別の字幕の形式は"Text(1).Format"で取得できます。
しかし、BMSからはうまく取得できなかったりします。Mediainfo情報のメモリー展開にミスがある感じです。minfo["General;TextCount"]では日によって読めたり読めなかったする感じ・・・なぜ?
minfo["Text(1).Format"]でも正しく読める時があったり、頭の数文字しか読めない時があったり。
BMS2で字幕をテレビに送りテレビで切り替えるソフトサブ方式は目途が無いため、トランスコード時にビデオへ焼き付けるハードサブ方式で実装してみる事にします。
General;TextCountが実質使えないため字幕の有り無しの判断が難しくなります。そのためText(1).Format と Text(2).Format を読み出し、対応できるフォーマットの文字が返ってきたら字幕ありと判断することにします。対応字幕数は2つまでです。
そして、字幕のフォーマットはグラフィックになっているPGS形式とVobSub形式にしました。ffmpegはテキスト字幕も扱う事ができますが、私が実験できるファイルを持っていないので考慮しません。
さて、これで情報は引き出せましたので後は字幕を焼き付けます。
字幕の焼き付けは、前回の記事でコメント頂いたように、mencoderを使うと簡単にできます。しかし、今回はそれを使いません。mencoderでのやり方はDVD ISOと同じようにすれば良いです。やり方も探せばすぐに見つかります。私があらためて書いても面白くないです。
なにより、mencoderでは複数の音声トラックを送る事ができません。せっかく音声トラックの切り替えをテレビでできるようにしたのに、その機能を実現できないのです。
ffmpegで字幕の焼きこみ方法を検索すると日本語の情報がとても少ないです。明らかにこっちの方が記事的に良いです。
という事でffmpegでやってみる事にします。
ffmpegで字幕を焼きこむにはoverlayフィルタを使います。これは2つのビデオファイルを重ねるフィルターです。字幕のグラフィックをビデオと同じ扱いにするわけです。字幕だけではなくjpgファイルなどももちろん重ねられます。
オプションとしては -vf か -filter_complexで行います。-filter_complexが上位版という感じです。overlayフィルタを使うにはffmpegのストリームという考え方を理解しないとすぐに動かなくなってしまいます。ffmpegのフィルタ機能は何でもできるなぁ、というくらい良くできています。(正しく動くかは別です・・・)
そして、このフィルターの中には変な物もあります。マンデブロ集合を生成したり、ライフゲームを生成したり、音声を波形表示にしたり、音声のスペクトルを表示したり。
この機能を使ってVIERAで音声ファイルを再生できるようにしてみます。VIERAは映像の無い音声をDLNAで再生する事ができません。ダミーの映像を作ってビデオファイル化すれば再生できます。特に面白い事もないので実装しませんでしたが、今回はライフゲームを表示させながら音声を再生するようにしてみます。
この変換をffmpeg1行でやると何かノイズが載った様な音になってしまいます。ほんの短い時間間隔で音が途切れている感じになります。試行錯誤の結果、今のところ事前に音声をwavへ変換しておくと回避できます。そのため、パイプ処理を使います。
DVD ISOの字幕は今回の方法を使っていません!以前のまま未検証です。MKVファイルなどマルチトラックコンテナ内の字幕トラックを想定しています。
高解像度ビデオで字幕の焼きこみに時間がかかるようでトランスコードが間に合いません。この時CPUの使用率は高くないのでCPUの性能不足では無いようです。フィルタグラフではマルチスレッド処理がされないのかもしれません。このためHDビデオでの字幕焼き付けは実用になりません。SD画質なら大丈夫みたいです。
それでは、今回のVIERA GT3用Luaスクリプトです。今回はベータ版です。
【2017/5/26 追記
DLNAサーバー BMS2の最新の設定方法は
BMS2用Luaスクリプト
にまとめています】
VIERA-GT3.lua
ffmpegの実行ファイルをBMSと同じフォルダに置いてください。QSVを使う場合はUseQSVをtrueにしてください。
QSVEncCをBMSと同じフォルダに置いてください。
common.luaはBeer Media Server 2のレグザ ZP2用スクリプトを修正しメディアの種類を増やしてみた と同じものです。
audioファイルに対応しました。再生中にライフゲームを表示します。
DVD ISOの動作は確かめていません。
MKVファイルの字幕を焼き付け表示します。対応字幕はPGS、VobSubです。
(たぶん)対応ビデオ: mpeg1, mpeg2, h.264, wmv, mpeg4, mp4, flv, mkv
(たぶん)対応オーディオ:wav, wma, mp3, pcm, ac3, aac
下のソースはダブルクリックすると全文選択状態になります。コピーしてテキストエディタへ貼り付けVIERA-GT3.luaと名前を付けて保存してください。
--[[ VIERA GT3用スクリプト 2013-05-19 オーディオファイルはライフゲームを表示して再生対応 PGS,VobSUBのオーバーレイ表示を試行 2013-05-12 16:9より横長darに対応 2013-05-03 setsarを使用し画面モード1でアスペクト比修正 2013-05-01 REGZA ZP2用を移植 音声のマルチトラック、QSVトランスコードに対応 2012-06-16 ffmpegトランスコードにASYNCを指定しスキップ時の音ずれ補正 2012-06-15 トランスコード時の最大解像度1280x720へ 2012-06-09 GetTranscodeCommandを簡略化 2012-06-08 連想配列を用いてGetMimeType 関数をシンプルにした 2012-06-07 MOD10のMPEG_PS_NTSC.luaに基づきMODへ対応 2012-03-24 頂いたコメントよりトランスコード時に返信するmimetypeを修正しました。 トランスコード時に早送り・30秒スキップ等でるかも。 2012-03-22 ISO DVDのチャプタを指定できるようにしてみた 字幕指定の場合分けをまとめた 2012-03-20 ロジックを整理 2012-03-19 初版 SignalFlag_Z http://signal-flag-z.blogspot.jp/ ]] ---------------------------------------------------------------------- -- トランスコード時QSVEncCを使う場合はtrueにする ---------------------------------------------------------------------- local UseQSV = false ---------------------------------------------------------------------- -- ffmpeg用パラメータ ---------------------------------------------------------------------- local vf_param local vf_cmd local b_cmd local video_cmd local audio_cmd local format_cmd ---------------------------------------------------------------------- -- この機種がサポートしているメディア情報のリスト ---------------------------------------------------------------------- SUPPORT_MEDIA_LIST = { "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC_XAC3;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_JP_MPEG1_L2_T;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_JP_AAC_T;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_FLAGS=8d100000000000000000000000000000", "image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_FLAGS=8c900000000000000000000000000000", "image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_FLAGS=8c900000000000000000000000000000", "image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_FLAGS=8c900000000000000000000000000000", "image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_FLAGS=8c900000000000000000000000000000", "image/jpeg:DLNA.ORG_PN=JPEG_SM_ICO;DLNA.ORG_FLAGS=8c900000000000000000000000000000", "image/jpeg:DLNA.ORG_PN=JPEG_LRG_ICO;DLNA.ORG_FLAGS=8c900000000000000000000000000000", "video/mp4:*", "video/quicktime:*", "image/jpeg:*", "video/vnd.dlna.mpeg-tts:*", "video/mpeg:*" } ---------------------------------------------------------------------- local MimeTypeString={} --JPEG MimeTypeString["JPEG"] = "image/jpeg:*" --PCM MimeTypeString["Wave"] = "audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM" --MP3 MimeTypeString["MPEG Audio"] = "audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=10" --動画 MimeTypeString["MPEG-TS"] = "video/mpeg:*" MimeTypeString["MPEG-PS"] = "video/mpeg:*" MimeTypeString["DVD ISO"] = "video/mpeg:*" MimeTypeString["TRANSCODE"] = "video/mpeg:DLNA.ORG_OP=10;DLNA.ORG_CI=0" --MimeTypeString["TRANSCODE"] = "video/vnd.dlna.mpeg-tts:DLNA.ORG_OP=10;DLNA.ORG_CI=0" MimeTypeString["TRANSCODE_AVC"] = "video/mpeg:DLNA.ORG_OP=10;DLNA.ORG_CI=0" MimeTypeString["MPEG-4"] = "video/mp4:*" ---------------------------------------------------------------------- -- BMS.GetPlayInfo 関数 -- メディアファイルの再生方法の情報を返す。 -- 引数: -- fname: ファイル名 -- minfo: MediaInfo.dll などから得られた情報 -- 戻り値: -- 1: MimeType または トランスコード情報テーブル -- 2: 表示用文字列(省略でファイル名そのまま) -- 3: ソート用文字列(省略でファイル名そのまま) ---------------------------------------------------------------------- function BMS.GetPlayInfo(fname, minfo) --print("\r\nDEBUG: "..BMS.ClientInfo.ext.."\r\n") --local MimeTypeString=MimeTypeString -- print("\r\n>>>>".. minfo.General.Format.."/"..minfo.Video.Format.."/"..minfo.Audio.Format) ---------- --トランスコードコマンドを返す関数 ---------- local function ffmpegCommand() local ret if UseQSV then ret = {} ret[1] = [[ffmpeg.exe -v 0 $_cmd_seek_ffmpeg_$ -i "$_in_$" -c:v rawvideo ]]..vf_cmd..[[ -r ]]..FPS..[[ -pix_fmt yuv420p -an -f yuv4mpegpipe -threads 4 -y -]] ret[2] = [[QSVEncC.exe --y4m --tff -i - --output-res 1920:1080 --sar 1:1 --vbr 4000 --maxbitrate 12000 --vpp-deinterlace none --vpp-denoise 20 --vpp-detail-enhance 15 -u quality --tff --videoformat ntsc --gop-len 30 --scenechange -o -]] --ret[2] = [[QSVEncC.exe --y4m --tff -i - --output-res 1440:1080 --sar 32:27 --vbr 4000 --maxbitrate 12000 --vpp-deinterlace none --vpp-denoise 10 --vpp-detail-enhance 20 -u quality --tff --videoformat ntsc --gop-len 30 --scenechange -o -]] ret[3] = [[ffmpeg.exe -v 0 -f h264 -i - -f avi -vcodec copy -an -threads 1 -y -]] --ret[4] = [[ffmpeg.exe -v 0 -f avi -i - -f avi -vcodec copy -an -threads 1 -y -]] ret[4] = [[ffmpeg.exe $_cmd_quiet_ffmpeg_$ -f avi -i - $_cmd_seek_ffmpeg_$ -i "$_in_$" ]]..mapq..[[ -c:v copy -c:a libfaac -ac 2 -ar 48000 -b:a 192k -async 1 -f mpegts -mpegts_m2ts_mode -1 -packetsize 188 -threads 2 -y "$_out_$"]] else ret = [[ffmpeg.exe $_cmd_seek_ffmpeg_$ -i "$_in_$" ]]..video_cmd..[[ ]]..audio_cmd..[[ ]]..vf_cmd..[[ ]]..format_cmd..[[ -y "$_out_$"]] end return ret end ---------- --メディアではない? if minfo.General.Format == "" then return "" end --JPEG if minfo.General.Format == "JPEG" then return MimeTypeString["JPEG"] end --WAVE if minfo.General.Format == "Wave" or minfo.General.Format == "Windows Media" or minfo.General.Format == "MPEG Audio" then local t = {} t.name = ">>>"..fileu.ExtractFileName(fname) t.mime = MimeTypeString["TRANSCODE"] t.duration = minfo.General.Duration --音がぶつぶつ不連続になるため音声を分離しておく。 t.command = {} t.command[1] = [[ffmpeg.exe $_cmd_seek_ffmpeg_$ -i "$_in_$" -f wav -]] --GAME of Life t.command[2] = [[ffmpeg.exe -i - -f lavfi -i "life=rate=15:s=160x90:mold=10:death_color=#C83232:life_color=#00ff00,fifo,scale=720x480:flags=neighbor" -map 1:v:0:0 -c:v mpeg2video -b:v 2000k -r 30000/1001 -vsync 1 -map 0:a:0:1 -c:a libfaac -ac 2 -ar 48k -b:a 192k -threads 2 -f mpegts -packetsize 188 -shortest -y "$_out_$"]] return t, "/ "..fileu.ExtractFileName(fname) end if not (minfo.Video.Format ~= "" or minfo.Audio.Format ~= "")then return "" end local ret --ビデオ if minfo.Video.Format == "MPEG Video" then if minfo.General.Format =="MPEG-TS" then ret =MimeTypeString["MPEG-TS"] elseif minfo.General.Format =="MPEG-PS" then ret =MimeTypeString["MPEG-PS"] end end --MP4 -- if minfo.General.Format == "MPEG-4" then -- if minfo.Video.Format == "AVC" then -- return MimeTypeString["MPEG-4"] -- end -- end if ret then return ret end ---------------- 以下、トランスコード --トランスコードするminfo.General.Formatを列挙しておく -- "ISO DVDはmencoderを使うので含めない local TranscodeList = OrdSet({"MPEG-4", "BDAV", "Matroska"}) --common.luaの関数 local t, t2 = {}, {} if minfo.General.Format == "ISO DVD" then --↓DVD ISO トランスコード local DVD_title; DVD_title = minfo.DVD["title"..minfo.DVD.longest_title] t2.mime = "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0" if DVD_title.lang_a.en and DVD_title.lang_s.ja then -- 英語音声と日本語字幕がある場合 t[1] = {} t[1].mime = t2.mime t[1].name = GetFileBaseName(fname).." (英語音声・日本語字幕)" t[1].duration = DVD_title.length_s t[1].command = [[ mencoder -dvd-device "$_in_$" dvd://]]..minfo.DVD.longest_title..[[ $_cmd_quiet_mencoder_$ $_cmd_seek_mencoder_$ -o "$_out_$" -alang en -slang ja -channels 6 -ofps 30000/1001 -ovc lavc -vf scale=720:480,expand=720:480,pp=l5,harddup -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:threads=2:aspect=1.778 -oac lavc -channels 2 -srate 48000 -af lavcresample=48000 -lavcopts acodec=ac3:abitrate=192 -of mpeg -mpegopts format=dvd:tsaf ]] t[2] = {} t[2].mime = t2.mime t[2].name = GetFileBaseName(fname).." (日本語音声)" t[2].duration = DVD_title.length_s t[2].command = [[ mencoder -dvd-device "$_in_$" dvd://]]..minfo.DVD.longest_title..[[ $_cmd_quiet_mencoder_$ $_cmd_seek_mencoder_$ -o "$_out_$" -alang ja -slang ja -forcedsubsonly -channels 6 -ofps 30000/1001 -ovc lavc -vf scale=720:480,expand=720:480,pp=l5,harddup -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:threads=2:aspect=1.778 -oac lavc -srate 48000 -af lavcresample=48000 -lavcopts acodec=ac3:abitrate=192 -of mpeg -mpegopts format=dvd:tsaf ]] t[3] = {} t[3].mime = t2.mime t[3].name = GetFileBaseName(fname).." (英語音声)" t[3].duration = DVD_title.length_s t[3].command = [[ mencoder -dvd-device "$_in_$" dvd://]]..minfo.DVD.longest_title..[[ $_cmd_quiet_mencoder_$ $_cmd_seek_mencoder_$ -o "$_out_$" -alang en -slang en -forcedsubsonly -channels 6 -ofps 30000/1001 -ovc lavc -vf scale=720:480,expand=720:480,pp=l5,harddup -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:threads=2:aspect=1.778 -oac lavc -srate 48000 -af lavcresample=48000 -lavcopts acodec=ac3:abitrate=192 -of mpeg -mpegopts format=dvd:tsaf ]] return t, "/ "..fileu.ExtractFileName(fname) else t.mime = t2.mime t.name = GetFileBaseName(fname) t.duration = DVD_title.length_s t.command = [[ mencoder -dvd-device "$_in_$" dvd://]]..minfo.DVD.longest_title..[[ $_cmd_quiet_mencoder_$ $_cmd_seek_mencoder_$ -o "$_out_$" -ofps 30000/1001 -ovc lavc -vf scale=720:480,expand=720:480,pp=l5,harddup -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:threads=2:aspect=1.778 -oac lavc -channels 6 -srate 48000 -af lavcresample=48000 -lavcopts acodec=ac3:abitrate=192 -of mpeg -mpegopts format=dvd:tsaf ]] if BMS.ShowTranscodeFolder then t2 = {t} else t2 = t end return t2, "/ "..fileu.ExtractFileName(fname) end --↑DVD ISO トランスコード elseif TranscodeList[minfo.General.Format] then --↓トランスコード --↓アスペクト比の設定 local w = tonumber(minfo.Video.Width) local h = tonumber(minfo.Video.Height) local dar = tonumber(minfo.Video.DisplayAspectRatio) local par = dar * h / w local x, y --Screen size local dar2 = 16/9 --Display Aspect Ratio for Output local par2 --Pixel Aspect Ratio for Output local sar = "" --fullHDで指定するsar local pad = "" --Pad option for ffmpeg local vbitrate = math.floor(math.sqrt(w * h)) * 6000 local interlace = " -flags +ildct+ilme" --インターレース化 if dar > 1.6 then --16:9の場合 dar2 = 16/9 if w<=640 then x, y = 640, 480 elseif w<=720 then x, y = 720, 480 elseif w<=800 then x, y = 800, 600 interlace = "" elseif w<=960 then x, y = 960, 540 sar = "40:33" interlace = "" elseif w<=1280 then x, y = 1280, 720 sar = "40:33" interlace = "" elseif w<=1440 then x, y = 1440, 1080 interlace = "" else x, y = 1920, 1080 interlace = "" sar = "40:33" end -- par2 = dar2 * y / x local y2 = math.floor((h * (x / w) * (par2/par) + 2)/4)*4 local padY = y - y2 if padY > 4 then --計算誤差吸収 pad = ",pad="..x..":"..y..":0:"..padY/2 y = y2 end else --4:3の場合 local w2 = w / 0.75 dar2 = 4/3 if w2>1440 then x, y = 1920, 1080 sar = "40:33" elseif w2>1280 then x, y = 1440, 1080 elseif w2>960 then x, y = 1280, 720 sar = "40:33" interlace = "" elseif w2>800 then x, y = 960, 540 sar = "40:33" interlace = "" elseif w2>720 then x, y = 800, 600 interlace = "" elseif w2>640 then x, y = 720, 480 interlace = "" else x, y = 640, 480 interlace = "" end --16:9 黒帯追加 pad = ",pad="..x..":"..y..":"..x * 0.125 ..":0" x = x * 0.75 sar = "40:33" end if sar == "" then sar = par2 --sar = dar * y / h end --↑アスペクト比の設定 --↓オーディオのマップ local map = " -map [video1]:0 -map 0:a:0 -streamid 0:33 -streamid 1:34" local mapq = " -map [video1]:0 -map 1:a:0 -streamid 0:33 -streamid 1:34" --qsv用マップ local atracks,i i=2 atracks = tonumber(minfo.General.AudioCount) while i <= atracks do map = map .. " -map 0:a:"..i-1 .." -streamid "..i..":"..i+33 mapq = mapq .." -map 1:a:"..i-1 .." -streamid "..i..":"..i+33 i=i+1 end --↑オーディオのマップ --frames per second local FPS = "30000/1001" if minfo.Video.FrameRate ~= "" and not UseQSV then if tonumber(minfo.Video.FrameRate) <= 24 then FPS = "24000/1001" interlace = "" end end --ffmpeg用 vf_param = "scale="..x..":"..y..pad..",setsar="..sar..",yadif=0:-1" vf_cmd = ' -filter_complex "[0:v:0]'..vf_param..'[video1]"' b_cmd = " -b:v "..vbitrate video_cmd = " -c:v mpeg2video -r "..FPS.." "..interlace.." "..b_cmd audio_cmd = " -c:a ac3 -ac 2 -dmix_mode 1 -ar 48000 -b:a 192k -async 1000" format_cmd = " -sn -f mpegts -mpegts_m2ts_mode 0 -packetsize 188 -threads 8"..map --local TextFormatList = OrdSet({"PGS", "VobSub"}) --対応字幕フォーマット --字幕があるか? local j=1 local subF = string.sub(minfo["Text(1);Format"], 1, 3) if subF == "PGS" or subF == "Vob" then --字幕を焼きこむ filergraph vf_cmd = ' -filter_complex "[0:v:0][0:s:0]overlay,'..vf_param..'[video1]"' t[j+1] = {} t[j+1].mime = MimeTypeString["TRANSCODE"] t[j+1].name = minfo["Text(1);Language"]..":"..GetFileBaseName(fname) t[j+1].command = ffmpegCommand() j=j+1 end subF = string.sub(minfo["Text(2);Format"], 1, 3) if subF == "PGS" or subF == "Vob" then --字幕を焼きこむ filergraph vf_cmd = ' -filter_complex "[0:v:0][0:s:1]overlay,'..vf_param..'[video1]"' t[j+1] = {} t[j+1].mime = MimeTypeString["TRANSCODE"] t[j+1].name = minfo["Text(2);Language"]..":"..GetFileBaseName(fname) t[j+1].command = ffmpegCommand() j=j+1 end --字幕なしのメニュー if j> 1 then vf_cmd = ' -filter_complex "[0:v:0]'..vf_param..'[video1]"' t[1] = {} t[1].mime = MimeTypeString["TRANSCODE"] t[1].name = GetFileBaseName(fname) t[1].command = ffmpegCommand() end --字幕が無かったら if #t == 0 then t.name = ">"..fileu.ExtractFileName(fname) t.mime =MimeTypeString["TRANSCODE"] t.command = ffmpegCommand() end --↑トランスコード else --その他のフォーマット return "" end if BMS.ShowTranscodeFolder then t2 = {t} else t2 = t end return t2, "/ "..fileu.ExtractFileName(fname) end
コメント
コメントを投稿