Beer Media ServerでISO DVDのチャプタ選択を表示させてみた

なんとか家のVIERA GT3とREGZA ZP2からBeer Media Serverに接続して動画ファイルを見れるようになってきました。
ISO DVDが見れるのは便利だなぁ…と思ったのですが、REGZAでは早送りも30秒スキップもできません。VIERAでは早送りくらいはできます。これではDVDの視聴を途中でやめたらもう続きを見る気にはならないです。

せっかくISO DVDが見れるのにもったいないあなぁ…
ということでせめてチャプタの選択ができるようにしてみました。

BMSでISO DVDのトランスコードに標準ではmencoderを使うよう設定されています。そして、mencoderには再生するチャプタを指定するオプションがあります。
これを使えば少しでもDVDを見やすくできるのではないでしょうか。(もうBDしか見る気は起きないんだけどね・・・)

しかし、ここでちょっとした問題が存在します。DVDのタイトル数とチャプタ数を知る術がない…。
ちなみにDVDのTITLEの中でどうやって本編のTITLE番号を見つけているのでしょうか。BMS作者様スクリプトから読み解くとlongestというMediaInfo情報を参照して最も長いDVD TITLEを本編として指定できるようです。これと同じようにlongest TITLEのchaptersが取得できればチャプター数が判る事になります。もしかしたら何か変数に記憶されてるのでしょうか?それはBMSの作者様しかわかりません。
あるいはLuaスクリプトから外部プログラムを呼び出せるのなら他のプログラムからチャプタ数を取得できるかもしれません。私はBMSで初めてLuaスクリプトを見たので細かい事は解りませんが気が向いたら調べてみます。

しかたないのでチャプタ数はもう固定にしてしまう事にします。存在しないチャプタを指定してもフリーズしないようなのでこれでいいや!
手元にあるISOファイルでチャプタ数をざっと見て、とりあえず30個のチャプタを並べるようにしてみました。
字幕のあるDVDの場合、字幕有り無しで60個のチャプタが表示されます…

簡単にこんなカスタマイズができるBMSは便利ですね。

それでは REGZA ZP2 と VIERA GT3 用の設定ファイルを晒しておきます。

#2012-03-24 コメント頂いた内容に修正

新しいLuaスクリプトを"BMS2用Luaスクリプト"に公開しています。

REGZA-ZP2.lua


--[[
REGZA ZP2用スクリプト
2012-03-24 頂いたコメントよりトランスコード時に返信するmimetypeを修正しました。
   トランスコード時に早送り・30秒スキップ等でるかも。
2012-03-22 ISO DVDのチャプタを指定できるようにしてみた
   字幕指定の場合分けをまとめた
2012-03-20 ロジックを整理
2012-03-19 初版 SignalFlag_Z
     http://pub.ne.jp/SignalFlag_Z/
]]


-- この機種がサポートしているメディア情報のリスト
SUPPORT_MEDIA_LIST = {
    "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC",
    "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T",
    "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_JP_AAC_T",
    "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_60_AC3_T",
    "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_24_AC3_T",
    "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_JP_MPEG1_L2_T",
    "audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM",
    "audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM",
    "audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM",
    "audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM",
    "audio/mpeg:DLNA.ORG_PN=MP3",
    "image/jpeg:DLNA.ORG_PN=JPEG_SM",
    "image/jpeg:DLNA.ORG_PN=JPEG_MED"
}


