add format aac.go
This commit is contained in:
parent
9fad1bb467
commit
ea26f04c10
119
format/aac/aac.go
Normal file
119
format/aac/aac.go
Normal file
@ -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
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user