Skip to content

Commit 6bccc84

Browse files
committed
Improve simulcast checkbox
1 parent c13b233 commit 6bccc84

File tree

3 files changed

+88
-51
lines changed

3 files changed

+88
-51
lines changed

assets/publisher.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ export function createPublisherHook(iceServers = []) {
9595
view.audioApplyButton.disabled = true;
9696
view.videoApplyButton.disabled = true;
9797
view.bitrate.disabled = true;
98-
view.simulcast.disabled = true;
9998
},
10099

101100
enableControls(view) {
@@ -110,7 +109,6 @@ export function createPublisherHook(iceServers = []) {
110109
view.audioApplyButton.disabled = false;
111110
view.videoApplyButton.disabled = false;
112111
view.bitrate.disabled = false;
113-
view.simulcast.disabled = false;
114112
},
115113

116114
async findDevices(view) {

lib/live_ex_webrtc/core_components.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ defmodule LiveExWebRTC.CoreComponents do
309309

310310
~H"""
311311
<div phx-feedback-for={@name}>
312-
<label class="flex items-center gap-4 text-sm leading-6 text-zinc-600">
312+
<label class="flex items-center gap-4 leading-6 text-zinc-600">
313+
{@label}
313314
<input type="hidden" name={@name} value="false" />
314315
<input
315316
type="checkbox"
@@ -320,7 +321,6 @@ defmodule LiveExWebRTC.CoreComponents do
320321
class="rounded border-zinc-300 text-zinc-900 focus:ring-0"
321322
{@rest}
322323
/>
323-
{@label}
324324
</label>
325325
<.error :for={msg <- @errors}>{msg}</.error>
326326
</div>

lib/live_ex_webrtc/publisher.ex

Lines changed: 86 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -309,49 +309,56 @@ defmodule LiveExWebRTC.Publisher do
309309
id="lex-video-settings"
310310
class="hidden transition-all duration-700 text-[#606060] flex flex-col gap-6 px-4 pb-3"
311311
>
312-
<div id="lex-resolution" class="flex gap-2.5 items-center">
313-
<label for="lex-width">Width</label>
314-
<input
315-
type="text"
316-
id="lex-width"
317-
value="1280"
318-
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
319-
/>
320-
<label for="lex-height">Height</label>
321-
<input
322-
type="text"
323-
id="lex-height"
324-
value="720"
325-
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
326-
/>
327-
</div>
328-
<div class="flex gap-2.5 items-center">
329-
<label for="lex-fps">FPS</label>
330-
<input
331-
type="text"
332-
id="lex-fps"
333-
value="24"
334-
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
335-
/>
336-
</div>
337-
<button
338-
id="lex-video-apply-button"
339-
class="rounded-lg px-10 py-2.5 bg-brand disabled:bg-brand/50 hover:bg-brand/90 text-white font-bold"
340-
disabled
341-
>
342-
Apply
343-
</button>
344-
<div class="flex gap-2.5 items-center">
345-
<label for="lex-bitrate">Max Bitrate (kbps)</label>
346-
<input
347-
type="text"
348-
id="lex-bitrate"
349-
value="1500"
350-
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
351-
/>
312+
<div id="lex-video-static" phx-update="ignore" class="flex flex-col gap-6">
313+
<div id="lex-resolution" class="flex gap-2.5 items-center">
314+
<label for="lex-width">Width</label>
315+
<input
316+
type="text"
317+
id="lex-width"
318+
value="1280"
319+
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
320+
/>
321+
<label for="lex-height">Height</label>
322+
<input
323+
type="text"
324+
id="lex-height"
325+
value="720"
326+
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
327+
/>
328+
</div>
329+
<div class="flex gap-2.5 items-center">
330+
<label for="lex-fps">FPS</label>
331+
<input
332+
type="text"
333+
id="lex-fps"
334+
value="24"
335+
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
336+
/>
337+
</div>
338+
<button
339+
id="lex-video-apply-button"
340+
class="rounded-lg px-10 py-2.5 bg-brand disabled:bg-brand/50 hover:bg-brand/90 text-white font-bold"
341+
disabled
342+
>
343+
Apply
344+
</button>
345+
<div class="flex gap-2.5 items-center">
346+
<label for="lex-bitrate">Max Bitrate (kbps)</label>
347+
<input
348+
type="text"
349+
id="lex-bitrate"
350+
value="1500"
351+
class="rounded-lg disabled:text-gray-400 disabled:border-gray-400 focus:border-brand focus:outline-none focus:ring-0"
352+
/>
353+
</div>
352354
</div>
353355
<.form for={@publisher.form} phx-change="change_simulcast" phx-update="replace">
354-
<.input type="checkbox" field={@publisher.form[:simulcast]} label="Simulcast" />
356+
<.input
357+
type="checkbox"
358+
field={@publisher.form[:simulcast]}
359+
label="Simulcast"
360+
{if @publisher.streaming?, do: %{"disabled" => true}, else: %{"disabled" => false}}
361+
/>
355362
</.form>
356363
</div>
357364
</div>
@@ -583,18 +590,34 @@ defmodule LiveExWebRTC.Publisher do
583590
end
584591

585592
@impl true
586-
def handle_event("change_simulcast", params, socket) do
587-
publisher = %Publisher{
588-
socket.assigns.publisher
589-
| form:
590-
to_form(params,
593+
def handle_event("change_simulcast", %{"simulcast" => "true"} = params, socket) do
594+
codecs =
595+
socket.assigns.publisher.video_codecs || PeerConnection.Configuration.default_video_codecs()
596+
597+
publisher =
598+
if simulcast_supported?(codecs) == true do
599+
%Publisher{socket.assigns.publisher | form: to_form(params, id: "lex-form")}
600+
else
601+
# FIXME this doesn't work when simulcast is not supported and user re-check the checkbox
602+
form =
603+
to_form(socket.assigns.publisher.form,
591604
id: "lex-form",
592605
errors: [
593606
simulcast: {"Server must be configured with H264 codec to support simulcast", []}
594607
]
595608
)
596-
}
597609

610+
%Publisher{socket.assigns.publisher | form: form}
611+
end
612+
613+
socket = assign(socket, publisher: publisher)
614+
{:noreply, socket}
615+
end
616+
617+
@impl true
618+
def handle_event("change_simulcast", %{"simulcast" => "false"} = params, socket) do
619+
form = to_form(params, id: "lex-form")
620+
publisher = %Publisher{socket.assigns.publisher | form: form}
598621
socket = assign(socket, publisher: publisher)
599622
{:noreply, socket}
600623
end
@@ -624,4 +647,20 @@ defmodule LiveExWebRTC.Publisher do
624647
1000 -> :ok
625648
end
626649
end
650+
651+
defp simulcast_supported?(codecs) do
652+
Enum.any?(codecs, fn codec ->
653+
fmtp = codec.sdp_fmtp_line
654+
655+
fmtp_correct =
656+
if fmtp == nil do
657+
false
658+
else
659+
fmtp.level_asymmetry_allowed == true and fmtp.packetization_mode == 0 and
660+
fmtp.profile_level_id == 0x42E01F
661+
end
662+
663+
codec.mime_type == "video/H264" and fmtp_correct == true
664+
end)
665+
end
627666
end

0 commit comments

Comments
 (0)