えーとっ まず断っておくと、私はAVIの構造について詳しいわけじゃないです(^^;
しっかりした情報がほしい方はMSDNのページで情報を得てください。
簡単に説明すると(良くわかってないから簡単にしか説明できないんだけど・・・)、
まずRIFFファイルヘッダーってのがあります。その次にLIST 'hdrl' チャンクってのが有り、その中にAVI
メイン ヘッダーが有り、その直後にLIST'strl' チャンクが有り、その中にAVIストリームヘッダーが有ります。
言葉で書くと何がなんだかですね。
表にすると、次のようになります。(今回の表は長い・・・)
説明 |
バイト数 |
"RIFF" |
4バイト |
ファイルの大きさ |
4バイト |
"AVI " |
4バイト |
"LIST" |
4バイト |
LIST'hdrl'チャンクの大きさ |
4バイト |
"hdrl" |
4バイト |
"avih" |
4バイト |
AVIメインヘッダーの大きさ |
4バイト |
フレーム間の間隔(マイクロ秒単位) |
4バイト |
ファイルの概算最大データ レート |
4バイト |
予約されている。ゼロに設定すること |
4バイト |
ファイルに対するフラグ |
4バイト |
ファイル内のデータのフレームの総数 |
4バイト |
インターリーブされたファイルの開始フレーム |
4バイト |
ファイル内のストリーム数 |
4バイト |
ファイルを読み取るためのバッファ サイズ |
4バイト |
AVI ファイルの幅(ピクセル単位) |
4バイト |
AVI ファイルの高さ(ピクセル単位) |
4バイト |
予約されている。この配列はゼロに設定する |
16バイト |
"LIST" |
4バイト |
LIST'strl'チャンクの大きさ |
4バイト |
"strl" |
4バイト |
"strh" |
4バイト |
AVIストリームヘッダーの大きさ |
4バイト |
ストリームに含まれるデータのタイプ |
4バイト |
特定のデータ ハンドラを示す(いわゆるコーデック) |
4バイト |
データ ストリームに対するフラグ |
4バイト |
ストリーム タイプの優先順位 |
4バイト |
AVI シーケンスの開始フレームより前にあるフレーム数 |
4バイト |
このストリームが使用するタイム スケール |
4バイト |
dwRateをdwScale で割ると、1 秒あたりのサンプル数が求められる |
4バイト |
AVI ファイルの開始タイム |
4バイト |
このストリームの長さ |
4バイト |
このストリームを読み取るために必要なバッファの大きさ |
4バイト |
ストリーム内のデータの品質を示す値 |
4バイト |
データの 1 サンプルのサイズ |
4バイト |
どんな構造かは色で汲み取ってやってください・・・
(バイナリエディタで見たのとこの表を見比べればもっと良く分かるかも)
このあとにまだ色んなチャンクが続くようだけど、取り合えずこれらの情報はこの位置にあるので良しとして下さい。
まぁこの表にある情報だけなら各データの位置が固定なので、しっかりとユーザー定義型作ってやればすぐです。
ってことでサンプルコードを。
今回はユーザー定義型が長いです(^^;
Private Type tagMainAVIHeader
dwMicroSecPerFrame As Long'フレーム間の間隔(マイクロ秒単位)
dwMaxBytesPerSec As Long'ファイルの概算最大データ レート
dwReserved1 As Long'予約されている。ゼロに設定すること
dwFlags As Long'ファイルに対するフラグ
dwTotalFrames As Long'ファイル内のデータのフレームの総数
dwInitialFrames As Long'インターリーブされたファイルの開始フレーム
dwStreams As Long'ファイル内のストリーム数
dwSuggestedBufferSize As Long'ファイルを読み取るためのバッファ サイズ
dwWidth As Long'AVI ファイルの幅(ピクセル単位)
dwHeight As Long'AVI ファイルの高さ(ピクセル単位)
dwReserved(3) As Long'予約されている。この配列はゼロに設定する
End Type
Private Type tagAVIStreamHeader
fccType As String * 4 'ストリームに含まれるデータのタイプ
fccHandler As String * 4 '特定のデータ ハンドラを示す
dwFlags As Long'データ ストリームに対するフラグ
dwPriority As Long'ストリーム タイプの優先順位
dwInitialFrames As Long'AVI シーケンスの開始フレームより前にあるフレーム数
dwScale As Long'このストリームが使用するタイム スケール
dwRate As Long'dwRateをdwScale で割ると、1 秒あたりのサンプル数が求められる
dwStart As Long'AVI ファイルの開始タイム
dwLength As Long'このストリームの長さ
dwSuggestedBufferSize As Long'このストリームを読み取るために必要なバッファの大きさ
dwQuality As Long'ストリーム内のデータの品質を示す値
dwSampleSize As Long'データの 1 サンプルのサイズ
rcFrame As Long'テキストまたはビデオ ストリームに対する転送先矩形
End Type
'AVIの情報を得る
Private Function GetAviInfo() As String
Dim MainAVIHeader As tagMainAVIHeader
Dim AVIStreamHeader As tagAVIStreamHeader
Dim FN As Long
Dim PerFrame As Long
FN = FreeFile
Open FileName For Binary As FN
Get FN, 33, MainAVIHeader
Get FN, 33 + Len(MainAVIHeader) + 20, AVIStreamHeader
Close
PerFrame = Format(1000000 / MainAVIHeader.dwMicroSecPerFrame, 0)
GetAviInfo = "幅 :" & MainAVIHeader.dwWidth
& "ピクセル" & vbCrLf & _
"高さ :" & MainAVIHeader.dwHeight & "ピクセル"
& vbCrLf & _
"長さ :" & SecToHour(Format(AVIStreamHeader.dwLength
/ PerFrame, 0)) & vbCrLf & _
"フレーム率 :" & PerFrame & "フレーム/秒"
& vbCrLf & _
"CODEC :" & AVIStreamHeader.fccHandler & vbCrLf
End Function
'秒を時間に直す
11/26 零さんの指摘により修正。 ありがとうございます。
Private Function SecToHour(Sec As Long) As String
Dim temp As Long
Dim Hour As Integer
Dim Minute As Integer
Dim Second As Integer
Hour = Sec \ 3600
temp = Sec Mod 3600
Minute = temp \ 60
Second = temp Mod 60
SecToHour = Format(Hour, "00") & ":" &
Format(Minute, "00") & _
":" & Format(Second, "00")
End Function |
AVIStreamHeader.fccHandlerからCODECの名前を得るにはThe Almost Definitive FOURCC Definition List - Video Codec Listのページを参考にしてください。 |