web-dev-qa-db-ja.com

埋め込まれたメタデータを使用して、ビデオ録画のファイルのタイムスタンプを復元するにはどうすればよいですか?

*.mp4」ファイルのメタデータを読み取り、ファイルのタイムスタンプと動画の作成時間を変更するコマンドを探しています。コマンドは、ファイルの内容に関して読み取り専用である必要があります。つまり、ファイルを前後にハッシュすると、同じ結果が得られます。

状況:スマートフォンの内部ストレージからAndroidのストックツールを使用してSDカードに画像や動画を移動するのを間違えました(「設定」→「ストレージ」→「SDカードにデータを転送」)。残念ながら、これによりすべてのファイルのタイムスタンプがぶつかり、DCIM/以外のディレクトリが乱雑になりました(画像とビデオもDownload/image/Pictures/、およびvideo/ディレクトリから移動されました)。後から考えて、私がそのようなツールを使用したのはばかげているように見えます(私は通常 Ghost Commander を使用します)が、スペースが足りなくなったときに通知として表示され、とても簡単に見えました。現在、さまざまな画像や動画のタイムスタンプをつなぎ合わせようとしています。

DCIM/100ANDRO/で画像を並べ替えるために使用した 次のコマンド に相当するビデオを効果的に探しています。

exiv2 -T mv *.JPG

FFmpegのドキュメント をざっと読みましたが、読み取り専用のコマンドやタイムスタンプの出力についての言及はありません。

(残念ながら私の状況では、このアプローチは、私が作成しなかったファイル(Download/内のものなど)の解決策を提供しません。このファイルについては、入手した日付順にメディアコレクションに表示する必要があります。)

6
James Haigh

mediainfo コマンドについて部分的に回答してくれたWarrenに感謝します。

タイムスタンプの復元を実現するコマンドをなんとか構築しました。該当するファイルをループし、ファイルごとにmediainfoがメタデータを読み取り、grepsedがタイムスタンプを選択してフォーマットし、touchが適用します。

for file in *.mp4; do touch -t "$(mediainfo "$file" | grep -m 1 'Tagged date' | sed -r 's/.*([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).*/\1\2\3\4\5.\6/')" "$file"; done

「選択とフォーマット」の部分は、間違いなくはるかに短く/優れています。それは私には扱いにくいように見えますが、私は正規表現に堪能ではありません。それにもかかわらず、コマンドは完全に機能しました。私はすべてを正しく引用していると思うので、どのファイル名でも機能するはずです。 mediainfoが異なる形式を出力する場合は機能しない可能性がありますが、簡単に適応できます。

たとえば、以下は、*.mp4などのUTC 2013-11-15 11:36:06ファイルからの出力の形式と、2014-2-23T09:00:00Zからのmy.movのウォーレンの例の形式の両方に正しく一致する正規表現です。 :

's/-/-0/g; s/.*([0-9]{4})-0?([0-9]{2})-0?([0-9]{2})[T ]([0-9]{2}):([0-9]{2}):([0-9]{2}).*/\1\2\3\4\5.\6/'

そして、ディストリビューションのリポジトリにないために手動でインストールしなければならなかったmediainfoを除いて(新しいリリースではパッケージ化されているように見えますが)、かなり移植性が高く、同様の問題。

注:タイムゾーンを確認することを忘れないでください。 GNU infoページ、touchdate、および他のGNU=ユーティリティは設定されている場合はTZ環境変数、設定されていない場合は「システムのデフォルトルール」使用されるタイムゾーンオフセットを確認するには、次のコマンドを発行します。

date +%:::z

これを変更するには、TZ環境変数を設定します。

export TZ="UTC0"

動画のタイムスタンプが正しく、正しく表されている場合(つまり、タイムゾーンの時間値が正しい時点を表す場合)、実行する前にdate +%:::zがタイムスタンプのタイムゾーンに一致するオフセットを出力することを確認する必要がありますtouch -tこれらのファイルを上書きします(上記のとおり)。 statを使用して、ファイルをチェックします。これは、(date +%:::zのように)時間オフセットを示すためです。

8
James Haigh

そのために MediaInfo を使用できます。

_$ mediainfo my.mov | grep 'Recorded date'
Recorded date                            : 2014-2-23T09:00:00Z
_

その日付形式からtouchコマンドに取得するのは、プログラミングの小さな問題です。個人的には、Perlの _Date::Manip_ モジュールを使用します。上記のフォーマットにほぼ対応できます。この特定の日付形式を理解するには、2桁の月とゼロパディングが必要です。これを修正するには、簡単な正規表現のみが必要です。これは、もちろんPerlでは簡単です。

_$ Perl -M'Date::Manip' -e 'print ParseDate("2014-02-23T09:00:00Z")'
2014022302:00:00
_

印刷されているという事実は、それが解析であることを示しています。 _0_をドロップすると、ParseDate()undefを返すため、何も出力されないことがわかります。

2
Warren Young

exiftool:

exiftool "-CreateDate>FileModifyDate" FILES or FOLDERS

必要な値の名前は、ファイル形式やその他の要因によって異なる場合があります。以下を使用してそれらを印刷します。

exiftool -time:all -s FILE
0
Gringo Suave

MP4およびほとんどのQuickTimeファイルについては、上記のJamesのアドバイスに従ってください。 AVIファイルの場合、mediainfoは_Mastered date_を出力しますが、形式はほとんど解析できません。 ffmpegをインストールしてffprobeavprobeとも呼ばれる)を取得し、次を使用します。

for file in *.avi; do touch -t "$(ffprobe "$file" 2>&1 | grep -m 1 'creation_time' | sed -r 's/.*([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).*/\1\2\3\4\5.\6/')" "$file"; done

grepにパイプする前にmodに注意してください。これは、ffprobeがstdoutではなくstderrを使用するためです。

0
Glenn Batuyong