MP4のファイルを見てみる
https://www.nicovideo.jp/watch/sm40824809
をnicozonで保存してみた
容量は18MBくらいだった。
まずは素でバイナリを読んでみる
StirlingのコードセットはASCIIに設定して、読み込んだ
https://scrapbox.io/files/64180e089ad4e0001bccce45.png
最初はこうなっていた。
MP4を理解するの記事群によれば、次のように解釈できる。
File Type Box
0x0000 0000 ~ 0x0000 0003(4バイト)
意味
ルートのBoxの size
値
00 00 00 1C(= 28バイト)
先に読んだ記事では、Boxは前方8バイトがHeader部だから、Data部は残り20バイトである。
0x0000 0004 ~ 0x0000 0007(4バイト)
意味
ルートのBoxの type
値
Ascii文字列「ftyp」
これを読むには右を見る。
今回見たいのはこの行の 04 ~ 07バイト
右側の各列の見出しを見て、 4, 5, 6, 7 になっている部分を見る
解釈
このBox全体が、「ftyp」についてのデータ、または子Boxを持っていることを示している。
今後Boxを見る際には、Header部のtypeを見てデータのタイプを判断し、Data部を解釈するという流れを繰り返す。
0x0000 0008 ~ 0x0000 001B(20バイト)
意味
ルートのBoxの Data 部
mp4ファイルのブランド
値
isom
isomiso2mp41
解釈
https://unoh.github.io/2007/09/12/mp43gpp3gpp2.html
これによれば、ftype ボックスの Data 部はmp4ファイルのブランドを表す。
http://ftyps.com/composite.htm#6.3
ftypsのこのページで解説されている。
ftype ボックスは、File Type Boxと呼ばれている。
isomとは、ISO Base Media Fileの略。
code: ftype.format.c
aligned(8) class FileTypeBox
extends Box(‘ftyp’)
{
unsigned int(32) major_brand;
unsigned int(32) minor_version;
unsigned int(32) compatible_brands[];
// to end of the box
}
int32 -> 4バイト
これに従うと、値は次のように読める
major_brand
isom
minor_version
00 00 02 00
512?
compatible_brands
isom
iso2
mp41
Free Box
0x0000 001C ~ 0x0000 001F(4バイト)
意味
Boxのsize
値
8バイト
解釈
このボックスは Data 部がなく Header 部だけ、と解釈できる
0x0000 0020 ~ 0x0000 0023(4バイト)
意味
Boxのtype
値
free
解釈
この領域は多分後々のことを考えて用意されたBoxだったんだ
無視してok
Moov Box
0x0000 0024 ~ 0x0000 0027 (4バイト)
意味
Moov Boxのsize
値
189a3(=100771バイト)
解釈
でっか
0x0000 0028 ~ 0x0000 002B(4バイト)
意味
Moov Boxのtype
値
moov
0x0000 002C ~ ??? (100771バイト)
意味
Moov Box の Data 部
Moov Box - Mvhd Box
0x0000 002C ~ 0x0000 002F(4バイト)
意味
Mvhd Boxのsize
値
0000 006C (=108バイト)
解釈
108 - 8 = 100バイトが Mvhd Box の Data部のバイトサイズ。
0x0000 0030 ~ 0x0000 0033(4バイト)
意味
Mvhd Boxのtype
値
mvhd
0x0000 0034 ~ 0x0000 0097(100バイト)
意味
Mvhd BoxのData
値
?
Moov Box - Trak Box
0x0000 0098 ~ 0x0000 009B(4バイト)
意味
Trak Boxのsize
値
0x136FB(79611バイト)
0x0000 009C ~ 0x0000 009F(4バイト)
意味
Trak Boxのtype
値
trak
Moov Box - Trak Box - Tkhd box
0x0000 00A0 ~ 0x0000 00A3(4バイト)
意味
Tkhd Boxのsize
値
0x5C(92バイト)
解釈
Tkhd Boxの Data 部のサイズは 92 - 8 = 84バイト
0x0000 00A4 ~ 0x0000 00A7(4バイト)
意味
Tkhd Boxのtype
値
tkhd
0x0000 00A8 ~ 0x0000 00FB(84バイト)
意味
Tkhd Boxの Data 部
値
?
めんどくさい!!!!!w
読めるようになったからやめていい?
更に読んで見る
moov (100771バイト)
Header(8バイト)
data(100763バイト)
mvhd(108バイト)
Header(8バイト)
Data(100バイト)
trak(79611バイト)
Header(8バイト)
Data(79603バイト)
tkhd(92バイト)
Header(8バイト)
Data(84バイト)
edts(36バイト)
Header(8バイト)
elst(28バイト)
Header(8バイト)
Data(20バイト)
mdia(79475バイト)
Header(8バイト)
mdhd(32バイト)
Header(8バイト)
Data(24バイト)
hdlr(45バイト)
Header(8バイト)
Data(37バイト)
"VideoHandler"
minf(79390バイト)
Header(8バイト)
Data(79382バイト)
vmhd(20バイト)
Header(8バイト)
Data(12バイト)
dinf(36バイト)
Header(8バイト)
Data(28バイト)
dref(28バイト)
Header(8バイト)
Data(20バイト)
"url"
stbl(79326バイト)
Header(8バイト)
Data(79318バイト)
stsd(154バイト)
Header(8バイト)
Data(146バイト→9行先+α)
"avc1"
stts(24バイト)
Header(8バイト)
Data(16バイト→1行先)
stss(244バイト)
Header(8バイト)
Data(236バイト→14行半先+α)
ctts(50808バイト)
Header(8バイト)
Data(50800バイト)
stsc(28バイト)
Header(8バイト)
Data(20バイト)
stsz(27140バイト)
Header(8バイト)
Data(27132バイト)
co64(920バイト)
Header(8バイト)
Data(918バイト)
trak(21044バイト)
Header(8バイト)
Data(8バイト)
tkhd(92バイト)
Header(8バイト)
Data(84バイト)
edts(36バイト)
Header(8バイト)
Data(28バイト)
elst(28バイト)
Header(8バイト)
Data(20バイト)
mdia(20908バイト)
Header(8バイト)
Data(20900バイト)
mdhd(32バイト)
Header(8バイト)
Data(24バイト)
hdlr(45バイト)
Header(8バイト)
Data(37バイト)
"soun"
"SoundHandler"
minf(20823バイト)
Header(8バイト)
Data(20815バイト)
smhd(16バイト)
Header(8バイト)
Data(8バイト)
dinf(36バイト)
Header(8バイト)
Data(28バイト)
dref(28バイト)
Header(8バイト)
Data(20バイト)
"url"
stbl(20763バイト)
Header(8バイト)
Data(20755バイト)
stsd(103バイト)
Header(8バイト)
Data(95バイト)
stts(24バイト)
Header(8バイト)
Data(16バイト)
stsc(208バイト)
Header(8バイト)
Data(200バイト)
stsz(19492バイト)
Header(8バイト)
Data(19484バイト)
co64(928バイト)
Header(8バイト)
Data(920バイト)
※ sbtlはここまで
※ minfはここまで
※ mdiaはここまで
※ trakはここまで
以下引っかかったところだけ
Moov Box - Edts Box - Elst Box
28バイトなので、Data部は20バイト
0x0000 010C ~ 0x0000 011F(20バイト)
意味
Elst BoxのData部
値
Moov Box - Mdia Box - Mdhd Box
32バイトなので、Data部は24バイト
0x000 0130 - 0x0000 0147(24バイト)
意味
Mdhd BoxのData部
値
Moov Box - Trak Box(1) - Mdia Box - Minf Box - Sbtl Box - Ctts Box
50808バイトなので、Data部は50800バイト
そしてtype部の「s」の次のバイトのアドレスは 0x0000 036B
→Data部の終わりは 0x0000 C9DB
次のBoxは Stsc Box だ
Moov Box - Trak Box(1) - Mdia Box - Minf Box - Stbl Box - Stsz Box
Data部は27132バイト
Data部の始まりのバイトのアドレスは 0x0000 C9FF
Data部の終わりは0x0001 33FB
Moov Box - Trak Box(2) - Mdia Box - Minf Box - Stbl Box - Stsz Box
Data部は19484バイト
Data部の始まりのバイトのアドレスは0x0001 3A0B
Data部の終わりは 0x0001 8627
階層構造のまとめ
ftyp
free
moov
mvhd
trak
trak
...
trakの階層構造(1)
trak
tkhd
edts
elst
mdia
mdhd
hdlr
minf
vmhd
dinf
stbl
stsd
stss
ctts
stsc
stsz
co64
trakの階層構造(2)
trak
tkhd
edts
elst
mdia
mdhd
hdlr
minf
smhd
dinf
dref
stbl
stsd
stts
stsc
stsz
co64
メモ
4ビット = 2^4 -> 0 - Fの値を取る
8ビット = 1バイト = 2^8 = (2^4)^2 -> 00-FFの値を取る
2バイト = 16ビット = 2^16 = (2^4)^4 -> 0000 - FFFF の値を取る
4バイト = 32ビット = 2^32 = (2^4)^8 -> 0000 0000 - FFFF FFFF の値を取る