このブログを検索

2011年2月26日土曜日

Everio の動画ファイル名(.mod)を 撮影日時+.mpg にする

あまりネタが無いので、2年近く前に作ったスクリプトを載せることにします。

今使っているビデオカメラは Victor GZ-MG275 という HDD ビデオカメラです。
SD画質で、撮影した映像は MPEG-2 ファイルとして保存されます。

さすがに、近頃の AVCHD カメラは綺麗で、残すならこれぐらい綺麗でないとと思うぐらいに差があります。SD と HD だから当たり前といえばそうですが、、。
ちょっと前までは、AVCHD カメラ買ったって PC が遅すぎて見るのがやっとで編集なんて再エンコードが長くて面倒くさいしと強がっていましたが、、、最新の MacBook Pro も Sandy Bridge 搭載で、エンコードなんかも劇的に早いんだろうなーと思うと、新しいマシンやカメラが欲しくなります。

話は元に戻りますが、Everio の映像は .mod というわけのわからない拡張子な上に、収録日付が同名の .moi というファイルに格納されており、付属ソフトを使わない人にとっては面倒くさいことこの上ありません。

私は付属ソフトなど使わずに、マシン(Mac)上で、ビデオカメラの映像ファイルをダイレクトにコピーする派なので、連番の .mod ファイルなどはめちゃくちゃ困ります。

困りごと

  1. ファイル名が連番で、撮影日付がわからない。
  2. 拡張子が .mod である。
  3. Mac だと、そのままでは MPEG-2 ファイル(音声AC3)は編集できない。


3 については先人が Everioの動画を MPEG4 にお手軽変換できるワークフロー などで公開されているので、それでよいとして、1 と 2 の簡単な解決策があまり提示されていません。というか見つけられませんでした。
なので、それを解決するために Automator スクリプトを作りました。


中身は Ruby なので、その部分だけでも Mac や Win でも動かせます。
ちなみに Automator 動かすと、コピー元とコピー先のフォルダを聞いてくるので、Everio の映像のルートフォルダを選択して、後はパソコン内蔵HDDもしくは外付けのHDDなどのコピー先フォルダを指定するだけです。

ここで示す Automator スクリプトでできること

  • コピー元フォルダからコピー先フォルダへ映像ファイルがコピーされる。
  • コピーする際にファイル名が撮影日時に、拡張子が .mpg に変わります。
  • 何度実行しても、既にコピーしたものはスキップするので、追加されたものだけがコピーされます。





require "fileutils"

APP_SAVE_EXT = ".mpg";
APP_MOI_EXT = ".MOI";
APP_MOD_EXT = ".MOD";

# .MOI ファイルから撮影日時の映像ファイル名を作成する
def getDateTimeFileName(strModPath_)
 if ( File::ftype(strModPath_) != "file" )
  return "";
 end
 # MODファイル名 から MOI ファイル名を作成
 strDir = File::dirname(strModPath_);
 strBaseName = File::basename(strModPath_, APP_MOD_EXT);
 strMoiPath = [strDir, strBaseName].join(File::SEPARATOR);
 strMoiPath += APP_MOI_EXT;
 if ( File::ftype(strMoiPath) != "file" )
  return "";
 end
 # MOI ファイルを開く
 fileMoi = File::open(strMoiPath, "rb");
 #fileMoi.binmode;
 # 読み飛ばす
 fileMoi.read(6);
 # 年月日を読み出す
 binData = fileMoi.read(2);
 nYear = binData.unpack("n")[0];
 binData = fileMoi.read(1);
 nMonth = binData.unpack("C")[0];
 binData = fileMoi.read(1);
 nDay = binData.unpack("C")[0];
 binData = fileMoi.read(1);
 # 時分秒を読み出す
 #   ただし、秒はミリ秒として格納されている
 nHour = binData.unpack("C")[0];
 binData = fileMoi.read(1);
 nMinute = binData.unpack("C")[0];
 binData = fileMoi.read(2);
 nMSec = binData.unpack("n")[0];
 nSecond = nMSec / 1000;
 nMSec %= 1000;
 # ここで文字列化しているので、好きなフォーマットにしてください。
 strDateTime = sprintf("%04d%02d%02d%02d%02d%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond);
 #print(nYear, "/" , nMonth, "/", nDay, " ", nHour, ":", nMinute, ":", nSecond, ".", nMSec);
 #puts strTime;
 strFileName = strDateTime + APP_SAVE_EXT;
 return strFileName;
end

# MOD を列挙してコピーする
def  copyModAsMpg(strSrcDir, strDestDir)
 # MOD を列挙する
 strSearch = [strSrcDir, "*" + APP_MOD_EXT].join(File::SEPARATOR);
 Dir::glob(strSearch).each {|strFileMod|
  strFileMpg = getDateTimeFileName(strFileMod);
  if ( FileTest.file?(strFileMpg) and  File::size(strFileMod) <= File::size(strFileMpg))
   puts("skip : " + File::basename(strFileMod) + " -> " + File::basename(strFileMpg));
  else
   puts("copy : " + File::basename(strFileMod) + " -> " + File::basename(strFileMpg));
   FileUtils.cp(strFileMod, strFileMpg);
  end
 } 
end

#メイン処理
if ( 2 <= ARGV.length )
 strSrcDir = ARGV[0];
 strDestDir = ARGV[1];
 if ( File::ftype(strSrcDir) != "directory" )
  print(strSrcDir, "はディレクトリではありません");
 elsif ( File::ftype(strDestDir) != "directory" )
  print(strDestDir, "はディレクトリではありません");
 else
  copyModAsMpg(strSrcDir, strDestDir);
 end
else
 puts("引数が足りません");
end

2 件のコメント:

  1. こんばんは。ファイル名の不便さに疲れてこちらにたどり着きました。
    あまりPCに詳しくないのですが、Automatorはダウンロードさせていただけないのでしょうか?

    返信削除
    返信
    1. Automater とは、MacOS X に標準で付属しているものです。Windowsであれば、コマンドラインから 「ruby スクリプト名 コピー元フォルダ コピー先フォルダ」として実行します。

      削除