View Source Membrane.ICE.Endpoint (Membrane ICE plugin v0.14.3)

Endpoint used for establishing ICE connection, sending and receiving messages.


Architecture and pad semantic

Both input and output pads are dynamic ones. One instance of ICE Endpoint is responsible for handling only one ICE stream with only one component.


Linking using output pad

To receive messages after establishing ICE connection you have to link ICE Endpoint to your element via Pad.ref(:output, 1). 1 is an id of component from which your element will receive messages - because there will be always at most one component, id of it will be equal 1.

Important: you can link to ICE Endpoint using its output pad in any moment you want but if you don't want to miss any messages do it before playing your pipeline.


Linking using input pad

To send messages after establishing ICE connection you have to link to ICE Endpoint via Pad.ref(:input, 1). 1 is an id of component which will be used to send messages via net. To send data from multiple elements via the same component you have to use membrane_funnel_plugin.


Notifications API

ICE Endpoint handles the following notifications:

  • :gather_candidates

  • {:set_remote_credentials, credentials} - credentials are string in form of "ufrag passwd"

  • :peer_candidate_gathering_done

ICE Endpoint sends the following notifications:

  • {:new_candidate_full, candidate} Triggered by: :gather_candidates

  • {:udp_integrated_turn, udp_integrated_turn}

  • {:handshake_init_data, component_id, handshake_init_data}

  • {:connection_ready, stream_id, component_id}

  • {:component_state_failed, stream_id, component_id}


Sending and receiving messages

To send or receive messages just link to ICE Endpoint using relevant pads. As soon as connection is established your element will receive demands and incoming messages.


Establishing a connection

Gathering ICE candidates

Data about integrated TURN servers set up by Membrane.ICE.Endpoint, passed to the parent via notification, should be forwarded to the second peer, that will try to establish ICE connection with Membrane.ICE.Endpoint. The second peer should have at least one allocation, in any of running integrated TURN servers (Firefox or Chrome will probably have one allocation per TURN Server)

Performing ICE connectivity checks, selecting candidates pair

All ICE candidates from the second peer, that are not relay candidates corresponded to allocations on integrated TURN servers, will be ignored. Every ICE connectivity check sent via integrated TURN server is captured, parsed, and forwarded to ICE Endpoint in message {:connectivity_check, attributes, allocation_pid}. ICE Endpoint sends to messages in form of {:send_connectivity_check, attributes} on allocation_pid, to send his connectivity checks to the second peer. Role of ICE Endpoint can be ice-controlled, but cannot be ice-controlling. It is suggested, to use ice-lite option in SDP message, but it is not necessary. ICE Endpoint supports both, aggressive and normal nomination. After starting ICE or after every ICE restart, ICE Endpoint will pass all traffic and connectivity checks via allocation, which corresponds to the last selected ICE candidates pair.


Element options

Passed via struct Membrane.ICE.Endpoint.t/0

  • dtls?


    Default value: true
    true, if using DTLS Handshake, false otherwise

  • ice_lite?


    Default value: true
    true, when ice-lite option was send in SDP message, false otherwise

  • handshake_opts


    Default value: []
    Options for ExDTLS module. They will be passed to ExDTLS.start_link/1

  • integrated_turn_options


    Integrated TURN Options

  • telemetry_label


    Default value: []
    Label passed to Membrane.TelemetryMetrics functions

  • trace_context

    :list | any()

    Default value: []
    Trace context for otel propagation

  • parent_span

    :opentelemetry.span_ctx() | nil

    Default value: nil
    Parent span of ice_endpoint.life_span





Accepted formats:

Demand mode::manual
Demand unit::buffers



Accepted formats:

%RemoteStream{content_format: nil, type: :packetized}
Demand mode::manual

Link to this section Summary


Options defining the behavior of ICE.Endpoint in relation to integrated TURN servers.


Struct containing options for Membrane.ICE.Endpoint


Returns description of options available for this module

Link to this section Types

Link to this type


View Source
@type integrated_turn_options_t() :: [
  ip: :inet.ip4_address() | nil,
  mock_ip: :inet.ip4_address() | nil,
  ports_range: {:inet.port_number(), :inet.port_number()} | nil,
  cert_file: binary() | nil

Options defining the behavior of ICE.Endpoint in relation to integrated TURN servers.

  • :ip - IP, where integrated TURN server will open its sockets
  • :mock_ip - IP, that will be part of the allocation address contained in Allocation Succes message. Because of the fact, that in integrated TURNS no data is relayed via allocation address, there is no need to open socket there. There are some cases, where it is necessary, to tell the browser, that we have opened allocation on different IP, that we have TURN listening on, eg. we are using Docker container
  • :ports_range - range, where integrated TURN server will try to open ports
  • :cert_file - path to file with certificate and private key, used for estabilishing TLS connection for TURN using TLS over TCP
@type t() :: %Membrane.ICE.Endpoint{
  dtls?: boolean(),
  handshake_opts: keyword(),
  ice_lite?: boolean(),
  integrated_turn_options: [integrated_turn_options_t()],
  parent_span: :opentelemetry.span_ctx() | nil,
  telemetry_label: Membrane.TelemetryMetrics.label(),
  trace_context: :list | any()

Struct containing options for Membrane.ICE.Endpoint

Link to this section Functions

@spec options() :: keyword()

Returns description of options available for this module