From ea26f04c107e32732471dd2c3771636afaf71195 Mon Sep 17 00:00:00 2001 From: nareix Date: Mon, 4 Jul 2016 23:04:55 +0800 Subject: [PATCH] add format aac.go --- format/aac/aac.go | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 format/aac/aac.go diff --git a/format/aac/aac.go b/format/aac/aac.go new file mode 100644 index 0000000..7a31b1d --- /dev/null +++ b/format/aac/aac.go @@ -0,0 +1,119 @@ + +package aac + +import ( + "github.com/nareix/joy4/av/avutil" + "github.com/nareix/joy4/av" + "github.com/nareix/joy4/codec/aacparser" + "time" + "fmt" + "io" + "bufio" +) + +type Muxer struct { + w io.Writer + config aacparser.MPEG4AudioConfig + adtshdr []byte +} + +func NewMuxer(w io.Writer) *Muxer { + return &Muxer{ + adtshdr: make([]byte, aacparser.ADTSHeaderLength), + w: w, + } +} + +func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) { + if len(streams) > 1 || streams[0].Type() != av.AAC { + err = fmt.Errorf("aac: must be only one aac stream") + return + } + self.config = streams[0].(aacparser.CodecData).Config + return +} + +func (self *Muxer) WritePacket(pkt av.Packet) (err error) { + aacparser.FillADTSHeader(self.adtshdr, self.config, 1024, len(pkt.Data)) + if _, err = self.w.Write(self.adtshdr); err != nil { + return + } + if _, err = self.w.Write(pkt.Data); err != nil { + return + } + return +} + +func (self *Muxer) WriteTrailer() (err error) { + return +} + +type Demuxer struct { + r *bufio.Reader + config aacparser.MPEG4AudioConfig + codecdata av.CodecData + ts time.Duration +} + +func NewDemuxer(r io.Reader) *Demuxer { + return &Demuxer{ + r: bufio.NewReader(r), + } +} + +func (self *Demuxer) Streams() (streams []av.CodecData, err error) { + if self.codecdata == nil { + var adtshdr []byte + var config aacparser.MPEG4AudioConfig + if adtshdr, err = self.r.Peek(9); err != nil { + return + } + if config, _, _, _, err = aacparser.ParseADTSHeader(adtshdr); err != nil { + return + } + if self.codecdata, err = aacparser.NewCodecDataFromMPEG4AudioConfig(config); err != nil { + return + } + } + streams = []av.CodecData{self.codecdata} + return +} + +func (self *Demuxer) ReadPacket() (pkt av.Packet, err error) { + var adtshdr []byte + var config aacparser.MPEG4AudioConfig + var hdrlen, framelen, samples int + if adtshdr, err = self.r.Peek(9); err != nil { + return + } + if config, hdrlen, framelen, samples, err = aacparser.ParseADTSHeader(adtshdr); err != nil { + return + } + + pkt.Data = make([]byte, framelen) + if _, err = io.ReadFull(self.r, pkt.Data); err != nil { + return + } + pkt.Data = pkt.Data[hdrlen:] + + pkt.Time = self.ts + self.ts += time.Duration(samples) * time.Second / time.Duration(config.SampleRate) + return +} + +func Handler(h *avutil.RegisterHandler) { + h.Ext = ".aac" + + h.ReaderDemuxer = func(r io.Reader) av.Demuxer { + return NewDemuxer(r) + } + + h.WriterMuxer = func(w io.Writer) av.Muxer { + return NewMuxer(w) + } + + h.Probe = func(b []byte) bool { + _, _, _, _, err := aacparser.ParseADTSHeader(b) + return err == nil + } +}