MiniDV形式ビデオテープを撮影日時つきファイルでバックアップ[PowerShell版]
公開日 更新日 2016/02/14
去年からちょいちょいPowerShellを使い出しました。
勉強の一環で、ちょっとしたツール開発を通じてのPowerShell入門中です。
今回はこちらの記事(MiniDV形式ビデオテープを撮影日時ファイルでパソコンにバックアップ)で作った、ビデオテープをバックアップするツールを題材にして、すべてPowerShellで作りなおしてみました。
また、今回さらにPowerShellがBATファイルよりも強力で複雑な処理もできるため、単に作りなおすだけではなくもう少し凝ったこともやってみました。
Contents
ツールの背景
ツール開発に至った背景は関連記事と同じで、リンク先に詳しく書きましたので良かったらこちらもご覧ください。
簡単に並べるとこんな感じです。
- 自力でMiniDVテープをバックアップする需要があった。
- カメラにバンドルされていた純正のバックアップツールだと、ファイル名とプロパティの設定が撮影日を元に作ってなかった。
- とはいえ純正ツールのバックアップファイルには撮影日情報が格納されてあり、これを確認できるツールが見つかった。
- 以上の経緯でファイル名とプロパティを書き換えるツールを作成!
PowerShell版のツールについて
関連記事の元々のツールは「取りあえず動くもの」としてBATファイルで作ったものです。
しかしながら、結局ファイルのWindowsプロパティがどうしてもPowerShellで記述しないといけなくなり、そのときも一部PowerShellを織り交ぜた作りになっています。
一部でもPowerShellを使っているのであれば、いっその事ぜんぶPowerShellでつくろう!と思いたち作り変えることにしました。
今回PowerShellの入門という位置づけなので、単に書き直すだけでも良いのですが、改良点を盛り込みます。
ダイアログで変換対象のディレクトリを指定する
BATファイルだった時から気になってたのですが、ツールの中にディレクトリ名を書き込むという作りだったので、変換したいディレクトリがたくさんあった場合に、ツールを実行する毎、ディレクトリ名を書き換えないといけないため、かなり面倒でした…。
そこで、こちらの記事にあるディレクトリの選択ダイアログを活用してわざわざ作り変える手間を撤廃してみました。
サブディレクトリも再帰的に実行する
ファイル・ディレクトリの操作は、PowerShellの強みの一つです。
ディレクトリを指定して、そのさらに下に続く全てのディレクトリ一式を変換対象とするのはお約束だと思いますので、当然盛り込みました。
さすがに深いディレクトリ構造でビデオを格納する使い方は稀だとは思いますが、BATファイルで実現しなかった自己満足として、再帰的に走査するという作りにしてみました。
ソースコード(PS1コード)
今回作ったPowerShellファイルを掲載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
#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 Install Dir>\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; } } } } } } } |
外部コマンド実行について(補足)
PowerShellでの外部コマンド実行は難易度が高いようで、Web検索するといくつか似たサンプルコードが見つかります。
今回は以下のサイトで公開されているコードを参考にさせていただきました。
- Hello, world!さん
PowerShellでコマンドの実行結果を取得する
ツールの使い方
※念のためテスト用にビデオのコピーを格納したディレクトリを用意することで、きちんと動作することを確認して下さい。
- PS1ファイル中の★箇所を書き換える。以下3箇所。
- 21行目の「D:\<Video Dir>」
変換したいファイルが格納されているドライブ/ディレクトリにします。
これはディレクトリの選択ダイアログに表示されるデフォルト値であり、実行時に変更できます。 - 24行目の「.avi」
変換したいファイルを一覧できる表記にします。ここでは拡張子.aviのファイルを一覧にしてます。 - 27行目の「C:\<MediaInfo CLI Install Dir>」
MediaInfoファイルをインストールしたドライブ/ディレクトリにします。
- 21行目の「D:\<Video Dir>」
- 変換したいファイルを、1番の21行目で指定したドライブ/ディレクトリに格納する。
- ツール(PS1ファイル)を右クリックメニューから「PowerShellで実行」を選択する。
- 表示されるダイアログにて、変換対象のファイルが格納されているディレクトリを選択する。
最後に
個人的には今のところBATファイルで変換すべきビデオはひと通り変換が完了していて、それ以来の本ツール本格活用はしてません。
あくまでPowerShellでの勉強用途および機能拡充が目的でした。
本当はMediaInfoにはもっと多くの情報が詰まっていて、再度、変換する契機はある気がしたのですが、未だ沈黙を守っています。
ツール作成による効果は不明ですが、PowerShellの勉強として最近学んだ事柄をひと通り試せたので良しとします。
レスポンシブ広告
関連記事
-
PowerShellの開発速度の改善を考える
私はどちらかというとWindowよりもUNIXの方がなれてますが、仕事ではWin …
-
MiniDV形式ビデオテープを撮影日時つきファイルでバックアップ
我が家では旅行や行事など、ホームビデオの撮影ペースが毎月それなりにあります。 3 …
-
デジタルビデオカメラに広角レンズを取り付ける
我が家で使っているビデオカメラは、2009年製のSonyハンディカムHDR-CX …
-
.NETダイアログが表示されずスクリプトが止まる問題の対策
PowerShell入門中です。 先日のこちらの記事(PowerShellでダイ …
-
PowerShellスクリプトを動かすための設定
PowerShellは最近のWindowsで追加されたスクリプト言語で、今のWi …
-
PowerShellでダイアログを表示し入力結果を取得
PowerShellの入門中です。 今回はPowerShellスクリプトからのW …
Comment
はじめまして。
昔のデジカメで撮ったビデオをリネームしようとしたのですが、
撮影日の情報書式が違うため、プログラムが途中で止まってしまいます。
何度やっても「Recorded_Dateが取得できませんでした。」となってしまいます。
以下のように対応しているのですが、お時間があればアドバイスお願いします。
30行目 Recorded_Date を Mastered_Date に修正
139行目 撮影日の書式の整形方法がうまくいかない
DDの後の”/ ” の変換
SSの情報がない
以下 私の機種のInformです。
General
Complete name : D:\EXCILM\CIMG0158.AVI
Format : AVI
Format/Info : Audio Video Interleave
File size : 17.4 MiB
Duration : 14 s 948 ms
Overall bit rate : 9 791 kb/s
Mastered date : 2009/09/21/ 17:08
Writing application : CASIO EX-Z400
Writing library : QVMI
追伸です。
139行目の書式の整形については、BATファイルの方で解決しました。
次は、30行目の撮影日の取得にトライしたいと思います。(これもBATのほうで。)
荒川さん、はじめまして
当サイトを管理してますbeyondです。
ご連絡が遅れてしまいましたが申告いただいた症状を拝見させていただきました。
使ったことのないSONY以外の機器のため解決できるか自信がないのですが
またBATファイルでということですでに解決に向けて進んでいるかもしれませんが、
気になったところを以下に3点まとめます。
1) MediaInfoコマンドがちゃんと応答を返すか確認
スクリプトからは、次のような使い方でMediaInfo.exeを実行していますので
コマンドプロンプトで、このコマンドをそのまま実行することで期待する結果が出せているのかを確認できます。
その際、項目名としてMastered_Dateを指定します。
MediaInfo.exe --Inform=General;%Mastered_Date% 解析対象のAVIファイル
この結果に日時を示す文字列が返ってくるかどうかがポイントです。
参考にならないかもしれませんが、SONYのビデオで保存したAVIファイルの場合は次のような出力になります。
MediaInfo.exe --Inform=General;%Recorded_Date% 解析対象のAVIファイル
2004-03-14 15:15:12.000
2) スクリプトの修正箇所
間違っている可能性があるのですが、Mastered_Dateに対応させるための変更箇所を以下に並べます。
①30行目のMediaInfoコマンドの引数 ※ご連絡いただいた箇所です
【変更前】
#MediaInfoコマンド実行時に指定する引数
[String] $mediaInfoArg = " --Inform=General;%Recorded_Date%";
【変更後】
#MediaInfoコマンド実行時に指定する引数
[String] $mediaInfoArg = " --Inform=General;%Mastered_Date%";
②146行目付近の日時の書式変換処理 ※ファイル名に使えない文字を置き換える処理です
【変更前】
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($recordedTime -eq ""){
"Recorded_Dateが取得できませんでした。対象ファイル:{0}" -f $oldFilePath;
}Else{
#変更前の日時「yyyy/MM/dd/ HH:mm」)
#変更後の日時「yyyy-MM-dd_HH-mm」)
[String] $newFileNameWoExt = $recordedTime -replace "/ ","_" -replace "/","-" -replace ":","-";
※最初に”/ “の2文字を”_”に変換しているところがポイントです。
3) もしかするとファイルの重複が起きるかもしれません
これはMediaInfoとは関係がないのですが
Mastered_Dateに秒の情報がないとすると、1分以内に2枚以上撮影していた場合、ファイル名の変換をすることで重複するファイル名となってしまい、エラーメッセージを出すと思います。
今のスクリプトでは同一日時の撮影には対応してないのですが、簡単に済ますとしたらカウントアップする変数を使って無理やりファイル名をユニークにするという案があります。
以上です。よろしくお願いします。
はじめまして。丁寧にありがとうございます。
早速コマンドプロンプトで確認しましたところ、文字列が取得できませんでした。
そもそもMediainfoが認識されていないということでしょうか?
CLI版で一瞬開いて消えるという状況は確認できているのですが。
MediaInfo.exe –Inform=General;%Mastered_Date%D:\EXCILM\CIMG0237.AVI
‘MediaInfo.exe’ は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
プログラミングに疎いのですが、最初にcdでディレクトリの指定とか必要なのでしょうか?
何度もすいません。
コマンドプロンプトについて少し調べ、
MediaInfo.exeの格納場所を、ユーザーフォルダに変更したところ、実行できるようになりました。
ところがInform-Parameters で一覧は取得できるのですが、Mastered Dateが取得できません。
そこで–Help等で調べていくと、現在のMediaInfoでは、Optionに InformがなくOutputになっているらしいことや、%Mastered Date%の後ろにスペースが必要なことがわかりました。
その結果、なんとか以下の命令で、日付を取得できることができました。
MediaInfo.exe –Output=General;%Mastered_Date% D:\EXCILM\CIMG0237.AVI
2009/09/26/ 13:55
時間がなく、少しづつですが、進捗していることをお伝えしておきます。
荒川さん
先に進んでいるようで安心しました!
私が昨日試したのは、MediaInfo CLI v17.12ですが、–Informオプションは動作しておりましたが、たしかに–helpオプションではリストされてません。
試しに私も「–Output=General;%Recorded_Date%」でSONYビデオで撮影したAVIファイルを解析したところ、–Inform同様の結果になりました。
さらにソースファイルも恐る恐るのぞいてみたところ、斜め読みですが–Informと–Outputは同じ動作になるような気がしました。(CommandLine_Parser.cppというファイルを見ました…)
何はともあれ、先に進んで私もとてもうれしいです。応援しております。(^^)
荒川さん
文字列が取得できない件ですが、
メッセージ「‘MediaInfo.exe’ は、内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして認識されていません。」
はcd等でディレクトリを合わせなかった時の症状にそっくりです。
ご推察の通りで「コマンドをそのまま実行」という返信のシンプルすぎな表現だったところが反省点ですね。
簡単にお伝えするいい方法がないかと考えてみたのですが↓こういうのはいかがでしょう?
1) コマンドプロンプトを開く
2) コマンドプロンプトとは別に、エクスプローラーでMediaInfo.exeファイルのあるフォルダを開き、MediaInfo.exeファイルをコマンドプロンプトの黒いエリアへドラッグ&ドロップする。
3) するとコマンドプロンプトの画面にドライブ番号から始まる絶対パスでMediaInfo.exeのコマンド名が表示される!
4) 続けてキーボードでMediaInfoコマンドのための引数を付け足すようにタイプしてあげて
「<MediaInfo.exeのパス表記> –Inform=General;%Mastered_Date% 」というコマンド文にする。 ★最後にスペースを1文字入れるところを忘れずに。
5) さらに、エクスプローラーで解析対象のAVIファイルがあるフォルダを開き、MediaInfo.exeと同じようにAVIファイルをコマンドプロンプトの黒いエリアへドラッグ&ドロップする。
6) するとコマンド文の末尾にAVIファイルの絶対パスで表示される!
7) 最後にENTERキーを押してコマンド文を実行する。
入れ違いになってしまいましたが、返信ありがとうございます。
なるほど。ドラッグ&ドロップができるんですね。知りませんでした。
コピー&ペーストで苦労してました。これでもっと早く進めていけそうです。
おかげさまで無事リネーム完了しました。
秒の情報がありませんでしたが、幸い同じ分のものがなかったので、末尾に「:00」をつけることで処理しました。
次々にファイルがリネームされていくのを見たときは感動しました。
本当にアドバイスありがとうございました。
荒川さん
おめでとうございます!
SONYのビデオしか試したことがなかったのですが、CASIOのビデオでもうまく動作できてよかったです。
こんなにうまくいくなんてさすがMediaInfo。
秒のところの重複があると面倒だったのですが、写真と違いビデオはずっと撮影するわけだし、冷静に考えると普通のビデオであれば秒はなくても大丈夫ですね。
また機会があればよろしくお願いします。
先日はアドバイスありがとうございました。
次は昔MacでPCに取り込んでいたmovファイルと格闘しています。
MP4に変換しつつ、日付を揃えたいというものです。
現在考えている手順は以下のとおりです。
1)該当ファイルについて、beyondさんのプログラムでファイル名と作成日、更新日を揃える。
2)YYYY-MM-DD_ HH-MM-SS.movというファイルをHANDBREAK等の変換ソフトでmp4形式に変換する。この時点で作成日、更新日が、変換時点のものになる。
3)ファイル名の日付情報を取得し、作成日および更新日を、同じ時刻に変更する(=元に戻す)
という考えのもと、手順3のプログラムを手順1のスクリプトを利用して作成すれば、なんとかできるのではないか?と構想しています。
MediaInfoに関する命令を、ファイル名取得の命令に置き換えることで達成できますでしょうか?
荒川さん
HANDBREAKというツールはこちらのサイトで公開されているツールであってますでしょうか?
https://handbrake.fr/
多分これだと思いドキュメントを見てみたところこちらのページにコマンドラインの説明がありました。 Set destination file name
https://handbrake.fr/docs/en/1.0.0/cli/cli-guide.html
> -o, –output
mov形式のファイルが手元になくてすぐ試せてないのですが、この-oオプションに任意の出力ファイル名を指定できるようです。
これをWindowsのBatファイルを活用するとできる気がしました。
例えばこんなイメージです
—–
@echo off
for %%i in (*.mov) do (
echo handbrake -i %%~fi -o %%~dpni.mp4
)
—–
<実行結果>
handbrake -i c:\test.mov -o c:\test.mp4
もしかすると詳しく調べていくと、handbrake自身に同様のことができる機能があるのかもしれません。
すいません。書き方が良くなかったみたいです。
手順として1→2→3と進め、それぞれで異なるツールを使おうかと。そうすると、手順3では対象ファイルのファイル名から、BAT又はpowershllだけで、作成日や更新日を元に戻せることが完結できるかなと考えた次第です。
荒川さん
整理させてください。
↓であっておりますでしょうか。
– 手順1でmov形式のファイルからMediaInfoを使って日時情報を取り出せた
– 手順2で変換した時の日時も残したい
– また、手順2で得られるmp4ファイルを残しつつ、手順1の日時を使ってコピーしたmp4も作りたい
手順1が出来ている前提ですが、もう少し見てみます。
荒川さん
movファイルは持ってないため手元にあるSONY製ハンディカムから取り込んだaviファイルを使ってhandbrakeを実行してみました。
handbrake -i c:\sample.avi -o c:\test.mp4
これで得られたtest.mp4ファイルですが、残念ながらMediaInfoで確認すると、撮影日時は引き継がれていませんでした。
そのため、handbrakeで得られたmp4ファイルに何とかしてaviファイルの撮影日時を使ってファイル名を与えないといけないようです。
変換日時は「今」の時刻でよいはずなので、例えば手順2の変換日時を最後の手順に変えると比較的容易に実現するのですが、こんな感じでどうでしょうかね
@echo off
for %%i in (*.mov) do (
set movfile=%%~fi
set mp4file=%%~dpni.mp4
echo handbrake -i %movfile% -o %mp4file%
set time2=%time: =0%
set convfile=%date:~0,4%-%date:~5,2%-%date:~8,2%_%time2:~0,2%-%time2:~3,2%-%time2:~6,2%.mp4
echo copy %mp4file% %convfile%
)
<実行結果>
C:>test.bat
handbrake -i C:\2001-03-09_00-27-46.mov -o C:\2001-03-09_00-27-46.mp4
copy C:\2001-03-09_00-27-46.mp4 2018-03-09_00-27-46.mp4
調べていたいたようで大変恐縮です。
手順1で、MediaInfoから取得した日時情報を使ってリネームし、ファイル作成日・更新日も変更したmovファイルにしておきます。
手順2は、手順1でリネームしたmovを、HandbrakeでMP4に変換します。この時にご確認いただいた通り、撮影日情報が失われてします。したがって事前に手順1でリネームしたファイル名称が撮影日の唯一の情報になります。
手順3で、撮影日がファイル名となっているMP4ファイルについて、変換日となっているファイル作成日・更新日を、撮影日にするというものです。
最後に残したいのは、ファイルの名称、作成日・更新日が、変換前の撮影日情報になったMP4
ファイルで、変換日は残さなくても良いと思っています。
変換しなくてはいけないが、そこで撮影日情報が引き継ぎされず失われてしまうので、ファイル名称に手掛かりを残しておけばと、考えた次第です。
beyondさん
MP4変換後のファイルの作成日。更新日を撮影日に変更する件ですが、
beyondさんのプログラムから、
MediaInfo関連と思われる行を削除し、
ファイル名を取得する部分がありましたので、そこからRecorded_timeを設定し、
ファイルの作成日、更新日を、ファイル名の日付に変更することに成功しました。
全く基礎も身についておらず、見よう見まねでなんとかここまできました。
以下がスクリプトですが、参考までに無駄な部分とかありますでしょうか?
後学のためにアドバイスいただければと思います。
———————–
#Setmp4Date.ps1
#[Version]
# 1.0
#[Released]
# 2018/03/09
#[Abstract]
# YYYY_MM_DD HH-MM-SSのファイル名を使って、
# ファイルプロパティの作成日と更新日を変更します。
#[Usage]
# Setmp4Date.ps1
#[Requirement]
# Windows 7以降 (PowerShell 2.0以降)
#StrictModeをLatestに設定
Set-StrictMode -version Latest
#————————————————————————-
#設定
#★操作対象のファイルが格納されているディレクトリ(デフォルト)
[String] $targetDir = “D:\”;
#★操作対象のファイル拡張子
[String] $targetExt = “.mp4”;
#————————————————————————-
#メイン処理
#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;
}
}
}
#.NET Frameworkのダイアログ関連オブジェクトの取り込み
Add-Type -AssemblyName System.Windows.Forms;
#ディレクトリ選択ダイアログのオブジェクト取得
[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($_);
#変更前のファイル名をRecorded_Dateに取得(書式:「YYYY_MM_DD HH-MM-SS」)
[String] $recordedTime = $oldFileNameWoExt;
#ファイルの作成日と更新日を設定(書式:「yyyy/MM/dd HH:mm:ss」)
[String] $propTime = $recordedTime -replace “_”,”/” -replace “-“,”:”;
Set-ItemProperty $oldFilePath -Name CreationTime -Value $propTime;
Set-ItemProperty $oldFilePath -Name LastWriteTime -Value $propTime;
}
}
}
荒川さん
変換日時を残すことは不要であること、ファイルのプロパティにあるファイル作成日・更新日へ日時情報として残したいこと
この2点がずれてしまってたんですね。
そして返信が遅れましたが既に修正コードを作成いただいており素早いですね。
拝見させていただいたところ、私からは特にコメントすべきことはなさそうです。
プロパティの設定に関しては重複によるエラーは起きないはずで、チェック処理も不要だしこのままで問題ないと思います。
# もともとのツールを読み返してみるとファイル名の変換とファイルのプロパティの変換を同時にやるという仕組みですが、
# 荒川さんのようにどちらか片方でよい場合もあるし、時間を見てもう少し改善したほうがよい気がしました。
beyondさん
確認ありがとうございます!
今回、たまたま拡張子が違うものでしたので、
対象拡張子をダイアログで選択もしくは入力できるようにできたらいいなと感じました。
何度もすいません。
beyondさんのプログラムで,過去の様々な動画ファイルを同じように整理しています。
次に検討しているのが、movファイルを対象に、
ファイルのプロパティの撮影日時のデータを用いて、
ファイル名をYYYY_mm_SS HH-MM-SSに変更しようと思っています。
MediaInfoでは撮影日時が見つからす、プロパティの作成日時がそれに該当すると思われるからです、
Item Property の CreationTime を取得すれば良いと思うのですが、
どのような命令にするのがよいでしょうか?
beyondさん
こちらのページで、MEDIAINFO以外のツールも見つかったので、movのファイル名変更できました。
ご参考まで。
https://cosmic-voyager.com/iphonemov.html
またまた返信が遅れてしまいましたが、便利なツールがあってよかったです。
PowerShellを使ってもうまくいくと思いますし、ご紹介いただいたツールでも当然同じようなことができるはずです。
結果が同じなら当然何もしないでやりたいことを達成することができるというのが楽なんですよね。
バッチファイル版でお世話になった者です。
厚かましくも、こちらのツールも利用させていただきました。
「ダイアログで変換対象のディレクトリを指定する」のと「サブディレクトリも変換対象にする」のはすごい便利ですね。まさに「痒いところに手がとどく」って感じの機能です。ありがたく使わせていただきます。ありがとうございました。
もととさん
こちらの記事にもご連絡いただきありがとうございます。
また別の機会で需要がありましたらその際はよろしくお願いします。
# しかしながら、やりたいことが達成できた後で大変恐縮なのですが、実は以前上の方にあるコメントにて紹介いただいたExifToolなる別のツールを用いることでも似たことができているようです。(私は試してないためそれはそれで申し訳ないのですが…)
# 世の中はより良い改善に向けて様々なツールが開発されるのが一般的だとすれば、”DVテープのバックアップ業界”も見捨てられず複数の開発者により救ってもらえる世の中になってるので心強い限りです。
こちらにもご返信いただきましてありがとうございます。
他のツールのご紹介もしていただきましてありがとうございます。
でも、私は普段はMacを使っていてあまりWindows系に詳しくなく、DVテープの取り込みのためだけに中古のVAIOをメルカリで購入したような者なので、コマンドプロンプトに馴染みも薄い私のとっては、こちらのページに丁寧に解説していただけておりますし、先のコメントにも書いた通り「痒いところに手が届く」beyondさんの方法の方がありがたいです。
DVテープは市中の業者さんがDVD化してくれるサービスを提供しているので、そちらを選択する方が多いのでしょう。
しかし、DVD化すれば画質も劣化もしますし、何よりDVDもテープも劣化しますので、元データの保存が大事だと個人的には思います。できれば二重、三重で。
今回、思っても見なかったテープの劣化に直面して身にしみて実感しました。
その助けとなる大変有益な手段を提供していただきまして大変感謝しております。ありがとうございました。
長文失礼いたしました。
もととさん
返信遅れてしまいましたが、貴重なコメントありがとうございました!