--[[
 GetMimeType 関数

 メディアファイルに応じたメディア情報を返す。

 引数:
   fname: ファイル名
   minfo: MediaInfo.dll などから得られた情報
]]
function GetMimeType(fname, minfo)

 -- 録画中のファイル?
 if minfo.General.Format == "NowRecording" then
  return ""  -- 無視させる
 end

 --local ext = string.lower(string.match(fname, ".*%.([^.]+)$"))
 
 if minfo.General.Format == "" then

  --メディアファイルではない?
  if minfo.Video.Format == "" then 
   return ""
  end
 
 --JPEG
 elseif minfo.General.Format == "JPEG" then
      return "image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=10;DLNA.ORG_CI=0"
 
 --WAVE ノイズしか出なかった
 elseif minfo.General.Format == "Wave" then
  if minfo.Audio.SamplingRate == "48000" and minfo.Audio.Channels == "2" then
   return  "audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM"
  elseif minfo.Audio.SamplingRate == "48000" and minfo.Audio.Channels == "1" then
   return   "audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM"
  elseif minfo.Audio.SamplingRate == "44100" and minfo.Audio.Channels == "2" then
   return  "audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM"
  elseif minfo.Audio.SamplingRate == "44100" and minfo.Audio.Channels == "1" then
   return   "audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM"
  else
   return ""
  end
 
 --MP3
 elseif minfo.General.Format == "MPEG Audio" then
  return "audio/mpeg:DLNA.ORG_PN=MP3"
  
 --MPEG-TS
 elseif minfo.General.Format == "MPEG-TS" then
  return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01;DLNA.ORG_CI=0"
 
 --MPEG-PS
 elseif minfo.General.Format == "MPEG-PS" then
  return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01"
 
 --MP4 トランスコード
 elseif minfo.General.Format == "MPEG-4" then
  if minfo.Video.Format == "AVC" then
   --return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC:::TRANS:::;DLNA.ORG_OP=11;DLNA.ORG_CI=0"
   return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
  end
 
 --ISO DVD トランスコード
 elseif minfo.General.Format == "ISO DVD" then
  
  --スキップ・早送り可能 チャプタ指定がでません。
  --return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
  
  --スキップ・早送りできません。チャプタ指定できます。
  return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=00;DLNA.ORG_CI=0:::TRANS:::"

 --その他 とりあえずトランスコード
 else
  --return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC:::TRANS:::;DLNA.ORG_OP=11;DLNA.ORG_CI=0"
  return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"

 end
 return ""   --おまじない
end




--[[
 GetTranscodeCommand 関数
 
 トランスコードのコマンドを返す。

 引数:
   fname: ファイル名
   minfo: MediaInfo.dll などから得られた情報
]]
function GetTranscodeCommand(fname, minfo)

 local aspect = minfo.Video.DisplayAspectRatio
 if aspect == "" then aspect = "1.333" end
 --print("\r\nDEBUG: "..fname.." aspect="..aspect.."\r\n")
 local w = minfo.Video.Width
 local h = minfo.Video.Height

 -- この機種ではサイズによりアスペクト比を判定しているみたいなので
 -- mpeg2 のサイズとアスペクト比を固定にする。
 w = "720" h = "480"
 local vfs0 = "scale="..w..":"..h
 if aspect ~= "1.778" then
  local sw = w
  local sh = h
  if tonumber(aspect) < 1.778 then
    sw = math.floor(w / 1.778 * aspect + 0.5)
  else
    sh = math.floor(h * 1.778 / aspect + 0.5)
  end
  vfs0 = "scale="..sw..":"..sh..",expand="..w..":"..h
  aspect = "1.778"
 end

 local vfs = vfs0 .. ",pp=l5,harddup"

 -- DVD ISO
 if minfo.General.Format == "ISO DVD" then
  if minfo.DVD.ALANG.en and minfo.DVD.SLANG.ja then
   local ret=""
   local i=1
    -- 英語音声と日本語字幕がある場合
     for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "en", "ja")
   end
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "ja", "none")
   end
   return ret
              
  elseif minfo.DVD.ALANG.ja and minfo.DVD.ALANG.en and minfo.DVD.SLANG.en then
   local ret=""
   local i=1
   -- 英語音声と英語字幕がある場合
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "en", "en")
   end
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "ja", "none")
   end
   return ret

  else
   local ret =""
   --チャプタ30個つくってみた
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "ja", "none")
   end
   
   return ret
  end

 --MP4
    elseif minfo.General.Format == "MPEG-4" and minfo.Video.Format == "AVC" then
  return [[
   [$_name_$ (MP4 to MPEG-PS)]
   mencoder "$_in_$" -o "$_out_$"
   -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf
   -vf ]]..vfs..[[ -srate 48000 -af lavcresample=48000
   -ofps 30000/1001 -channels 6
   -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=]]
   ..aspect

 --とりあえずトランスコード
 else
  return [[
   [$_name_$ (TRANSCODE to MPEG-PS)]
   mencoder "$_in_$" -o "$_out_$"
   -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf
   -vf ]]..vfs..[[ -srate 48000 -af lavcresample=48000
   -ofps 30000/1001 -channels 6
   -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=]]
   ..aspect
    end
