예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }