Skip to content

Commit 3c1997c

Browse files
committed
[Broadcaster] Update configuration for Kubernetes deployment
1 parent 903f215 commit 3c1997c

File tree

9 files changed

+127
-31
lines changed

9 files changed

+127
-31
lines changed

broadcaster/assets/js/panel.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ const mediaConstraints = {
4141
let localStream = undefined;
4242
let pc = undefined;
4343

44+
let pcConfig;
45+
const pcConfigData = document.body.getAttribute('data-pcConfig');
46+
if (pcConfigData) {
47+
pcConfig = JSON.parse(pcConfigData);
48+
} else {
49+
pcConfig = {};
50+
}
51+
console.log(pcConfig);
52+
4453
function setupSaveConfigButtons() {
4554
saveStreamConfigButton.onclick = async () => {
4655
const title = document.getElementById('stream-title').value;
@@ -136,7 +145,7 @@ async function startStreaming() {
136145

137146
const candidates = [];
138147
let patchEndpoint = undefined;
139-
pc = new RTCPeerConnection();
148+
pc = new RTCPeerConnection(pcConfig);
140149

141150
pc.onicegatheringstatechange = () =>
142151
console.log('Gathering state change:', pc.iceGatheringState);

broadcaster/assets/js/whep-client.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
const pcConfig = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
1+
let pcConfig;
2+
const pcConfigData = document.body.getAttribute('data-pcConfig');
3+
if (pcConfigData) {
4+
pcConfig = JSON.parse(pcConfigData);
5+
} else {
6+
pcConfig = {};
7+
}
28

39
export class WHEPClient {
410
constructor(url) {

broadcaster/config/runtime.exs

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,39 @@ import Config
1616
#
1717
# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server`
1818
# script that automatically sets the env var above.
19+
20+
read_k8s_dist_config! = fn ->
21+
case System.get_env("K8S_SERVICE_NAME") do
22+
nil ->
23+
raise "Distribution mode `k8s` requires setting the env variable K8S_SERVICE_NAME"
24+
25+
service ->
26+
[
27+
strategy: Cluster.Strategy.Kubernetes.DNS,
28+
config: [
29+
application_name: "broadcaster",
30+
service: service
31+
]
32+
]
33+
end
34+
end
35+
36+
read_dns_dist_config! = fn ->
37+
case System.get_env("DNS_CLUSTER_QUERY") do
38+
nil ->
39+
raise "Distribution mode `dns` requires setting the env variable DNS_CLUSTER_QUERY"
40+
41+
query ->
42+
[
43+
strategy: Cluster.Strategy.DNSPoll,
44+
config: [
45+
node_basename: "broadcaster",
46+
query: query
47+
]
48+
]
49+
end
50+
end
51+
1952
read_ice_port_range! = fn ->
2053
case System.get_env("ICE_PORT_RANGE") do
2154
nil ->
@@ -29,12 +62,41 @@ read_ice_port_range! = fn ->
2962
end
3063
end
3164

65+
dist_config =
66+
case System.get_env("DISTRIBUTION_MODE") do
67+
"k8s" -> read_k8s_dist_config!.()
68+
"dns" -> read_dns_dist_config!.()
69+
_else -> nil
70+
end
71+
72+
ice_server_config =
73+
%{
74+
urls: System.get_env("ICE_SERVER_URL") || "stun:stun.l.google.com:19302",
75+
username: System.get_env("ICE_SERVER_USERNAME"),
76+
credential: System.get_env("ICE_SERVER_CREDENTIAL")
77+
}
78+
|> Map.reject(fn {_k, v} -> is_nil(v) end)
79+
80+
ice_transport_policy =
81+
case System.get_env("ICE_TRANSPORT_POLICY") do
82+
"relay" -> :relay
83+
_other -> :all
84+
end
85+
86+
pc_config = [
87+
ice_servers: [ice_server_config],
88+
ice_transport_policy: ice_transport_policy,
89+
ice_port_range: read_ice_port_range!.()
90+
]
91+
92+
config :broadcaster,
93+
dist_config: dist_config,
94+
pc_config: pc_config
95+
3296
if System.get_env("PHX_SERVER") do
3397
config :broadcaster, BroadcasterWeb.Endpoint, server: true
3498
end
3599

36-
config :broadcaster, ice_port_range: read_ice_port_range!.()
37-
38100
if config_env() == :prod do
39101
# The secret key base is used to sign/encrypt cookies and other secrets.
40102
# A default value is used in config/dev.exs and config/test.exs but you
@@ -51,8 +113,6 @@ if config_env() == :prod do
51113
host = System.get_env("PHX_HOST") || "example.com"
52114
port = String.to_integer(System.get_env("PORT") || "4000")
53115

54-
config :broadcaster, :dns_cluster_query, System.get_env("DNS_CLUSTER_QUERY")
55-
56116
config :broadcaster, BroadcasterWeb.Endpoint,
57117
url: [host: host, port: 443, scheme: "https"],
58118
http: [

broadcaster/lib/broadcaster/application.ex

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,25 @@ defmodule Broadcaster.Application do
1212

1313
@impl true
1414
def start(_type, _args) do
15-
children = [
16-
BroadcasterWeb.Telemetry,
17-
{DNSCluster, query: Application.get_env(:broadcaster, :dns_cluster_query) || :ignore},
18-
{Phoenix.PubSub, name: Broadcaster.PubSub},
19-
# Start a worker by calling: Broadcaster.Worker.start_link(arg)
20-
# {Broadcaster.Worker, arg},
21-
# Start to serve requests, typically the last entry
22-
BroadcasterWeb.Endpoint,
23-
BroadcasterWeb.Presence,
24-
Broadcaster.PeerSupervisor,
25-
Broadcaster.Forwarder,
26-
Broadcaster.ChatHistory,
27-
{Registry, name: Broadcaster.PeerRegistry, keys: :unique},
28-
{Registry, name: Broadcaster.ChatNicknamesRegistry, keys: :unique}
29-
]
15+
children =
16+
[
17+
BroadcasterWeb.Telemetry,
18+
{Phoenix.PubSub, name: Broadcaster.PubSub},
19+
BroadcasterWeb.Endpoint,
20+
BroadcasterWeb.Presence,
21+
Broadcaster.PeerSupervisor,
22+
Broadcaster.Forwarder,
23+
Broadcaster.ChatHistory,
24+
{Registry, name: Broadcaster.PeerRegistry, keys: :unique},
25+
{Registry, name: Broadcaster.ChatNicknamesRegistry, keys: :unique}
26+
] ++
27+
case Application.fetch_env!(:broadcaster, :dist_config) do
28+
nil ->
29+
[]
30+
31+
config ->
32+
[{Cluster.Supervisor, [[cluster: config], [name: Broadcaster.ClusterSupervisor]]}]
33+
end
3034

3135
# See https://hexdocs.pm/elixir/Supervisor.html
3236
# for other strategies and supported options

broadcaster/lib/broadcaster/peer_supervisor.ex

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@ defmodule Broadcaster.PeerSupervisor do
2424
}
2525
]
2626

27-
@opts [
28-
ice_servers: [%{urls: "stun:stun.l.google.com:19302"}],
29-
audio_codecs: @audio_codecs,
30-
video_codecs: @video_codecs
31-
]
27+
@spec client_pc_config() :: String.t()
28+
def client_pc_config() do
29+
pc_config = Application.fetch_env!(:broadcaster, :pc_config)
30+
31+
%{
32+
iceServers: pc_config[:ice_servers],
33+
iceTransportPolicy: pc_config[:ice_transport_policy]
34+
}
35+
|> Jason.encode!()
36+
end
3237

3338
@spec start_link(any()) :: Supervisor.on_start()
3439
def start_link(arg) do
@@ -102,9 +107,15 @@ defmodule Broadcaster.PeerSupervisor do
102107
end
103108

104109
defp spawn_peer_connection(id) do
105-
ice_port_range = Application.fetch_env!(:broadcaster, :ice_port_range)
106110
gen_server_opts = [name: {:via, Registry, {Broadcaster.PeerRegistry, id}}]
107-
pc_opts = @opts ++ [controlling_process: self(), ice_port_range: ice_port_range]
111+
112+
pc_opts =
113+
Application.fetch_env!(:broadcaster, :pc_config) ++
114+
[
115+
audio_codecs: @audio_codecs,
116+
video_codecs: @video_codecs,
117+
controlling_process: self()
118+
]
108119

109120
child_spec = %{
110121
id: PeerConnection,

broadcaster/lib/broadcaster_web/components/layouts/root.html.heex

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
1212
</script>
1313
</head>
14-
<body class="bg-white antialiased h-svh flex flex-col">
14+
<body
15+
class="bg-white antialiased h-svh flex flex-col"
16+
data-pcConfig={Broadcaster.PeerSupervisor.client_pc_config()}
17+
>
1518
<%= @inner_content %>
1619
</body>
1720
</html>

broadcaster/mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ defmodule Broadcaster.MixProject do
5656
{:telemetry_metrics, "~> 1.0"},
5757
{:telemetry_poller, "~> 1.0"},
5858
{:jason, "~> 1.2"},
59-
{:dns_cluster, "~> 0.1.1"},
6059
{:bandit, "~> 1.2"},
6160
{:corsica, "~> 2.1.3"},
6261
{:ex_webrtc, "~> 0.6.0"},
6362
{:ex_webrtc_dashboard, "~> 0.6.0"},
6463
{:earmark, "~> 1.4"},
64+
{:libcluster, "~> 3.4"},
6565

6666
# Dialyzer and credo
6767
{:dialyxir, ">= 0.0.0", only: :dev, runtime: false},

broadcaster/mix.lock

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
2929
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
3030
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
31-
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]},
31+
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]},
3232
"hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"},
3333
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
34+
"libcluster": {:hex, :libcluster, "3.4.1", "271d2da892763bbef53c2872036c936fe8b80111eb1feefb2d30a3bb15c9b4f6", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1d568157f069c6afa70ec0d736704cf799734bdbb6343f0322af4a980301c853"},
3435
"membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.1.2", "8af73b7dc15ba55c9f5fbfc0453d4a8edfb007ade54b56c37d626be0d1189aba", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "7fe3e07361510445a29bee95336adde667c4162b76b7f4c8af3aeb3415292023"},
3536
"mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"},
3637
"mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"},

broadcaster/rel/env.sh.eex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export RELEASE_DISTRIBUTION=name
2+
[ "${DISTRIBUTION_MODE}" = "k8s" ] && export RELEASE_NODE=<%= @release.name %>@${POD_IP}

0 commit comments

Comments
 (0)