Skip to content

Commit 4824fc3

Browse files
committed
Rewrite save_to_file example
1 parent 5e73616 commit 4824fc3

File tree

12 files changed

+404
-293
lines changed

12 files changed

+404
-293
lines changed

examples/save_to_file/.formatter.exs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

examples/save_to_file/.gitignore

+28
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,30 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# Ignore .fetch files in case you like to edit your project deps locally.
14+
/.fetch
15+
16+
# If the VM crashes, it generates a dump, let's ignore it too.
17+
erl_crash.dump
18+
19+
# Also ignore archive artifacts (built via "mix archive.build").
20+
*.ez
21+
22+
# Ignore package tarball (built via "mix hex.build").
23+
save_to_file-*.tar
24+
25+
# Temporary files, for example, from tests.
26+
/tmp/
27+
28+
# Media files
129
video.ivf
230
audio.ogg

examples/save_to_file/README.md

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
# Save to File
22

3-
Receive video from a browser and save it to a file.
3+
Receive video and audio from a browser and save it to files.
44

5-
1. Start `ex_ice/signalling_server` with `mix run --no-halt`
6-
2. Run `elixir example.exs`
7-
3. Visit `example.html` in your browser e.g. `file:///home/Repos/elixir-webrtc/ex_webrtc/examples/save_to_file/example.html`
8-
4. Press `Start` button to start the connection, then `Stop` button to stop recording.
9-
5. Video and audio have been saved to `video.ivf` and `audio.ogg` files. Play it with
5+
While in `examples/save_to_file` directory
106

11-
```console
7+
1. Run `mix deps.get`
8+
2. Run `mix run --no-halt`
9+
3. Visit `http://127.0.0.1:8829` in your browser.
10+
4. Press the `start` button to start recording.
11+
5. Press the `stop` button to stop recording.
12+
13+
Audio and video have been saved to `audio.ogg` and `video.ivf` files.
14+
You can play them using `ffplay`:
15+
16+
```shell
1217
ffplay audio.ogg
1318
ffplay video.ivf
1419
```
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
4-
<head>
3+
<head>
54
<meta charset="UTF-8">
65
<meta name="viewport" content="width=device-width, initial-scale=1.0">
76
<meta http-equiv="X-UA-Compatible" content="ie=edge">
87
<title>Elixir WebRTC Save to File Example</title>
9-
</head>
10-
11-
<body>
8+
</head>
9+
<body>
1210
<main>
1311
<h1>Elixir WebRTC Save to File Example</h1>
1412
</main>
1513
<button id="button">Start</button>
1614
<video id="videoPlayer" autoplay muted></video>
17-
<script src="example.js"></script>
18-
</body>
19-
20-
</html>
15+
<script src="script.js"></script>
16+
</body>
17+
</html>
+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const pcConfig = { 'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' },] };
2+
const mediaConstraints = {audio: true, video: {
3+
width: { ideal: 640 },
4+
height: { ideal: 480 },
5+
frameRate: { ideal: 15 }
6+
}}
7+
const address = "ws://127.0.0.1:8829/ws"
8+
9+
const button = document.getElementById("button")
10+
button.onclick = () => {
11+
const ws = new WebSocket(address);
12+
ws.onopen = _ => start_connection(ws);
13+
ws.onclose = event => console.log("WebSocket connection was terminated:", event);
14+
15+
button.textContent = "Stop";
16+
button.onclick = () => ws.close();
17+
}
18+
19+
const start_connection = async (ws) => {
20+
const pc = new RTCPeerConnection(pcConfig);
21+
pc.onicecandidate = event => {
22+
if (event.candidate === null) return;
23+
24+
console.log("Sent ICE candidate:", event.candidate);
25+
ws.send(JSON.stringify({ type: "ice", data: event.candidate }));
26+
};
27+
28+
const localStream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
29+
document.getElementById("videoPlayer").srcObject = localStream;
30+
31+
for (const track of localStream.getTracks()) {
32+
pc.addTrack(track, localStream);
33+
}
34+
35+
ws.onmessage = async event => {
36+
const {type, data} = JSON.parse(event.data);
37+
38+
switch (type) {
39+
case "answer":
40+
console.log("Received SDP answer:", data);
41+
await pc.setRemoteDescription(data)
42+
break;
43+
case "ice":
44+
console.log("Recieved ICE candidate:", data);
45+
await pc.addIceCandidate(data);
46+
}
47+
};
48+
49+
const offer = await pc.createOffer();
50+
await pc.setLocalDescription(offer);
51+
console.log("Sent SDP offer:", offer)
52+
ws.send(JSON.stringify({type: "offer", data: offer}));
53+
};

examples/save_to_file/example.exs

-215
This file was deleted.

0 commit comments

Comments
 (0)