Packages
membrane_rtc_engine
0.10.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.1
0.17.0
0.16.0
0.15.1
0.15.0
0.14.2
0.14.1
0.14.0
0.13.0
0.12.1
0.12.0
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha
Membrane RTC Engine and its client library
Current section
Files
Jump to
Current section
Files
lib/membrane_rtc_engine/display_manager/endpoint_manager.ex
defmodule Membrane.RTC.Engine.EndpointManager do
@moduledoc false
alias Membrane.RTC.Engine.Track
@enforce_keys [:id, :video_tracks_limit]
defstruct @enforce_keys ++
[
inbound_tracks: %{},
outbound_tracks: %{},
prioritized_tracks: [],
screens_sizes: %{
same_size?: true,
big_screens: nil,
small_screens: nil,
medium_screens: nil
}
]
@type id :: String.t()
@type t :: %__MODULE__{
id: id(),
inbound_tracks: %{Track.id() => Track.t()},
outbound_tracks: %{Track.id() => Track.t()},
video_tracks_limit: integer() | nil,
prioritized_tracks: [String.t()],
screens_sizes: %{
same_size?: boolean(),
big_screens: nil | integer(),
medium_screens: nil | integer(),
small_screens: nil | integer()
}
}
@doc """
Creates a new EndpointManager.
"""
@spec new(
endpoint_id :: id(),
video_tracks_limit :: integer() | nil
) :: t()
def new(endpoint_id, video_tracks_limit) do
%__MODULE__{
id: endpoint_id,
video_tracks_limit: video_tracks_limit
}
end
@spec add_tracks(
endpoint :: t(),
tracks :: [Track.t()],
type :: :inbound_tracks | :outbound_tracks
) :: t()
def add_tracks(endpoint, tracks, type) do
Map.update!(endpoint, type, &update_tracks(tracks, &1))
end
@spec remove_tracks(
endpoint :: t(),
tracks :: [Track.t()],
type :: :inbound_tracks | :outbound_tracks
) :: t()
def remove_tracks(endpoint, tracks, type) do
track_id_to_track = Map.fetch!(endpoint, type)
track_id_to_track =
Enum.reduce(tracks, track_id_to_track, fn track, acc -> Map.pop(acc, track.id) end)
Map.put(endpoint, type, track_id_to_track)
end
@spec map_audio_to_video(endpoint_manager :: t(), track_id :: Track.id()) :: [Track.t()]
def map_audio_to_video(endpoint_manager, track_id) do
if Map.has_key?(endpoint_manager.inbound_tracks, track_id) do
endpoint_manager.inbound_tracks
|> Map.values()
|> Enum.filter(&(&1.type == :video))
else
[]
end
end
@spec calculate_track_priorities(endpoint :: t(), ordered_tracks :: [Track.id()]) :: [
Track.id()
]
def calculate_track_priorities(endpoint, ordered_tracks) do
ordered_tracks =
Enum.reject(ordered_tracks, fn track ->
Map.has_key?(endpoint.inbound_tracks, track.id) or track.id in endpoint.prioritized_tracks
end)
video_tracks_limit =
if endpoint.video_tracks_limit == nil do
endpoint.outbound_tracks |> Map.values() |> Enum.count()
else
max(endpoint.video_tracks_limit - Enum.count(endpoint.prioritized_tracks), 0)
end
ordered_tracks = ordered_tracks |> Enum.take(video_tracks_limit) |> Enum.map(& &1.id)
endpoint.prioritized_tracks ++ ordered_tracks
end
@spec prioritize_track(endpoint :: t(), track_id :: Track.id()) :: t()
def prioritize_track(endpoint, track_id) do
%{endpoint | prioritized_tracks: [track_id | endpoint.prioritized_tracks]}
end
@spec unprioritize_track(endpoint :: t(), track_id :: Track.id()) :: t()
def unprioritize_track(endpoint, track_id) do
%{endpoint | prioritized_tracks: Enum.reject(endpoint.prioritized_tracks, &(&1 == track_id))}
end
@spec get_inbound_video_tracks(endpoint :: t()) :: [Track.t()]
def get_inbound_video_tracks(nil) do
[]
end
def get_inbound_video_tracks(endpoint) do
endpoint.inbound_tracks |> Map.values() |> Enum.filter(&(&1.type == :video))
end
defp update_tracks(tracks, track_id_to_track) do
Enum.reduce(tracks, track_id_to_track, fn track, acc ->
Map.put(acc, track.id, track)
end)
end
end