diff --git a/pkg/opus/opus.go b/pkg/opus/opus.go index 95956b93..fb67c66d 100644 --- a/pkg/opus/opus.go +++ b/pkg/opus/opus.go @@ -85,3 +85,34 @@ func parseFrames(c byte) byte { } return 0xFF } + +func JoinFrames(b1, b2 []byte) []byte { + // can't join + if b1[0]&0b11 != 0 || b2[0]&0b11 != 0 { + return append(b1, b2...) + } + + size1, size2 := len(b1)-1, len(b2)-1 + + // join same sizes + if size1 == size2 { + b := make([]byte, 1+size1+size2) + copy(b, b1) + copy(b[1+size1:], b2[1:]) + b[0] |= 0b01 + return b + } + + b := make([]byte, 1, 3+size1+size2) + b[0] = b1[0] | 0b10 + if size1 >= 252 { + b0 := 252 + byte(size1)&0b11 + b = append(b, b0, byte(size1/4)-b0) + } else { + b = append(b, byte(size1)) + } + + b = append(b, b1[1:]...) + b = append(b, b2[1:]...) + return b +} diff --git a/pkg/xiaomi/backchannel.go b/pkg/xiaomi/backchannel.go index 0c4cefc4..0224a594 100644 --- a/pkg/xiaomi/backchannel.go +++ b/pkg/xiaomi/backchannel.go @@ -4,6 +4,7 @@ import ( "time" "github.com/AlexxIT/go2rtc/pkg/core" + "github.com/AlexxIT/go2rtc/pkg/opus" "github.com/AlexxIT/go2rtc/pkg/pcm" "github.com/AlexxIT/go2rtc/pkg/xiaomi/miss" "github.com/pion/rtp" @@ -45,8 +46,22 @@ func (p *Producer) AddTrack(media *core.Media, _ *core.Codec, track *core.Receiv } } case core.CodecOpus: - sender.Handler = func(pkt *rtp.Packet) { - _ = p.client.WriteAudio(miss.CodecOPUS, pkt.Payload) + if p.model == "chuangmi.camera.72ac1" { + var buf []byte + sender.Handler = func(pkt *rtp.Packet) { + if buf == nil { + buf = pkt.Payload + } else { + // convert two 20ms to one 40ms + buf = opus.JoinFrames(buf, pkt.Payload) + _ = p.client.WriteAudio(miss.CodecOPUS, buf) + buf = nil + } + } + } else { + sender.Handler = func(pkt *rtp.Packet) { + _ = p.client.WriteAudio(miss.CodecOPUS, pkt.Payload) + } } }