diff --git a/examples/whip-whep/main.go b/examples/whip-whep/main.go index b8e784fc06e..b796c92dfad 100644 --- a/examples/whip-whep/main.go +++ b/examples/whip-whep/main.go @@ -14,119 +14,119 @@ import ( "log" "net" "net/http" + "time" "github.com/pion/webrtc/v4" ) -var ( - videoTrack *webrtc.TrackLocalStaticRTP - rtpListener *net.UDPConn - err error -) +const mtuSize = 1600 -const MTU_SIZE = 1600 +// nolint:gocognit +func main() { + // Everything below is the Pion WebRTC API! Thanks for using it ❤️. -func whipHandler(w http.ResponseWriter, r *http.Request) { - offer, err := io.ReadAll(r.Body) + // Open a UDP Listener for RTP Packets on port 5004 + rtpListener, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 5004}) if err != nil { panic(err) } - peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{}) + videoTrack, err := webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264}, "video", "pion") if err != nil { panic(err) } - rtpSender, err := peerConnection.AddTrack(videoTrack) - if err != nil { - panic(err) - } + // Serve up html on port 8080 + http.Handle("/", http.FileServer(http.Dir("."))) - go func() { - rtcpBuf := make([]byte, MTU_SIZE) - for { - if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil { - return - } + http.HandleFunc("/whip", func(w http.ResponseWriter, r *http.Request) { + offer, readAllErr := io.ReadAll(r.Body) + if readAllErr != nil { + panic(readAllErr) } - }() - - // Set the handler for ICE connection state - // This will notify you when the peer has connected/disconnected - peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) { - fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String()) - if connectionState == webrtc.ICEConnectionStateFailed { - peerConnection.Close() + peerConnection, pcErr := webrtc.NewPeerConnection(webrtc.Configuration{}) + if pcErr != nil { + panic(pcErr) } - }) - if err = peerConnection.SetRemoteDescription(webrtc.SessionDescription{Type: webrtc.SDPTypeOffer, SDP: string(offer)}); err != nil { - panic(err) - } + rtpSender, addTrackErr := peerConnection.AddTrack(videoTrack) + if addTrackErr != nil { + panic(addTrackErr) + } - // Create channel that is blocked until ICE Gathering is complete - gatherComplete := webrtc.GatheringCompletePromise(peerConnection) + go func() { + rtcpBuf := make([]byte, mtuSize) + for { + if _, _, rtcpErr := rtpSender.Read(rtcpBuf); rtcpErr != nil { + return + } + } + }() - answer, err := peerConnection.CreateAnswer(nil) - if err != nil { - panic(err) - } else if err = peerConnection.SetLocalDescription(answer); err != nil { - panic(err) - } + // Set the handler for ICE connection state + // This will notify you when the peer has connected/disconnected + peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) { + fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String()) - log.Printf("answer %s", string(answer.SDP)) + if connectionState == webrtc.ICEConnectionStateFailed { + peerConnection.Close() + } + }) - <-gatherComplete + if err = peerConnection.SetRemoteDescription(webrtc.SessionDescription{Type: webrtc.SDPTypeOffer, SDP: string(offer)}); err != nil { + panic(err) + } - go func() { - inboundRTPPacket := make([]byte, MTU_SIZE) - for { - n, _, err := rtpListener.ReadFrom(inboundRTPPacket) + // Create channel that is blocked until ICE Gathering is complete + gatherComplete := webrtc.GatheringCompletePromise(peerConnection) - if err != nil { - panic(fmt.Sprintf("error during read: %s", err)) - } - - if _, err = videoTrack.Write(inboundRTPPacket[:n]); err != nil { - if errors.Is(err, io.ErrClosedPipe) { - // The peerConnection has been closed. - return - } - panic(err) - } + answer, createAnsErr := peerConnection.CreateAnswer(nil) + if createAnsErr != nil { + panic(createAnsErr) + } else if err = peerConnection.SetLocalDescription(answer); err != nil { + panic(err) } - }() - w.Header().Add("Location", "/whip") - w.WriteHeader(http.StatusCreated) - fmt.Fprint(w, peerConnection.LocalDescription().SDP) -} + log.Printf("answer %s", answer.SDP) -// nolint:gocognit -func main() { - // Everything below is the Pion WebRTC API! Thanks for using it ❤️. + <-gatherComplete - // Open a UDP Listener for RTP Packets on port 5004 - rtpListener, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 5004}) - if err != nil { - panic(err) - } + go func() { + inboundRTPPacket := make([]byte, mtuSize) + for { + n, _, readErr := rtpListener.ReadFrom(inboundRTPPacket) - videoTrack, err = webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeH264}, "video", "pion") - if err != nil { - panic(err) - } + if readErr != nil { + panic(fmt.Sprintf("error during read: %s", readErr)) + } - http.Handle("/", http.FileServer(http.Dir("."))) - http.HandleFunc("/whip", whipHandler) + if _, err = videoTrack.Write(inboundRTPPacket[:n]); err != nil { + if errors.Is(err, io.ErrClosedPipe) { + // The peerConnection has been closed. + return + } + panic(err) + } + } + }() + + w.Header().Add("Location", "/whip") + w.WriteHeader(http.StatusCreated) + fmt.Fprint(w, peerConnection.LocalDescription().SDP) + }, + ) // Start the server on port 8080 fmt.Println("Server is listening on port 8080") - err = http.ListenAndServe(":8080", nil) + server := &http.Server{ + Addr: ":8080", + ReadHeaderTimeout: 10 * time.Second, + } + + err = server.ListenAndServe() if err != nil { panic(err) } - }