Skip to content

Commit 396e8ae

Browse files
committed
Moved echo test demo file to dedicated html directory.
1 parent 2cdd359 commit 396e8ae

File tree

9 files changed

+206
-27
lines changed

9 files changed

+206
-27
lines changed

aiortc/server.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ async def recv(self):
3535
return frame
3636

3737
async def index(request):
38-
content = open(os.path.join(ROOT, "index.html"), "r").read()
38+
content = open(os.path.join(ROOT, "../html/index.html"), "r").read()
3939
return web.Response(content_type="text/html", text=content)
4040

4141
async def offer(request):

html/index.html

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<!DOCTYPE html>
2+
<head>
3+
<meta charset="UTF-8">
4+
5+
<script type="text/javascript">
6+
7+
"use strict";
8+
9+
function RestSignaler(signalUrl) {
10+
11+
this.sendOffer = async function (offer) {
12+
return (await fetch(signalUrl, {
13+
method: 'POST',
14+
body: JSON.stringify(offer),
15+
headers: { 'Content-Type': 'application/json' }
16+
})).json();
17+
}
18+
}
19+
20+
</script>
21+
22+
<script type="text/javascript">
23+
24+
"use strict";
25+
26+
const STUN_SERVER = "stun:stun.sipsorcery.com";
27+
const NOISE_FRAME_WIDTH = 80;
28+
const NOISE_FRAME_HEIGHT = 60;
29+
const ICE_GATHERING_TIMEOUT = 3000;
30+
31+
var pc;
32+
var signaler;
33+
var isClosed = true;
34+
var isOfferSent = false;
35+
36+
window.onload = () => {
37+
let host = window.location.hostname.concat(window.location.port ? `:${window.location.port}` : "");
38+
document.getElementById('signalingUrl').value = `${window.location.protocol}//${host}/offer`;
39+
};
40+
41+
async function start() {
42+
43+
if (!isClosed) {
44+
// Close any existing peer connection.
45+
await closePeer();
46+
}
47+
48+
isOfferSent = false;
49+
50+
let signalingUrl = document.getElementById('signalingUrl').value;
51+
52+
// Create the noise.
53+
let noiseStm = whiteNoise(NOISE_FRAME_WIDTH, NOISE_FRAME_HEIGHT);
54+
document.getElementById("localVideoCtl").srcObject = noiseStm;
55+
56+
signaler = new RestSignaler(signalingUrl);
57+
58+
// Create the peer connections.
59+
pc = createPeer("echoVideoCtl", noiseStm);
60+
61+
pc.onicegatheringstatechange = async () => {
62+
console.log(`onicegatheringstatechange: ${pc.iceGatheringState}.`);
63+
64+
if (pc.iceGatheringState === 'complete') {
65+
sendOffer();
66+
}
67+
}
68+
69+
let offer = await pc.createOffer();
70+
await pc.setLocalDescription(offer);
71+
72+
setTimeout(sendOffer, ICE_GATHERING_TIMEOUT);
73+
}
74+
75+
async function sendOffer() {
76+
77+
if (!isOfferSent) {
78+
isOfferSent = true;
79+
80+
var offerWithIce = pc.localDescription;
81+
console.log(offerWithIce);
82+
var answer = await signaler.sendOffer(offerWithIce);
83+
84+
if (answer != null) {
85+
console.log(answer.sdp)
86+
await pc.setRemoteDescription(answer);
87+
}
88+
else {
89+
console.log("Failed to get an answer from the Echo Test server.")
90+
pc.close();
91+
}
92+
}
93+
}
94+
95+
function createPeer(videoCtlID, noiseStm) {
96+
97+
console.log("Creating peer ...");
98+
isClosed = false;
99+
100+
let pc = new RTCPeerConnection({ iceServers: [{ urls: STUN_SERVER }] });
101+
noiseStm.getTracks().forEach(track => pc.addTrack(track, noiseStm));
102+
pc.ontrack = evt => document.getElementById(videoCtlID).srcObject = evt.streams[0];
103+
pc.onicecandidate = evt => evt.candidate && console.log(evt.candidate);
104+
105+
// Diagnostics.
106+
pc.onicegatheringstatechange = () => console.log(`onicegatheringstatechange: ${pc.iceGatheringState}.`);
107+
pc.oniceconnectionstatechange = () => console.log(`oniceconnectionstatechange: ${pc.iceConnectionState}.`);
108+
pc.onsignalingstatechange = () => console.log(`onsignalingstatechange: ${pc.signalingState}.`);
109+
pc.onconnectionstatechange = () => console.log(`onconnectionstatechange: ${pc.connectionState}.`);
110+
111+
return pc;
112+
}
113+
114+
async function closePeer() {
115+
console.log("Closing...")
116+
isClosed = true;
117+
await pc?.close();
118+
};
119+
120+
function whiteNoise(width, height) {
121+
const canvas = Object.assign(document.createElement("canvas"), { width, height });
122+
const ctx = canvas.getContext('2d');
123+
ctx.fillRect(0, 0, width, height);
124+
const p = ctx.getImageData(0, 0, width, height);
125+
requestAnimationFrame(function draw() {
126+
if (!isClosed) {
127+
for (var i = 0; i < p.data.length; i++) {
128+
p.data[i++] = Math.random() * 255;
129+
p.data[i++] = Math.random() * 255;
130+
p.data[i++] = Math.random() * 255;
131+
}
132+
ctx.putImageData(p, 0, 0);
133+
requestAnimationFrame(draw);
134+
}
135+
});
136+
return canvas.captureStream();
137+
}
138+
139+
</script>
140+
</head>
141+
<body>
142+
143+
<table>
144+
<thead>
145+
<tr>
146+
<th>Source</th>
147+
<th>Echo</th>
148+
</tr>
149+
</thead>
150+
<tr>
151+
<td>
152+
<video controls autoplay="autoplay" id="localVideoCtl" width="320" height="240"></video>
153+
</td>
154+
<td>
155+
<video controls autoplay="autoplay" id="echoVideoCtl" width="320" height="240"></video>
156+
</td>
157+
158+
</tr>
159+
</table>
160+
161+
<div>
162+
<label>Signaling URL:</label> <input type="text" id="signalingUrl" size="40" /><br />
163+
<button type="button" class="btn btn-success" onclick="start();">Start</button>
164+
<button type="button" class="btn btn-success" onclick="closePeer();">Close</button>
165+
</div>
166+
167+
</body>

