mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
194 lines
4.0 KiB
Go
194 lines
4.0 KiB
Go
package box
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
)
|
|
|
|
var (
|
|
TypeURL = BoxType{'u', 'r', 'l', ' '}
|
|
TypeURN = BoxType{'u', 'r', 'n', ' '}
|
|
)
|
|
|
|
// aligned(8) class DataEntryUrlBox (bit(24) flags) extends FullBox('url ', version = 0, flags) {
|
|
// string location;
|
|
// }
|
|
// aligned(8) class DataEntryUrnBox (bit(24) flags) extends FullBox('urn ', version = 0, flags) {
|
|
// string name;
|
|
// string location;
|
|
// }
|
|
// aligned(8) class DataReferenceBox extends FullBox('dref', version = 0, 0) {
|
|
// unsigned int(32) entry_count;
|
|
// for (i=1; i <= entry_count; i++) {
|
|
// DataEntryBox(entry_version, entry_flags) data_entry;
|
|
// }
|
|
// }
|
|
|
|
type DataInformationBox struct {
|
|
BaseBox
|
|
Dref *DataReferenceBox
|
|
}
|
|
|
|
type DataReferenceBox struct {
|
|
FullBox
|
|
Entries []IBox
|
|
}
|
|
|
|
type DataEntryUrlBox struct {
|
|
FullBox
|
|
Location string
|
|
}
|
|
|
|
type DataEntryUrnBox struct {
|
|
FullBox
|
|
Name string
|
|
Location string
|
|
}
|
|
|
|
func CreateDataInformationBox() *DataInformationBox {
|
|
dref := CreateDataReferenceBox()
|
|
return &DataInformationBox{
|
|
BaseBox: BaseBox{
|
|
typ: TypeDINF,
|
|
size: uint32(BasicBoxLen + dref.size),
|
|
},
|
|
Dref: dref,
|
|
}
|
|
}
|
|
|
|
func CreateDataReferenceBox() *DataReferenceBox {
|
|
url := CreateDataEntryUrlBox("")
|
|
return &DataReferenceBox{
|
|
FullBox: FullBox{
|
|
BaseBox: BaseBox{
|
|
typ: TypeDREF,
|
|
size: uint32(FullBoxLen + 4 + url.size), // 4 for entry_count
|
|
},
|
|
Version: 0,
|
|
Flags: [3]byte{0, 0, 0},
|
|
},
|
|
Entries: []IBox{url},
|
|
}
|
|
}
|
|
|
|
func CreateDataEntryUrlBox(location string) *DataEntryUrlBox {
|
|
return &DataEntryUrlBox{
|
|
FullBox: FullBox{
|
|
BaseBox: BaseBox{
|
|
typ: TypeURL,
|
|
size: uint32(FullBoxLen + len(location)),
|
|
},
|
|
Version: 0,
|
|
Flags: [3]byte{0, 0, 1}, // self-contained flag
|
|
},
|
|
Location: location,
|
|
}
|
|
}
|
|
|
|
func CreateDataEntryUrnBox(name, location string) *DataEntryUrnBox {
|
|
return &DataEntryUrnBox{
|
|
FullBox: FullBox{
|
|
BaseBox: BaseBox{
|
|
typ: TypeURN,
|
|
size: uint32(FullBoxLen + len(name) + 1 + len(location)),
|
|
},
|
|
Version: 0,
|
|
Flags: [3]byte{0, 0, 0},
|
|
},
|
|
Name: name,
|
|
Location: location,
|
|
}
|
|
}
|
|
|
|
func (box *DataInformationBox) WriteTo(w io.Writer) (n int64, err error) {
|
|
return WriteTo(w, box.Dref)
|
|
}
|
|
|
|
func (box *DataInformationBox) Unmarshal(buf []byte) (b IBox, err error) {
|
|
b, err = ReadFrom(bytes.NewReader(buf))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if dref, ok := b.(*DataReferenceBox); ok {
|
|
box.Dref = dref
|
|
}
|
|
return box, nil
|
|
}
|
|
|
|
func (box *DataReferenceBox) WriteTo(w io.Writer) (n int64, err error) {
|
|
var tmp [4]byte
|
|
binary.BigEndian.PutUint32(tmp[:], uint32(len(box.Entries)))
|
|
nn, err := w.Write(tmp[:])
|
|
if err != nil {
|
|
return int64(nn), err
|
|
}
|
|
n = int64(nn)
|
|
|
|
for _, entry := range box.Entries {
|
|
var en int64
|
|
en, err = WriteTo(w, entry)
|
|
if err != nil {
|
|
return
|
|
}
|
|
n += en
|
|
}
|
|
return
|
|
}
|
|
|
|
func (box *DataReferenceBox) Unmarshal(buf []byte) (IBox, error) {
|
|
if len(buf) < 4 {
|
|
return nil, io.ErrShortBuffer
|
|
}
|
|
entryCount := binary.BigEndian.Uint32(buf)
|
|
r := bytes.NewReader(buf[4:])
|
|
box.Entries = make([]IBox, 0, entryCount)
|
|
|
|
for i := uint32(0); i < entryCount; i++ {
|
|
entry, err := ReadFrom(r)
|
|
if err != nil {
|
|
break
|
|
}
|
|
box.Entries = append(box.Entries, entry)
|
|
}
|
|
return box, nil
|
|
}
|
|
|
|
func (box *DataEntryUrlBox) WriteTo(w io.Writer) (n int64, err error) {
|
|
if len(box.Location) > 0 {
|
|
nn, err := w.Write([]byte(box.Location))
|
|
return int64(nn), err
|
|
}
|
|
return 0, nil
|
|
}
|
|
|
|
func (box *DataEntryUrlBox) Unmarshal(buf []byte) (IBox, error) {
|
|
if len(buf) > 0 {
|
|
box.Location = string(buf)
|
|
}
|
|
return box, nil
|
|
}
|
|
|
|
func (box *DataEntryUrnBox) WriteTo(w io.Writer) (n int64, err error) {
|
|
nn, err := w.Write([]byte(box.Name + "\x00" + box.Location))
|
|
return int64(nn), err
|
|
}
|
|
|
|
func (box *DataEntryUrnBox) Unmarshal(buf []byte) (IBox, error) {
|
|
parts := bytes.SplitN(buf, []byte{0}, 2)
|
|
if len(parts) > 0 {
|
|
box.Name = string(parts[0])
|
|
if len(parts) > 1 {
|
|
box.Location = string(parts[1])
|
|
}
|
|
}
|
|
return box, nil
|
|
}
|
|
|
|
func init() {
|
|
RegisterBox[*DataInformationBox](TypeDINF)
|
|
RegisterBox[*DataReferenceBox](TypeDREF)
|
|
RegisterBox[*DataEntryUrlBox](TypeURL)
|
|
RegisterBox[*DataEntryUrnBox](TypeURN)
|
|
}
|