Add support OPUS, MP3, PCMU, PCMA for MP4
This commit is contained in:
+50
-22
@@ -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
@@ -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
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user