2023年2月5日日曜日

やっとできたminiDVの取り込み

 2007年に撮影したminiDVテープ、撮影した日付と時間のファイルネームで、カットごとに1ファイルにすることができた。一本のテープになんと318カット、1カットあたり数秒しかない。

当時読んでいた雑誌で紹介されていた、一カットは7秒前後でカットせよ、繋がりを考えて撮影せよ、という「無編集一本撮り」を実践していたためで、そのまま再生するには良い撮り方だった。

が、わずか20年ほどでテープ媒体は駆逐され、録画はメモリーになり、318カットもある巨大ファイルでは編集時に不便なのでやり方を模索していたら先人が道を切り拓いていたのであった、ありがたや。

さてテープはあと80本以上あるわけだが、やるかなあ?

以下にパワーシェルのソースを置いておく。
----------

#SetAviDate.ps1

#[Version]

#  1.0

#[Released]

#  2015/02/13

#[Abstract]

#  MediaInfoコマンドから取得できる撮影日情報(Recorded_Dateの値)を使って、

#  ファイル名とファイルプロパティの作成日と更新日を変更します。

#[Usage]

#  PowerShell SetAviDate.ps1

#[Requirement]

#  Windows 7以降 (PowerShell 2.0以降)

 

#StrictModeをLatestに設定

Set-StrictMode -version Latest

 

#-------------------------------------------------------------------------

#設定

 

#★操作対象のファイルが格納されているディレクトリ(デフォルト)

[String] $targetDir = "D:\<Video Dir>";

 

#★操作対象のファイル拡張子

[String] $targetExt = ".avi";

 

#★MediaInfoコマンド(CLI版)のフルパス

[String] $mediaInfoCmd = "C:\MediaInfo_CLI_21.03_Windows_i386\MediaInfo.exe"

 

#MediaInfoコマンド実行時に指定する引数

[String] $mediaInfoArg = " --Inform=General;%Recorded_Date%";

 

#-------------------------------------------------------------------------

#関数

 

#MediaInfoコマンドを実行する関数

#引数

#  $strCmdArg : MediaInfoコマンドの引数

 

Function ExecMediaInfoCmd([String]$strCmdArg)

{

    $proc = [System.Diagnostics.Process];

    $pinfo = [System.Diagnostics.ProcessStartInfo];

 

    $pinfo = New-Object System.Diagnostics.ProcessStartInfo;

 

    #実行するコマンド名(cmd.exe, 環境変数ComSpecより取得)

    $pinfo.FileName = [System.Environment]::GetEnvironmentVariable("ComSpec");

    

    #コマンドの引数(実行コマンド名)

    $pinfo.Arguments = "/c " + $mediaInfoCmd + " " + $strCmdArg;

    

    #標準出力を受け取る場合はFalse

    $pinfo.UseShellExecute = $false;

    #標準出力を受け取る場合はTrue

    $pinfo.RedirectStandardOutput = $true;

 

    #コマンド実行

    $proc = [System.Diagnostics.Process]::Start($pinfo);

    

    #コマンド実行の完了を監視(500ミリ秒ごとにポーリング)

    While(! $proc.HasExited){

        #スリープ(500ミリ秒)

        Start-Sleep -m 500

    }

    

    $output = [String];

    #コマンドの標準出力

    $output = $proc.StandardOutput.ReadToEnd();

    $proc.WaitForExit();

    $proc.Close();

 

    Return $output;

}

 

#-------------------------------------------------------------------------

#メイン処理

 

#ApartmentStateにてSTAモードのチェック(.NET Frameworkオブジェクトを利用する前提)

[Boolean] $reRun = $false;

Switch($host.Runspace.ApartmentState){

    'STA' {

        #何もしない

    }

    'MTA' {

        #MTAモードの場合は、STAモードを指定して再実行

        $reRun = $true;

    }

    default {

        #STAモードでもMTAモードでもない場合はUnknown(デフォルト)

        If($PSVersionTable.PSVersion.Major -eq "2"){

            #PowerShell2.0の場合、デフォルトがMTAモードなのでSTAモードを指定して再実行

            $reRun = $true;

        }

    }

}

