summaryrefslogtreecommitdiff
path: root/vendor/github.com/abema/go-mp4/mp4.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/abema/go-mp4/mp4.go')
-rw-r--r--vendor/github.com/abema/go-mp4/mp4.go151
1 files changed, 151 insertions, 0 deletions
diff --git a/vendor/github.com/abema/go-mp4/mp4.go b/vendor/github.com/abema/go-mp4/mp4.go
new file mode 100644
index 000000000..6aa5b307a
--- /dev/null
+++ b/vendor/github.com/abema/go-mp4/mp4.go
@@ -0,0 +1,151 @@
+package mp4
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+var ErrBoxInfoNotFound = errors.New("box info not found")
+
+// BoxType is mpeg box type
+type BoxType [4]byte
+
+func StrToBoxType(code string) BoxType {
+ if len(code) != 4 {
+ panic(fmt.Errorf("invalid box type id length: [%s]", code))
+ }
+ return BoxType{code[0], code[1], code[2], code[3]}
+}
+
+func (boxType BoxType) String() string {
+ if isPrintable(boxType[0]) && isPrintable(boxType[1]) && isPrintable(boxType[2]) && isPrintable(boxType[3]) {
+ s := string([]byte{boxType[0], boxType[1], boxType[2], boxType[3]})
+ s = strings.ReplaceAll(s, string([]byte{0xa9}), "(c)")
+ return s
+ }
+ return fmt.Sprintf("0x%02x%02x%02x%02x", boxType[0], boxType[1], boxType[2], boxType[3])
+}
+
+func isASCII(c byte) bool {
+ return c >= 0x20 && c <= 0x7e
+}
+
+func isPrintable(c byte) bool {
+ return isASCII(c) || c == 0xa9
+}
+
+func (lhs BoxType) MatchWith(rhs BoxType) bool {
+ if lhs == boxTypeAny || rhs == boxTypeAny {
+ return true
+ }
+ return lhs == rhs
+}
+
+var boxTypeAny = BoxType{0x00, 0x00, 0x00, 0x00}
+
+func BoxTypeAny() BoxType {
+ return boxTypeAny
+}
+
+type boxDef struct {
+ dataType reflect.Type
+ versions []uint8
+ isTarget func(Context) bool
+ fields []*field
+}
+
+var boxMap = make(map[BoxType][]boxDef, 64)
+
+func AddBoxDef(payload IBox, versions ...uint8) {
+ boxMap[payload.GetType()] = append(boxMap[payload.GetType()], boxDef{
+ dataType: reflect.TypeOf(payload).Elem(),
+ versions: versions,
+ fields: buildFields(payload),
+ })
+}
+
+func AddBoxDefEx(payload IBox, isTarget func(Context) bool, versions ...uint8) {
+ boxMap[payload.GetType()] = append(boxMap[payload.GetType()], boxDef{
+ dataType: reflect.TypeOf(payload).Elem(),
+ versions: versions,
+ isTarget: isTarget,
+ fields: buildFields(payload),
+ })
+}
+
+func AddAnyTypeBoxDef(payload IAnyType, boxType BoxType, versions ...uint8) {
+ boxMap[boxType] = append(boxMap[boxType], boxDef{
+ dataType: reflect.TypeOf(payload).Elem(),
+ versions: versions,
+ fields: buildFields(payload),
+ })
+}
+
+func AddAnyTypeBoxDefEx(payload IAnyType, boxType BoxType, isTarget func(Context) bool, versions ...uint8) {
+ boxMap[boxType] = append(boxMap[boxType], boxDef{
+ dataType: reflect.TypeOf(payload).Elem(),
+ versions: versions,
+ isTarget: isTarget,
+ fields: buildFields(payload),
+ })
+}
+
+func (boxType BoxType) getBoxDef(ctx Context) *boxDef {
+ boxDefs := boxMap[boxType]
+ for i := len(boxDefs) - 1; i >= 0; i-- {
+ boxDef := &boxDefs[i]
+ if boxDef.isTarget == nil || boxDef.isTarget(ctx) {
+ return boxDef
+ }
+ }
+ return nil
+}
+
+func (boxType BoxType) IsSupported(ctx Context) bool {
+ return boxType.getBoxDef(ctx) != nil
+}
+
+func (boxType BoxType) New(ctx Context) (IBox, error) {
+ boxDef := boxType.getBoxDef(ctx)
+ if boxDef == nil {
+ return nil, ErrBoxInfoNotFound
+ }
+
+ box, ok := reflect.New(boxDef.dataType).Interface().(IBox)
+ if !ok {
+ return nil, fmt.Errorf("box type not implements IBox interface: %s", boxType.String())
+ }
+
+ anyTypeBox, ok := box.(IAnyType)
+ if ok {
+ anyTypeBox.SetType(boxType)
+ }
+
+ return box, nil
+}
+
+func (boxType BoxType) GetSupportedVersions(ctx Context) ([]uint8, error) {
+ boxDef := boxType.getBoxDef(ctx)
+ if boxDef == nil {
+ return nil, ErrBoxInfoNotFound
+ }
+ return boxDef.versions, nil
+}
+
+func (boxType BoxType) IsSupportedVersion(ver uint8, ctx Context) bool {
+ boxDef := boxType.getBoxDef(ctx)
+ if boxDef == nil {
+ return false
+ }
+ if len(boxDef.versions) == 0 {
+ return true
+ }
+ for _, sver := range boxDef.versions {
+ if ver == sver {
+ return true
+ }
+ }
+ return false
+}