Skip to content

Commit edcddb8

Browse files
committed
Spawn recorder inside publisher
1 parent 4bf7fab commit edcddb8

File tree

1 file changed

+67
-33
lines changed

1 file changed

+67
-33
lines changed

lib/live_ex_webrtc/publisher.ex

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,23 @@ defmodule LiveExWebRTC.Publisher do
109109
alias ExWebRTC.{ICECandidate, PeerConnection, Recorder, SessionDescription}
110110
alias Phoenix.PubSub
111111

112+
@typedoc """
113+
Called when WebRTC has connected.
114+
"""
112115
@type on_connected :: (publisher_id :: String.t() -> any())
113116

114117
@typedoc """
115-
Function signature of the `on_disconnected` callback.
118+
Called when WebRTC has disconnected.
119+
"""
120+
@type on_disconnected :: (publisher_id :: String.t() -> any())
121+
122+
@typedoc """
123+
Called when recorder finishes stream recording.
116124
117-
* If `recorder` was passed to `attach/2` and the "Record stream?" checkbox ticked,
118-
the second argument contains the result of calling `ExWebRTC.Recorder.end_tracks/2`.
119-
See `t:ExWebRTC.Recorder.end_tracks_ok_result/0` for more info.
120-
* Otherwise, the second argument is `nil` and can be ignored.
125+
For exact meaning of the second argument, refer to `t:ExWebRTC.Recorder.end_tracks_ok_result/0`.
121126
"""
122-
@type on_disconnected :: (publisher_id :: String.t(),
123-
ExWebRTC.Recorder.end_tracks_ok_result()
124-
| nil ->
125-
any())
127+
@type on_recording_finished :: (publisher_id :: String.t(), Recorder.end_tracks_ok_result() ->
128+
any())
126129

