Skip to content

Instantly share code, notes, and snippets.

@Xosrov
Created January 31, 2022 18:56
Show Gist options
  • Save Xosrov/cf11986c85f6386523ded8b66c5c4cc3 to your computer and use it in GitHub Desktop.
Save Xosrov/cf11986c85f6386523ded8b66c5c4cc3 to your computer and use it in GitHub Desktop.
Pion WebRTC implementing NACK response
// Define codec and create local track
videoRTCPFeedback := []webrtc.RTCPFeedback{{"goog-remb", ""}, {"ccm", "fir"}, {"nack", ""}, {"nack", "pli"}}
codec := webrtc.RTPCodecParameters{
RTPCodecCapability: webrtc.RTPCodecCapability{webrtc.MimeTypeH264, 90000, 0, "level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f", videoRTCPFeedback},
PayloadType: 102,
}
vidTrack, err := webrtc.NewTrackLocalStaticRTP(codec.RTPCodecCapability, "video", "vid")
if err != nil {
panic(err)
}
// Register codecs into media engine
mediaEngine := &webrtc.MediaEngine{}
if err := mediaEngine.RegisterCodec(codec, webrtc.RTPCodecTypeVideo); err != nil {
panic(err)
}
// Enable NACK interceptor
intRegistry := &interceptor.Registry{}
if err := webrtc.ConfigureNack(mediaEngine, intRegistry); err != nil {
panic(err)
}
// Create API to extract PeerConnection later
api := webrtc.NewAPI(webrtc.WithMediaEngine(mediaEngine), webrtc.WithInterceptorRegistry(intRegistry))
// Prepare the configuration
configuration := webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: []string{"stun:stun.l.google.com:19302"},
},
},
}
// Create peer connection
serverConnection, err := api.NewPeerConnection(configuration)
if err != nil {
panic(err)
}
// Add video track to connection
rtcpSender, err := serverConnection.AddTrack(vidTrack)
if err != nil {
panic(err)
}
// Create UDP listener to read from ffmpeg
vidListener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP(receiveIP), Port: 5004})
if err != nil {
panic(err)
}
// Start video track reader
go func() {
inboundRTPPacket := make([]byte, rtcBufferSize)
fmt.Println("Started reading from video port")
for {
n, _, err := vidListener.ReadFrom(inboundRTPPacket)
if err != nil {
break
}
// write to track
if _, err = vidTrack.Write(inboundRTPPacket[:n]); err != nil {
if errors.Is(err, io.ErrClosedPipe) {
break
}
panic(err)
}
}
fmt.Println("Stopped reading from video port")
}()
// Read rtcp info like NACK from client
go func() {
for {
rtcpList, _, err := rtcpSender.ReadRTCP()
if err != nil {
panic(err)
}
fmt.Println(rtcpList)
}
}()
// ... (receive sdp from browser client and initiate webrtc connection)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment