BMS MODを使ってみた ~REGZA ZP2編~

あまりREGZAのDLNAで再生をしていないので放っておいたのですが、BEER Media ServerのMOD版ができているようなので試してみました。
 
とりあえずREGZA ZP2で動くようにしてみました。


BEER Media ServerとREGZAの組み合わせの問題点はトランスコード再生をしているとREGZAが反応しなくなる事でした。これはBMSが応答しなくなってしまうのが原因のようですが、どっちが悪いのかはわかりませんでした。そしてBMSのMOD版を作られた方はいろいろDLNAの応答を見ながら改善されているようです。もしかしたらREGZAで応答しなくなる問題も直ってるかもしれません。ざっくり試してみることにしました。

以前に紹介していたREGZA用luaファイルですが、そのままではうまく動かない感じでした。MOD作者様のサンプルluaである”MPEG_PS_NTSC.lua”をそのまま使うとtsファイルが表示されません。というか、手元でまともに再生できるファイルがありませんでした。もう少しまじめにREGZA用ファイルを作らなくてはいけないようです。

そこで、MOD作者様のサンプルluaである”MPEG_PS_NTSC.lua”のフレームの中にREGZA用に作った部分を入れました。これで、tsファイルやMP4のトランスコード再生はできるようになりましたが、ISO DVDだけはうまく再生できませんでした。エラーにはなりませんが、音声だけ流れ画面が真っ黒な状態です。

何かが足りないようなので、mencoderオプションでscale,expandとaspectの設定を追加したところ画面が表示されました。30秒スキップもできてます。

あまり試していませんが、BMSがフリーズする事も無くなったみたいです。これはいいかも。
BMS作者様 MOD作者様 ありがとうございます。
(フリーズしないけど落ちる事はあります。原因不明・・・)

ということで、MOD10対応のREGZA-ZP2用Luaファイルをさらしておきます。
6月8日変更点
ファイルリストの表示が少しでも速くなれば・・・と、GetMimeType 関数を大幅に変更。速くなった気はしない。
"MimeTypeString"にキーを追加していくと対応ファイルを増やせる可能性がある。現在対応していないメディアはログに"★登録されていないメディア"と表示する。

6月9日変更点
GetTranscodeCommand関数をざっくりとシンプルな構成にしました。音声用トランスコード設定は消してしまいました。REGZA ZP2では解像度が合ってないと画面が黒くなったままです。音だけ出ます。800x600を超える解像度でトランスコードしても画面が表示されませんでした。プレビューでは表示されてるのになぁ。解像度の低いほうは720x480にしないと表示されない感じでした。
また、QSVエンコードがうまく動きません。VIERAでもダメです。

6月15日変更点
BMS Mod13で動作確認。MP4トランスコード時の解像度1280x720まで確認。1440x1080とかは画面が黒いままになる。サイズとアスペクト比指定をvf に移動すると画面は黒いままだが画面表示で映像形式を表示するようになった。30秒送りがうまく動かないものもあるようだが詳細不明。res@指定をつけると動画を認識しない模様。

6月16日変更点
トランスコードのffmpegオプションにvsyncとasyncを指定すると30秒スキップで音ずれしなくなった。vsyncでは映像のカクツキが見えるのでasyncにした。そのため音声が途切れ途切れに同期される。スキップしまくるとトランスコードが停止する事もある。


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

REGZA-ZP2.lua


