From 1612f9c81e3714d6c431f4e078b628dfed327169 Mon Sep 17 00:00:00 2001 From: Alexey Khit Date: Thu, 25 May 2023 06:49:04 +0300 Subject: [PATCH] Fix AAC inside MP4 --- pkg/aac/rtp.go | 32 ++++++++++++++++++++++++-------- pkg/iso/atoms.go | 1 + pkg/mp4/muxer.go | 22 +++++++++++++--------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/pkg/aac/rtp.go b/pkg/aac/rtp.go index ba3dfce9..ec92ebad 100644 --- a/pkg/aac/rtp.go +++ b/pkg/aac/rtp.go @@ -9,6 +9,8 @@ import ( const RTPPacketVersionAAC = 0 func RTPDepay(handler core.HandlerFunc) core.HandlerFunc { + var timestamp uint32 + return func(packet *rtp.Packet) { // support ONLY 2 bytes header size! // streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1408 @@ -16,15 +18,29 @@ func RTPDepay(handler core.HandlerFunc) core.HandlerFunc { //log.Printf("[RTP/AAC] units: %d, size: %4d, ts: %10d, %t", headersSize/2, len(packet.Payload), packet.Timestamp, packet.Marker) - data := packet.Payload[2+headersSize:] - if IsADTS(data) { - data = data[7:] - } + headers := packet.Payload[2 : 2+headersSize] + units := packet.Payload[2+headersSize:] - clone := *packet - clone.Version = RTPPacketVersionAAC - clone.Payload = data - handler(&clone) + for len(headers) > 0 { + unitSize := binary.BigEndian.Uint16(headers) >> 3 + + unit := units[:unitSize] + + headers = headers[2:] + units = units[unitSize:] + + timestamp += 1024 + + clone := *packet + clone.Version = RTPPacketVersionAAC + clone.Timestamp = timestamp + if IsADTS(unit) { + clone.Payload = unit[7:] + } else { + clone.Payload = unit + } + handler(&clone) + } } } diff --git a/pkg/iso/atoms.go b/pkg/iso/atoms.go index 6a4c9fe7..174f16ea 100644 --- a/pkg/iso/atoms.go +++ b/pkg/iso/atoms.go @@ -40,6 +40,7 @@ const ( SampleVideoIFrame = sampleDependsOn2 SampleVideoNonIFrame = sampleDependsOn1 | sampleIsNonSync SampleAudio = sampleIsNonSync + SampleAudioAAC = sampleDependsOn2 ) func (m *Movie) WriteFileType() { diff --git a/pkg/mp4/muxer.go b/pkg/mp4/muxer.go index b1ec37f4..8f9afc4c 100644 --- a/pkg/mp4/muxer.go +++ b/pkg/mp4/muxer.go @@ -151,19 +151,14 @@ func (m *Muxer) Reset() { func (m *Muxer) Marshal(trackID byte, packet *rtp.Packet) []byte { codec := m.codecs[trackID] + m.fragIndex++ + duration := packet.Timestamp - m.pts[trackID] m.pts[trackID] = packet.Timestamp - // minumum duration important for MSE in Apple Safari - if duration == 0 || duration > codec.ClockRate { - duration = codec.ClockRate/1000 + 1 - m.pts[trackID] += duration - } - - size := len(packet.Payload) - // flags important for Apple Finder video preview var flags uint32 + switch codec.Name { case core.CodecH264: if h264.IsKeyframe(packet.Payload) { @@ -177,11 +172,20 @@ func (m *Muxer) Marshal(trackID byte, packet *rtp.Packet) []byte { } else { flags = iso.SampleVideoNonIFrame } + case core.CodecAAC: + duration = 1024 // important for Apple Finder and QuickTime + flags = iso.SampleAudioAAC // not important default: flags = iso.SampleAudio // not important } - m.fragIndex++ + // minumum duration important for MSE in Apple Safari + if duration == 0 || duration > codec.ClockRate { + duration = codec.ClockRate/1000 + 1 + m.pts[trackID] += duration + } + + size := len(packet.Payload) mv := iso.NewMovie(1024 + size) mv.WriteMovieFragment(