[chore]: Bump github.com/abema/go-mp4 from 1.1.1 to 1.2.0 (#2559)
This commit is contained in:
parent
a858831387
commit
605b2fde91
2
go.mod
2
go.mod
|
@ -22,7 +22,7 @@ require (
|
||||||
codeberg.org/superseriousbusiness/exif-terminator v0.7.0
|
codeberg.org/superseriousbusiness/exif-terminator v0.7.0
|
||||||
github.com/DmitriyVTitov/size v1.5.0
|
github.com/DmitriyVTitov/size v1.5.0
|
||||||
github.com/KimMachineGun/automemlimit v0.5.0
|
github.com/KimMachineGun/automemlimit v0.5.0
|
||||||
github.com/abema/go-mp4 v1.1.1
|
github.com/abema/go-mp4 v1.2.0
|
||||||
github.com/buckket/go-blurhash v1.1.0
|
github.com/buckket/go-blurhash v1.1.0
|
||||||
github.com/coreos/go-oidc/v3 v3.9.0
|
github.com/coreos/go-oidc/v3 v3.9.0
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -81,8 +81,8 @@ github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW5
|
||||||
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
|
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
|
||||||
github.com/KimMachineGun/automemlimit v0.5.0 h1:BeOe+BbJc8L5chL3OwzVYjVzyvPALdd5wxVVOWuUZmQ=
|
github.com/KimMachineGun/automemlimit v0.5.0 h1:BeOe+BbJc8L5chL3OwzVYjVzyvPALdd5wxVVOWuUZmQ=
|
||||||
github.com/KimMachineGun/automemlimit v0.5.0/go.mod h1:di3GCKiu9Y+1fs92erCbUvKzPkNyViN3mA0vti/ykEQ=
|
github.com/KimMachineGun/automemlimit v0.5.0/go.mod h1:di3GCKiu9Y+1fs92erCbUvKzPkNyViN3mA0vti/ykEQ=
|
||||||
github.com/abema/go-mp4 v1.1.1 h1:OfzkdMO6SWTBR1ltNSVwlTHatrAK9I3iYLQfkdEMMuc=
|
github.com/abema/go-mp4 v1.2.0 h1:gi4X8xg/m179N/J15Fn5ugywN9vtI6PLk6iLldHGLAk=
|
||||||
github.com/abema/go-mp4 v1.1.1/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws=
|
github.com/abema/go-mp4 v1.2.0/go.mod h1:vPl9t5ZK7K0x68jh12/+ECWBCXoWuIDtNgPtU2f04ws=
|
||||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||||
|
|
|
@ -6,9 +6,14 @@ go-mp4
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/abema/go-mp4/badge.svg)](https://coveralls.io/github/abema/go-mp4)
|
[![Coverage Status](https://coveralls.io/repos/github/abema/go-mp4/badge.svg)](https://coveralls.io/github/abema/go-mp4)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/github.com/abema/go-mp4)](https://goreportcard.com/report/github.com/abema/go-mp4)
|
[![Go Report Card](https://goreportcard.com/badge/github.com/abema/go-mp4)](https://goreportcard.com/report/github.com/abema/go-mp4)
|
||||||
|
|
||||||
go-mp4 is Go library and CLI tool which provide low-level I/O interfaces of MP4.
|
go-mp4 is Go library which provides low-level I/O interfaces of MP4.
|
||||||
This library supports you to parse or build any MP4 boxes(atoms) directly.
|
This library supports you to parse or build any MP4 boxes(atoms) directly.
|
||||||
|
|
||||||
|
go-mp4 provides very flexible interfaces for reading boxes.
|
||||||
|
If you want to read only specific parts of MP4 file, this library extracts those boxes via io.ReadSeeker interface.
|
||||||
|
|
||||||
|
On the other hand, this library is not suitable for complex data conversions.
|
||||||
|
|
||||||
## Integration with your Go application
|
## Integration with your Go application
|
||||||
|
|
||||||
### Reading
|
### Reading
|
||||||
|
|
|
@ -12,6 +12,9 @@ type Context struct {
|
||||||
// IsQuickTimeCompatible represents whether ftyp.compatible_brands contains "qt ".
|
// IsQuickTimeCompatible represents whether ftyp.compatible_brands contains "qt ".
|
||||||
IsQuickTimeCompatible bool
|
IsQuickTimeCompatible bool
|
||||||
|
|
||||||
|
// QuickTimeKeysMetaEntryCount the expected number of items under the ilst box as observed from the keys box
|
||||||
|
QuickTimeKeysMetaEntryCount int
|
||||||
|
|
||||||
// UnderWave represents whether current box is under the wave box.
|
// UnderWave represents whether current box is under the wave box.
|
||||||
UnderWave bool
|
UnderWave bool
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package mp4
|
||||||
|
|
||||||
|
/*************************** ipcm ****************************/
|
||||||
|
|
||||||
|
func BoxTypeIpcm() BoxType { return StrToBoxType("ipcm") }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddAnyTypeBoxDef(&AudioSampleEntry{}, BoxTypeIpcm())
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** fpcm ****************************/
|
||||||
|
|
||||||
|
func BoxTypeFpcm() BoxType { return StrToBoxType("fpcm") }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddAnyTypeBoxDef(&AudioSampleEntry{}, BoxTypeFpcm())
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** pcmC ****************************/
|
||||||
|
|
||||||
|
func BoxTypePcmC() BoxType { return StrToBoxType("pcmC") }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddBoxDef(&PcmC{}, 0, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
type PcmC struct {
|
||||||
|
FullBox `mp4:"0,extend"`
|
||||||
|
FormatFlags uint8 `mp4:"1,size=8"`
|
||||||
|
PCMSampleSize uint8 `mp4:"1,size=8"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (PcmC) GetType() BoxType {
|
||||||
|
return BoxTypePcmC()
|
||||||
|
}
|
|
@ -107,6 +107,8 @@ const (
|
||||||
DataTypeFloat64BigEndian = 23
|
DataTypeFloat64BigEndian = 23
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Data is a Value BoxType
|
||||||
|
// https://developer.apple.com/documentation/quicktime-file-format/value_atom
|
||||||
type Data struct {
|
type Data struct {
|
||||||
Box
|
Box
|
||||||
DataType uint32 `mp4:"0,size=32"`
|
DataType uint32 `mp4:"0,size=32"`
|
||||||
|
@ -167,6 +169,89 @@ func (sd *StringData) StringifyField(name string, indent string, depth int, ctx
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************** numbered items ****************************/
|
||||||
|
|
||||||
|
// Item is a numbered item under an item list atom
|
||||||
|
// https://developer.apple.com/documentation/quicktime-file-format/metadata_item_list_atom/item_list
|
||||||
|
type Item struct {
|
||||||
|
AnyTypeBox
|
||||||
|
Version uint8 `mp4:"0,size=8"`
|
||||||
|
Flags [3]byte `mp4:"1,size=8"`
|
||||||
|
ItemName []byte `mp4:"2,size=8,len=4"`
|
||||||
|
Data Data `mp4:"3"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringifyField returns field value as string
|
||||||
|
func (i *Item) StringifyField(name string, indent string, depth int, ctx Context) (string, bool) {
|
||||||
|
switch name {
|
||||||
|
case "ItemName":
|
||||||
|
return fmt.Sprintf("\"%s\"", util.EscapeUnprintables(string(i.ItemName))), true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
func isUnderIlstFreeFormat(ctx Context) bool {
|
func isUnderIlstFreeFormat(ctx Context) bool {
|
||||||
return ctx.UnderIlstFreeMeta
|
return ctx.UnderIlstFreeMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BoxTypeKeys() BoxType { return StrToBoxType("keys") }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AddBoxDef(&Keys{})
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** keys ****************************/
|
||||||
|
|
||||||
|
// Keys is the Keys BoxType
|
||||||
|
// https://developer.apple.com/documentation/quicktime-file-format/metadata_item_keys_atom
|
||||||
|
type Keys struct {
|
||||||
|
FullBox `mp4:"0,extend"`
|
||||||
|
EntryCount int32 `mp4:"1,size=32"`
|
||||||
|
Entries []Key `mp4:"2,len=dynamic"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetType implements the IBox interface and returns the BoxType
|
||||||
|
func (*Keys) GetType() BoxType {
|
||||||
|
return BoxTypeKeys()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFieldLength implements the ICustomFieldObject interface and returns the length of dynamic fields
|
||||||
|
func (k *Keys) GetFieldLength(name string, ctx Context) uint {
|
||||||
|
switch name {
|
||||||
|
case "Entries":
|
||||||
|
return uint(k.EntryCount)
|
||||||
|
}
|
||||||
|
panic(fmt.Errorf("invalid name of dynamic-length field: boxType=keys fieldName=%s", name))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** key ****************************/
|
||||||
|
|
||||||
|
// Key is a key value field in the Keys BoxType
|
||||||
|
// https://developer.apple.com/documentation/quicktime-file-format/metadata_item_keys_atom/key_value_key_size-8
|
||||||
|
type Key struct {
|
||||||
|
BaseCustomFieldObject
|
||||||
|
KeySize int32 `mp4:"0,size=32"`
|
||||||
|
KeyNamespace []byte `mp4:"1,size=8,len=4"`
|
||||||
|
KeyValue []byte `mp4:"2,size=8,len=dynamic"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFieldLength implements the ICustomFieldObject interface and returns the length of dynamic fields
|
||||||
|
func (k *Key) GetFieldLength(name string, ctx Context) uint {
|
||||||
|
switch name {
|
||||||
|
case "KeyValue":
|
||||||
|
// sizeOf(KeySize)+sizeOf(KeyNamespace) = 8 bytes
|
||||||
|
return uint(k.KeySize) - 8
|
||||||
|
}
|
||||||
|
panic(fmt.Errorf("invalid name of dynamic-length field: boxType=key fieldName=%s", name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringifyField returns field value as string
|
||||||
|
func (k *Key) StringifyField(name string, indent string, depth int, ctx Context) (string, bool) {
|
||||||
|
switch name {
|
||||||
|
case "KeyNamespace":
|
||||||
|
return fmt.Sprintf("\"%s\"", util.EscapeUnprintables(string(k.KeyNamespace))), true
|
||||||
|
case "KeyValue":
|
||||||
|
return fmt.Sprintf("\"%s\"", util.EscapeUnprintables(string(k.KeyValue))), true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package mp4
|
package mp4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -19,6 +20,13 @@ func StrToBoxType(code string) BoxType {
|
||||||
return BoxType{code[0], code[1], code[2], code[3]}
|
return BoxType{code[0], code[1], code[2], code[3]}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uint32ToBoxType returns a new BoxType from the provied uint32
|
||||||
|
func Uint32ToBoxType(i uint32) BoxType {
|
||||||
|
b := make([]byte, 4)
|
||||||
|
binary.BigEndian.PutUint32(b, i)
|
||||||
|
return BoxType{b[0], b[1], b[2], b[3]}
|
||||||
|
}
|
||||||
|
|
||||||
func (boxType BoxType) String() string {
|
func (boxType BoxType) String() string {
|
||||||
if isPrintable(boxType[0]) && isPrintable(boxType[1]) && isPrintable(boxType[2]) && isPrintable(boxType[3]) {
|
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 := string([]byte{boxType[0], boxType[1], boxType[2], boxType[3]})
|
||||||
|
@ -92,6 +100,8 @@ func AddAnyTypeBoxDefEx(payload IAnyType, boxType BoxType, isTarget func(Context
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var itemBoxFields = buildFields(&Item{})
|
||||||
|
|
||||||
func (boxType BoxType) getBoxDef(ctx Context) *boxDef {
|
func (boxType BoxType) getBoxDef(ctx Context) *boxDef {
|
||||||
boxDefs := boxMap[boxType]
|
boxDefs := boxMap[boxType]
|
||||||
for i := len(boxDefs) - 1; i >= 0; i-- {
|
for i := len(boxDefs) - 1; i >= 0; i-- {
|
||||||
|
@ -100,6 +110,16 @@ func (boxType BoxType) getBoxDef(ctx Context) *boxDef {
|
||||||
return boxDef
|
return boxDef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ctx.UnderIlst {
|
||||||
|
typeID := int(binary.BigEndian.Uint32(boxType[:]))
|
||||||
|
if typeID >= 1 && typeID <= ctx.QuickTimeKeysMetaEntryCount {
|
||||||
|
return &boxDef{
|
||||||
|
dataType: reflect.TypeOf(Item{}),
|
||||||
|
isTarget: isIlstMetaContainer,
|
||||||
|
fields: itemBoxFields,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,18 @@ func readBoxStructureFromInternal(r io.ReadSeeker, bi *BoxInfo, path BoxPath, ha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse numbered ilst items after keys box by saving EntryCount field to context
|
||||||
|
if bi.Type == BoxTypeKeys() {
|
||||||
|
var keys Keys
|
||||||
|
if _, err := Unmarshal(r, bi.Size-bi.HeaderSize, &keys, bi.Context); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bi.QuickTimeKeysMetaEntryCount = int(keys.EntryCount)
|
||||||
|
if _, err := bi.SeekToPayload(r); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ctx := bi.Context
|
ctx := bi.Context
|
||||||
if bi.Type == BoxTypeWave() {
|
if bi.Type == BoxTypeWave() {
|
||||||
ctx.UnderWave = true
|
ctx.UnderWave = true
|
||||||
|
@ -172,6 +184,11 @@ func readBoxStructure(r io.ReadSeeker, totalSize uint64, isRoot bool, path BoxPa
|
||||||
if bi.IsQuickTimeCompatible {
|
if bi.IsQuickTimeCompatible {
|
||||||
ctx.IsQuickTimeCompatible = true
|
ctx.IsQuickTimeCompatible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// preserve keys entry count on context for subsequent ilst number item box
|
||||||
|
if bi.Type == BoxTypeKeys() {
|
||||||
|
ctx.QuickTimeKeysMetaEntryCount = bi.QuickTimeKeysMetaEntryCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if totalSize != 0 && !ctx.IsQuickTimeCompatible {
|
if totalSize != 0 && !ctx.IsQuickTimeCompatible {
|
||||||
|
|
|
@ -72,7 +72,7 @@ github.com/DmitriyVTitov/size
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/KimMachineGun/automemlimit
|
github.com/KimMachineGun/automemlimit
|
||||||
github.com/KimMachineGun/automemlimit/memlimit
|
github.com/KimMachineGun/automemlimit/memlimit
|
||||||
# github.com/abema/go-mp4 v1.1.1
|
# github.com/abema/go-mp4 v1.2.0
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/abema/go-mp4
|
github.com/abema/go-mp4
|
||||||
github.com/abema/go-mp4/internal/bitio
|
github.com/abema/go-mp4/internal/bitio
|
||||||
|
|
Loading…
Reference in New Issue