private static Task <RTCPeerConnection> CreatePeerConnection(X509Certificate2 cert) { //RTCConfiguration config = new RTCConfiguration //{ // iceServers = new List<RTCIceServer> { new RTCIceServer { urls = STUN_URL } }, // certificates = new List<RTCCertificate> { new RTCCertificate { Certificate = cert } } //}; //var pc = new RTCPeerConnection(config); var pc = new RTCPeerConnection(null); var testPatternSource = new VideoTestPatternSource(new SIPSorceryMedia.Encoders.VideoEncoder()); testPatternSource.SetFrameRate(60); //testPatternSource.SetMaxFrameRate(true); //var videoEndPoint = new SIPSorceryMedia.FFmpeg.FFmpegVideoEndPoint(); //videoEndPoint.RestrictFormats(format => format.Codec == VideoCodecsEnum.H264); //var videoEndPoint = new SIPSorceryMedia.Windows.WindowsEncoderEndPoint(); //var videoEndPoint = new SIPSorceryMedia.Encoders.VideoEncoderEndPoint(); MediaStreamTrack track = new MediaStreamTrack(testPatternSource.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(track); //testPatternSource.OnVideoSourceRawSample += videoEndPoint.ExternalVideoSourceRawSample; testPatternSource.OnVideoSourceRawSample += MesasureTestPatternSourceFrameRate; testPatternSource.OnVideoSourceEncodedSample += pc.SendVideo; pc.OnVideoFormatsNegotiated += (formats) => testPatternSource.SetVideoSourceFormat(formats.First()); pc.onconnectionstatechange += async(state) => { logger.LogDebug($"Peer connection state change to {state}."); if (state == RTCPeerConnectionState.failed) { pc.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.closed) { await testPatternSource.CloseVideo(); await testPatternSource.CloseVideo(); testPatternSource.Dispose(); } else if (state == RTCPeerConnectionState.connected) { await testPatternSource.StartVideo(); await testPatternSource.StartVideo(); } }; // Diagnostics. //pc.OnReceiveReport += (re, media, rr) => logger.LogDebug($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}"); //pc.OnSendReport += (media, sr) => logger.LogDebug($"RTCP Send for {media}\n{sr.GetDebugSummary()}"); //pc.GetRtpChannel().OnStunMessageReceived += (msg, ep, isRelay) => logger.LogDebug($"STUN {msg.Header.MessageType} received from {ep}."); pc.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}."); return(Task.FromResult(pc)); }
private static Task <RTCPeerConnection> CreatePeerConnection() { RTCConfiguration config = new RTCConfiguration { iceServers = new List <RTCIceServer> { new RTCIceServer { urls = STUN_URL } } }; var pc = new RTCPeerConnection(config); var testPatternSource = new VideoTestPatternSource(); var videoEncoderEndPoint = new VideoEncoderEndPoint(); var audioSource = new AudioExtrasSource(new AudioEncoder(), new AudioSourceOptions { AudioSource = AudioSourcesEnum.Music }); MediaStreamTrack videoTrack = new MediaStreamTrack(videoEncoderEndPoint.GetVideoSourceFormats(), MediaStreamStatusEnum.SendRecv); pc.addTrack(videoTrack); MediaStreamTrack audioTrack = new MediaStreamTrack(audioSource.GetAudioSourceFormats(), MediaStreamStatusEnum.SendRecv); pc.addTrack(audioTrack); testPatternSource.OnVideoSourceRawSample += videoEncoderEndPoint.ExternalVideoSourceRawSample; videoEncoderEndPoint.OnVideoSourceEncodedSample += pc.SendVideo; audioSource.OnAudioSourceEncodedSample += pc.SendAudio; pc.OnVideoFormatsNegotiated += (formats) => videoEncoderEndPoint.SetVideoSourceFormat(formats.First()); pc.onconnectionstatechange += async(state) => { logger.LogDebug($"Peer connection state change to {state}."); if (state == RTCPeerConnectionState.connected) { await audioSource.StartAudio(); await testPatternSource.StartVideo(); } else if (state == RTCPeerConnectionState.failed) { pc.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.closed) { await testPatternSource.CloseVideo(); await audioSource.CloseAudio(); } }; // Diagnostics. pc.OnReceiveReport += (re, media, rr) => logger.LogDebug($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}"); pc.OnSendReport += (media, sr) => logger.LogDebug($"RTCP Send for {media}\n{sr.GetDebugSummary()}"); pc.GetRtpChannel().OnStunMessageReceived += (msg, ep, isRelay) => logger.LogDebug($"STUN {msg.Header.MessageType} received from {ep}."); pc.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}."); return(Task.FromResult(pc)); }
private static Task <RTCPeerConnection> CreatePeerConnection() { RTCConfiguration config = new RTCConfiguration { iceServers = new List <RTCIceServer> { new RTCIceServer { urls = STUN_URL } } }; //var pc = new RTCPeerConnection(config); var pc = peer = new RTCPeerConnection(null); var testPatternSource = new VideoTestPatternSource(); testPatternSource.SetFrameRate(60); testPatternSource.SetMaxFrameRate(true); var videoEndPoint = new SIPSorceryMedia.FFmpeg.FFmpegVideoEndPoint(); videoEndPoint.RestrictFormats(format => format.Codec == VideoCodecsEnum.H264); //var videoEndPoint = new SIPSorceryMedia.Windows.WindowsVideoEndPoint(true); //var videoEndPoint = new SIPSorceryMedia.Windows.WindowsEncoderEndPoint(); //var videoEndPoint = new SIPSorceryMedia.Encoders.VideoEncoderEndPoint(); MediaStreamTrack track = new MediaStreamTrack(videoEndPoint.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(track); testPatternSource.OnVideoSourceRawSample += TestPatternSource_OnVideoSourceRawSample; pc.OnVideoFormatsNegotiated += (formats) => { videoEndPoint.SetVideoSourceFormat(formats.First()); }; pc.onconnectionstatechange += async(state) => { if (state == RTCPeerConnectionState.failed) { pc.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.closed) { await testPatternSource.CloseVideo(); await videoEndPoint.CloseVideo(); } else if (state == RTCPeerConnectionState.connected) { await videoEndPoint.StartVideo(); await testPatternSource.StartVideo(); } }; return(Task.FromResult(pc)); }
private static RTCPeerConnection CreatePeerConnection() { RTCConfiguration config = new RTCConfiguration { iceServers = new List <RTCIceServer> { new RTCIceServer { urls = STUN_URL } } }; var pc = new RTCPeerConnection(config); var testPatternSource = new VideoTestPatternSource(); WindowsVideoEndPoint windowsVideoEndPoint = new WindowsVideoEndPoint(true); MediaStreamTrack track = new MediaStreamTrack(windowsVideoEndPoint.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(track); testPatternSource.OnVideoSourceRawSample += windowsVideoEndPoint.ExternalVideoSourceRawSample; windowsVideoEndPoint.OnVideoSourceEncodedSample += pc.SendVideo; pc.OnVideoFormatsNegotiated += (sdpFormat) => windowsVideoEndPoint.SetVideoSourceFormat(SDPMediaFormatInfo.GetVideoCodecForSdpFormat(sdpFormat.First().FormatCodec)); pc.onconnectionstatechange += async(state) => { logger.LogDebug($"Peer connection state change to {state}."); if (state == RTCPeerConnectionState.failed) { pc.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.closed) { await testPatternSource.CloseVideo(); await windowsVideoEndPoint.CloseVideo(); } else if (state == RTCPeerConnectionState.connected) { await windowsVideoEndPoint.StartVideo(); await testPatternSource.StartVideo(); } }; // Diagnostics. pc.OnReceiveReport += (re, media, rr) => logger.LogDebug($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}"); pc.OnSendReport += (media, sr) => logger.LogDebug($"RTCP Send for {media}\n{sr.GetDebugSummary()}"); pc.GetRtpChannel().OnStunMessageReceived += (msg, ep, isRelay) => logger.LogDebug($"STUN {msg.Header.MessageType} received from {ep}."); pc.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}."); return(pc); }
private static RTCPeerConnection CreatePeerConnection() { var peerConnection = new RTCPeerConnection(null); var testPatternSource = new VideoTestPatternSource(); WindowsVideoEndPoint windowsVideoEndPoint = new WindowsVideoEndPoint(new VpxVideoEncoder()); MediaStreamTrack track = new MediaStreamTrack(windowsVideoEndPoint.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); peerConnection.addTrack(track); testPatternSource.OnVideoSourceRawSample += windowsVideoEndPoint.ExternalVideoSourceRawSample; windowsVideoEndPoint.OnVideoSourceEncodedSample += peerConnection.SendVideo; peerConnection.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change {state}."); peerConnection.OnReceiveReport += RtpSession_OnReceiveReport; peerConnection.OnSendReport += RtpSession_OnSendReport; peerConnection.OnTimeout += (mediaType) => logger.LogWarning($"Timeout on {mediaType}."); peerConnection.onconnectionstatechange += async(state) => { logger.LogDebug($"Peer connection state changed to {state}."); if (state == RTCPeerConnectionState.closed) { peerConnection.OnReceiveReport -= RtpSession_OnReceiveReport; peerConnection.OnSendReport -= RtpSession_OnSendReport; await windowsVideoEndPoint.CloseVideo(); await testPatternSource.CloseVideo(); } else if (state == RTCPeerConnectionState.connected) { await testPatternSource.StartVideo(); await windowsVideoEndPoint.StartVideo(); } }; return(peerConnection); }
static async Task Main() { Console.WriteLine("Janus Echo Test Demo"); AddConsoleLogger(); CancellationTokenSource cts = new CancellationTokenSource(); bool isFormActivated = false; #region Set up a simple Windows Form with two picture boxes. var form = new Form(); form.AutoSize = true; form.BackgroundImageLayout = ImageLayout.Center; var localVideoPicBox = new PictureBox { Size = new Size(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT), Location = new Point(0, 0), Visible = true }; var remoteVideoPicBox = new PictureBox { Size = new Size(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT), Location = new Point(0, VIDEO_FRAME_HEIGHT), Visible = true }; form.Controls.Add(localVideoPicBox); form.Controls.Add(remoteVideoPicBox); Application.EnableVisualStyles(); ThreadPool.QueueUserWorkItem(delegate { Application.Run(form); }); form.FormClosing += (sender, e) => isFormActivated = false; form.Activated += (sender, e) => isFormActivated = true; #endregion Console.WriteLine("Creating peer connection."); RTCPeerConnection pc = new RTCPeerConnection(null); var videoSource = new VideoTestPatternSource(new VpxVideoEncoder()); var videoSink = new VideoEncoderEndPoint(); MediaStreamTrack videoTrack = new MediaStreamTrack(videoSink.GetVideoSourceFormats(), MediaStreamStatusEnum.SendRecv); pc.addTrack(videoTrack); pc.OnVideoFrameReceived += videoSink.GotVideoFrame; videoSource.OnVideoSourceEncodedSample += pc.SendVideo; pc.OnVideoFormatsNegotiated += (formats) => { videoSink.SetVideoSourceFormat(formats.First()); videoSource.SetVideoSourceFormat(formats.First()); }; pc.OnTimeout += (mediaType) => Console.WriteLine($"Peer connection timeout on media {mediaType}."); pc.oniceconnectionstatechange += (state) => Console.WriteLine($"ICE connection state changed to {state}."); pc.onconnectionstatechange += async(state) => { Console.WriteLine($"Peer connection connected changed to {state}."); if (state == RTCPeerConnectionState.closed || state == RTCPeerConnectionState.failed) { await videoSource.CloseVideo().ConfigureAwait(false); videoSource.Dispose(); } }; #region Wire up the video source and sink to the picutre boxes. videoSource.OnVideoSourceRawSample += (uint durationMilliseconds, int width, int height, byte[] sample, VideoPixelFormatsEnum pixelFormat) => { if (isFormActivated) { form?.BeginInvoke(new Action(() => { if (form.Handle != IntPtr.Zero) { unsafe { fixed(byte *s = sample) { var bmpImage = new Bitmap(width, height, width * 3, PixelFormat.Format24bppRgb, (IntPtr)s); localVideoPicBox.Image = bmpImage; } } } })); } }; videoSink.OnVideoSinkDecodedSample += (byte[] bmp, uint width, uint height, int stride, VideoPixelFormatsEnum pixelFormat) => { if (isFormActivated) { form.BeginInvoke(new Action(() => { unsafe { fixed(byte *s = bmp) { Bitmap bmpImage = new Bitmap((int)width, (int)height, (int)(bmp.Length / height), PixelFormat.Format24bppRgb, (IntPtr)s); remoteVideoPicBox.Image = bmpImage; } } })); } }; #endregion var offer = pc.CreateOffer(null); await pc.setLocalDescription(new RTCSessionDescriptionInit { type = RTCSdpType.offer, sdp = offer.ToString() }).ConfigureAwait(false); Console.WriteLine($"SDP Offer: {pc.localDescription.sdp}"); await videoSource.StartVideo().ConfigureAwait(false); if (_useJanusRest) { JanusRestClient janusClient = new JanusRestClient( JANUS_BASE_URI, SIPSorcery.LogFactory.CreateLogger <JanusRestClient>(), cts.Token); //var serverInfo = await janusClient.GetServerInfo().ConfigureAwait(false); //Console.WriteLine($"Name={serverInfo.name}."); //Console.WriteLine($"Version={serverInfo.version}."); janusClient.OnJanusEvent += async(resp) => { if (resp.jsep != null) { Console.WriteLine($"get event jsep={resp.jsep.type}."); Console.WriteLine($"SDP Answer: {resp.jsep.sdp}"); var result = pc.setRemoteDescription(new RTCSessionDescriptionInit { type = RTCSdpType.answer, sdp = resp.jsep.sdp }); Console.WriteLine($"SDP Answer: {pc.remoteDescription.sdp}"); if (result == SetDescriptionResultEnum.OK) { Console.WriteLine("Starting peer connection."); await pc.Start().ConfigureAwait(false); } else { Console.WriteLine($"Error setting remote SDP description {result}."); } } }; await janusClient.StartSession().ConfigureAwait(false); await janusClient.StartEcho(offer.ToString()).ConfigureAwait(false); } else { //RestClient signalingClient = new RestClient($"{WEBRTC_SIGNALING_JANUS_URL}?duration=15"); RestClient signalingClient = new RestClient($"{WEBRTC_SIGNALING_JANUS_URL}"); var echoTestReq = new RestRequest(string.Empty, Method.POST, DataFormat.Json); echoTestReq.AddJsonBody(pc.localDescription.sdp.ToString()); var echoTestResp = await signalingClient.ExecutePostAsync <string>(echoTestReq).ConfigureAwait(false); if (echoTestResp.IsSuccessful) { var sdpAnswer = echoTestResp.Data; Console.WriteLine($"SDP Answer: {sdpAnswer}"); var result = pc.setRemoteDescription(new RTCSessionDescriptionInit { type = RTCSdpType.answer, sdp = sdpAnswer }); Console.WriteLine($"SDP Answer: {pc.remoteDescription.sdp}"); if (result == SetDescriptionResultEnum.OK) { Console.WriteLine("Starting peer connection."); await pc.Start().ConfigureAwait(false); } else { Console.WriteLine($"Error setting remote SDP description {result}."); } } else { Console.WriteLine($"Janus echo test plugin request failed {echoTestResp.ErrorMessage}."); } } Console.WriteLine("Press any key to exit..."); Console.ReadLine(); isFormActivated = false; cts.Cancel(); //await janusClient.DestroySession().ConfigureAwait(false); }