If($reRun){

    $ScriptPath = $MyInvocation.MyCommand.Path;

    Start-Process PowerShell.exe -ArgumentList "-sta $ScriptPath";

    Exit;

}

 

#.NET Frameworkのダイアログ関連オブジェクトの取り込み

Add-Type -AssemblyName System.Windows.Forms;

 

#外部コマンドのテスト

[String] $usageOutput = ExecMediaInfoCmd;

If($usageOutput -eq ""){

    "MediaInfoコマンドが不正です。CLI版を使っているか確認してください。";

}Else{

    #MediaInfoの引数を追加

    $mediaInfoCmd += $mediaInfoArg;

 

    #ディレクトリ選択ダイアログのオブジェクト取得

    [System.Windows.Forms.FolderBrowserDialog] $dialog = New-Object System.Windows.Forms.FolderBrowserDialog;

    #ダイアログへ説明を追加

    $dialog.Description = "変換対象ファイル({0})が格納されたディレクトリを選択" -f $targetExt;

    #新規ディレクトリ作成ボタンの表示設定(false:表示しない)

    $dialog.ShowNewFolderButton = $false;

    #初期選択ディレクトリを設定

    $dialog.SelectedPath = $targetDir;

 

    #ダイアログ選択結果からOKボタンをおした時のみ実行

    If($dialog.ShowDialog() -eq "OK"){

        #ダイアログで選択したディレクトリを操作対象ディレクトリに再設定

        $targetDir = $dialog.SelectedPath;

        #操作対象ディレクトリ以下のサブディレクトリを再帰的に対象ファイルを検索

        Get-ChildItem($targetDir) -Recurse | ForEach-Object {

            #拡張子名取得

            [String] $extName = $_.Extension;

            If($extName -eq $targetExt){

                #変更前のファイル名(フルパス)

                [String] $oldFilePath = $_.FullName;

                #ディレクトリ名取得

                [String] $dirName = $_.DirectoryName;

                #変更前のファイル名

                [String] $oldFileNameWoExt = [System.IO.Path]::GetFileNameWithoutExtension($_);

 

                #MediaInfoの実行とRecorded_Dateの取得(書式:「yyyy-MM-dd HH:mm:ss.000」)

                [String] $recordedTime = ExecMediaInfoCmd $oldFilePath;

                #改行コードを削除

                $recordedTime = $recordedTime -replace "[\r\n]","";

 

                If($recordedTime -eq ""){

                    "Recorded_Dateが取得できませんでした。対象ファイル:{0}" -f $oldFilePath;

                }Else{

                    #末尾「.000」を削除

                    $recordedTime = $recordedTime -replace "\.[0-9]+ *$","";

 

                    #変更後のファイル名(書式:「yyyy-MM-dd_HH-mm-ss.avi」)

                    [String] $newFileNameWoExt = $recordedTime -replace " ","_" -replace ":","-";

 

                    #ファイル名の変更前後で一致する場合は操作の対象外

                    If(! $oldFileNameWoExt.Equals($newFileNameWoExt)){

                        [String] $newFileName = $newFileNameWoExt + $extName;

                        [String] $newFilePath = $dirName + "\" + $newFileName;

 

                        #変更後ファイル名が存在する場合は操作の対象外

                        If(! (Test-Path -path $newFilePath)){

                            #ファイル名の変更

                            Rename-Item -Path $oldFilePath -newName $newFileName;

 

                            #ファイルの作成日と更新日を設定(書式:「yyyy/MM/dd HH:mm:ss」)

                            [String] $propTime = $recordedTime -replace "-","/";

                            Set-ItemProperty $newFilePath -Name CreationTime  -Value $propTime;

                            Set-ItemProperty $newFilePath -Name LastWriteTime -Value $propTime;

                        }

                    }

                }

            }

        }

    }

}

0 件のコメント: