private static Task OnKeyPress(CancellationToken exit) { while (!exit.WaitHandle.WaitOne(0)) { var keyProps = Console.ReadKey(); if (keyProps.KeyChar == 'k') { if (_activePeerConnection != null) { Console.WriteLine("Requesting key frame."); var localVideoSsrc = _activePeerConnection.VideoLocalTrack.Ssrc; var remoteVideoSsrc = _activePeerConnection.VideoRemoteTrack.Ssrc; RTCPFeedback pli = new RTCPFeedback(localVideoSsrc, remoteVideoSsrc, PSFBFeedbackTypesEnum.PLI); _activePeerConnection.SendRtcpFeedback(SDPMediaTypesEnum.video, pli); } } else if (keyProps.KeyChar == 'q') { // Quit application. Console.WriteLine("Quitting"); break; } } return(Task.CompletedTask); }
/// <summary> /// Requests the SIP device to send a video key frame. /// </summary> /// <param name="rtpSession"></param> private static void RequestSIPAgentKeyFrame(RTPSession rtpSession) { if (rtpSession != null && !rtpSession.IsClosed) { var localVideoSsrc = rtpSession.VideoLocalTrack.Ssrc; var remoteVideoSsrc = rtpSession.VideoRemoteTrack.Ssrc; Console.WriteLine($"Requesting key frame from SIP connection for remote ssrc {remoteVideoSsrc}."); RTCPFeedback pli = new RTCPFeedback(localVideoSsrc, remoteVideoSsrc, PSFBFeedbackTypesEnum.PLI); rtpSession.SendRtcpFeedback(SDPMediaTypesEnum.video, pli); } }
private static void RequestPeerConnectionKeyFrame(RTCPeerConnection pc) { if (pc != null && pc.connectionState == RTCPeerConnectionState.connected) { var localVideoSsrc = pc.VideoLocalTrack.Ssrc; var remoteVideoSsrc = pc.VideoRemoteTrack.Ssrc; Console.WriteLine($"Requesting key frame from peer connection for remote ssrc {remoteVideoSsrc}."); RTCPFeedback pli = new RTCPFeedback(localVideoSsrc, remoteVideoSsrc, PSFBFeedbackTypesEnum.PLI); pc.SendRtcpFeedback(SDPMediaTypesEnum.video, pli); } }
public void SendVideoRtcpFeedbackReportUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { Certificate = DtlsUtils.CreateSelfSignedCert() } }, X_UseRtpFeedbackProfile = true }; RTCPeerConnection pcSrc = new RTCPeerConnection(pcConfiguration); var videoTrackSrc = new MediaStreamTrack(SDPMediaTypesEnum.video, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }); pcSrc.addTrack(videoTrackSrc); var offer = pcSrc.createOffer(new RTCOfferOptions()); logger.LogDebug($"offer: {offer.sdp}"); RTCPeerConnection pcDst = new RTCPeerConnection(pcConfiguration); var videoTrackDst = new MediaStreamTrack(SDPMediaTypesEnum.video, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }); pcDst.addTrack(videoTrackDst); var setOfferResult = pcDst.setRemoteDescription(offer); Assert.Equal(SetDescriptionResultEnum.OK, setOfferResult); var answer = pcDst.createAnswer(null); var setAnswerResult = pcSrc.setRemoteDescription(answer); Assert.Equal(SetDescriptionResultEnum.OK, setAnswerResult); logger.LogDebug($"answer: {answer.sdp}"); RTCPFeedback pliReport = new RTCPFeedback(pcDst.VideoLocalTrack.Ssrc, pcDst.VideoRemoteTrack.Ssrc, PSFBFeedbackTypesEnum.PLI); pcDst.SendRtcpFeedback(SDPMediaTypesEnum.video, pliReport); }
public void SendVideoRtcpFeedbackReportUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { X_Fingerprint = "sha-256 C6:ED:8C:9D:06:50:77:23:0A:4A:D8:42:68:29:D0:70:2F:BB:C7:72:EC:98:5C:62:07:1B:0C:5D:CB:CE:BE:CD" } }, X_UseRtpFeedbackProfile = true }; RTCPeerConnection pcSrc = new RTCPeerConnection(pcConfiguration); var videoTrackSrc = new MediaStreamTrack(SDPMediaTypesEnum.video, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }); pcSrc.addTrack(videoTrackSrc); var offer = pcSrc.createOffer(new RTCOfferOptions()); logger.LogDebug($"offer: {offer.sdp}"); RTCPeerConnection pcDst = new RTCPeerConnection(pcConfiguration); var videoTrackDst = new MediaStreamTrack(SDPMediaTypesEnum.video, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }); pcDst.addTrack(videoTrackDst); var setOfferResult = pcDst.setRemoteDescription(offer); Assert.Equal(SetDescriptionResultEnum.OK, setOfferResult); var answer = pcDst.createAnswer(null); var setAnswerResult = pcSrc.setRemoteDescription(answer); Assert.Equal(SetDescriptionResultEnum.OK, setAnswerResult); logger.LogDebug($"answer: {answer.sdp}"); RTCPFeedback pliReport = new RTCPFeedback(pcDst.VideoLocalTrack.Ssrc, pcDst.VideoRemoteTrack.Ssrc, PSFBFeedbackTypesEnum.PLI); pcDst.SendRtcpFeedback(SDPMediaTypesEnum.video, pliReport); }
public void RoundtripPictureLossIndicationReportUnitTest() { logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name); uint senderSsrc = 33; uint mediaSsrc = 44; RTCPFeedback rtcpPli = new RTCPFeedback(senderSsrc, mediaSsrc, PSFBFeedbackTypesEnum.PLI); byte[] buffer = rtcpPli.GetBytes(); logger.LogDebug($"Serialised PLI feedback report: {ByteBufferInfo.HexStr(buffer)}."); RTCPFeedback parsedPli = new RTCPFeedback(buffer); Assert.Equal(RTCPReportTypesEnum.PSFB, parsedPli.Header.PacketType); Assert.Equal(PSFBFeedbackTypesEnum.PLI, parsedPli.Header.PayloadFeedbackMessageType); Assert.Equal(senderSsrc, parsedPli.SenderSSRC); Assert.Equal(mediaSsrc, parsedPli.MediaSSRC); Assert.Equal(2, parsedPli.Header.Length); }
private static RTCPeerConnection Createpc(WebSocketContext context) { var pc = new RTCPeerConnection(null); pc.GetRtpChannel().OnStunMessageReceived += (msg, ep, isRelay) => { bool hasUseCandidate = msg.Attributes.Any(x => x.AttributeType == STUNAttributeTypesEnum.UseCandidate); Console.WriteLine($"STUN {msg.Header.MessageType} received from {ep}, use candidate {hasUseCandidate}."); }; pc.onicecandidateerror += (candidate, error) => logger.LogWarning($"Error adding remote ICE candidate. {error} {candidate}"); pc.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}."); //pc.OnReceiveReport += (type, rtcp) => logger.LogDebug($"RTCP {type} report received."); pc.OnRtcpBye += (reason) => logger.LogDebug($"RTCP BYE receive, reason: {(string.IsNullOrWhiteSpace(reason) ? "<none>" : reason)}."); //pc.onicecandidate += (candidate) => //{ // if (pc.signalingState == RTCSignalingState.have_local_offer || // pc.signalingState == RTCSignalingState.have_remote_offer) // { // context.WebSocket.Send($"candidate:{candidate}"); // } //}; pc.onconnectionstatechange += (state) => { logger.LogDebug($"Peer connection state changed to {state}."); if (state == RTCPeerConnectionState.connected) { logger.LogDebug("Creating RTP session for ffplay."); var rtpSession = CreateRtpSession(pc.AudioLocalTrack?.Capabilities, pc.VideoLocalTrack?.Capabilities); Core.Initialize(); _libvlc = new LibVLC(); _mediaPlayer = new MediaPlayer(_libvlc); //_mediaPlayer.Volume = 10; var sdpFullPath = Path.Combine(Directory.GetParent(typeof(Program).Assembly.Location).FullName, FFPLAY_DEFAULT_SDP_PATH); using var media = new Media(_libvlc, new Uri(sdpFullPath)); _mediaPlayer.Play(media); //if (_activePeerConnection != null) { // request key frames var localVideoSsrc = _activePeerConnection.VideoLocalTrack.Ssrc; var remoteVideoSsrc = _activePeerConnection.VideoRemoteTrack.Ssrc; RTCPFeedback pli = new RTCPFeedback(localVideoSsrc, remoteVideoSsrc, PSFBFeedbackTypesEnum.PLI); _activePeerConnection.SendRtcpFeedback(SDPMediaTypesEnum.video, pli); } pc.OnRtpPacketReceived += (rep, media, rtpPkt) => { if (media == SDPMediaTypesEnum.audio && rtpSession.AudioDestinationEndPoint != null) { //logger.LogDebug($"Forwarding {media} RTP packet to ffplay timestamp {rtpPkt.Header.Timestamp}."); rtpSession.SendRtpRaw(media, rtpPkt.Payload, rtpPkt.Header.Timestamp, rtpPkt.Header.MarkerBit, rtpPkt.Header.PayloadType); } else if (media == SDPMediaTypesEnum.video && rtpSession.VideoDestinationEndPoint != null) { //logger.LogDebug($"Forwarding {media} RTP packet to ffplay timestamp {rtpPkt.Header.Timestamp}."); rtpSession.SendRtpRaw(media, rtpPkt.Payload, rtpPkt.Header.Timestamp, rtpPkt.Header.MarkerBit, rtpPkt.Header.PayloadType); } }; pc.OnRtpClosed += (reason) => rtpSession.Close(reason); } }; _activePeerConnection = pc; return(pc); }