forked from nareix/joy4
/
aac.go
124 lines (106 loc) · 2.64 KB
/
aac.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
if self.config.ObjectType > aacparser.AOT_AAC_LTP {
err = fmt.Errorf("aac: AOT %d is not allowed in ADTS", self.config.ObjectType)
}
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
}
h.CodecTypes = []av.CodecType{av.AAC}
}