Membrane SRT Live Transmit Plugin
A Membrane source element that receives data from an
SRT stream via the srt-live-transmit CLI tool.
Instead of linking against libsrt, this plugin spawns srt-live-transmit as a
child process and reads its stdout. This keeps the Erlang VM isolated from the
SRT C library while still supporting the full set of SRT socket options.
Prerequisites
srt-live-transmit must be available on $PATH. Install it via your package
manager or build from source:
# macOS
brew install srt
# Ubuntu/Debian
apt install srt-toolsInstallation
Add membrane_srt_live_transmit to your list of dependencies in mix.exs:
def deps do
[
{:membrane_srt_live_transmit, "~> 0.1.0"}
]
end
Docker / erlexec considerations
This library uses erlexec to spawn and
supervise the srt-live-transmit child process. When you run your application
inside Docker, there are two important things to keep in mind:
erlexecrefuses to run asrooterlexecexpects theSHELLenvironment variable to be set
That means your container should run the application as a non-root user, and
should define a valid shell path such as /bin/bash.
For example, in the test stage of
/Users/dmorn/projects/video-taxi/speech/Dockerfile, the container switches to
an unprivileged user before running tests and sets SHELL explicitly:
# erlexec refuses to run as root and requires SHELL to be set.
# Hex/Rebar are per-user installs, so copy root's Mix home to testuser.
RUN useradd -m -s /bin/bash testuser \
&& cp -a /root/.mix /home/testuser/.mix \
&& chown -R testuser:testuser /app /home/testuser/.mix
USER testuser
ENV HOME=/home/testuser
ENV SHELL=/bin/bash
RUN mix test
The same applies to release images. In the example Dockerfile, the final image
sets SHELL and runs as nobody instead of root:
WORKDIR "/app"
RUN chown nobody /app
ENV MIX_ENV="prod"
ENV SHELL=/bin/bash
COPY --from=release --chown=nobody:root /app/_build/${MIX_ENV}/rel/speech ./
USER nobody
If your image does not already include Bash, make sure to install it or set
SHELL to another valid shell binary available in the container.
Usage
Source element
Membrane.SRTLT.Source connects to (or listens for) an SRT peer and outputs
raw bytes as a push-mode stream:
child(:srt_source, %Membrane.SRTLT.Source{
host: "10.0.0.1",
port: 9000,
mode: :caller,
latency_ms: 350,
stream_id: "my-stream",
passphrase: "secret123456"
})
|> child(:parser, ...)All options have sensible defaults. See the module docs for the full list.
Options
| Option | Default | Description |
|---|---|---|
host | "127.0.0.1" | Hostname or IP of the SRT peer |
port | 9710 | Port of the SRT peer |
mode | :caller | :caller or :listener |
latency_ms | 350 | Symmetric SRT latency in ms |
peer_latency_ms | nil |
Peer (send) latency override, falls back to latency_ms |
rcv_latency_ms | nil |
Receive latency override, falls back to latency_ms |
transtype | "live" | SRT transport type |
stream_id | nil | SRT stream identifier |
passphrase | nil |
Encryption passphrase (10–79 chars), nil = no encryption |
chunk_size_bytes | 1316 | Max bytes per read (188×7, ideal for MPEG-TS) |
buffering_packets | 10 | Application-level read batch size |
Lifecycle notifications
The source sends these notifications to its parent:
{:source_state, :connected}— first data received from the SRT peer{:source_state, :disconnected}— peer disconnected after data was flowing (followed by end-of-stream)
Send a :close parent notification to shut down the source gracefully.
URI builder
Membrane.SRTLT.build_uri/1 assembles an SRT URI from discrete parameters,
useful when constructing URIs for other tools or a future Sink element:
Membrane.SRTLT.build_uri(
host: "192.168.1.10",
port: 9000,
mode: :caller,
latency: 350,
transtype: "live",
streamid: "my-stream"
)
# => "srt://192.168.1.10:9000?latency=350&mode=caller&streamid=my-stream&transtype=live"Reference
See docs/srt-live-transmit-reference.md
for a complete reference of all srt-live-transmit CLI options and SRT socket
parameters.
License
TODO