go - 使用 Pion/Webrtc 的 Nack 响应者拦截器
问题描述
我正在尝试使用 nack rtx 拦截器。这是我的代码拦截器代码:
func (n *ResponderInterceptor) resendPackets(nack *rtcp.TransportLayerNack) {
rtpVideoPktDecoded := rtp.Packet{}
for _, i := range nack.Nacks {
offsetTotal := Rtop.VideoRTPPacketSequenceNumber - i.PacketID
var offsetIndex uint16
offsetIndex = 0
if offsetTotal < RTP_PACKET_SIZE { // Still in buffer
// Get the packet from the circular buffer
if Rtop.VideoRTPPacketIndex <= offsetTotal {
offsetIndex = RTP_PACKET_SIZE - (offsetTotal - Rtop.VideoRTPPacketIndex) - 1
} else {
offsetIndex = Rtop.VideoRTPPacketIndex - offsetTotal - 1
}
// We have found the need packet within the buffer
if Rtop.ClientVideoTrack != nil {
rtpPacketSize := Rtop.VideoRTPPacketsSize[offsetIndex]
err := rtpVideoPktDecoded.Unmarshal(Rtop.VideoRTPPackets[offsetIndex][:rtpPacketSize])
if err != nil {
log.Println("Err parser header ", err)
}
// Copy the packet
// Changing its payload type the Payload according to SDP
// 121 is the 96 Nack RTX
rtpVideoPktDecoded.Payload).Elem().Size()
rtpVideoPktDecoded.PayloadType = 121
rtxRtpVideoPktDecoded := rtp.Packet{}
rtxRtpVideoPktDecoded.Header = rtpVideoPktDecoded.Header
rtxRtpVideoPktDecoded.PayloadType = 121
rtxRtpVideoPktDecoded.SequenceNumber = Rtop.VideoRTPPacketRtxSequenceNumber
Rtop.VideoRTPPacketRtxSequenceNumber++
rtxPayload := RtxPacket{}
rtxPayload.OriginalSequenceNumber = rtpVideoPktDecoded.SequenceNumber
rtxPayload.Payload = rtpVideoPktDecoded.Payload
sz := uintptr(len(rtpVideoPktDecoded.Payload))*reflect.TypeOf(rtpVideoPktDecoded.Payload).Elem().Size() + uintptr(binary.Size(rtxPayload.OriginalSequenceNumber))
var asByteSlice []byte = (*(*[PKTMAXLEN]byte)(unsafe.Pointer(&rtxPayload)))[:sz]
rtxRtpVideoPktDecoded.Payload = asByteSlice
if err := Rtop.ClientVideoTrack.WriteRTP(&rtpVideoPktDecoded); err != nil {
log.Println("Error Resend Seq:", i.PacketID)
}
} else {
fmt.Printf("O no ClientVideoTrack")
}
} else {
log.Println("No more in buffer PacketID:", i.PacketID, ", CurrentSequenceNumber:", Rtop.VideoRTPPacketSequenceNumber, ", offsetTotal:", offsetTotal)
}
}
}
每当 pion/webrtc 由于检测到数据包丢失而收到 nack 时,此功能就会正确触发并重新发送数据包。但它没有被另一端(chrome 浏览器)正确解释。并且多次询问同一个数据包。因此,溪流冻结了。
这是我使用 pion/webrtc 设置流的方法:
...
m := webrtc.MediaEngine{}
videoRTCPFeedback := []webrtc.RTCPFeedback{{"goog-remb", ""}, {"ccm", "fir"}, {"nack", ""}, {"nack", "pli"}}
//videoRTCPFeedback := []webrtc.RTCPFeedback{{"goog-remb", ""}, {"ccm", "fir"}}
//videoRtxRTCPFeedback := []webrtc.RTCPFeedback{{"nack", ""}, {"nack", "pli"}}
//videoUlpFecRTCPFeedback := []webrtc.RTCPFeedback{{"nack", ""}, {"nack", "pli"}}
m.RegisterCodec(webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{"video/h264", 90000, 0, "level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f", videoRTCPFeedback},
PayloadType: 102,
}, webrtc.RTPCodecTypeVideo)
m.RegisterCodec(webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{"video/rtx", 90000, 0, "apt=102;rtx-time=3000", nil},
PayloadType: 121,
}, webrtc.RTPCodecTypeVideo)
m.RegisterCodec(webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{"video/ulpfec", 90000, 0, "", nil},
PayloadType: 116,
}, webrtc.RTPCodecTypeVideo)
m.RegisterCodec(webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{"audio/opus", 48000, 2, "minptime=10;useinbandfec=1", nil},
PayloadType: 111,
}, webrtc.RTPCodecTypeAudio)
//m.RegisterFeedback(webrtc.RTCPFeedback{Type: "nack"}, webrtc.RTPCodecTypeVideo)
//m.RegisterFeedback(webrtc.RTCPFeedback{Type: "nack", Parameter: "pli"}, webrtc.RTPCodecTypeVideo)
myInterceptor := &interceptor.Registry{}
generator, _ := nack.NewGeneratorInterceptor()
responder, _ := NewAirtopCloudResponderInterceptor()
...
谢谢您的帮助
解决方案
推荐阅读
- python - 如何为 pyttsx3 python 添加自己的 tts 声音
- android - kotlin.Unit 不能转换为 java.util.List。用于 getFilter 上的自定义适配器
- blockchain - 您如何为您的运行时编写系统测试?
- google-bigquery - 在 BigQuery 上使用以下查询时出现 TIMESTAMP 错误
- python - 为 anaconda 安装 cot-reports 模块
- html - Angular:以HTML显示上传文件的文件名
- c++ - 查找检测到的 blob opencv 的颜色
- r - 按位置加条件过滤器访问列
- python - 如何在 json 参数中传递多个“标题”值
- google-cloud-platform - Terraform Bigquery 创建表替换表而不是编辑