Fix AAC inside MP4

This commit is contained in:
Alexey Khit
2023-05-25 06:49:04 +03:00
parent bff9b06d5d
commit 1612f9c81e
3 changed files with 38 additions and 17 deletions
+21 -5
View File
@@ -9,6 +9,8 @@ import (
const RTPPacketVersionAAC = 0 const RTPPacketVersionAAC = 0
func RTPDepay(handler core.HandlerFunc) core.HandlerFunc { func RTPDepay(handler core.HandlerFunc) core.HandlerFunc {
var timestamp uint32
return func(packet *rtp.Packet) { return func(packet *rtp.Packet) {
// support ONLY 2 bytes header size! // support ONLY 2 bytes header size!
// streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1408 // streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1408
@@ -16,16 +18,30 @@ 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) //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:] headers := packet.Payload[2 : 2+headersSize]
if IsADTS(data) { units := packet.Payload[2+headersSize:]
data = data[7:]
} for len(headers) > 0 {
unitSize := binary.BigEndian.Uint16(headers) >> 3
unit := units[:unitSize]
headers = headers[2:]
units = units[unitSize:]
timestamp += 1024
clone := *packet clone := *packet
clone.Version = RTPPacketVersionAAC clone.Version = RTPPacketVersionAAC
clone.Payload = data clone.Timestamp = timestamp
if IsADTS(unit) {
clone.Payload = unit[7:]
} else {
clone.Payload = unit
}
handler(&clone) handler(&clone)
} }
}
} }
func RTPPay(handler core.HandlerFunc) core.HandlerFunc { func RTPPay(handler core.HandlerFunc) core.HandlerFunc {
+1
View File
@@ -40,6 +40,7 @@ const (
SampleVideoIFrame = sampleDependsOn2 SampleVideoIFrame = sampleDependsOn2
SampleVideoNonIFrame = sampleDependsOn1 | sampleIsNonSync SampleVideoNonIFrame = sampleDependsOn1 | sampleIsNonSync
SampleAudio = sampleIsNonSync SampleAudio = sampleIsNonSync
SampleAudioAAC = sampleDependsOn2
) )
func (m *Movie) WriteFileType() { func (m *Movie) WriteFileType() {
+13 -9
View File
@@ -151,19 +151,14 @@ func (m *Muxer) Reset() {
func (m *Muxer) Marshal(trackID byte, packet *rtp.Packet) []byte { func (m *Muxer) Marshal(trackID byte, packet *rtp.Packet) []byte {
codec := m.codecs[trackID] codec := m.codecs[trackID]
m.fragIndex++
duration := packet.Timestamp - m.pts[trackID] duration := packet.Timestamp - m.pts[trackID]
m.pts[trackID] = packet.Timestamp 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 // flags important for Apple Finder video preview
var flags uint32 var flags uint32
switch codec.Name { switch codec.Name {
case core.CodecH264: case core.CodecH264:
if h264.IsKeyframe(packet.Payload) { if h264.IsKeyframe(packet.Payload) {
@@ -177,11 +172,20 @@ func (m *Muxer) Marshal(trackID byte, packet *rtp.Packet) []byte {
} else { } else {
flags = iso.SampleVideoNonIFrame flags = iso.SampleVideoNonIFrame
} }
case core.CodecAAC:
duration = 1024 // important for Apple Finder and QuickTime
flags = iso.SampleAudioAAC // not important
default: default:
flags = iso.SampleAudio // not important 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 := iso.NewMovie(1024 + size)
mv.WriteMovieFragment( mv.WriteMovieFragment(