### Building WebRTC FFmpeg Docker Image Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/README.md This command builds the Docker image for the WebRTC FFmpeg Get Started application. It tags the image as 'webrtcgetstarted' and uses the Dockerfile located in the current directory. Ensure you are in the correct project directory before executing. ```Shell docker build -t webrtcgetstarted --progress=plain -f Dockerfile . ``` -------------------------------- ### Starting the .NET Core Application Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/FfmpegToWebRTC/README.md This command initiates the .NET Core test application, which serves as the server component for the WebRTC video streaming setup. It prepares the environment for interaction with FFmpeg and the browser. ```Shell dotnet run ``` -------------------------------- ### Piping SDP to Pion Go Data Channels Example (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/webrtccmdline/README.md This command pipes a base64 encoded SDP offer, generated by the .NET application, as input to the Pion Go Data Channels example program, facilitating the exchange of SDP for WebRTC connection setup. ```Bash echo | go run main.go ``` -------------------------------- ### Starting the .Net Core WebRTC Application Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCtoFfplay/README.md This command initiates the sipsorcery .Net Core test application, which is responsible for handling WebRTC signaling and generating the ffplay.sdp file. It's the first step to get the WebRTC stream processing started and requires .Net Core to be installed. ```Shell dotnet run ``` -------------------------------- ### Starting Sipsorcery WebRTC Sine Wave App (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCSendAudio/README.md This Bash command executes the Sipsorcery .NET Core application, which generates a sine wave audio signal and makes it available for WebRTC connections. Ensure .NET Core is installed and the project is ready to run. After starting, open 'webrtc.html' in a browser to listen to the generated audio. ```Bash dotnet run ``` -------------------------------- ### Starting SIPSorcery WebRTC Test Application (.NET Core) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCTestPatternServer/README.md This command initiates the SIPSorcery WebRTC test application on Windows. It starts the server-side component responsible for generating and streaming the test pattern video to any connected WebRTC peers. This command requires .NET Core to be installed and configured on the system. ```Shell dotnet run ``` -------------------------------- ### Cloning the Repository (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCLightningExamples/README.md This command clones the sipsorcery repository from GitHub and then navigates into the specific example directory for the WebRTC Lightning demo. It's the initial step to get the project files locally on your system. ```bash git clone git@github.com:sipsorcery-org/sipsorcery.git cd sipsorcery/examples/WebRTCLightningExamples/WebRTCLightningGetStarted ``` -------------------------------- ### Running WebRTC FFmpeg Docker Container Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/README.md These commands attempt to run the WebRTC FFmpeg application within a Docker container, exploring various networking options. The different configurations address challenges with WebRTC's ICE mechanism and Docker's default networking, including port mapping, host networking, and explicit UDP port forwarding for ICE, along with environment variables for ASP.NET Core and ICE gathering. ```Shell docker run --rm -it -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" webrtcgetstarted ``` ```Shell docker run --rm -it --network=host -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" webrtcgetstarted ``` ```Shell docker run --rm -it -p 8080:8080 -p 50042:50042/udp -e ASPNETCORE_URLS="http://0.0.0.0:8080" -e BIND_PORT="50042" webrtcgetstarted ``` ```Shell docker run --rm -it -p 8080:8080 -p 50042:50042/udp --add-host=host.docker.internal:host-gateway -e ASPNETCORE_URLS="http://0.0.0.0:8080" -e BIND_PORT="50042" webrtcgetstarted ``` ```Shell docker run --rm -it -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" -e WAIT_FOR_ICE_GATHERING_TO_SEND_OFFER="True" webrtcgetstarted ``` ```Shell docker run --rm -it -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" -e WAIT_FOR_ICE_GATHERING_TO_SEND_OFFER="True" -e STUN_URL="stun:stun.cloudflare.com" webrtcgetstarted ``` -------------------------------- ### Running WebRTC FFmpeg from DockerHub Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/README.md This command runs the WebRTC FFmpeg application directly from its official image hosted on DockerHub. It maps port 8080 from the container to the host and sets the ASP.NET Core URL environment variable for the application. ```Shell docker run --rm -it -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" sipsorcery/webrtcgetstarted ``` -------------------------------- ### SIP Registration with SIPSorcery in C# Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/notebooks/Register.ipynb This C# code snippet illustrates how to perform SIP registration using the SIPSorcery library. It initializes a SIPRegistrationUserAgent with user credentials, sets up event handlers for registration success, failure, and temporary issues, and then starts the periodic registration process. It requires the SIPSorcery NuGet package. ```C# #r "nuget:SIPSorcery, 4.0.13-pre" const string USERNAME = "softphonesample"; const string PASSWORD = "password"; const string DOMAIN = "sipsorcery.com"; const int EXPIRY = 120; Console.WriteLine("SIPSorcery Registration Demo"); var sipTransport = new SIPTransport(); var regUserAgent = new SIPRegistrationUserAgent(sipTransport, USERNAME, PASSWORD, DOMAIN, EXPIRY); // Event handlers for the different stages of the registration. regUserAgent.RegistrationFailed += (uri, err) => Console.WriteLine($"{uri.ToString()}: {err}"); regUserAgent.RegistrationTemporaryFailure += (uri, msg) => Console.WriteLine($"{uri.ToString()}: {msg}"); regUserAgent.RegistrationRemoved += (uri) => Console.WriteLine($"{uri.ToString()} registration failed."); regUserAgent.RegistrationSuccessful += (uri) => Console.WriteLine($"{uri.ToString()} registration succeeded."); // Start the thread to perform the initial registration and then periodically resend it. regUserAgent.Start(); Console.WriteLine("Waiting 10s for registration to complete..."); await Task.Delay(10000); Console.WriteLine("Finished."); ``` -------------------------------- ### Initializing WebRTC Peer Connection and Signaling - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/webrtccmdline/webrtc.html This `start` function initializes an `RTCPeerConnection`, optionally configured with STUN/TURN servers or an RSA certificate. It creates a data channel, sets up various event listeners for the peer connection (e.g., `ontrack`, `onicecandidate`, `ondatachannel`, connection state changes) and the data channel. It also establishes a WebSocket connection for signaling, handling incoming ICE candidates and SDP offers/answers. ```JavaScript async function start() { // Generate an RSA certificate for the peer connection //const rsaCert = await RTCPeerConnection.generateCertificate({ // name: "RSASSA-PKCS1-v1_5", // Specify RSA algorithm // modulusLength: 2048, // Key size (2048-bit RSA) // publicExponent: new Uint8Array([1, 0, 1]), // hash: "SHA-256" // Hash algorithm //}); pc = new RTCPeerConnection({ //iceServers: [{ urls: STUN_URL }] //iceServers: [ // { // urls: TURN_URL, // username: TURN_USERNAME, // credential: TURN_CREDENTIAL // } //] //certificates: [rsaCert] }); dc = pc.createDataChannel("dc1"); pc.ontrack = evt => document.querySelector('#audioCtl').srcObject = evt.streams[0]; pc.onicecandidate = evt => evt.candidate && ws.send(JSON.stringify(evt.candidate)); pc.ondatachannel = e => { console.log(`ondatachannel ${JSON.stringify(e.channel)}`); e.channel.onopen = (event) => console.log(`data channel onopen: ${event}.`); e.channel.onclose = (event) => console.log(`data channel onclose: ${event}.`); e.channel.onmessage = (event) => console.log(`data channel onmessage: ${event.data}.`); }; // Diagnostics. pc.onicegatheringstatechange = () => console.log("onicegatheringstatechange: " + pc.iceGatheringState); pc.oniceconnectionstatechange = () => console.log("oniceconnectionstatechange: " + pc.iceConnectionState); pc.onsignalingstatechange = () => console.log("onsignalingstatechange: " + pc.signalingState); pc.onconnectionstatechange = () => console.log("onconnectionstatechange: " + pc.connectionState); dc.onopen = (event) => console.log(`data channel onopen: ${event}.`); dc.onclose = (event) => console.log(`data channel onclose: ${event}.`); dc.onmessage = (event) => console.log(`data channel onmessage: ${event.data}.`); // Signalling. ws = new WebSocket(document.querySelector('#websockurl').value, []); ws.onmessage = async function (evt) { if (/^[\{\"\'\s]*candidate/.test(evt.data)) { pc.addIceCandidate(JSON.parse(evt.data)); } else { await pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(evt.data))); pc.createAnswer() .then((answer) => pc.setLocalDescription(answer)) .then(() => ws.send(JSON.stringify(pc.localDescription))); } }; }; ``` -------------------------------- ### Troubleshooting WebRTC FFmpeg Docker Container Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/README.md This command runs the WebRTC FFmpeg Docker container with an overridden entrypoint, specifically launching a bash shell inside the container. This is useful for debugging purposes, allowing users to inspect the container's file system, environment, and troubleshoot issues directly within the container. ```Shell docker run --rm -it -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" --entrypoint "/bin/bash" webrtcgetstarted ``` -------------------------------- ### Placing Video Call to Softphone - Shell Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/Softphone/README.md This command line snippet demonstrates how to initiate a video call from the `VideoPhoneCmdLine` example application to the SIPSorcery softphone. It specifies the destination IP address and port for the softphone and enables video transmission. ```Shell dotnet run --dst=127.0.0.1:5060 --tp ``` -------------------------------- ### Starting WebRTC Peer Connection and Signaling in JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCEchoServer/wwwroot/index.html The `start` function initiates the WebRTC peer connection process. It first closes any existing connection, then retrieves the signaling URL, generates a local white noise stream, creates an RTCPeerConnection, generates an offer, sends it via the `Signaler`, and finally sets the remote description with the received answer. ```JavaScript async function start() { if (!isClosed) { // Close any existing peer connection. await closePeer(); } isClosed = false; let signalingUrl = document.getElementById('signalingUrl').value; // Create the noise. let noiseStm = whiteNoise(NOISE_FRAME_WIDTH, NOISE_FRAME_HEIGHT); document.getElementById("localVideoCtl").srcObject = noiseStm; let signaler = new Signaler(signalingUrl); // Create the peer connections. pc = createPeer("echoVideoCtl", noiseStm); let offer = await pc.createOffer(); await pc.setLocalDescription(offer); var answer = await signaler.sendOffer(offer); if (answer != null) { console.log(answer.sdp) await pc.setRemoteDescription(answer); } else { console.log("Failed to get an answer from the Echo Test server.") pc.close(); } } ``` -------------------------------- ### Installing SIPSorcery NuGet Package using .NET CLI Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/README.md This command installs the SIPSorcery library as a NuGet package into a .NET project using the .NET Command Line Interface. It adds the package reference to the project file, making the library's functionalities available for use. ```bash dotnet add package SIPSorcery ``` -------------------------------- ### Setting Initial WebSocket URL in UI (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/wwwroot/index.html This line of code sets the value of an HTML input element with the ID `websockurl` to the dynamically generated WebSocket URL. This allows the user interface to display or pre-fill the WebSocket endpoint, which can then be used by the `start` function to establish the connection. ```JavaScript document.querySelector('#websockurl').value = getWebSocketUrl(); ``` -------------------------------- ### Starting Docker Containers for Lightning Network (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCLightningExamples/README.md This command uses Docker Compose to start the necessary services in detached mode: a Bitcoin Signet node, an LND Lightning node, and the RTL web interface. These services are essential for the Lightning payment functionality of the demo. ```bash docker-compose up -d ``` -------------------------------- ### Basic Console Output in C# Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/notebooks/Register.ipynb This snippet demonstrates a fundamental C# operation: printing a string to the console using Console.WriteLine. ```C# Console.WriteLine("Hello World"); ``` -------------------------------- ### Setting Up SIPSorcery WebRTC Console Application (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/README.md This bash script provides the initial setup commands for a SIPSorcery WebRTC console application. It creates a new .NET project, changes the directory, and adds the `SIPSorcery` and `SIPSorceryMedia.Encoders` NuGet packages. The `SIPSorceryMedia.Encoders` package is crucial for WebRTC, often relying on `libvpx` and currently having primary support on Windows. ```bash dotnet new console --name WebRTCGetStarted cd WebRTCGetStarted dotnet add package SIPSorcery dotnet add package SIPSorceryMedia.Encoders ``` -------------------------------- ### Starting an Outgoing SIP Call with SIP.js - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/sipjs/sipphone.html Defines the `StartCall` function to initiate an outgoing SIP call. It configures local and remote media elements, starts the User Agent, creates a SIP URI target, and sends an invite. ```JavaScript function StartCall() { var options = { media: { local: { //video: document.getElementById('localVideo') audio: document.getElementById('audioCtl') }, remote: { //video: document.getElementById('remoteVideo'), // This is necessary to do an audio/video call as opposed to just a video call audio: document.getElementById('audioCtl') } }, //ua: {} }; userAgent.start().then(() => { const target = SIP.UserAgent.makeURI("sip:bob@example.com"); const inviter = new SIP.Inviter(userAgent, target); inviter.invite(); }); } ``` -------------------------------- ### Initializing on Window Load (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/RtspToWebRTCAudioAndVideo/webrtc_tester.html An event listener that executes the `fillWsPlaceholder` function once the entire window content has been loaded, ensuring the UI is properly initialized with default values. ```JavaScript window.onload = (event) => { console.log('window.onload'); fillWsPlaceholder(); }; ``` -------------------------------- ### Running the WebRTC Lightning Demo Application (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCLightningExamples/README.md This command executes the .NET demo application. It starts the server-side component that integrates WebRTC streaming with the Lightning payment processing, making the video stream accessible and controllable via payments. ```bash dotnet run ``` -------------------------------- ### Installing SIPSorcery NuGet Package using PowerShell Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/README.md This command installs the SIPSorcery library as a NuGet package using the Visual Studio Package Manager Console. It's an alternative method to the .NET CLI for adding the package reference to a project within the Visual Studio environment. ```ps1 Install-Package SIPSorcery ``` -------------------------------- ### Handling Start Connection Button Click in JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/OpenAIExamples/WebRTCOpenAI/openai-js-test.html This snippet attaches an event listener to a 'Start Connection' button. When clicked, it retrieves the ephemeral key from an input field, validates it, and then calls the `init` function to establish the WebRTC connection. It includes basic error handling for the `init` function. ```JavaScript document.getElementById('startConnectionBtn').addEventListener('click', () => { const key = document.getElementById('ephemeralKey').value.trim(); if (!key) { alert('Please enter an ephemeral key.'); return; } init(key).catch(err => console.error("Error during init:", err)); }); ``` -------------------------------- ### Starting .NET Core Application with Codec Option Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/FfmpegToWebRTC/README.md This command starts the .NET Core test application, allowing the user to specify a preferred video codec (VP8, VP9, or H.264) as a command-line option. This overrides any default codec settings within the application for the WebRTC stream. ```Shell dotnet run -- ``` -------------------------------- ### Starting .NET WebRTC App with Web Socket Signaling (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/webrtccmdline/README.md This command starts the .NET WebRTC application in web socket signaling mode, allowing a browser-based client (webrtc.html) to establish a WebRTC connection using web sockets for SDP exchange. ```Bash dotnet run -- --ws ``` -------------------------------- ### Establishing WebRTC and WebSocket Connection (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/RtspToWebRTCAudioAndVideo/webrtc_tester.html Initiates a WebSocket connection to the specified URL and sets up an RTCPeerConnection. It handles incoming ICE candidates by adding them to the peer connection and processes SDP offers by setting the remote description and creating/sending an SDP answer. ```JavaScript async function start(url) { console.log(`start ${url}.`); alert(`подключаем веб сокет по адресу: ${url}`); closePeer(); let videoControl = document.querySelector('#videoCtl'); ws = new WebSocket(url, []); ws.onopen = async function () { console.log("web socket onopen."); pc = new RTCPeerConnection(); pc.ontrack = ({ track, streams: [stream] }) => { track.onunmute = () => { console.log("Adding track to video control."); videoControl.srcObject = stream; }; }; }; ws.onmessage = async function (evt) { if (!evt.data.startsWith("v=")) { console.log("Remote ICE candidate received."); console.log(evt.data); await pc.addIceCandidate({ candidate: evt.data, sdpMid: "0", sdpMLineIndex: 0 }); } else { // Received SDP offer from the remote web socket server. console.log("Offer SDP received:"); console.log(evt.data); await pc.setRemoteDescription(new RTCSessionDescription({ type: "offer", sdp: evt.data })) // Now create our offer SDP to send back to the web socket server. pc.createAnswer().then(function (answer) { return pc.setLocalDescription(answer); }).then(function () { console.log("Sending answer SDP:"); console.log(pc.localDescription.sdp); ws.send(pc.localDescription.sdp); }); } }; }; ``` -------------------------------- ### Initiating WebRTC Peer Connection - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCTestPatternRest/index.html The `start` function initializes or re-initializes the WebRTC peer connection. It closes any existing connection, retrieves the signaling URL, creates a `RestSignaler` instance, and then sets up a new `RTCPeerConnection`. It creates an SDP offer and sets it as the local description, triggering ICE gathering before sending the offer. ```JavaScript async function start() { if (!isClosed) { // Close any existing peer connection. await closePeer(); } isOfferSent = false; let signalingUrl = document.getElementById('signalingUrl').value; signaler = new RestSignaler(signalingUrl); // Create the peer connections. pc = createPeer("videoCtl"); pc.onicegatheringstatechange = async () => { console.log(`onicegatheringstatechange: ${pc.iceGatheringState}.`); if (pc.iceGatheringState === 'complete') { sendOffer(); } } let offer = await pc.createOffer(); await pc.setLocalDescription(offer); //setTimeout(sendOffer, ICE_GATHERING_TIMEOUT); } ``` -------------------------------- ### Packaging OpenAI.Realtime Library for Local NuGet (Shell) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/OpenAIExamples/WebRTCOpenAIBridge/notes.txt This command packages the OpenAI.Realtime library into a local NuGet feed. This is necessary to ensure the WebRTCOpenAIBridge project can access the correct version of the dependency during its build process. The package is output to the local-nuget directory within the WebRTCOpenAIBridge example. ```Shell c:\dev\sipsorcery\examples\OpenAIExamples\OpenAI.Realtime> dotnet pack --configuration Debug --output ..\WebRTCOpenAIBridge\local-nuget /p:TargetFrameworks=net8.0 ``` -------------------------------- ### Starting .NET WebRTC App to Generate SDP Offer (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/webrtccmdline/README.md This command initiates the .NET WebRTC application to generate a base64 encoded SDP offer, which can then be manually copied and pasted to another WebRTC peer for connection establishment. ```Bash dotnet run -- --offer ``` -------------------------------- ### Initializing WebRTC Peer Connection and WebSocket Signaling Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCGetStartedVP8Net/getstarted.html The `start` function initializes an `RTCPeerConnection` and a `WebSocket`. It configures event handlers for `ontrack` to display remote media, `onicecandidate` to send candidates via WebSocket, and `onclose` for cleanup. The WebSocket handles incoming SDP offers/answers and ICE candidates to establish and maintain the peer connection. ```javascript async function start() { pc = new RTCPeerConnection(); pc.ontrack = evt => { console.log("Adding track to video control."); document.querySelector('#videoCtl').srcObject = evt.streams[0]; evt.streams[0].onunmute = () => { console.log("Adding track to video control."); }; evt.streams[0].onended = () => { console.log("Track ended."); }; } pc.onicecandidate = evt => evt.candidate && ws.send(JSON.stringify(evt.candidate)); pc.onclose= () => { console.log("pc close"); }; ws = new WebSocket(document.querySelector('#websockurl').value, []); ws.onmessage = async function (evt) { var obj = JSON.parse(evt.data); if (obj?.candidate) { pc.addIceCandidate(obj); } else if (obj?.sdp) { await pc.setRemoteDescription(new RTCSessionDescription(obj)); pc.createAnswer() .then((answer) => pc.setLocalDescription(answer)) .then(() => ws.send(JSON.stringify(pc.localDescription))); } }; }; ``` -------------------------------- ### Running the .NET Core Console Application Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/JanusWebRTCStream/README.md This command starts the .NET Core console application. It compiles and runs the project from the current directory, initiating the WebRTC peer connection test. ```Shell dotnet run ``` -------------------------------- ### Initializing Global WebSocket and WebRTC Variables (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/RtspToWebRTCAudioAndVideo/webrtc_tester.html Declares global variables for WebSocket port, server address, RTCPeerConnection, and WebSocket instance, which are used across various functions for WebRTC and WebSocket communication. ```JavaScript var wsport = "5300"; var wsserver = "ws://127.0.0.1:"; var pc; var ws; ``` -------------------------------- ### Starting SIPSorcery .Net Core Applications Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPScenarios/OnHoldScenario/README.md This snippet provides the shell commands to launch the Caller and Callee .Net Core applications. These programs are fundamental for the SIP On Hold test, acting as the endpoints for SIP signaling and RTP media. They must be running before initiating any calls. ```Shell Caller$ dotnet run Callee$ dotnet run ``` -------------------------------- ### Initializing WebRTC Peer Connection and WebSocket - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCTestPatternServer/testpatternbw.html The `start` function initializes an `RTCPeerConnection` with a STUN server, sets up event handlers for ICE candidates, track events, and various connection state changes for diagnostics. It also establishes a WebSocket connection to a signaling server and defines the message handler for processing ICE candidates and SDP offers/answers. ```JavaScript async function start() { pc = new RTCPeerConnection({ iceServers: [{ urls: STUN_URL }] }); getBitrateInterval = window.setInterval(getBitrate, 1000); pc.ontrack = evt => document.querySelector('#videoCtl').srcObject = evt.streams[0]; pc.onicecandidate = evt => evt.candidate && ws.send(JSON.stringify(evt.candidate)); // Diagnostics. pc.onicegatheringstatechange = () => console.log("onicegatheringstatechange: " + pc.iceGatheringState); pc.oniceconnectionstatechange = () => console.log("oniceconnectionstatechange: " + pc.iceConnectionState); pc.onsignalingstatechange = () => console.log("onsignalingstatechange: " + pc.signalingState); pc.onconnectionstatechange = () => console.log("onconnectionstatechange: " + pc.connectionState); ws = new WebSocket(document.querySelector('#websockurl').value, []); ws.onmessage = async function (evt) { if (/^[\{\"'\s]*candidate/.test(evt.data)) { pc.addIceCandidate(JSON.parse(evt.data)); } else { await pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(evt.data))); pc.createAnswer() .then((answer) => pc.setLocalDescription(answer)) .then(() => ws.send(JSON.stringify(pc.localDescription))); } }; }; ``` -------------------------------- ### Example ffplay SDP File Content Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCtoFfplay/README.md This snippet illustrates the typical content of the ffplay.sdp file generated by the application. It defines the audio (Opus) and video (VP8) streams, their respective ports, and attributes necessary for ffplay to interpret the incoming RTP streams from the local application. ```SDP v=0 o=- 1474529382 0 IN IP4 127.0.0.1 s=- c=IN IP4 127.0.0.1 t=0 0 m=audio 5016 RTP/AVP 111 a=rtpmap:111 opus/48000/2 a=fmtp:111 minptime=10;useinbandfec=1 a=sendrecv m=video 5018 RTP/AVP 98 a=rtpmap:98 VP8/90000 a=sendrecv ``` -------------------------------- ### Starting .Net Core SIP Transfer Programs Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPScenarios/BlindTransferScenario/README.md This snippet provides the shell commands to launch the three .Net Core applications essential for the SIP Blind Transfer test: Transferor, Transferee, and Target. Each command should be executed in a separate console window to run the respective program. ```Shell Transferor$ dotnet run Transferee$ dotnet run Target$ dotnet run ``` -------------------------------- ### Loading Typeface from Android Assets (C#) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPExamples/AndroidSIPGetStarted/Assets/AboutAssets.txt This example shows how to load a custom font, 'samplefont.ttf', directly from the application's assets directory using Typeface.CreateFromAsset(). This method simplifies the process of integrating custom fonts into an Android application. ```C# Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); ``` -------------------------------- ### Starting SIP Load Test Server (.Net Core) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPScenarios/LoadTestScenario/README.md This command executes the .Net Core server application located in the `LoadServer` directory. This server component is essential for the SIP and RTP load test, acting as the target for client calls. ```Shell dotnet run ``` -------------------------------- ### Defining WebRTC and WebSocket Constants (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/wwwroot/index.html This snippet defines global constants for the WebSocket signaling server URL and the STUN server URL, which are essential for WebRTC ICE candidate discovery. It also declares global variables `pc` for the RTCPeerConnection and `ws` for the WebSocket instance, which will be initialized later. ```JavaScript const WEBSOCKET_URL = "ws://127.0.0.1:8080/ws" const STUN_URL = "stun:stun.cloudflare.com"; var pc, ws; ``` -------------------------------- ### Initializing Multiple WebRTC Peer Connections in JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCTestPatternServer/3x3.html This snippet defines the `start` function, which initializes multiple WebRTC peer connections. It iterates up to 9 times, creating a new peer connection for each iteration using the `startPeer` function and pushing it into the global `pcs` array, with a 1-second delay between each initialization. ```JavaScript const url = "ws://localhost:8081/" var pcs = []; async function start() { for (i = 0; i < 9; i++) { let name = `#videoCtl${i}`; let pc = startPeer(document.querySelector(name), name); pcs.push(pc); await new Promise(r => setTimeout(r, 1000)); } } ``` -------------------------------- ### Starting SIP Load Test Client (.Net Core) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPScenarios/LoadTestScenario/README.md This command executes the .Net Core client application located in the `LoadClient` directory. The client initiates 100 calls to the server and sends DTMF sequences to verify RTP channel establishment, marking a test as failed if DTMF is not received within 5 seconds. ```Shell dotnet run ``` -------------------------------- ### Setting Up SIPSorcery VoIP Console Application (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/README.md This bash script outlines the steps to initialize a new .NET console project for SIPSorcery VoIP development. It includes commands to create the project, navigate to its directory, and add the necessary `SIPSorcery` and `SIPSorceryMedia.Windows` NuGet packages, which are crucial for audio handling on Windows platforms. ```bash dotnet new console --name SIPGetStarted --framework net8.0 --target-framework-override net8.0-windows10.0.17763.0 cd SIPGetStarted dotnet add package SIPSorcery dotnet add package SIPSorceryMedia.Windows # Paste the code below into Program.cs. dotnet run # If successful you will hear a "Hello World" announcement. ``` -------------------------------- ### Dynamically Generating WebSocket URL (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCFFmpegGetStarted/wwwroot/index.html This function dynamically constructs the WebSocket URL based on the current page's protocol (HTTP/HTTPS) and host. It ensures that the WebSocket connection uses the appropriate secure or non-secure protocol and connects to the same host as the web page, simplifying deployment. ```JavaScript function getWebSocketUrl() { const location = window.location; const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:'; const host = location.host; const path = '/ws'; // Change this to match your server's WebSocket endpoint return `${protocol}//${host}${path}`; } ``` -------------------------------- ### Building and Running OpenAI Bridge (Bash) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/OpenAIExamples/WebRTCOpenAIBridge/README.md This snippet outlines the steps to clone the repository, set essential environment variables (`OPENAIKEY`, `STUN_URL`), and then build and run the ASP.NET Core application using the `dotnet run` command. This sequence is typical for Linux or macOS environments. ```bash git clone https://github.com/your-org/demo-webrtc-openai.git cd demo-webrtc-openai export OPENAIKEY="" export STUN_URL="stun:stun.l.google.com:19302" dotnet run ``` -------------------------------- ### Defining WebRTC Configuration Constants and Globals - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/webrtccmdline/webrtc.html This snippet defines constants for STUN/TURN server URLs and credentials, along with the WebSocket signaling URL. It also declares global variables pc, ws, and dc to hold the RTCPeerConnection, WebSocket, and RTCDataChannel objects, respectively, for later use. ```JavaScript const STUN_URL = "stun:stun.l.google.com:19302"; const TURN_URL = "turn:coturn"; const TURN_USERNAME = "user"; const TURN_CREDENTIAL = "password"; const WEBSOCKET_URL = "ws://127.0.0.1:8081/" var pc, ws, dc; ``` -------------------------------- ### Initializing MediaStream and RTCPeerConnection - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCReceiver/captureopts_manlesdp.html This snippet requests access to the user's media devices using `navigator.mediaDevices.getUserMedia` with the defined `captureOptions`. The obtained local media stream (`captureStm`) is then displayed in a video element. An `RTCPeerConnection` is initialized with a STUN server for ICE candidate gathering, and an interval is set to periodically fetch connection statistics. ```JavaScript let captureStm = await navigator.mediaDevices.getUserMedia(captureOptions); document.querySelector('#videoCtl').srcObject = captureStm; // No remote streams so render local ones. pc = new RTCPeerConnection({ iceServers: [{ urls: STUN_URL }] }); statsInterval = window.setInterval(getConnectionStats, 1000); ``` -------------------------------- ### Placing an Audio-Only SIP Call with SIPSorcery (C#) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/README.md This C# code snippet demonstrates how to programmatically place a basic audio-only SIP call using the SIPSorcery library. It initializes a `SIPUserAgent` and `VoIPMediaSession` with a `WindowsAudioEndPoint` for audio playback, then asynchronously initiates a call to a specified SIP URI. This example is specific to Windows due to its audio endpoint dependency. ```csharp string DESTINATION = "music@iptel.org"; Console.WriteLine("SIP Get Started"); var userAgent = new SIPSorcery.SIP.App.SIPUserAgent(); var winAudio = new SIPSorceryMedia.Windows.WindowsAudioEndPoint(new SIPSorcery.Media.AudioEncoder()); var voipMediaSession = new SIPSorcery.Media.VoIPMediaSession(winAudio.ToMediaEndPoints()); // Place the call and wait for the result. bool callResult = await userAgent.Call(DESTINATION, null, null, voipMediaSession); Console.WriteLine($"Call result {(callResult ? "success" : "failure")}."); Console.WriteLine("Press any key to hangup and exit."); Console.ReadLine(); ``` -------------------------------- ### Initializing WebRTC Peer Connection and WebSocket Server in C# Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/README.md This C# code sets up a console application that acts as a WebRTC peer. It initializes a WebSocket server to handle signaling for WebRTC connections and creates an RTCPeerConnection that sends a video test pattern. It manages the peer connection state, starting and stopping the video stream based on connection status. ```csharp using System; using System.Linq; using System.Net; using System.Threading.Tasks; using SIPSorcery.Media; using SIPSorcery.Net; using SIPSorceryMedia.Encoders; using WebSocketSharp.Server; namespace demo { class Program { private const int WEBSOCKET_PORT = 8081; static void Main() { Console.WriteLine("WebRTC Get Started"); // Start web socket. Console.WriteLine("Starting web socket server..."); var webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT); webSocketServer.AddWebSocketService("/", (peer) => peer.CreatePeerConnection = () => CreatePeerConnection()); webSocketServer.Start(); Console.WriteLine($"Waiting for web socket connections on {webSocketServer.Address}:{webSocketServer.Port}..."); Console.WriteLine("Press any key exit."); Console.ReadLine(); } private static Task CreatePeerConnection() { var pc = new RTCPeerConnection(null); var testPatternSource = new VideoTestPatternSource(new VpxVideoEncoder()); MediaStreamTrack videoTrack = new MediaStreamTrack(testPatternSource.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(videoTrack); testPatternSource.OnVideoSourceEncodedSample += pc.SendVideo; pc.OnVideoFormatsNegotiated += (formats) => testPatternSource.SetVideoSourceFormat(formats.First()); pc.onconnectionstatechange += async (state) => { Console.WriteLine($"Peer connection state change to {state}."); switch(state) { case RTCPeerConnectionState.connected: await testPatternSource.StartVideo(); break; case RTCPeerConnectionState.failed: pc.Close("ice disconnection"); break; case RTCPeerConnectionState.closed: await testPatternSource.CloseVideo(); testPatternSource.Dispose(); break; } }; return Task.FromResult(pc); } } } ``` -------------------------------- ### Packaging SIPSorcery .NET Project Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPExamples/SIPCloudCallServer/readme-docker.txt This command packages the SIPSorcery .NET project into a NuGet package. It specifies the 'Debug' configuration and outputs the package to a local directory for testing or local consumption. ```Shell dotnet pack SIPSorcery.csproj --configuration Debug --output c:\dev\local-nuget ``` -------------------------------- ### Building SIPSorcery Docker Image Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPExamples/SIPCloudCallServer/readme-docker.txt This command builds a Docker image for the SIPSorcery SIPCloudCallServer. It tags the image with 'sipsorcery/sipcloudcallserver' and version '0.1' based on the Dockerfile in the current directory. ```Shell docker build -t sipsorcery/sipcloudcallserver:0.1 . ``` -------------------------------- ### Displaying Help Options for SIP Testing Tool (Shell) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/sipcmdline/README.md This command executes the `sipsorcery` program to display all available command-line options and usage instructions. It's essential for understanding the tool's capabilities and parameters. ```Shell dotnet run -- --help ``` -------------------------------- ### Starting .Net Core WebRTC Application and Displaying SDP Offer Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCNoSignalling/README.md This snippet shows the console output when starting the .Net Core WebRTC application. It initializes OpenSSL and libsrtp, then displays the generated SDP offer, including ICE candidates, ufrag, and password, which is required for the browser peer. ```Console examples\WebRTCNoSignalling>dotnet run WebRTC No Signalling Server Sample Program Press ctrl-c to exit. Initialising OpenSSL and libsrtp... Using WebM Project VP8 Encoder v1.8.1 Starting Peer Connection... [11:14:30 DBG] CreateRtpSocket start port using OS default ephemeral port range on ::. [11:14:30 DBG] Successfully bound RTP socket on [::]:52259 (dual mode True). [11:14:31 DBG] v=0 o=- 35588 0 IN IP4 127.0.0.1 s=- t=0 0 a=group:BUNDLE 0 m=video 9 RTP/SAVP 100 c=IN IP4 0.0.0.0 a=ice-ufrag:WFEG a=ice-pwd:NIWGINQKDLYWXDABENRYNGBE a=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 a=candidate:2306 1 udp 659136 fe80::910e:8bfe:e7e3:7919%52 52259 typ host generation 0 a=candidate:2337 1 udp 659136 172.20.16.1 52259 typ host generation 0 a=candidate:2441 1 udp 659136 fe80::54a9:d238:b2ee:ceb%21 52259 typ host generation 0 a=candidate:2944 1 udp 659136 192.168.11.50 52259 typ host generation 0 a=ice-options:ice2,trickle a=mid:0 a=rtpmap:100 VP8/90000 a=rtcp-mux a=rtcp:9 IN IP4 0.0.0.0 a=setup:actpass a=sendrecv ``` -------------------------------- ### Building WebRTC Lightning Demo Docker Image (Docker) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCLightningExamples/README.md This command builds the `webrtclightningdemo` Docker image from the current directory using the specified Dockerfile. The `--progress=plain` flag ensures a clear output during the build process. ```docker docker build -t webrtclightningdemo --progress=plain -f Dockerfile . ``` -------------------------------- ### Troubleshooting WebRTC Lightning Demo Docker Container (Docker) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCLightningExamples/README.md This command runs the `webrtclightningdemo` Docker image but overrides its default entrypoint to `/bin/bash`. This allows users to access an interactive shell within the container for debugging purposes, such as checking file paths or configurations. ```docker docker run --rm -it -p 8080:8080 -e ASPNETCORE_URLS="http://0.0.0.0:8080" -e Lnd__Url="%LND_URL%" -e Lnd__MacaroonHex="%LND_MACAROON_HEX%" -e Lnd__CertificateBase64="%LND_CERTIFICATE_BASE64%" --entrypoint "/bin/bash" webrtclightningdemo ``` -------------------------------- ### Polling Node DSS for WebRTC Signaling Data with AJAX GET in JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/UnityVideoSource/webrtc-viewer.html The `pollNodeDss` function periodically checks the Node DSS for incoming signaling messages using an AJAX GET request. It includes an optional delay and ensures polling stops if the peer connection is closed. This mechanism retrieves ICE candidates or SDP offers/answers from the signaling server. ```JavaScript async function pollNodeDss(delayms) { if (delayms > 0) { await new Promise(r => setTimeout(r, delayms)); } if (!isClosed) { $.ajax({ url: `${nodeDssUrl}/data/${nodeDssOurID}`, type: 'GET', success: onSuccess, error: onError }); } } ``` -------------------------------- ### Starting WebRTC Peer Connection and Event Handlers in JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/UnityVideoSource/webrtc-viewer.html The `start` function initializes a new `RTCPeerConnection` with a STUN server for NAT traversal. It configures `ontrack` to display remote media, `onicecandidate` to send ICE candidates via the signaling server, and various diagnostic event handlers for connection state changes. It also retrieves updated DSS IDs from the UI and initiates polling. ```JavaScript async function start() { isClosed = false; pc = new RTCPeerConnection({ iceServers: [{ urls: STUN_URL }] }); pc.ontrack = evt => document.querySelector('#videoCtl').srcObject = evt.streams[0]; pc.onicecandidate = evt => evt.candidate && sendSignal(JSON.stringify(evt.candidate)); // Diagnostics. pc.onicegatheringstatechange = () => console.log("onicegatheringstatechange: " + pc.iceGatheringState); pc.oniceconnectionstatechange = () => console.log("oniceconnectionstatechange: " + pc.iceConnectionState); pc.onsignalingstatechange = () => console.log("onsignalingstatechange: " + pc.signalingState); pc.onconnectionstatechange = () => console.log("onconnectionstatechange: " + pc.connectionState); nodeDssUrl = $('#nodedssurl').val(); nodeDssOurID = $('#ourID').val(); nodeDssTheirID = $('#theirID').val(); pollNodeDss(); }; ``` -------------------------------- ### Configuring Global Constants and Page Load Initialization in JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/WebRTCEchoServer/wwwroot/index.html This section defines global constants for the STUN server and dimensions for the white noise video. It also includes a `window.onload` event handler that dynamically sets the default signaling URL in the UI based on the current host and port. ```JavaScript "use strict"; const STUN_SERVER = "stun:stun.sipsorcery.com"; const NOISE_FRAME_WIDTH = 80; const NOISE_FRAME_HEIGHT = 60; var pc; var isClosed = true; window.onload = () => { let host = window.location.hostname.concat(window.location.port ? `:${window.location.port}` : ""); document.getElementById('signalingUrl').value = `${window.location.protocol}//${host}/offer`; }; ``` -------------------------------- ### Closing WebRTC Peer Connection and WebSocket (JavaScript) Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/WebRTCExamples/RtspToWebRTCAudioAndVideo/webrtc_tester.html Safely closes the active WebSocket connection and the RTCPeerConnection instance if they exist, releasing resources and terminating the communication. ```JavaScript function closePeer() { console.log("close peer"); if (ws != null) { ws.close(); } if (pc != null) { pc.close(); } }; ``` -------------------------------- ### Initializing WebRTC Peer Connection and WebSocket Signaling - JavaScript Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/OpenAIExamples/WebRTCOpenAIBridge/wwwroot/index.html This asynchronous function initializes an RTCPeerConnection with a STUN server for NAT traversal and obtains local audio. It sets up event handlers for ontrack to display remote media, onicecandidate to send ICE candidates via WebSocket, and onclose for cleanup. It also establishes a WebSocket connection and defines its onmessage, onclose, and onerror handlers for SDP and ICE candidate exchange. ```JavaScript async function start() { pc = new RTCPeerConnection({ iceServers: [ { urls: STUN_URL } ] }); localStream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true }); localStream.getTracks().forEach(track => { console.log('add local track ' + track.kind + ' to peer connection.'); console.log(track); pc.addTrack(track, localStream); }); pc.ontrack = evt => { console.log("Adding track to video control."); document.querySelector('#videoCtl').srcObject = evt.streams[0]; evt.streams[0].onunmute = () => { console.log("Adding track to video control."); }; evt.streams[0].onended = () => { console.log("Track ended."); }; } pc.onicecandidate = evt => evt.candidate && ws.send(JSON.stringify(evt.candidate)); pc.onclose = () => { console.log("pc close"); }; ws = new WebSocket(document.querySelector('#websockurl').value, []); ws.onmessage = async function (evt) { console.log("WebSocket message received:", evt.data); var obj = JSON.parse(evt.data); if (obj?.candidate) { pc.addIceCandidate(obj); } else if (obj?.sdp) { await pc.setRemoteDescription(new RTCSessionDescription(obj)); pc.createAnswer() .then((answer) => pc.setLocalDescription(answer)) .then(() => ws.send(JSON.stringify(pc.localDescription))); } }; ws.onclose = function (evt) { console.log("WebSocket closed, code: " + evt.code + ", reason: " + evt.reason); }; ws.onerror = function (evt) { console.error("WebSocket error:", evt); }; }; ``` -------------------------------- ### Starting Target .Net Core Application Source: https://github.com/sipsorcery-org/sipsorcery/blob/master/examples/SIPScenarios/AttendedTransferScenario/README.md Initiates the Target application, which will be the final destination of the transferred call. This application is one of three required components for the test scenario. ```bash Target$ dotnet run ```