Files
monibuca/plugin/mp4/pkg/box/box.go
2024-09-14 18:16:23 +08:00

211 lines
4.2 KiB
Go

package box
import (
"encoding/binary"
"io"
)
const (
BasicBoxLen = 8
FullBoxLen = 12
)
func f(s string) [4]byte {
return [4]byte([]byte(s))
}
var (
TypeFTYP = f("ftyp")
TypeSTYP = f("styp")
TypeMOOV = f("moov")
TypeMVHD = f("mvhd")
TypeTRAK = f("trak")
TypeTKHD = f("tkhd")
TypeMDIA = f("mdia")
TypeMDHD = f("mdhd")
TypeHDLR = f("hdlr")
TypeMINF = f("minf")
TypeSTBL = f("stbl")
TypeSTSD = f("stsd")
TypeSTTS = f("stts")
TypeSTSC = f("stsc")
TypeSTSZ = f("stsz")
TypeSTCO = f("stco")
TypeMDAT = f("mdat")
TypeFREE = f("free")
TypeUUID = f("uuid")
TypeVMHD = f("vmhd")
TypeSMHD = f("smhd")
TypeHMHD = f("hmhd")
TypeNMHD = f("nmhd")
TypeCTTS = f("ctts")
TypeCO64 = f("co64")
TypePSSH = f("pssh")
TypeSTSS = f("stss")
TypeENCV = f("encv")
TypeSINF = f("sinf")
TypeFRMA = f("frma")
TypeSCHI = f("schi")
TypeTENC = f("tenc")
TypeAVC1 = f("avc1")
TypeHVC1 = f("hvc1")
TypeHEV1 = f("hev1")
TypeENCA = f("enca")
TypeMP4A = f("mp4a")
TypeULAW = f("ulaw")
TypeALAW = f("alaw")
TypeOPUS = f("opus")
TypeAVCC = f("avcC")
TypeHVCC = f("hvcC")
TypeESDS = f("esds")
TypeEDTS = f("edts")
TypeELST = f("elst")
TypeMVEX = f("mvex")
TypeMOOF = f("moof")
TypeMFHD = f("mfhd")
TypeTRAF = f("traf")
TypeTFHD = f("tfhd")
TypeTFDT = f("tfdt")
TypeTRUN = f("trun")
TypeSENC = f("senc")
TypeSAIZ = f("saiz")
TypeSAIO = f("saio")
TypeSGPD = f("sgpd")
TypeWAVE = f("wave")
TypeMSDH = f("msdh")
TypeMSIX = f("msix")
TypeISOM = f("isom")
TypeISO2 = f("iso2")
TypeISO3 = f("iso3")
TypeISO4 = f("iso4")
TypeISO5 = f("iso5")
TypeISO6 = f("iso6")
TypeMP41 = f("mp41")
TypeMP42 = f("mp42")
TypeDASH = f("dash")
TypeMFRA = f("mfra")
TypeMFRO = f("mfro")
TypeTREX = f("trex")
TypeTFRA = f("tfra")
TypeSIDX = f("sidx")
TypeDINF = f("dinf")
TypeDREF = f("dref")
TypeVIDE = f("vide")
TypeSOUN = f("soun")
TypeMETA = f("meta")
TypeAUXV = f("auxv")
TypeHINT = f("hint")
)
type BoxEncoder interface {
Encode(buf []byte) (int, []byte)
}
type BoxDecoder interface {
Decode(buf []byte) (int, error)
}
type BoxSize interface {
Size() uint64
}
// aligned(8) class Box (unsigned int(32) boxtype, optional unsigned int(8)[16] extended_type) {
// unsigned int(32) size;
// unsigned int(32) type = boxtype;
// if (size==1) {
// unsigned int(64) largesize;
// } else if (size==0) {
// // box extends to end of file
// }
// if (boxtype=='uuid') {
// unsigned int(8)[16] usertype = extended_type;
// }
// }
type IBox interface {
Decode(io.Reader, *BasicBox) (int, error)
}
type BasicBox struct {
Offset int64
Size uint64
Type [4]byte
}
func NewBasicBox(boxtype [4]byte) *BasicBox {
return &BasicBox{
Type: boxtype,
}
}
func (box *BasicBox) Decode(r io.Reader) (nn int, err error) {
if _, err = io.ReadFull(r, box.Type[:]); err != nil {
return
}
nn = 4
if box.Size = uint64(binary.BigEndian.Uint32(box.Type[:])); box.Size == 1 {
var largeSize [8]byte
if _, err = io.ReadFull(r, largeSize[:]); err != nil {
return
}
box.Size = binary.BigEndian.Uint64(largeSize[:])
nn += 8
}
if _, err = io.ReadFull(r, box.Type[:]); err != nil {
return
}
nn += 4
return
}
func (box *BasicBox) Encode() (int, []byte) {
buf := make([]byte, box.Size)
binary.BigEndian.PutUint32(buf, uint32(box.Size))
copy(buf[4:], box.Type[:])
return BasicBoxLen, buf
}
// aligned(8) class FullBox(unsigned int(32) boxtype, unsigned int(8) v, bit(24) f) extends Box(boxtype) {
// unsigned int(8) version = v;
// bit(24) flags = f;
// }
type FullBox struct {
Box *BasicBox
Version uint8
Flags [3]byte
}
func NewFullBox(boxtype [4]byte, version uint8) *FullBox {
return &FullBox{
Box: NewBasicBox(boxtype),
Version: version,
}
}
func (box *FullBox) Size() uint64 {
if box.Box.Size > 0 {
return box.Box.Size
} else {
return FullBoxLen
}
}
func (box *FullBox) Decode(r io.Reader) (int, error) {
buf := make([]byte, 4)
if n, err := io.ReadFull(r, buf); err != nil {
return n, err
}
box.Version = buf[0]
copy(box.Flags[:], buf[1:])
return 4, nil
}
func (box *FullBox) Encode() (int, []byte) {
box.Box.Size = box.Size()
offset, buf := box.Box.Encode()
buf[offset] = box.Version
copy(buf[offset+1:], box.Flags[:])
return offset + 4, buf
}