adjust newapi
This commit is contained in:
parent
25ee94037e
commit
eec4063cf9
29
demuxer.go
29
demuxer.go
@ -6,9 +6,20 @@ import (
|
|||||||
"github.com/nareix/av"
|
"github.com/nareix/av"
|
||||||
"github.com/nareix/mp4/atom"
|
"github.com/nareix/mp4/atom"
|
||||||
"github.com/nareix/mp4/isom"
|
"github.com/nareix/mp4/isom"
|
||||||
|
"github.com/nareix/codec/aacparser"
|
||||||
|
"github.com/nareix/codec/h264parser"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Open(R io.ReadSeeker) (demuxer *Demuxer, err error) {
|
||||||
|
_demuxer := &Demuxer{R: R}
|
||||||
|
if err = _demuxer.ReadHeader(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
demuxer = _demuxer
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type Demuxer struct {
|
type Demuxer struct {
|
||||||
R io.ReadSeeker
|
R io.ReadSeeker
|
||||||
|
|
||||||
@ -16,7 +27,7 @@ type Demuxer struct {
|
|||||||
movieAtom *atom.Movie
|
movieAtom *atom.Movie
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Demuxer) Streams() (streams []av.Stream) {
|
func (self *Demuxer) Streams() (streams []av.CodecData) {
|
||||||
for _, stream := range self.streams {
|
for _, stream := range self.streams {
|
||||||
streams = append(streams, stream)
|
streams = append(streams, stream)
|
||||||
}
|
}
|
||||||
@ -76,19 +87,17 @@ func (self *Demuxer) ReadHeader() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if avc1 := atom.GetAvc1ConfByTrack(atrack); avc1 != nil {
|
if avc1 := atom.GetAvc1ConfByTrack(atrack); avc1 != nil {
|
||||||
stream.SetType(av.H264)
|
if stream.CodecData, err = h264parser.NewCodecDataFromAVCDecoderConfRecord(avc1.Data); err != nil {
|
||||||
if err = stream.SetCodecData(avc1.Data); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.streams = append(self.streams, stream)
|
self.streams = append(self.streams, stream)
|
||||||
|
|
||||||
} else if mp4a := atom.GetMp4aDescByTrack(atrack); mp4a != nil && mp4a.Conf != nil {
|
} else if mp4a := atom.GetMp4aDescByTrack(atrack); mp4a != nil && mp4a.Conf != nil {
|
||||||
stream.SetType(av.AAC)
|
|
||||||
var config []byte
|
var config []byte
|
||||||
if config, err = isom.ReadElemStreamDesc(bytes.NewReader(mp4a.Conf.Data)); err != nil {
|
if config, err = isom.ReadElemStreamDesc(bytes.NewReader(mp4a.Conf.Data)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = stream.SetCodecData(config); err != nil {
|
if stream.CodecData, err = aacparser.NewCodecDataFromMPEG4AudioConfigBytes(config); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.streams = append(self.streams, stream)
|
self.streams = append(self.streams, stream)
|
||||||
@ -295,17 +304,17 @@ func (self *Stream) sampleCount() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Demuxer) ReadPacket() (streamIndex int, pkt av.Packet, err error) {
|
func (self *Demuxer) ReadPacket() (streamIndex int, pkt av.Packet, err error) {
|
||||||
var choose *Stream
|
var chosen *Stream
|
||||||
for i, stream := range self.streams {
|
for i, stream := range self.streams {
|
||||||
if choose == nil || stream.tsToTime(stream.dts) < choose.tsToTime(choose.dts) {
|
if chosen == nil || stream.tsToTime(stream.dts) < chosen.tsToTime(chosen.dts) {
|
||||||
choose = stream
|
chosen = stream
|
||||||
streamIndex = i
|
streamIndex = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if false {
|
if false {
|
||||||
fmt.Printf("ReadPacket: choose index=%v time=%v\n", choose.idx, choose.tsToTime(choose.dts))
|
fmt.Printf("ReadPacket: chosen index=%v time=%v\n", chosen.idx, chosen.tsToTime(chosen.dts))
|
||||||
}
|
}
|
||||||
pkt, err = choose.readPacket()
|
pkt, err = chosen.readPacket()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
41
muxer.go
41
muxer.go
@ -11,14 +11,23 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func Create(W io.WriteSeeker, streams []av.CodecData) (muxer *Muxer, err error) {
|
||||||
|
_muxer := &Muxer{W: W}
|
||||||
|
if err = _muxer.WriteHeader(streams); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
muxer = _muxer
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
type Muxer struct {
|
type Muxer struct {
|
||||||
W io.WriteSeeker
|
W io.WriteSeeker
|
||||||
streams []*Stream
|
streams []*Stream
|
||||||
mdatWriter *atom.Writer
|
mdatWriter *atom.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Muxer) NewStream() av.Stream {
|
func (self *Muxer) NewStream(codec av.CodecData) (err error) {
|
||||||
stream := &Stream{}
|
stream := &Stream{CodecData: codec}
|
||||||
|
|
||||||
stream.sample = &atom.SampleTable{
|
stream.sample = &atom.SampleTable{
|
||||||
SampleDesc: &atom.SampleDesc{},
|
SampleDesc: &atom.SampleDesc{},
|
||||||
@ -66,7 +75,7 @@ func (self *Muxer) NewStream() av.Stream {
|
|||||||
stream.muxer = self
|
stream.muxer = self
|
||||||
self.streams = append(self.streams, stream)
|
self.streams = append(self.streams, stream)
|
||||||
|
|
||||||
return stream
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Stream) fillTrackAtom() (err error) {
|
func (self *Stream) fillTrackAtom() (err error) {
|
||||||
@ -74,7 +83,8 @@ func (self *Stream) fillTrackAtom() (err error) {
|
|||||||
self.trackAtom.Media.Header.Duration = int(self.duration)
|
self.trackAtom.Media.Header.Duration = int(self.duration)
|
||||||
|
|
||||||
if self.Type() == av.H264 {
|
if self.Type() == av.H264 {
|
||||||
width, height := self.Width(), self.Height()
|
codec := self.CodecData.(av.H264CodecData)
|
||||||
|
width, height := codec.Width(), codec.Height()
|
||||||
self.sample.SampleDesc.Avc1Desc = &atom.Avc1Desc{
|
self.sample.SampleDesc.Avc1Desc = &atom.Avc1Desc{
|
||||||
DataRefIdx: 1,
|
DataRefIdx: 1,
|
||||||
HorizontalResolution: 72,
|
HorizontalResolution: 72,
|
||||||
@ -84,7 +94,7 @@ func (self *Stream) fillTrackAtom() (err error) {
|
|||||||
FrameCount: 1,
|
FrameCount: 1,
|
||||||
Depth: 24,
|
Depth: 24,
|
||||||
ColorTableId: -1,
|
ColorTableId: -1,
|
||||||
Conf: &atom.Avc1Conf{Data: self.CodecData()},
|
Conf: &atom.Avc1Conf{Data: codec.AVCDecoderConfRecordBytes()},
|
||||||
}
|
}
|
||||||
self.sample.SyncSample = &atom.SyncSample{}
|
self.sample.SyncSample = &atom.SyncSample{}
|
||||||
self.trackAtom.Media.Handler = &atom.HandlerRefer{
|
self.trackAtom.Media.Handler = &atom.HandlerRefer{
|
||||||
@ -98,15 +108,16 @@ func (self *Stream) fillTrackAtom() (err error) {
|
|||||||
self.trackAtom.Header.TrackHeight = atom.IntToFixed(int(height))
|
self.trackAtom.Header.TrackHeight = atom.IntToFixed(int(height))
|
||||||
|
|
||||||
} else if self.Type() == av.AAC {
|
} else if self.Type() == av.AAC {
|
||||||
|
codec := self.CodecData.(av.AACCodecData)
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
if err = isom.WriteElemStreamDesc(buf, self.CodecData(), uint(self.trackAtom.Header.TrackId)); err != nil {
|
if err = isom.WriteElemStreamDesc(buf, codec.MPEG4AudioConfigBytes(), uint(self.trackAtom.Header.TrackId)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.sample.SampleDesc.Mp4aDesc = &atom.Mp4aDesc{
|
self.sample.SampleDesc.Mp4aDesc = &atom.Mp4aDesc{
|
||||||
DataRefIdx: 1,
|
DataRefIdx: 1,
|
||||||
NumberOfChannels: self.ChannelCount(),
|
NumberOfChannels: codec.ChannelCount(),
|
||||||
SampleSize: self.ChannelCount() * 8,
|
SampleSize: codec.ChannelCount() * 8,
|
||||||
SampleRate: atom.IntToFixed(self.SampleRate()),
|
SampleRate: atom.IntToFixed(codec.SampleRate()),
|
||||||
Conf: &atom.ElemStreamDesc{
|
Conf: &atom.ElemStreamDesc{
|
||||||
Data: buf.Bytes(),
|
Data: buf.Bytes(),
|
||||||
},
|
},
|
||||||
@ -126,12 +137,18 @@ func (self *Stream) fillTrackAtom() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Muxer) WriteHeader() (err error) {
|
func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) {
|
||||||
|
for _, stream := range streams {
|
||||||
|
if err = self.NewStream(stream); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self.mdatWriter, err = atom.WriteAtomHeader(self.W, "mdat"); err != nil {
|
if self.mdatWriter, err = atom.WriteAtomHeader(self.W, "mdat"); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, stream := range self.streams {
|
for _, stream := range self.streams {
|
||||||
if stream.Type().IsVideo() {
|
if stream.IsVideo() {
|
||||||
stream.sample.CompositionOffset = &atom.CompositionOffset{}
|
stream.sample.CompositionOffset = &atom.CompositionOffset{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +160,7 @@ func (self *Muxer) WritePacket(streamIndex int, pkt av.Packet) (err error) {
|
|||||||
frame := pkt.Data
|
frame := pkt.Data
|
||||||
|
|
||||||
if stream.Type() == av.AAC && aacparser.IsADTSFrame(frame) {
|
if stream.Type() == av.AAC && aacparser.IsADTSFrame(frame) {
|
||||||
sampleRate := stream.SampleRate()
|
sampleRate := stream.CodecData.(av.AudioCodecData).SampleRate()
|
||||||
for len(frame) > 0 {
|
for len(frame) > 0 {
|
||||||
var payload []byte
|
var payload []byte
|
||||||
var samples int
|
var samples int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user