From 1a111b087608dae29d72a882851588af06e89aaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wala?= Date: Wed, 25 Oct 2023 13:30:49 +0200 Subject: [PATCH] Add option to be the offerer in examples --- examples/example.exs | 36 +++++++++++++++++++++++--------- examples/example.js | 35 ++++++++++++++++++------------- lib/ex_webrtc/peer_connection.ex | 2 -- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/examples/example.exs b/examples/example.exs index ceb4643e..41ea7852 100644 --- a/examples/example.exs +++ b/examples/example.exs @@ -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") @@ -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)}") @@ -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) @@ -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 @@ -115,9 +130,9 @@ 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 @@ -125,7 +140,8 @@ defmodule Peer do end end -{:ok, pid} = Peer.start_link() +mode = :active +{:ok, pid} = Peer.start_link(mode) ref = Process.monitor(pid) receive do diff --git a/examples/example.js b/examples/example.js index 0b48c5b7..ad63e977 100644 --- a/examples/example.js +++ b/examples/example.js @@ -5,10 +5,6 @@ const pcConfig = { ] }; -const mediaConstraints = { - audio: true -}; - const start_connection = async (ws) => { const pc = new RTCPeerConnection(pcConfig); @@ -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); @@ -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); diff --git a/lib/ex_webrtc/peer_connection.ex b/lib/ex_webrtc/peer_connection.ex index 99d7c151..53659010 100644 --- a/lib/ex_webrtc/peer_connection.ex +++ b/lib/ex_webrtc/peer_connection.ex @@ -262,8 +262,6 @@ defmodule ExWebRTC.PeerConnection do error -> {:reply, error, state} end end - - {:reply, :ok, state} end @impl true