-[[
REGZA ZP2用スクリプト
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://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"
}

local UseQSV = false --うまくいかない
local ConvertAudioToVideo = true
local DVDSelectTitle = true
local DVDSelectChapter = true
local DVDSelectAudio = true
local DVDSelectSubtitle = true

--フォーマット毎の配列を作る
--minfo.General.Format minfo.Video.Format minfo.Audio.Format minfo.Audio.SamplingRatをキーとしている
local MimeTypeString={}
--動画
MimeTypeString["MPEG-TS/MPEG Video"] = "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01;DLNA.ORG_CI=0"
MimeTypeString["MPEG-PS/MPEG Video"] = "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=01"
if UseQSV then
 MimeTypeString["MPEG-4/AVC"] = "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
 MimeTypeString["MPEG-4/MPEG-4 Visual"] = "video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_24_AC3_T:::TRANS:::"
else
 MimeTypeString["MPEG-4/AVC"] =  "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
 MimeTypeString["MPEG-4/MPEG-4 Visual"] = "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
end
MimeTypeString["ISO DVD/ISO DVD Video"] = "video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=10;DLNA.ORG_CI=0:::TRANS:::"
--音声
MimeTypeString["Wave/PCM/48000"] = "audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM"
--画
MimeTypeString["JPEG"] = "image/jpeg:DLNA.ORG_PN=JPEG_MED"


--[[
 GetMimeType 関数

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

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

 --local MimeTypeString=MimeTypeString
 local minfo = minfo

 --メディアではない?
 if not (minfo.Video or minfo.Audio) then
  return ""
 end

 local ret
 if minfo.Video.Format == "" then
  if minfo.Audio.Format == "" then
   --画
   ret = MimeTypeString[minfo.General.Format]
  else
   --音声
   ret = MimeTypeString[minfo.General.Format.."/"..minfo.Audio.Format.."/"..minfo.Audio.SamplingRate]
  end
 else
  --ビデオ
  ret = MimeTypeString[minfo.General.Format.."/"..minfo.Video.Format]
 end

 if ret then
  return ret
 else
  print("★登録されていないメディア:".. minfo.General.Format.."/"..minfo.Video.Format.."/"..minfo.Audio.Format)
  return ""
 end

end


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

 引数:
   fname: ファイル名
   minfo: MediaInfo.dll などから得られた情報
]]
function GetTranscodeCommand(fname, minfo)
 local ext = string.lower(tostring(minfo.General.FileExtension))
 
 local minfo = minfo
 --メディアか否かのチェックはGetMimeTypeで行われているので省略

 local w,h,ret
 w, h = 720, 480
 ret=""
 if minfo.Video.Format == "" then
  if minfo.Audio.Format == "" then
   --画
   ret = ""
  else
   --音声
   ret = ""
  end
 else
  --ビデオ
  if minfo.General.Format == "ISO DVD" then
   ret = GetDVDCommands(fname, minfo)
   return ret
  end

  local w = tonumber(minfo.Video.Width)
  local h = tonumber(minfo.Video.Height)
  local aspect = "16:9"
 
  if tonumber(minfo.Video.DisplayAspectRatio) > 1.6 then
   --16:9の場合
   if w<=720 then 
    w, h = 720, 480
    aspect = "16:9"
   elseif w<=800 then
    w, h = 800, 600
    aspect = "16:9"
   elseif w<=1280 then
    w, h = 1280, 720 --30秒スキップできない
    aspect = "4:3"
   else
    w, h = 1280, 720 --解像度を上げられない
    aspect = "4:3"
   end
  else
   --4:3の場合
   if w<=720 then 
    w, h = 720, 480
    aspect = "4:3"
   elseif w<=800 then
    w, h = 800, 600
    aspect = "4:3"
   elseif w<=1280 then
    w, h = 1280, 720
    aspect = "4:3"

   else
    w, h = 1280, 720  --解像度を上げられない
    aspect = "4:3"
   end
  end

  local vbitrate
  if w > 720 then
   vbitrate = w * h * 8  -- 1920x1080(16.5Mbps) 1440x1080(12.4Mbps) 1280x720(7.3Mbps)
  else
   vbitrate = w * h * 16 -- 720x480(5.5Mbps) 640x480(4.9Mbps) 704x396(4.4Mbps)
  end

  local b_cmd = " -b "..tostring(vbitrate)
  local vf_cmd = " -vf scale="..w..":"..h..",setdar="..aspect
  if minfo.Video.ScanType == "Interlaced" then
  vf_cmd = vf_cmd..[[,yadif=0:-1]]
  end

  local video_cmd = " -vcodec mpeg2video -r 30000/1001 -threads 4 -thread_type frame"..b_cmd..vf_cmd
  local audio_cmd = " -acodec ac3 -ac 2 -ar 48000 -ab 192k -async 1"
  --local audio_cmd = " -acodec libfaac -ac 2 -ar 48000 -ab 192k -async 1"
  local format_cmd = " -f mpegts -mpegts_m2ts_mode 1 -map 0:0 -map 0:1"

  ret = [[
  [$_name_$]
  ffmpeg $_ff_ss_$ $_ff_t_$ -i "$_in_$" ]]..video_cmd..audio_cmd..format_cmd..[[ -y "$_out_$"
  ]]
      end
  return ret
end


function GetDVDCommands(fname, minfo)
  local ini = {}
  local dvd = minfo.DVD
  if dvd == nil then return "" end
  
  local longest_title = tonumber(dvd.LONGEST_TITLE)
  local title_count = tonumber(dvd.TITLE_COUNT)
  if longest_title == nil or title_count == nil then return "" end
  
  local title_range = {}
  if DVDSelectTitle then
    if longest_title == 1 then
      title_range = { {from=1, to=title_count} }
    else
      title_range = { {from=longest_title, to=longest_title}, {from=1, to=title_count} }
    end
  else
    title_range = { {from=longest_title, to=longest_title} }
  end
  
  local chapter_count, audio_count, subtitle_count = 1, 1, 0
  for i, range in ipairs(title_range) do
    for t = range.from, range.to do
      local title = "TITLE"..tostring(t)
      if dvd[title] then
        if DVDSelectChapter  then chapter_count  = tonumber(dvd[title].CHAPTER_COUNT)  end
        if DVDSelectAudio    then audio_count    = tonumber(dvd[title].AUDIO_COUNT)    end
        if DVDSelectSubtitle then subtitle_count = tonumber(dvd[title].SUBTITLE_COUNT) end
        for c = 1, chapter_count do
          for a = 1, audio_count do
            for s = 0, subtitle_count do -- if s == 0 then nosub
              if not DVDSelectChapter  then c = nil end
              if not DVDSelectAudio    then a = nil end
              if not DVDSelectSubtitle then s = nil end
              table.insert(ini, GetDVDIniSectionName(dvd, t, c, a, s))
              table.insert(ini, GetDVDIniCommandLine(dvd, t, c, a, s))
            end
          end
        end
      end
    end
  end
  
  return table.concat(ini, "\r\n")
end

function GetDVDIniSectionName(dvd, t, c, a, s)
  local secname = {}
  local title     = "TITLE"   ..tostring(t)
  local chapter   = "CHAPTER" ..tostring(c)
  local audio     = "AUDIO"   ..tostring(a)
  local subtitle  = "SUBTITLE"..tostring(s)
  
  if DVDSelectTitle then
    table.insert(secname, title)
  end
  if c and dvd[title][chapter] then
    table.insert(secname, chapter)
  end
  if a and dvd[title][audio] then
    table.insert(secname, audio)
    table.insert(secname, dvd[title][audio].LANGCODE)
  end
  if s and s == 0 then
    table.insert(secname, "NOSUBTITLE")
  elseif s and dvd[title][subtitle] then
    table.insert(secname, subtitle)
    table.insert(secname, dvd[title][subtitle].LANGCODE)
  end
  
  if table.maxn(secname) == 0 then
    table.insert(secname, title)
  end
  
  return "["..table.concat(secname, "_").."]"
end

function GetDVDIniCommandLine(dvd, t, c, a, s)
  local title     = "TITLE"   ..tostring(t)
  local chapter   = "CHAPTER" ..tostring(c)
  local audio     = "AUDIO"   ..tostring(a)
  local subtitle  = "SUBTITLE"..tostring(s)
  
  local title_cmd = tostring(t)
  local chapter_cmd = ""
  if c and dvd[title][chapter] then
    chapter_cmd = " -chapter "..tostring(c)
  end
  local audio_cmd = ""
  if a and dvd[title][audio] and dvd[title][audio].AVAILABLE == "1" then
    audio_cmd = " -aid "..dvd[title][audio].STREAMID
  end
  local subtitle_cmd = ""
  if s and s == 0 then
    subtitle_cmd = " -forcedsubsonly"
  elseif s and dvd[title][subtitle] and dvd[title][subtitle].AVAILABLE == "1" then
    subtitle_cmd = " -sid "..tostring(tonumber(dvd[title][subtitle].STREAMID) - 0x20)
  end
  
  return [[]]
  ..[[
    mencoder -quiet $_me_ss_sb_$ $_me_endpos_$ -dvd-device "$_in_$" dvd://]]..title_cmd..[[ -o "$_out_$"
    ]]..chapter_cmd..audio_cmd..subtitle_cmd..[[ -lavdopts threads=2
    -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
  ]]
end

コメント

最近のコメント

Threaded Recent Comments will be here.