127130
@type on_packet ::
128131
(publisher_id :: String.t(),
@@ -138,14 +141,19 @@ defmodule LiveExWebRTC.Publisher do
138141
pc: nil,
139142
streaming?: false,
140143
simulcast_supported?: nil,
144+
# record checkbox status
141145
record?: false,
146+
# whether recorings are allowed or not
147+
recordings?: true,
148+
# recorder instance
149+
recorder: nil,
142150
audio_track: nil,
143151
video_track: nil,
144152
on_packet: nil,
145153
on_connected: nil,
146154
on_disconnected: nil,
155+
on_recording_finished: nil,
147156
pubsub: nil,
148-
recorder: nil,
149157
ice_servers: nil,
150158
ice_ip_filter: nil,
151159
ice_port_range: nil,
@@ -185,10 +193,11 @@ defmodule LiveExWebRTC.Publisher do
185193
* `id` - publisher id. This is typically your user id (if there is users database).
186194
It is used to identify live view and generated HTML elements.
187195
* `pubsub` - a pubsub that publisher live view will use for broadcasting audio and video packets received from a browser. See module doc for more info.
188-
* `recorder` - optional `ExWebRTC.Recorder` instance that publisher live view will use for recording the stream.
196+
* `recordings?` - whether to allow for recordings or not. Defaults to true.
189197
See module doc and `t:on_disconnected/0` for more info.
190198
* `on_connected` - callback called when the underlying peer connection changes its state to the `:connected`. See `t:on_connected/0`.
191199
* `on_disconnected` - callback called when the underlying peer connection process terminates. See `t:on_disconnected/0`.
200+
* `on_recording_finished` - callback called when the stream recording has finised. See `t:on_recording_finished/0`.
192201
* `on_packet` - callback called for each audio and video RTP packet. Can be used to modify the packet before publishing it on a pubsub. See `t:on_packet/0`.
193202
* `ice_servers` - a list of `t:ExWebRTC.PeerConnection.Configuration.ice_server/0`,
194203
* `ice_ip_filter` - `t:ExICE.ICEAgent.ip_filter/0`,
@@ -204,10 +213,11 @@ defmodule LiveExWebRTC.Publisher do
204213
:id,
205214
:name,
206215
:pubsub,
207-
:recorder,
216+
:recordings?,
208217
:on_packet,
209218
:on_connected,
210219
:on_disconnected,
220+
:on_recording_finished,
211221
:ice_servers,
212222
:ice_ip_filter,
213223
:ice_port_range,
@@ -219,10 +229,11 @@ defmodule LiveExWebRTC.Publisher do
219229
publisher = %Publisher{
220230
id: Keyword.fetch!(opts, :id),
221231
pubsub: Keyword.fetch!(opts, :pubsub),
222-
recorder: Keyword.get(opts, :recorder),
232+
recordings?: Keyword.get(opts, :recordings?, true),
223233
on_packet: Keyword.get(opts, :on_packet),
224234
on_connected: Keyword.get(opts, :on_connected),
225235
on_disconnected: Keyword.get(opts, :on_disconnected),
236+
on_recording_finished: Keyword.get(opts, :on_recording_finished),
226237
ice_servers: Keyword.get(opts, :ice_servers, [%{urls: "stun:stun.l.google.com:19302"}]),
227238
ice_ip_filter: Keyword.get(opts, :ice_ip_filter),
228239
ice_port_range: Keyword.get(opts, :ice_port_range),
@@ -231,8 +242,8 @@ defmodule LiveExWebRTC.Publisher do
231242
pc_genserver_opts: Keyword.get(opts, :pc_genserver_opts, [])
232243
}
233244

234-
# Check the "Record stream?" checkbox by default if recorder was configured
235-
record? = publisher.recorder != nil
245+
# Check the "Record stream?" checkbox by default if recordings are allowed
246+
record? = publisher.recordings? != nil
236247

237248
socket
238249
|> assign(publisher: %Publisher{publisher | record?: record?})
@@ -434,16 +445,27 @@ defmodule LiveExWebRTC.Publisher do
434445
</div>
435446
</div>
436447
</div>
437-
<div :if={@publisher.recorder} class="flex gap-2.5 items-center">
438-
<label for="lex-record-stream">Record stream:</label>
439-
<input
440-
type="checkbox"
441-
phx-click="record-stream-change"
442-
id="lex-record-stream"
443-
class="rounded-full"
444-
checked={@publisher.record?}
445-
/>
446-
</div>
448+
<%= if @publisher.recordings? do %>
449+
<div class="flex gap-2.5 items-center">
450+
<label for="lex-record-stream">Record stream</label>
451+
<input
452+
type="checkbox"
453+
phx-click="record-stream-change"
454+
id="lex-record-stream"
455+
class="rounded-full"
456+
checked={@publisher.record?}
457+
/>
458+
</div>
459+
<% else %>
460+
<div class="flex gap-2.5 items-center">
461+
<label for="lex-record-stream">Record stream</label>
462+
<input type="checkbox" class="rounded-full bg-gray-300" disabled />
463+
</div>
464+
<p class="flex gap-2 text-sm leading-6 text-rose-600">
465+
<.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" />
466+
Recordings disabled by the server.
467+
</p>
468+
<% end %>
447469
<div id="lex-videoplayer-wrapper" class="flex flex-1 flex-col min-h-0 pt-2.5">
448470
<video
449471
id="lex-preview-player"
@@ -618,23 +640,35 @@ defmodule LiveExWebRTC.Publisher do
618640
{:DOWN, _ref, :process, pc, _reason},
619641
%{assigns: %{publisher: %{pc: pc} = pub}} = socket
620642
) do
621-
recorder_result =
622-
if pub.record? do
643+
if pub.record? do
644+
recorder_result =
623645
Recorder.end_tracks(pub.recorder, [pub.audio_track.id, pub.video_track.id])
624-
end
625646

626-
if pub.on_disconnected, do: pub.on_disconnected.(pub.id, recorder_result)
647+
if pub.on_recording_finished, do: pub.on_recording_finished.(pub.id, recorder_result)
648+
end
627649

628-
{:noreply,
629-
socket
630-
|> assign(publisher: %Publisher{pub | streaming?: false})}
650+
if pub.on_disconnected, do: pub.on_disconnected.(pub.id)
651+
652+
{:noreply, assign(socket, publisher: %Publisher{pub | streaming?: false})}
631653
end
632654

633655
@impl true
634656
def handle_event("start-streaming", _, socket) do
657+
publisher = socket.assigns.publisher
658+
659+
recorder =
660+
if publisher.record? == true and publisher.recorder == nil do
661+
{:ok, recorder} = Recorder.start_link()
662+
recorder
663+
else
664+
publisher.recorder
665+
end
666+
667+
publisher = %Publisher{socket.assigns.publisher | streaming?: true, recorder: recorder}
668+
635669
{:noreply,
636670
socket
637-
|> assign(publisher: %Publisher{socket.assigns.publisher | streaming?: true})
671+
|> assign(publisher: publisher)
638672
|> push_event("start-streaming", %{})}
639673
end
640674

0 commit comments

Comments
 (0)