Skip to content

Commit

Permalink
Add initial implementation of craete_offer, `apply_local_descriptio…
Browse files Browse the repository at this point in the history
…n` and `add_transceiver` (#6)
  • Loading branch information
LVala authored Oct 27, 2023
1 parent fd81504 commit 7c41057
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 44 deletions.
36 changes: 26 additions & 10 deletions examples/example.exs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ defmodule Peer do
%{urls: "stun:stun.l.google.com:19302"}
]

def start_link() do
GenServer.start_link(__MODULE__, [])
def start_link(mode \\ :passive) do
GenServer.start_link(__MODULE__, mode)
end

@impl true
def init(_) do
def init(mode) do
{:ok, conn} = :gun.open({127, 0, 0, 1}, 4000)
{:ok, _protocol} = :gun.await_up(conn)
:gun.ws_upgrade(conn, "/websocket")
Expand All @@ -30,11 +30,18 @@ defmodule Peer do
Logger.info("Connected to the signalling server")
Process.send_after(self(), :ws_ping, 1000)

{:ok, pc} = PeerConnection.start_link(
ice_servers: @ice_servers
)
{:ok, pc} = PeerConnection.start_link(ice_servers: @ice_servers)

{:ok, %{conn: conn, stream: stream, peer_connection: pc}}
if mode == :active do
{:ok, _transceiver} = PeerConnection.add_transceiver(pc, :audio)
{:ok, offer} = PeerConnection.create_offer(pc)
:ok = PeerConnection.set_local_description(pc, offer)
msg = %{"type" => "offer", "sdp" => offer.sdp}
:gun.ws_send(conn, stream, {:text, Jason.encode!(msg)})
Logger.info("Send SDP offer: #{offer.sdp}")
end

{:ok, %{conn: conn, stream: stream, peer_connection: pc, mode: mode}}

other ->
Logger.error("Couldn't connect to the signalling server: #{inspect(other)}")
Expand Down Expand Up @@ -84,7 +91,7 @@ defmodule Peer do
{:noreply, state}
end

defp handle_ws_message(%{"type" => "offer", "sdp" => sdp}, state) do
defp handle_ws_message(%{"type" => "offer", "sdp" => sdp}, %{mode: :passive} = state) do
Logger.info("Received SDP offer: #{inspect(sdp)}")
offer = %SessionDescription{type: :offer, sdp: sdp}
:ok = PeerConnection.set_remote_description(state.peer_connection, offer)
Expand All @@ -93,14 +100,22 @@ defmodule Peer do
:gun.ws_send(state.conn, state.stream, {:text, Jason.encode!(msg)})
end

defp handle_ws_message(%{"type" => "answer", "sdp" => sdp}, %{mode: :active} = state) do
Logger.info("Received SDP answer: #{inspect(sdp)}")
answer = %SessionDescription{type: :answer, sdp: sdp}
:ok = PeerConnection.set_remote_description(state.peer_connection, answer)
end

defp handle_ws_message(%{"type" => "ice", "data" => data}, state) do
Logger.info("Received remote ICE candidate: #{inspect(data)}")

candidate = %IceCandidate{
candidate: data["candidate"],
sdp_mid: data["sdpMid"],
sdp_m_line_index: data["sdpMLineIndex"],
username_fragment: data["usernameFragment"]
}

:ok = PeerConnection.add_ice_candidate(state.peer_connection, candidate)
end

Expand All @@ -115,17 +130,18 @@ defmodule Peer do
"sdpMLineIndex" => candidate.sdp_m_line_index,
"usernameFragment" => candidate.username_fragment
}

msg = %{"type" => "ice", "data" => candidate}
:gun.ws_send(state.conn, state.stream, {:text, Jason.encode!(msg)})

end

defp handle_webrtc_message(msg, _state) do
Logger.warning("Received unknown ex_webrtc message: #{inspect(msg)}")
end
end

{:ok, pid} = Peer.start_link()
mode = :active
{:ok, pid} = Peer.start_link(mode)
ref = Process.monitor(pid)

receive do
Expand Down
35 changes: 21 additions & 14 deletions examples/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ const pcConfig = {
]
};

const mediaConstraints = {
audio: true
};

const start_connection = async (ws) => {
const pc = new RTCPeerConnection(pcConfig);

Expand All @@ -25,13 +21,25 @@ const start_connection = async (ws) => {
ws.send(JSON.stringify({type: "ice", data: event.candidate}));
}
};

const localStream = await navigator.mediaDevices.getUserMedia({audio: true});
for (const track of localStream.getTracks()) {
pc.addTrack(track, localStream);
}

ws.onmessage = event => {
ws.onmessage = async event => {
const msg = JSON.parse(event.data);

if (msg.type === "answer") {
console.log("Recieved SDP answer:", msg);
pc.setRemoteDescription(msg);
} else if (msg.type === "offer") {
console.log("Received SDP offer:", msg);
await pc.setRemoteDescription(msg)

const desc = await pc.createAnswer();
await pc.setLocalDescription(desc);
ws.send(JSON.stringify(desc));
} else if (msg.type === "ice") {
console.log("Recieved remote ICE candidate:", msg.data);
pc.addIceCandidate(msg.data);
Expand All @@ -40,17 +48,16 @@ const start_connection = async (ws) => {
}
};

const localStream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
for (const track of localStream.getTracks()) {
pc.addTrack(track, localStream);
if (mode === "active") {
const desc = await pc.createOffer();
console.log("Generated SDP offer:", desc);
await pc.setLocalDescription(desc);
ws.send(JSON.stringify(desc))
}

const desc = await pc.createOffer();
console.log("Generated SDP offer:", desc);
await pc.setLocalDescription(desc);

ws.send(JSON.stringify(desc))
};

const mode = "passive"

const ws = new WebSocket("ws://127.0.0.1:4000/websocket");
ws.onclose = event => console.log("WebSocket was closed", event);
ws.onopen = _ => start_connection(ws);
Loading

0 comments on commit 7c41057

Please sign in to comment.