-
Notifications
You must be signed in to change notification settings - Fork 30
/
write_test.go
154 lines (137 loc) · 4.02 KB
/
write_test.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
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
package mp4
import (
"bytes"
"io"
"testing"
"gopkg.in/src-d/go-billy.v4/memfs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestWriter(t *testing.T) {
output, err := memfs.New().Create("output.mp4")
require.NoError(t, err)
defer output.Close()
w := NewWriter(output)
// start ftyp
bi, err := w.StartBox(&BoxInfo{Type: BoxTypeFtyp()})
require.NoError(t, err)
assert.Equal(t, uint64(0), bi.Offset)
assert.Equal(t, uint64(8), bi.Size)
ftyp := &Ftyp{
MajorBrand: [4]byte{'a', 'b', 'e', 'm'},
MinorVersion: 0x12345678,
CompatibleBrands: []CompatibleBrandElem{
{CompatibleBrand: [4]byte{'a', 'b', 'c', 'd'}},
{CompatibleBrand: [4]byte{'e', 'f', 'g', 'h'}},
},
}
_, err = Marshal(w, ftyp, Context{})
require.NoError(t, err)
// end ftyp
bi, err = w.EndBox()
require.NoError(t, err)
assert.Equal(t, uint64(0), bi.Offset)
assert.Equal(t, uint64(24), bi.Size)
// start moov
bi, err = w.StartBox(&BoxInfo{Type: BoxTypeMoov()})
require.NoError(t, err)
assert.Equal(t, uint64(24), bi.Offset)
assert.Equal(t, uint64(8), bi.Size)
// copy
err = w.CopyBox(bytes.NewReader([]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0a,
'u', 'd', 't', 'a',
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
}), &BoxInfo{Offset: 6, Size: 15})
require.NoError(t, err)
// start trak
bi, err = w.StartBox(&BoxInfo{Type: BoxTypeTrak()})
require.NoError(t, err)
assert.Equal(t, uint64(47), bi.Offset)
assert.Equal(t, uint64(8), bi.Size)
// start tkhd
bi, err = w.StartBox(&BoxInfo{Type: BoxTypeTkhd()})
require.NoError(t, err)
assert.Equal(t, uint64(55), bi.Offset)
assert.Equal(t, uint64(8), bi.Size)
_, err = Marshal(w, &Tkhd{
CreationTimeV0: 1,
ModificationTimeV0: 2,
TrackID: 3,
DurationV0: 4,
Layer: 5,
AlternateGroup: 6,
Volume: 7,
Width: 8,
Height: 9,
}, Context{})
require.NoError(t, err)
// end tkhd
bi, err = w.EndBox()
require.NoError(t, err)
assert.Equal(t, uint64(55), bi.Offset)
assert.Equal(t, uint64(92), bi.Size)
// end trak
bi, err = w.EndBox()
require.NoError(t, err)
assert.Equal(t, uint64(47), bi.Offset)
assert.Equal(t, uint64(100), bi.Size)
// end moov
bi, err = w.EndBox()
require.NoError(t, err)
assert.Equal(t, uint64(24), bi.Offset)
assert.Equal(t, uint64(123), bi.Size)
// update ftyp
n, err := w.Seek(8, io.SeekStart)
require.NoError(t, err)
assert.Equal(t, int64(8), n)
ftyp.CompatibleBrands[1].CompatibleBrand = [4]byte{'E', 'F', 'G', 'H'}
_, err = Marshal(w, ftyp, Context{})
require.NoError(t, err)
_, err = output.Seek(0, io.SeekStart)
require.NoError(t, err)
bin, err := io.ReadAll(output)
require.NoError(t, err)
assert.Equal(t, []byte{
// ftyp
0x00, 0x00, 0x00, 0x18, // size
'f', 't', 'y', 'p', // type
'a', 'b', 'e', 'm', // major brand
0x12, 0x34, 0x56, 0x78, // minor version
'a', 'b', 'c', 'd', // compatible brand
'E', 'F', 'G', 'H', // compatible brand
// moov
0x00, 0x00, 0x00, 0x7b, // size
'm', 'o', 'o', 'v', // type
// udta (copy)
0x00, 0x00, 0x00, 0x0a,
'u', 'd', 't', 'a',
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07,
// trak
0x00, 0x00, 0x00, 0x64, // size
't', 'r', 'a', 'k', // type
// tkhd
0x00, 0x00, 0x00, 0x5c, // size
't', 'k', 'h', 'd', // type
0, // version
0x00, 0x00, 0x00, // flags
0x00, 0x00, 0x00, 0x01, // creation time
0x00, 0x00, 0x00, 0x02, // modification time
0x00, 0x00, 0x00, 0x03, // track ID
0x00, 0x00, 0x00, 0x00, // reserved
0x00, 0x00, 0x00, 0x04, // duration
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
0x00, 0x05, // layer
0x00, 0x06, // alternate group
0x00, 0x07, // volume
0x00, 0x00, // reserved
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // matrix
0x00, 0x00, 0x00, 0x08, // width
0x00, 0x00, 0x00, 0x09, // height
}, bin)
}