pion/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ By default the in built web server will listen on `http://*:8080/`.
1212

1313
`go run main.go`
1414

15+
An alternative on Windows to avoid the firewall prompting for a new executable accessing the network:
16+
17+
`go build main.go && main.exe`
18+
1519
POST an SDP offer to `http://*:8080/offer` or open `http://localhost:8080/` in a browser to use the included `index.html` demo page.

pion/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func main() {
118118

119119
pcs = []*webrtc.PeerConnection{}
120120

121-
http.Handle("/", http.FileServer(http.Dir("../aiortc")))
121+
http.Handle("/", http.FileServer(http.Dir("../html")))
122122
http.HandleFunc("/offer", offer)
123123

124124
addr := fmt.Sprintf("%s:%d", *host, *port)

sipsorcery/client/Program.cs

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
4-
using System.Net;
53
using System.Net.Http;
64
using System.Text;
7-
using System.Text.Json;
85
using System.Threading;
96
using System.Threading.Tasks;
107
using Microsoft.Extensions.Logging;
118
using Microsoft.Extensions.Logging.Abstractions;
129
using Serilog;
10+
using Serilog.Events;
1311
using Serilog.Extensions.Logging;
1412
using SIPSorcery.Media;
1513
using SIPSorcery.Net;
@@ -27,7 +25,7 @@ static async Task Main(string[] args)
2725
{
2826
Console.WriteLine("Starting webrtc echo test client.");
2927

30-
logger = AddConsoleLogger();
28+
logger = AddConsoleLogger(LogEventLevel.Debug);
3129

3230
var pc = CreatePeerConnection();
3331
var offer = pc.createOffer(null);
@@ -51,7 +49,7 @@ static async Task Main(string[] args)
5149
Console.WriteLine("Failed to parse SDP answer from echo server.");
5250
}
5351

54-
Console.WriteLine("<ctrl>-c to exit.");
52+
Console.WriteLine("ctrl-c to exit.");
5553
var mre = new ManualResetEvent(false);
5654
Console.CancelKeyPress += (sender, eventArgs) =>
5755
{
@@ -81,9 +79,13 @@ private static RTCPeerConnection CreatePeerConnection()
8179
audioSource.SetAudioSourceFormat(formats.First());
8280

8381
pc.onicecandidateerror += (candidate, error) => logger.LogWarning($"Error adding remote ICE candidate. {error} {candidate}");
82+
pc.OnTimeout += (mediaType) => logger.LogWarning($"Timeout for {mediaType}.");
83+
pc.oniceconnectionstatechange += (state) => logger.LogInformation($"ICE connection state changed to {state}.");
84+
pc.onsignalingstatechange += () => logger.LogInformation($"Signaling state changed to {pc.signalingState}.");
85+
8486
pc.onconnectionstatechange += async (state) =>
8587
{
86-
logger.LogDebug($"Peer connection state changed to {state}.");
88+
logger.LogInformation($"Peer connection state changed to {state}.");
8789

8890
if (state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed)
8991
{
@@ -102,18 +104,17 @@ private static RTCPeerConnection CreatePeerConnection()
102104
pc.OnReceiveReport += (re, media, rr) => logger.LogDebug($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}");
103105
pc.OnSendReport += (media, sr) => logger.LogDebug($"RTCP Send for {media}\n{sr.GetDebugSummary()}");
104106
pc.OnRtcpBye += (reason) => logger.LogDebug($"RTCP BYE receive, reason: {(string.IsNullOrWhiteSpace(reason) ? "<none>" : reason)}.");
105-
pc.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}.");
106107

107108
pc.onsignalingstatechange += () =>
108109
{
109110
if (pc.signalingState == RTCSignalingState.have_remote_offer)
110111
{
111-
logger.LogDebug("Remote SDP:");
112+
logger.LogTrace("Remote SDP:");
112113
logger.LogTrace(pc.remoteDescription.sdp.ToString());
113114
}
114115
else if (pc.signalingState == RTCSignalingState.have_local_offer)
115116
{
116-
logger.LogDebug("Local SDP:");
117+
logger.LogTrace("Local SDP:");
117118
logger.LogTrace(pc.localDescription.sdp.ToString());
118119
}
119120
};
@@ -122,7 +123,7 @@ private static RTCPeerConnection CreatePeerConnection()
122123
}
123124

124125
private static Microsoft.Extensions.Logging.ILogger AddConsoleLogger(
125-
Serilog.Events.LogEventLevel logLevel = Serilog.Events.LogEventLevel.Debug)
126+
LogEventLevel logLevel = LogEventLevel.Debug)
126127
{
127128
var serilogLogger = new LoggerConfiguration()
128129
.Enrich.FromLogContext()

sipsorcery/client/webrtc-echo-client.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
1111
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
1212
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
13-
<PackageReference Include="SIPSorcery" Version="5.0.31-pre" />
13+
<PackageReference Include="SIPSorcery" Version="5.0.32-pre" />
1414
</ItemGroup>
1515

1616
</Project>

sipsorcery/server/Program.cs

+19-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Threading.Tasks;
77
using EmbedIO;
88
using Microsoft.Extensions.Logging;
9+
using Microsoft.Extensions.Logging.Abstractions;
910
using Serilog;
11+
using Serilog.Events;
1012
using Serilog.Extensions.Logging;
1113
using SIPSorcery.Net;
1214
using SIPSorceryMedia.Abstractions;
@@ -17,6 +19,8 @@ class Program
1719
{
1820
private const string DEFAULT_WEBSERVER_LISTEN_URL = "http://*:8080/";
1921

22+
private static Microsoft.Extensions.Logging.ILogger logger = NullLogger.Instance;
23+
2024
private static List<IPAddress> _icePresets = new List<IPAddress>();
2125

2226
static void Main(string[] args)
@@ -37,14 +41,14 @@ static void Main(string[] args)
3741
}
3842
}
3943

40-
AddConsoleLogger();
44+
logger = AddConsoleLogger(LogEventLevel.Information);
4145

4246
// Start the web server.
4347
using (var server = CreateWebServer(url))
4448
{
4549
server.RunAsync();
4650

47-
Console.WriteLine("<ctrl>-c to exit.");
51+
Console.WriteLine("ctrl-c to exit.");
4852
var mre = new ManualResetEvent(false);
4953
Console.CancelKeyPress += (sender, eventArgs) =>
5054
{
@@ -64,7 +68,7 @@ private static WebServer CreateWebServer(string url)
6468
.WithMode(HttpListenerMode.EmbedIO))
6569
.WithCors("*", "*", "*")
6670
.WithAction("/offer", HttpVerbs.Post, Offer)
67-
.WithStaticFolder("/", ".", false);
71+
.WithStaticFolder("/", "../../html", false);
6872
server.StateChanged += (s, e) => Console.WriteLine($"WebServer New State - {e.NewState}");
6973

7074
return server;
@@ -108,17 +112,20 @@ public class WebRTCEchoServer
108112
{
109113
private const int VP8_PAYLOAD_ID = 96;
110114

115+
private static Microsoft.Extensions.Logging.ILogger logger = NullLogger.Instance;
116+
111117
private List<IPAddress> _presetIceAddresses;
112118

113119
public WebRTCEchoServer(List<IPAddress> presetAddresses)
114120
{
121+
logger = SIPSorcery.LogFactory.CreateLogger<WebRTCEchoServer>();
115122
_presetIceAddresses = presetAddresses;
116123
}
117124

118125
public async Task<RTCSessionDescriptionInit> GotOffer(RTCSessionDescriptionInit offer)
119126
{
120-
Console.WriteLine($"SDP offer received.");
121-
//Console.WriteLine($"Offer SDP:\n{offer.sdp}");
127+
logger.LogTrace($"SDP offer received.");
128+
logger.LogTrace(offer.sdp);
122129

123130
var pc = new RTCPeerConnection();
124131

@@ -142,12 +149,12 @@ public async Task<RTCSessionDescriptionInit> GotOffer(RTCSessionDescriptionInit
142149
pc.SendRtpRaw(media, rtpPkt.Payload, rtpPkt.Header.Timestamp, rtpPkt.Header.MarkerBit, rtpPkt.Header.PayloadType);
143150
};
144151

145-
pc.OnTimeout += (mediaType) => Console.WriteLine($"Timeout for {mediaType}.");
146-
pc.oniceconnectionstatechange += (state) => Console.WriteLine($"ICE connection state changed to {state}.");
147-
pc.onsignalingstatechange += () => Console.WriteLine($"Signaling state changed to {pc.signalingState}.");
152+
pc.OnTimeout += (mediaType) => logger.LogWarning($"Timeout for {mediaType}.");
153+
pc.oniceconnectionstatechange += (state) => logger.LogInformation($"ICE connection state changed to {state}.");
154+
pc.onsignalingstatechange += () => logger.LogInformation($"Signaling state changed to {pc.signalingState}.");
148155
pc.onconnectionstatechange += (state) =>
149156
{
150-
Console.WriteLine($"Peer connection state changed to {state}.");
157+
logger.LogInformation($"Peer connection state changed to {state}.");
151158
if (state == RTCPeerConnectionState.failed)
152159
{
153160
pc.Close("ice failure");
@@ -161,15 +168,15 @@ public async Task<RTCSessionDescriptionInit> GotOffer(RTCSessionDescriptionInit
161168
await pc.setLocalDescription(offerSdp);
162169

163170
var answer = pc.createAnswer(null);
164-
await pc.setLocalDescription(answer);
165171

166-
//Console.WriteLine($"Answer SDP:\n{answer.sdp}");
172+
logger.LogTrace($"SDP answer created.");
173+
logger.LogTrace(answer.sdp);
167174

168175
return answer;
169176
}
170177
else
171178
{
172-
Console.WriteLine($"Failed to set remote description {setResult}.");
179+
logger.LogWarning($"Failed to set remote description {setResult}.");
173180
return null;
174181
}
175182
}

sipsorcery/server/webrtc-echo.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
1212
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
1313
<PackageReference Include="EmbedIO" Version="3.4.3" />
14-
<PackageReference Include="SIPSorcery" Version="5.0.31-pre" />
14+
<PackageReference Include="SIPSorcery" Version="5.0.32-pre" />
1515
</ItemGroup>
1616

1717
<ItemGroup>

0 commit comments

Comments
 (0)