-
Notifications
You must be signed in to change notification settings - Fork 4
/
mp4_media.go
107 lines (96 loc) · 2.33 KB
/
mp4_media.go
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
package mp4box
import (
"io"
"log"
)
type Mp4Media struct {
// mp4_header
video_track mp4_track // has desc
audio_track mp4_track // has desc
video_desc stsd_entry
audio_desc stsd_entry
samples []mp4_sample
chunks []mp4_chunk
timestamps []mp4_timestamp
sync_samples []uint32
mdat_offset uint64 // in file position byte
ftyp_offset uint64 // in file
moov_offset uint64 // in line
moov_body_length uint64
mdat_body_length uint64
time_scale uint64
duration uint64
volume uint16
rate uint32
brand string
}
func NewMp4Media(reader io.ReadSeeker) (fd *Mp4Media, err error) {
fd = &Mp4Media{}
h := next_box_header(reader)
ftyp := next_box_body(reader, h).to_ftyp()
fd.brand = string(ftyp.major_brand[:])
log.Println(h.box_type(), ftyp.major_brand)
L:
for {
h = next_box_header(reader)
if h.size == 0 {
break
}
switch string(h.typ[:]) {
default:
reader.Seek(int64(h.body_size), 1)
case "moov":
// mo, _ := reader.Seek(0, 1)
// fd.moov_offset = mo - (h.size - h.body_size)
fd.moov_body_length = h.body_size
fd.from_moov(next_box_body(reader, h))
break L
case "mdat":
// mo, _ := reader.Seek(0, 1)
// fd.mdat_offset = mo - (h.size - h.body_size)
fd.mdat_body_length = h.body_size
reader.Seek(int64(h.body_size), 1)
}
}
return
}
func (this *Mp4Media) from_mvhd(mvhd encoded_box) {
mvheader := mvhd.to_mvhd()
this.time_scale = uint64(mvheader.TimeScale)
this.duration = uint64(mvheader.Duration)
this.rate = mvheader.Rate
this.volume = mvheader.Volume
}
func (this *Mp4Media) from_moov(moov encoded_box) {
foreach_child_box(moov, func(child encoded_box, header mp4_box_header) {
log.Println(header.box_type(), header.body_size)
switch header.box_type() {
default:
case "mvhd":
this.from_mvhd(child)
case "trak":
this.from_trak(child)
}
})
}
func (this *Mp4Media) from_trak(trak encoded_box) {
var t mp4_track
foreach_child_box(trak, func(child encoded_box, header mp4_box_header) {
log.Println(header.box_type(), header.size)
switch header.box_type() {
case "tkhd":
t.from_tkhd(child)
case "mdia":
t.from_mdia(child)
default:
}
})
switch t.track_type {
default:
case track_type_audio:
this.audio_track = t
case track_type_video:
this.video_track = t
case track_type_hint:
}
}