| 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
 | package mp4
import (
	"errors"
	"io"
)
type BoxInfoWithPayload struct {
	Info    BoxInfo
	Payload IBox
}
func ExtractBoxWithPayload(r io.ReadSeeker, parent *BoxInfo, path BoxPath) ([]*BoxInfoWithPayload, error) {
	return ExtractBoxesWithPayload(r, parent, []BoxPath{path})
}
func ExtractBoxesWithPayload(r io.ReadSeeker, parent *BoxInfo, paths []BoxPath) ([]*BoxInfoWithPayload, error) {
	bis, err := ExtractBoxes(r, parent, paths)
	if err != nil {
		return nil, err
	}
	bs := make([]*BoxInfoWithPayload, 0, len(bis))
	for _, bi := range bis {
		if _, err := bi.SeekToPayload(r); err != nil {
			return nil, err
		}
		var ctx Context
		if parent != nil {
			ctx = parent.Context
		}
		box, _, err := UnmarshalAny(r, bi.Type, bi.Size-bi.HeaderSize, ctx)
		if err != nil {
			return nil, err
		}
		bs = append(bs, &BoxInfoWithPayload{
			Info:    *bi,
			Payload: box,
		})
	}
	return bs, nil
}
func ExtractBox(r io.ReadSeeker, parent *BoxInfo, path BoxPath) ([]*BoxInfo, error) {
	return ExtractBoxes(r, parent, []BoxPath{path})
}
func ExtractBoxes(r io.ReadSeeker, parent *BoxInfo, paths []BoxPath) ([]*BoxInfo, error) {
	if len(paths) == 0 {
		return nil, nil
	}
	for i := range paths {
		if len(paths[i]) == 0 {
			return nil, errors.New("box path must not be empty")
		}
	}
	boxes := make([]*BoxInfo, 0, 8)
	handler := func(handle *ReadHandle) (interface{}, error) {
		path := handle.Path
		if parent != nil {
			path = path[1:]
		}
		if handle.BoxInfo.Type == BoxTypeAny() {
			return nil, nil
		}
		fm, m := matchPath(paths, path)
		if m {
			boxes = append(boxes, &handle.BoxInfo)
		}
		if fm {
			if _, err := handle.Expand(); err != nil {
				return nil, err
			}
		}
		return nil, nil
	}
	if parent != nil {
		_, err := ReadBoxStructureFromInternal(r, parent, handler)
		return boxes, err
	}
	_, err := ReadBoxStructure(r, handler)
	return boxes, err
}
func matchPath(paths []BoxPath, path BoxPath) (forwardMatch bool, match bool) {
	for i := range paths {
		fm, m := path.compareWith(paths[i])
		forwardMatch = forwardMatch || fm
		match = match || m
	}
	return
}
 |