diff --git a/demuxer.go b/demuxer.go index 89c4c1d..7770df8 100644 --- a/demuxer.go +++ b/demuxer.go @@ -2,6 +2,7 @@ package mp4 import ( "bytes" + "time" "fmt" "github.com/nareix/av" "github.com/nareix/codec/aacparser" @@ -322,28 +323,28 @@ func (self *Demuxer) ReadPacket() (streamIndex int, pkt av.Packet, err error) { return } -func (self *Demuxer) CurrentTime() (time float32) { +func (self *Demuxer) CurrentTime() (tm time.Duration) { if len(self.streams) > 0 { stream := self.streams[0] - time = stream.tsToTime(stream.dts) + tm = stream.tsToTime(stream.dts) } return } -func (self *Demuxer) SeekToTime(time float32) (err error) { +func (self *Demuxer) SeekToTime(tm time.Duration) (err error) { for _, stream := range self.streams { - if stream.IsVideo() { - if err = stream.seekToTime(time); err != nil { + if stream.Type().IsVideo() { + if err = stream.seekToTime(tm); err != nil { return } - time = stream.tsToTime(stream.dts) + tm = stream.tsToTime(stream.dts) break } } for _, stream := range self.streams { - if !stream.IsVideo() { - if err = stream.seekToTime(time); err != nil { + if !stream.Type().IsVideo() { + if err = stream.seekToTime(tm); err != nil { return } } @@ -395,19 +396,19 @@ func (self *Stream) readPacket() (pkt av.Packet, err error) { return } -func (self *Stream) seekToTime(time float32) (err error) { - index := self.timeToSampleIndex(time) +func (self *Stream) seekToTime(tm time.Duration) (err error) { + index := self.timeToSampleIndex(tm) if err = self.setSampleIndex(index); err != nil { return } if false { - fmt.Printf("stream[%d]: seekToTime index=%v time=%v cur=%v\n", self.idx, index, time, self.tsToTime(self.dts)) + fmt.Printf("stream[%d]: seekToTime index=%v time=%v cur=%v\n", self.idx, index, tm, self.tsToTime(self.dts)) } return } -func (self *Stream) timeToSampleIndex(time float32) int { - targetTs := self.timeToTs(time) +func (self *Stream) timeToSampleIndex(tm time.Duration) int { + targetTs := self.timeToTs(tm) targetIndex := 0 startTs := int64(0) diff --git a/muxer.go b/muxer.go index 4493f1f..ab7e801 100644 --- a/muxer.go +++ b/muxer.go @@ -3,6 +3,7 @@ package mp4 import ( "bytes" "fmt" + "time" "github.com/nareix/av" "github.com/nareix/codec/aacparser" "github.com/nareix/codec/h264parser" @@ -162,7 +163,7 @@ func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) { return } for _, stream := range self.streams { - if stream.IsVideo() { + if stream.Type().IsVideo() { stream.sample.CompositionOffset = &atom.CompositionOffset{} } } @@ -184,7 +185,7 @@ func (self *Muxer) WritePacket(streamIndex int, pkt av.Packet) (err error) { } newpkt := pkt newpkt.Data = payload - newpkt.Duration = float32(samples) / float32(sampleRate) + newpkt.Duration = time.Duration(samples)*time.Second / time.Duration(sampleRate) if err = stream.writePacket(newpkt); err != nil { return } @@ -258,21 +259,21 @@ func (self *Muxer) WriteTrailer() (err error) { NextTrackId: 2, } - maxDur := float32(0) - timeScale := 10000 + maxDur := time.Duration(0) + timeScale := int64(10000) for _, stream := range self.streams { if err = stream.fillTrackAtom(); err != nil { return } dur := stream.tsToTime(stream.duration) - stream.trackAtom.Header.Duration = int(float32(timeScale) * dur) + stream.trackAtom.Header.Duration = int(timeToTs(dur, timeScale)) if dur > maxDur { maxDur = dur } moov.Tracks = append(moov.Tracks, stream.trackAtom) } - moov.Header.TimeScale = timeScale - moov.Header.Duration = int(float32(timeScale) * maxDur) + moov.Header.TimeScale = int(timeScale) + moov.Header.Duration = int(timeToTs(maxDur, timeScale)) if err = self.mdatWriter.Close(); err != nil { return diff --git a/stream.go b/stream.go index e2544dc..76f28ba 100644 --- a/stream.go +++ b/stream.go @@ -3,6 +3,7 @@ package mp4 import ( "github.com/nareix/av" "github.com/nareix/mp4/atom" + "time" "io" ) @@ -39,10 +40,18 @@ type Stream struct { cttsEntry *atom.CompositionOffsetEntry } -func (self *Stream) timeToTs(time float32) int64 { - return int64(time * float32(self.timeScale)) +func timeToTs(tm time.Duration, timeScale int64) int64 { + return int64(tm*time.Duration(timeScale) / time.Second) } -func (self *Stream) tsToTime(ts int64) float32 { - return float32(ts) / float32(self.timeScale) +func tsToTime(ts int64, timeScale int64) time.Duration { + return time.Duration(ts)*time.Second / time.Duration(timeScale) +} + +func (self *Stream) timeToTs(tm time.Duration) int64 { + return int64(tm*time.Duration(self.timeScale) / time.Second) +} + +func (self *Stream) tsToTime(ts int64) time.Duration { + return time.Duration(ts)*time.Second / time.Duration(self.timeScale) }