Add support OPUS, MP3, PCMU, PCMA for MP4

This commit is contained in:
Alexey Khit
2023-01-27 17:11:44 +03:00
parent e93d89ec96
commit 69dd4d26ec
3 changed files with 52 additions and 25 deletions
+50 -22
View File
@@ -2,22 +2,13 @@ package iso
import "github.com/AlexxIT/go2rtc/pkg/streamer"
const (
MoovTrakMdiaMinfStblStsdAvc1 = "avc1"
MoovTrakMdiaMinfStblStsdAvc1AvcC = "avcC"
MoovTrakMdiaMinfStblStsdHev1 = "hev1"
MoovTrakMdiaMinfStblStsdHev1HvcC = "hvcC"
MoovTrakMdiaMinfStblStsdMp4a = "mp4a"
MoovTrakMdiaMinfStblStsdOpus = "Opus"
)
func (m *Movie) WriteVideo(codec string, width, height uint16, conf []byte) {
// https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
switch codec {
case streamer.CodecH264:
m.StartAtom(MoovTrakMdiaMinfStblStsdAvc1)
m.StartAtom("avc1")
case streamer.CodecH265:
m.StartAtom(MoovTrakMdiaMinfStblStsdHev1)
m.StartAtom("hev1")
default:
panic("unsupported iso video: " + codec)
}
@@ -40,9 +31,9 @@ func (m *Movie) WriteVideo(codec string, width, height uint16, conf []byte) {
switch codec {
case streamer.CodecH264:
m.StartAtom(MoovTrakMdiaMinfStblStsdAvc1AvcC)
m.StartAtom("avcC")
case streamer.CodecH265:
m.StartAtom(MoovTrakMdiaMinfStblStsdHev1HvcC)
m.StartAtom("hvcC")
}
m.Write(conf)
m.EndAtom() // AVCC
@@ -52,10 +43,14 @@ func (m *Movie) WriteVideo(codec string, width, height uint16, conf []byte) {
func (m *Movie) WriteAudio(codec string, channels uint16, sampleRate uint32, conf []byte) {
switch codec {
case streamer.CodecAAC:
m.StartAtom(MoovTrakMdiaMinfStblStsdMp4a)
case streamer.CodecAAC, streamer.CodecMP3:
m.StartAtom("mp4a")
case streamer.CodecOpus:
m.StartAtom(MoovTrakMdiaMinfStblStsdOpus)
m.StartAtom("Opus")
case streamer.CodecPCMU:
m.StartAtom("ulaw")
case streamer.CodecPCMA:
m.StartAtom("alaw")
default:
panic("unsupported iso audio: " + codec)
}
@@ -73,8 +68,18 @@ func (m *Movie) WriteAudio(codec string, channels uint16, sampleRate uint32, con
switch codec {
case streamer.CodecAAC:
m.WriteEsdsAAC(conf)
case streamer.CodecMP3:
m.WriteEsdsMP3()
case streamer.CodecOpus:
m.WriteDops()
// don't know what means this magic
m.StartAtom("dOps")
m.WriteBytes(0, 0x02, 0x01, 0x38, 0, 0, 0xBB, 0x80, 0, 0, 0)
m.EndAtom()
case streamer.CodecPCMU, streamer.CodecPCMA:
// don't know what means this magic
m.StartAtom("chan")
m.WriteBytes(0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0)
m.EndAtom()
}
m.EndAtom() // MP4A/OPUS
@@ -115,9 +120,32 @@ func (m *Movie) WriteEsdsAAC(conf []byte) {
m.EndAtom() // ESDS
}
func (m *Movie) WriteDops() {
// don't know what means this magic
m.StartAtom("dOps")
m.WriteBytes(0, 0x02, 0x01, 0x38, 0, 0, 0xBB, 0x80, 0, 0, 0)
m.EndAtom()
func (m *Movie) WriteEsdsMP3() {
m.StartAtom("esds")
m.Skip(1) // version
m.Skip(3) // flags
// MP4ESDescrTag[3]:
// - MP4DecConfigDescrTag[4]:
// - Other[6]
const header = 5
const size3 = 3
const size4 = 13
const size6 = 1
m.WriteBytes(3, 0x80, 0x80, 0x80, size3+header+size4+header+size6)
m.Skip(2) // es id
m.Skip(1) // es flags
m.WriteBytes(4, 0x80, 0x80, 0x80, size4)
m.WriteBytes(0x6B) // object id
m.WriteBytes(0x15) // stream type
m.Skip(3) // buffer size db
m.Skip(4) // max bitraga
m.Skip(4) // avg bitraga
m.WriteBytes(6, 0x80, 0x80, 0x80, 1)
m.WriteBytes(2) // ?
m.EndAtom() // ESDS
}
+1 -2
View File
@@ -50,7 +50,6 @@ func (c *Consumer) GetMedias() []*streamer.Media {
Direction: streamer.DirectionRecvonly,
Codecs: []*streamer.Codec{
{Name: streamer.CodecAAC},
{Name: streamer.CodecOpus},
},
},
}
@@ -143,7 +142,7 @@ func (c *Consumer) AddTrack(media *streamer.Media, track *streamer.Track) *strea
return track.Bind(push)
case streamer.CodecOpus:
case streamer.CodecOpus, streamer.CodecMP3, streamer.CodecPCMU, streamer.CodecPCMA:
push := func(packet *rtp.Packet) error {
if c.wait != waitNone {
return nil
+1 -1
View File
@@ -108,7 +108,7 @@ func (m *Muxer) GetInit(codecs []*streamer.Codec) ([]byte, error) {
uint32(i+1), codec.Name, codec.ClockRate, codec.Channels, b,
)
case streamer.CodecOpus:
case streamer.CodecOpus, streamer.CodecMP3, streamer.CodecPCMU, streamer.CodecPCMA:
mv.WriteAudioTrack(
uint32(i+1), codec.Name, codec.ClockRate, codec.Channels, nil,
)