# sipsorcery **Repository Path**: liangmingwei92/sipsorcery ## Basic Information - **Project Name**: sipsorcery - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-21 - **Last Updated**: 2024-05-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README | Target | SIPSorcery | Examples
(Windows Only) | Softphone
(Windows Only) | | --------------| ------------- |:-------------|:--------- | | net461 | [![Build status](https://ci.appveyor.com/api/projects/status/1prvhq7jyw0s5fb1/branch/master?svg=true)](https://ci.appveyor.com/project/sipsorcery/sipsorcery/branch/master) | | | | netstandard2.0 | ![](https://github.com/sipsorcery/sipsorcery/workflows/sipsorcery-std20/badge.svg) | | | | dotnetcore3.1 |
Windows![](https://github.com/sipsorcery/sipsorcery/workflows/sipsorcery-core31-win/badge.svg)
MacOS![](https://github.com/sipsorcery/sipsorcery/workflows/sipsorcery-core31-mac/badge.svg)
Ubuntu![](https://github.com/sipsorcery/sipsorcery/workflows/sipsorcery-core31-ubuntu/badge.svg)
| ![](https://github.com/sipsorcery/sipsorcery/workflows/examples-core31/badge.svg)
[![Examples build status](https://ci.appveyor.com/api/projects/status/4myf11mda0p69ysm/branch/master?svg=true)](https://ci.appveyor.com/project/sipsorcery/sipsorcery-mre1o/branch/master) | [![Softphone build status](https://ci.appveyor.com/api/projects/status/xx1bcttkk4gbrd3y/branch/master?svg=true)](https://ci.appveyor.com/project/sipsorcery/sipsorcery-0p6s4/branch/master) | ## What Is It? **This fully C# library can be used to add Real-time Communications, typically audio and video calls, to .NET Core applications.** The diagram below is a high level overview of a Real-time audio and video call between Alice and Bob. It illustrates where the `SIPSorcery` library can help. ![Real-time Communications Overview](./img/sipsorcery_realtime_overview.png) **Supports both VoIP ([get started](#getting-started-voip)) and WebRTC ([get started](#getting-started-webrtc)).** **Some of the protocols supported:** - Session Initiation Protocol [(SIP)](https://tools.ietf.org/html/rfc3261), - Real-time Transport Protocol [(RTP)](https://tools.ietf.org/html/rfc3550), - Web Real-time Communications [(WebRTC)](https://www.w3.org/TR/webrtc/), - Interactive Connectivity Establishment [(ICE)](https://tools.ietf.org/html/rfc8445), - And more. **Media End Points - Audio/Video Sinks and Sources:** - This library does not provide access to audio and video devices or native codecs. Providing cross platform access on top of .NET Core is a large undertaking. A number of efforts in separate libraries are currently in progress. - [SIPSorceryMedia.Windows](https://github.com/sipsorcery/SIPSorceryMedia.Windows): Windows specific library that provides audio capture and playback. Also provides [VP8](https://www.webmproject.org/) encoding and decoding functions. The examples in this repository use it. - [SIPSorceryMedia.FFmpeg](https://github.com/sipsorcery/SIPSorceryMedia.FFmpeg): A in-progress effort to provide cross platform audio, video and codec functions using PInvoke and [FFmpeg](https://ffmpeg.org/). - Others: **Contributions welcome**. Frequently requested are Xamarin Forms on Android/iOS and Unix (Linux and/or Mac). New implementations need to implement one or more of the Audio Sink/Source and/or Video Sink/Source interfaces from [SIPSorceryMedia.Abstractions](https://github.com/sipsorcery/SIPSorceryMedia.Abstractions/blob/master/src/V1/MediaEndPoints.cs). - This library provides only a small number of audio and video codecs (G711, G722 and MJPEG). Additional codecs, particularly video ones, require C++ libraries. ## Installation The library is compliant with .NET Standard 2.0 (encompassing .NET Core 2.0+) and .NET Framework 4.6.1 (theoretically also encompassed by `netstandard2.0` but set as an explicit target due to compatibility issues between the two). It is available via NuGet. For .NET Core: ````bash dotnet add package SIPSorcery -v 4.0.71-pre ```` With Visual Studio Package Manager Console (or search for [SIPSorcery on NuGet](https://www.nuget.org/packages/SIPSorcery/)): ````ps1 Install-Package SIPSorcery -v 4.0.71-pre ```` ## Documentation Class reference documentation and articles explaining common usage are available at [https://sipsorcery.github.io/sipsorcery/](https://sipsorcery.github.io/sipsorcery/). ## Getting Started VoIP The simplest possible example to place an audio-only SIP call is shown below. This example relies on the Windows specific `SIPSorceryMedia` library to play the received audio and only works on Windows (due to lack of .NET Core audio device support on non-Windows platforms). ````bash dotnet new console --name SIPGetStarted -f netcoreapp3.1 cd SIPGetStarted dotnet add package SIPSorcery -v 4.0.71-pre dotnet add package SIPSorceryMedia.Windows -v 0.0.18-pre code . # If you have Visual Studio Code https://code.visualstudio.com installed. # edit Program.cs and paste in the contents below. dotnet run # if successful you will hear the current time read out. ctrl-c ```` ````csharp using System; using System.Threading.Tasks; using SIPSorcery.SIP.App; using SIPSorcery.Media; using SIPSorceryMedia.Windows; namespace SIPGetStarted { class Program { private static string DESTINATION = "time@sipsorcery.com"; static async Task Main() { Console.WriteLine("SIP Get Started"); var userAgent = new SIPUserAgent(); var winAudio = new WindowsAudioEndPoint(new AudioEncoder()); var voipMediaSession = new 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(); } } } ```` The [GetStarted](https://github.com/sipsorcery/sipsorcery/tree/master/examples/SIPExamples/GetStarted) example contains the full source and project file for the example above. The three key classes in the above example are described in dedicated articles: - [SIPTransport](https://sipsorcery.github.io/sipsorcery/articles/transport.html), - [SIPUserAgent](https://sipsorcery.github.io/sipsorcery/articles/sipuseragent.html), - [RTPSession](https://sipsorcery.github.io/sipsorcery/articles/rtpsession.html). The [examples folder](https://github.com/sipsorcery/sipsorcery/tree/master/examples/SIPExamples) contains sample code to demonstrate other common SIP/VoIP cases. ## Getting Started WebRTC The WebRTC specifications do not include directions about how signaling should be done (for VoIP the signaling protocol is SIP; WebRTC has no equivalent). The example below uses a simple JSON message exchange over web sockets for signaling. Part of the reason the `Getting Started WebRTC` is over 5 times as long as the `Getting Started VoIP` is the need for custom signaling. The example requires two steps: - Run the `dotnet` console application, - Open an HTML page in a browser on the same machine. The full project file and code are available at [WebRTC Get Started](https://github.com/sipsorcery/sipsorcery/tree/master/examples/WebRTCExamples/WebRTCGetStarted). The example relies on the Windows specific `SIPSorceryMedia.Windows` package. Hopefully in the future there will be equivalent packages for other platforms. Step 1: ````bash dotnet new console --name WebRTCGetStarted -f netcoreapp3.1 cd WebRTCGetStarted dotnet add package SIPSorcery -v 4.0.71-pre dotnet add package SIPSorceryMedia.Windows -v 0.0.18-pre dotnet add package Serilog.Sinks.Console dotnet add package Serilog.Extensions.Logging code . # If you have Visual Studio Code (https://code.visualstudio.com) installed # edit Program.cs and paste in the contents below. dotnet run ```` ````csharp using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Serilog; using SIPSorcery.Net; using SIPSorceryMedia.Windows; using WebSocketSharp.Server; using SIPSorcery.Media; using Serilog.Extensions.Logging; namespace demo { class Program { private const int WEBSOCKET_PORT = 8081; private const string STUN_URL = "stun:stun.sipsorcery.com"; private static Microsoft.Extensions.Logging.ILogger logger = NullLogger.Instance; static void Main() { Console.WriteLine("WebRTC Get Started"); logger = AddConsoleLogger(); // 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 ctrl-c to exit."); // Ctrl-c will gracefully exit the call at any point. ManualResetEvent exitMre = new ManualResetEvent(false); Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e) { e.Cancel = true; exitMre.Set(); }; // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed. exitMre.WaitOne(); } private static RTCPeerConnection CreatePeerConnection() { RTCConfiguration config = new RTCConfiguration { iceServers = new List { new RTCIceServer { urls = STUN_URL } } }; var pc = new RTCPeerConnection(config); var testPatternSource = new VideoTestPatternSource(); WindowsVideoEndPoint windowsVideoEndPoint = new WindowsVideoEndPoint(true); var audioSource = new AudioExtrasSource(new AudioEncoder(), new AudioSourceOptions { AudioSource = AudioSourcesEnum.Music }); MediaStreamTrack videoTrack = new MediaStreamTrack(windowsVideoEndPoint.GetVideoSourceFormats(), MediaStreamStatusEnum.SendRecv); pc.addTrack(videoTrack); MediaStreamTrack audioTrack = new MediaStreamTrack(audioSource.GetAudioSourceFormats(), MediaStreamStatusEnum.SendRecv); pc.addTrack(audioTrack); testPatternSource.OnVideoSourceRawSample += windowsVideoEndPoint.ExternalVideoSourceRawSample; windowsVideoEndPoint.OnVideoSourceEncodedSample += pc.SendVideo; audioSource.OnAudioSourceEncodedSample += pc.SendAudio; 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.connected) { await audioSource.StartAudio(); await windowsVideoEndPoint.StartVideo(); await testPatternSource.StartVideo(); } else if (state == RTCPeerConnectionState.failed) { pc.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.closed) { await testPatternSource.CloseVideo(); await windowsVideoEndPoint.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 pc; } /// /// Adds a console logger. Can be omitted if internal SIPSorcery debug and warning messages are not required. /// private static Microsoft.Extensions.Logging.ILogger AddConsoleLogger() { var seriLogger = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) .WriteTo.Console() .CreateLogger(); var factory = new SerilogLoggerFactory(seriLogger); SIPSorcery.LogFactory.Set(factory); return factory.CreateLogger(); } } } ```` Step 2: Create an HTML file, paste the contents below into it, open it in a browser that supports WebRTC and finally press the `start` button. ````html
```` Result: If successful the browser should display a test pattern image and play a music sample. The `dotnet` console should display a steady stream of RTCP reports. ````bash ... [19:40:25 DBG] STUN BindingRequest received from 192.168.0.50:57681. [19:40:26 DBG] RTCP Receive for video from 192.168.11.50:57681 SDES: SSRC=3458092865, CNAME=5+ksoe4uBNfyl5u5 Sender: SSRC=3458092865, PKTS=18, BYTES=16392 [19:40:26 DBG] RTCP Receive for video from 192.168.11.50:57681 Receiver: SSRC=3458092865 RR: SSRC=852075017, LOST=0, JITTER=390 [19:40:26 DBG] STUN BindingRequest received from 192.168.11.50:57681. [19:40:27 DBG] RTCP Receive for video from 192.168.11.50:57681 SDES: SSRC=3458092865, CNAME=5+ksoe4uBNfyl5u5 Sender: SSRC=3458092865, PKTS=46, BYTES=39676 [19:40:27 DBG] RTCP Receive for video from 192.168.11.50:57681 Receiver: SSRC=3458092865 RR: SSRC=852075017, LOST=0, JITTER=368 [19:40:27 DBG] STUN BindingRequest received from 192.168.11.50:57681. [19:40:27 DBG] RTCP Receive for audio from 192.168.11.50:57681 SDES: SSRC=1049319500, CNAME=5+ksoe4uBNfyl5u5 Sender: SSRC=1049319500, PKTS=106, BYTES=16960 [19:40:27 DBG] STUN BindingRequest received from 192.168.0.50:57681. [19:40:27 DBG] RTCP Receive for video from 192.168.11.50:57681 Receiver: SSRC=3458092865 RR: SSRC=852075017, LOST=0, JITTER=419 ... ```` The [examples folder](https://github.com/sipsorcery/sipsorcery/tree/master/examples/WebRTCExamples) contains sample code to demonstrate other common WebRTC cases.