forked from sipsorcery-org/sipsorcery
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Switch appveyor CI to VS Preview image for net5 builds.
- Loading branch information
1 parent
2ba379e
commit 23edc23
Showing
4 changed files
with
209 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 127 additions & 0 deletions
127
examples/WebRTCExamples/WebRTCRenegotiateAudio/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
//----------------------------------------------------------------------------- | ||
// Filename: Program.cs | ||
// | ||
// Description: An example WebRTC server application that serves a sine wave | ||
// audio stream to a WebRTC enabled browser. | ||
// | ||
// Author(s): | ||
// Aaron Clauson ([email protected]) | ||
// | ||
// History: | ||
// 28 Jul 2020 Aaron Clauson Created, Dublin, Ireland. | ||
// | ||
// License: | ||
// BSD 3-Clause "New" or "Revised" License, see included LICENSE.md file. | ||
//----------------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Logging.Abstractions; | ||
using Serilog; | ||
using Serilog.Extensions.Logging; | ||
using SIPSorcery.Net; | ||
using SIPSorcery.Media; | ||
using SIPSorceryMedia.Windows; | ||
using WebSocketSharp.Server; | ||
|
||
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 Audio Server Example Program"); | ||
|
||
logger = AddConsoleLogger(); | ||
|
||
// Start web socket. | ||
Console.WriteLine("Starting web socket server..."); | ||
var webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT); | ||
webSocketServer.AddWebSocketService<WebRTCWebSocketPeer>("/", (peer) => peer.CreatePeerConnection = CreatePeerConnection); | ||
webSocketServer.Start(); | ||
|
||
Console.WriteLine($"Waiting for browser web socket connection to {webSocketServer.Address}:{webSocketServer.Port}..."); | ||
|
||
Console.WriteLine("Press ctrl-c to exit."); | ||
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 Task<RTCPeerConnection> CreatePeerConnection() | ||
{ | ||
RTCConfiguration config = new RTCConfiguration | ||
{ | ||
iceServers = new List<RTCIceServer> { new RTCIceServer { urls = STUN_URL } } | ||
}; | ||
var pc = new RTCPeerConnection(config); | ||
|
||
//AudioExtrasSource audioSource = new AudioExtrasSource(new AudioEncoder(), new AudioSourceOptions { AudioSource = AudioSourcesEnum.SineWave }); | ||
//audioSource.OnAudioSourceEncodedSample += pc.SendAudio; | ||
WindowsAudioEndPoint audioSource = new WindowsAudioEndPoint(new AudioEncoder()); | ||
audioSource.OnAudioSourceEncodedSample += pc.SendAudio; | ||
|
||
MediaStreamTrack audioTrack = new MediaStreamTrack(audioSource.GetAudioSourceFormats(), MediaStreamStatusEnum.SendOnly); | ||
pc.addTrack(audioTrack); | ||
|
||
pc.OnAudioFormatsNegotiated += (audioFormats) => audioSource.SetAudioSourceFormat(audioFormats.First()); | ||
|
||
pc.onconnectionstatechange += async (state) => | ||
{ | ||
logger.LogDebug($"Peer connection state change to {state}."); | ||
if (state == RTCPeerConnectionState.connected) | ||
{ | ||
await audioSource.StartAudio(); | ||
} | ||
else if (state == RTCPeerConnectionState.failed) | ||
{ | ||
pc.Close("ice disconnection"); | ||
} | ||
else if (state == RTCPeerConnectionState.closed) | ||
{ | ||
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); | ||
} | ||
|
||
/// <summary> | ||
/// Adds a console logger. Can be omitted if internal SIPSorcery debug and warning messages are not required. | ||
/// </summary> | ||
private static Microsoft.Extensions.Logging.ILogger AddConsoleLogger() | ||
{ | ||
var serilogLogger = new LoggerConfiguration() | ||
.Enrich.FromLogContext() | ||
.MinimumLevel.Is(Serilog.Events.LogEventLevel.Debug) | ||
.WriteTo.Console() | ||
.CreateLogger(); | ||
var factory = new SerilogLoggerFactory(serilogLogger); | ||
SIPSorcery.LogFactory.Set(factory); | ||
return factory.CreateLogger<Program>(); | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
examples/WebRTCExamples/WebRTCRenegotiateAudio/WebRTCRenegotiateAudio.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp3.1</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.8" /> | ||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.1.8" /> | ||
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" /> | ||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> | ||
<PackageReference Include="SIPSorcery" Version="4.0.88-pre" /> | ||
<PackageReference Include="SIPSorcery.WebSocketSharp" Version="0.0.1" /> | ||
<PackageReference Include="SIPSorceryMedia.Windows" Version="0.0.25-pre" /> | ||
</ItemGroup> | ||
|
||
</Project> |
59 changes: 59 additions & 0 deletions
59
examples/WebRTCExamples/WebRTCRenegotiateAudio/webrtc.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<!DOCTYPE html> | ||
<head> | ||
<meta charset="UTF-8"> | ||
|
||
<script type="text/javascript"> | ||
|
||
const STUN_URL = "stun:stun.sipsorcery.com"; | ||
const WEBSOCKET_URL = "ws://127.0.0.1:8081/" | ||
|
||
var pc, ws; | ||
|
||
async function start() { | ||
pc = new RTCPeerConnection({ iceServers: [{ urls: STUN_URL }] }); | ||
|
||
pc.ontrack = evt => document.querySelector('#audioCtl').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))); | ||
} | ||
}; | ||
}; | ||
|
||
async function closePeer() { | ||
await pc.close(); | ||
await ws.close(); | ||
}; | ||
|
||
</script> | ||
</head> | ||
<body> | ||
|
||
<audio controls autoplay="autoplay" id="audioCtl"></audio> | ||
|
||
<div> | ||
<input type="text" id="websockurl" size="40" /> | ||
<button type="button" class="btn btn-success" onclick="start();">Start</button> | ||
<button type="button" class="btn btn-success" onclick="closePeer();">Close</button> | ||
</div> | ||
|
||
</body> | ||
|
||
<script> | ||
document.querySelector('#websockurl').value = WEBSOCKET_URL; | ||
</script> |