From 37fe5058b48cbc695e05c315a414c6c2ba594332 Mon Sep 17 00:00:00 2001 From: nareix Date: Sun, 22 Nov 2015 11:53:36 +0800 Subject: [PATCH] can extract mp4aConf --- atom/genStruct.js | 20 ++++++++ atom/struct.go | 126 +++++++++++++++++++++++++++++++++++++++++++++- example/read.go | 12 +++-- mp4.go | 4 +- 4 files changed, 154 insertions(+), 8 deletions(-) diff --git a/atom/genStruct.js b/atom/genStruct.js index 082e2a7..95354fb 100644 --- a/atom/genStruct.js +++ b/atom/genStruct.js @@ -167,6 +167,26 @@ var atoms = { mp4aDesc: { cc4: 'mp4a', fields: [ + ['_', '[6]byte'], + ['dataRefIdx', 'int16'], + ['version', 'int16'], + ['revisionLevel', 'int16'], + ['vendor', 'int32'], + ['numberOfChannels', 'int16'], + ['sampleSize', 'int16'], + ['compressionId', 'int16'], + ['_', 'int16'], + ['sampleRate', 'Fixed32'], + ['$atoms', [ + ['conf', '*elemStreamDesc'], + ]], + ], + }, + + elemStreamDesc: { + cc4: 'esds', + fields: [ + ['version', 'int32'], ['data', '[]byte'], ], }, diff --git a/atom/struct.go b/atom/struct.go index 2d0083a..548a2b7 100644 --- a/atom/struct.go +++ b/atom/struct.go @@ -984,15 +984,69 @@ func WriteSampleDesc(w io.WriteSeeker, self *SampleDesc) (err error) { } type Mp4aDesc struct { - Data []byte + DataRefIdx int + Version int + RevisionLevel int + Vendor int + NumberOfChannels int + SampleSize int + CompressionId int + SampleRate Fixed + Conf *ElemStreamDesc } func ReadMp4aDesc(r *io.LimitedReader) (res *Mp4aDesc, err error) { self := &Mp4aDesc{} - if self.Data, err = ReadBytes(r, int(r.N)); err != nil { + if _, err = ReadDummy(r, 6); err != nil { return } + if self.DataRefIdx, err = ReadInt(r, 2); err != nil { + return + } + if self.Version, err = ReadInt(r, 2); err != nil { + return + } + if self.RevisionLevel, err = ReadInt(r, 2); err != nil { + return + } + if self.Vendor, err = ReadInt(r, 4); err != nil { + return + } + if self.NumberOfChannels, err = ReadInt(r, 2); err != nil { + return + } + if self.SampleSize, err = ReadInt(r, 2); err != nil { + return + } + if self.CompressionId, err = ReadInt(r, 2); err != nil { + return + } + if _, err = ReadDummy(r, 2); err != nil { + return + } + if self.SampleRate, err = ReadFixed(r, 4); err != nil { + return + } + for r.N > 0 { + var cc4 string + var ar *io.LimitedReader + if ar, cc4, err = ReadAtomHeader(r, ""); err != nil { + return + } + switch cc4 { + case "esds": + { + if self.Conf, err = ReadElemStreamDesc(ar); err != nil { + return + } + } + + } + if _, err = ReadDummy(ar, int(ar.N)); err != nil { + return + } + } res = self return } @@ -1003,6 +1057,74 @@ func WriteMp4aDesc(w io.WriteSeeker, self *Mp4aDesc) (err error) { return } w = aw + if err = WriteDummy(w, 6); err != nil { + return + } + if err = WriteInt(w, self.DataRefIdx, 2); err != nil { + return + } + if err = WriteInt(w, self.Version, 2); err != nil { + return + } + if err = WriteInt(w, self.RevisionLevel, 2); err != nil { + return + } + if err = WriteInt(w, self.Vendor, 4); err != nil { + return + } + if err = WriteInt(w, self.NumberOfChannels, 2); err != nil { + return + } + if err = WriteInt(w, self.SampleSize, 2); err != nil { + return + } + if err = WriteInt(w, self.CompressionId, 2); err != nil { + return + } + if err = WriteDummy(w, 2); err != nil { + return + } + if err = WriteFixed(w, self.SampleRate, 4); err != nil { + return + } + if self.Conf != nil { + if err = WriteElemStreamDesc(w, self.Conf); err != nil { + return + } + } + if err = aw.Close(); err != nil { + return + } + return +} + +type ElemStreamDesc struct { + Version int + Data []byte +} + +func ReadElemStreamDesc(r *io.LimitedReader) (res *ElemStreamDesc, err error) { + + self := &ElemStreamDesc{} + if self.Version, err = ReadInt(r, 4); err != nil { + return + } + if self.Data, err = ReadBytes(r, int(r.N)); err != nil { + return + } + res = self + return +} +func WriteElemStreamDesc(w io.WriteSeeker, self *ElemStreamDesc) (err error) { + + var aw *Writer + if aw, err = WriteAtomHeader(w, "esds"); err != nil { + return + } + w = aw + if err = WriteInt(w, self.Version, 4); err != nil { + return + } if err = WriteBytes(w, self.Data, len(self.Data)); err != nil { return } diff --git a/example/read.go b/example/read.go index f6e0a14..1cfa22a 100644 --- a/example/read.go +++ b/example/read.go @@ -3,13 +3,19 @@ package main import ( mp4 "./.." + "flag" "log" ) func main() { - if _, err := mp4.Open("mid.mp4"); err != nil { - log.Println(err) - return + testconv := flag.Bool("testconv", false, "") + flag.Parse() + + if *testconv { + if _, err := mp4.TestConvert(flag.Arg(0)); err != nil { + log.Println(err) + return + } } } diff --git a/mp4.go b/mp4.go index d96328e..cb14d41 100644 --- a/mp4.go +++ b/mp4.go @@ -64,13 +64,11 @@ func changeMoov(moov *atom.Movie) { } } - /* if mp4a := desc.Mp4aDesc; mp4a != nil { if conf := mp4a.Conf; conf != nil { log.Println("mp4a", hex.Dump(conf.Data)) } } - */ } } @@ -78,7 +76,7 @@ func changeMoov(moov *atom.Movie) { } } -func Open(filename string) (file *File, err error) { +func TestConvert(filename string) (file *File, err error) { var osfile *os.File if osfile, err = os.Open(filename); err != nil { return