Membrane broadcasting tutorial

Now let's focus on how the Connection Manager works. As mentioned previously its role is to establish the RTSP connection with the RTSP server.

The ConnectionManager module will use the Connection behaviour, which provides additional callbacks to GenServer behaviour, aiding with building a connection process.

First of all we are defining the ConnectionStatus struct, which we will use to keep the state of the ConnectionManager:

lib/connection_manager.ex
defmodule ConnectionStatus do @moduledoc false @type t :: %__MODULE__{ stream_url: binary(), rtsp_session: pid(), pipeline: pid(), keep_alive: pid(), pipeline_options: keyword() } @enforce_keys [ :stream_url, :pipeline, :pipeline_options ] defstruct @enforce_keys ++ [ :rtsp_session, :keep_alive ] end

It holds the rtsp_session, which is the pid of a process started with Membrane.RTSP.start/1. The Membrane.RTSP allows us to execute RTSP client commands. You can read more about it here. The pipeline field is the pid of the pipeline, we will need it to notify the pipeline, that the RTSP connection is ready. In such notification we send pipeline_options, which contain necessary information about the stream. The keep_alive is a process which repeatedly pings the RTSP server, in order to keep the connection alive and prevent a timeout.

Let's take a look at the connect/2 callback, which is called immediately after the init/1:

lib/connection_manager.ex
def connect(_info, %ConnectionStatus{} = connection_status) do rtsp_session = start_rtsp_session(connection_status) connection_status = %{connection_status | rtsp_session: rtsp_session} if is_nil(rtsp_session) do {:backoff, @delay, connection_status} else with {:ok, connection_status} <- get_rtsp_description(connection_status), :ok <- setup_rtsp_connection(connection_status), {:ok, connection_status} <- start_keep_alive(connection_status), :ok <- play(connection_status) do send( connection_status.pipeline, {:rtsp_setup_complete, connection_status.pipeline_options} ) {:ok, connection_status} else {:error, error_message} -> {:backoff, @delay, connection_status} end end end

In the callback we go through the whole process of establishing RTSP connection - first starting the RTSP session, then getting the video parameters with, setting up the session, starting the keep alive process and finally playing the stream. If all those steps succeed we can notify the pipeline, otherwise we back off and try to set up the connection after a @delay amount of time.

What might seem unclear to you is the get_sps_pps function. It is responsible for getting the sps and pps parameters from the RTSP DESCRIBE method. In short, sps and pps are parameters used by the H.264 codec and are required to decode the stream. Once the RTSP connection is complete we are sending them to the pipeline.

Next chapter
RTSP to HLS - pipeline
Next Chapter