end

--[[
 チャプタ番号を指定してDVD_ISOを表示
]]
function DVDISO_Chapter(aspect, vfs, i,  alang, slang)
 
 if slang == "none" then slang = alang .. " -forcedsubsonly " end
 return  "\n[$_name_$ " .. "Chapter_" .. i .. ":"..alang.."/"..slang.. "]\n"
   ..[[
      mencoder -dvd-device "$_in_$" dvd://$_longest_$ 
      -chapter ]]..i.."-"..i
      ..[[ -o "$_out_$" -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf
      -vf ]]..vfs..[[ -srate 48000 -af lavcresample=48000
      -ofps 30000/1001 -alang ]]..alang..[[ -slang ]]..slang..[[ -channels 6
      -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=]]
     ..aspect

end

VIERA-GT3.lua


--[[
VIERA GT3用スクリプト
 2012-03-24 頂いたコメントよりトランスコード時に返信するmimetypeを修正しました。
 2012-03-22 ISO DVDのチャプタを指定できるようにしてみた
    字幕指定の場合分けをまとめた
 2012-03-20  初版 SignalFlag_Z
    http://pub.ne.jp/SignalFlag_Z/
]]


-- この機種がサポートしているメディア情報のリスト
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:*"
}


--[[
 GetMimeType 関数

 メディアファイルに応じたメディア情報を返す。

 引数:
   fname: ファイル名
   minfo: MediaInfo.dll などから得られた情報

]]
function GetMimeType(fname, minfo)

 -- 録画中のファイル?
 if minfo.General.Format == "NowRecording" then
  return ""  -- 無視させる
 end

 --local ext = string.lower(string.match(fname, ".*%.([^.]+)$"))
 
 if minfo.General.Format == "" then

  --メディアファイルではない?
  if minfo.Video.Format == "" then 
   return ""
  end
 
 --JPEG
 elseif minfo.General.Format == "JPEG" then
      return "image/jpeg:*"
 
 --WAVE
 elseif minfo.General.Format == "Wave" then
  return "" --画像なし動画にトランスコードするかも

 --MP3
 elseif minfo.General.Format == "MPEG Audio" then
  return "" --画像なし動画にトランスコードするかも
   
 --MPEG-TS
 elseif minfo.General.Format == "MPEG-TS" then
  --return "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_OP=11;DLNA.ORG_CI=0;DLNA.ORG_FLAGS=8d100000000000000000000000000000"
  return "video/mpeg:*"
 
 --MPEG-PS
 elseif minfo.General.Format == "MPEG-PS" then
  return "video/mpeg:*"
 
 --MP4
 elseif minfo.General.Format == "MPEG-4" then
  if minfo.Video.Format == "AVC" then
  --return "video/mpeg:*:::TRANS:::;DLNA.ORG_OP=11;DLNA.ORG_CI=0"
  return "video/mp4:*"
  end

 --Quicktime 試してません
 elseif minfo.General.Format == "QuickTime" then
  return "video/quicktime:*"

 --FLV トランスコード
 elseif minfo.General.Format == "Flash Video" then
  --return "video/mpeg:*;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
  return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"

 --ISO DVD トランスコード
 elseif minfo.General.Format == "ISO DVD" then
  --チャプタ指定がでません。
  --return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
  
  --チャプタ指定できます。
  return "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=00;DLNA.ORG_CI=0:::TRANS:::"

 --その他 リスト表示せず
 else
  return ""
 end

 return ""
end




--[[
 GetTranscodeCommand 関数
 
 トランスコードのコマンドを返す。

 引数:
   fname: ファイル名
   minfo: MediaInfo.dll などから得られた情報
]]
function GetTranscodeCommand(fname, minfo)

 local aspect = minfo.Video.DisplayAspectRatio
 if aspect == "" then aspect = "1.333" end
 --print("\r\nDEBUG: "..fname.." aspect="..aspect.."\r\n")
 local w = minfo.Video.Width
 local h = minfo.Video.Height

 -- この機種ではサイズによりアスペクト比を判定しているみたいなので
 -- mpeg2 のサイズとアスペクト比を固定にする。
 w = "720" h = "480"
 local vfs0 = "scale="..w..":"..h
 if aspect ~= "1.778" then
  local sw = w
  local sh = h
  if tonumber(aspect) < 1.778 then
    sw = math.floor(w / 1.778 * aspect + 0.5)
  else
    sh = math.floor(h * 1.778 / aspect + 0.5)
  end
  vfs0 = "scale="..sw..":"..sh..",expand="..w..":"..h
  aspect = "1.778"
 end


 local vfs = vfs0 .. ",pp=l5,harddup"

 -- DVD ISO
 if minfo.General.Format == "ISO DVD" then
  if minfo.DVD.ALANG.en and minfo.DVD.SLANG.ja then
   local ret=""
   local i=1
    -- 英語音声と日本語字幕がある場合
     for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "en", "ja")
   end
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "ja", "none")
   end
   return ret
              
  elseif minfo.DVD.ALANG.ja and minfo.DVD.ALANG.en and minfo.DVD.SLANG.en then
   local ret=""
   local i=1
   -- 英語音声と英語字幕がある場合
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "en", "en")
   end
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "ja", "none")
   end
   return ret

  else
   local ret =""
   --チャプタ30個つくってみた
   for i=1,30 do
    ret =  ret .. DVDISO_Chapter(aspect, vfs, i, "ja", "none")
   end
   
   return ret
  end


 --とりあえずトランスコード
 else
  return [[
   [$_name_$ (TRANSCODE to MPEG-PS)]
   mencoder "$_in_$" -o "$_out_$"
   -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf
   -vf ]]..vfs..[[ -srate 48000 -af lavcresample=48000
   -ofps 30000/1001 -channels 6
   -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=]]
   ..aspect
    end
end


--[[
 チャプタ番号を指定してDVD_ISOを表示
]]
function DVDISO_Chapter(aspect, vfs, i,  alang, slang)
 
 if slang == "none" then slang = alang .. " -forcedsubsonly " end
 return  "\n[$_name_$ " .. "Chapter_" .. i .. ":"..alang.."/"..slang.. "]\n"
   ..[[
      mencoder -dvd-device "$_in_$" dvd://$_longest_$ 
      -chapter ]]..i.."-"..i
      ..[[ -o "$_out_$" -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf
      -vf ]]..vfs..[[ -srate 48000 -af lavcresample=48000
      -ofps 30000/1001 -alang ]]..alang..[[ -slang ]]..slang..[[ -channels 6
      -lavcopts vcodec=mpeg2video:vrc_buf_size=1835:vrc_maxrate=9800:vbitrate=5000:keyint=18:vstrict=0:acodec=ac3:abitrate=192:aspect=]]
     ..aspect

end

コメント

最近のコメント

Threaded Recent Comments will be here.