Calms
Calms
SMSoftware Mansion
Created by Calms on 1/20/2024 in #membrane-help
Clustering and scale out behaviour
Context: I've a membrane application running in an elixir cluster of 1. It receives a RTSP stream (UDP packets) from a client and does the whole streaming thing - awesome! If/when the cluster expands, there will be multiple nodes receiving UDP packets (the packets are load-balanced between nodes). Does Membrane have any handling to route the packet to the correct node? 🤔
9 replies
SMSoftware Mansion
Created by Calms on 1/16/2024 in #membrane-help
Debugging bundlex/unifex errors
Hello, I've been tinkering with membrane cross-compiled to Nerves (rpi4). I've had features (e.g. microphone input) working recently but it seems it has broken with recent upgrades. Would anyone have any tips on debugging the unifex_create/3 error below? I suspect it's loading precompiled NIFs onto the wrong architecture but I'm not seeing where I can disable precompiled libraries (or if this is even the right thing to be investigating...)
(stop) {:membrane_child_crash, :encoder, {“Nif fail: Elixir.Membrane.Opus.Encoder.Native.unifex_create/3”, [{:erlang, :nif_error, [“Nif fail: Elixir.Membrane.Opus.Encoder.Native.unifex_create/3"], [error_info: %{module: :erl_erts_errors}]}, {Membrane.Opus.Encoder.Native.Nif, :unifex_create, 3, [file: ~c”lib/membrane_opus/encoder/native.ex”, line: 1]}, {Membrane.Opus.Encoder, :handle_setup, 2, [file: ~c”lib/membrane_opus/encoder.ex”, line: 70]}, {Membrane.Core.CallbackHandler, :exec_callback, 4, [file: ~c”lib/membrane/core/callback_handler.ex”, line: 139]}, {Membrane.Core.CallbackHandler, :exec_and_handle_callback, 5, [file: ~c”lib/membrane/core/callback_handler.ex”, line: 69]}, {Membrane.Core.Element.LifecycleController, :handle_setup, 1, [file: ~c”lib/membrane/core/element/lifecycle_controller.ex”, line: 62]}, {Membrane.Core.Element, :handle_continue, 2, [file: ~c”lib/membrane/core/element.ex”, line: 172]}, {:gen_server, :try_handle_continue, 3, [file: ~c”gen_server.erl”, line: 1085]}]}}
(stop) {:membrane_child_crash, :encoder, {“Nif fail: Elixir.Membrane.Opus.Encoder.Native.unifex_create/3”, [{:erlang, :nif_error, [“Nif fail: Elixir.Membrane.Opus.Encoder.Native.unifex_create/3"], [error_info: %{module: :erl_erts_errors}]}, {Membrane.Opus.Encoder.Native.Nif, :unifex_create, 3, [file: ~c”lib/membrane_opus/encoder/native.ex”, line: 1]}, {Membrane.Opus.Encoder, :handle_setup, 2, [file: ~c”lib/membrane_opus/encoder.ex”, line: 70]}, {Membrane.Core.CallbackHandler, :exec_callback, 4, [file: ~c”lib/membrane/core/callback_handler.ex”, line: 139]}, {Membrane.Core.CallbackHandler, :exec_and_handle_callback, 5, [file: ~c”lib/membrane/core/callback_handler.ex”, line: 69]}, {Membrane.Core.Element.LifecycleController, :handle_setup, 1, [file: ~c”lib/membrane/core/element/lifecycle_controller.ex”, line: 62]}, {Membrane.Core.Element, :handle_continue, 2, [file: ~c”lib/membrane/core/element.ex”, line: 172]}, {:gen_server, :try_handle_continue, 3, [file: ~c”gen_server.erl”, line: 1085]}]}}
7 replies
SMSoftware Mansion
Created by Calms on 7/21/2023 in #membrane-help
RTP demo with RawAudio
Hello friends, I'm trying to get microphone input (via Membrane.PortAudio.Source) packaged into an RTP stream and sent to a server and can't quite seem to get it right. Excerpt below based on the demo in membrane-demo/rtp but with microphone input substituted and newer syntax.
alias Membrane.{RTP, UDP, PortAudio, RawAudio}
...
links = [
child(:mic_input, %PortAudio.Source{
channels: 2,
sample_rate: 24_000
})
|> child(:encoder, %Membrane.Opus.Encoder{
application: :audio,
input_stream_format: %RawAudio{
channels: 2,
sample_format: :s16le,
sample_rate: 24_000
}
})
|> via_in(Pad.ref(:input, audio_ssrc), options: [payloader: RTP.Opus.Payloader])
|> child(:rtp, %RTP.SessionBin{
secure?: secure?,
srtp_policies: [
%ExLibSRTP.Policy{
ssrc: :any_inbound,
key: srtp_key
}
]
})
|> via_out(Pad.ref(:rtp_output, audio_ssrc), options: [encoding: :OPUS])
|> child(:audio_realtimer, Membrane.Realtimer)
|> child(:audio_sink, %UDP.Sink{
destination_port_no: destination_port,
destination_address: destination_address
})
]
alias Membrane.{RTP, UDP, PortAudio, RawAudio}
...
links = [
child(:mic_input, %PortAudio.Source{
channels: 2,
sample_rate: 24_000
})
|> child(:encoder, %Membrane.Opus.Encoder{
application: :audio,
input_stream_format: %RawAudio{
channels: 2,
sample_format: :s16le,
sample_rate: 24_000
}
})
|> via_in(Pad.ref(:input, audio_ssrc), options: [payloader: RTP.Opus.Payloader])
|> child(:rtp, %RTP.SessionBin{
secure?: secure?,
srtp_policies: [
%ExLibSRTP.Policy{
ssrc: :any_inbound,
key: srtp_key
}
]
})
|> via_out(Pad.ref(:rtp_output, audio_ssrc), options: [encoding: :OPUS])
|> child(:audio_realtimer, Membrane.Realtimer)
|> child(:audio_sink, %UDP.Sink{
destination_port_no: destination_port,
destination_address: destination_address
})
]
This seems to throw an error when generating the headers because buffer.pts is nil:
[error] <0.815.0>/:rtp/{:stream_send_bin, 1236}/:payloader/:header_generator Error handling action {:split, {:handle_buffer, [[:input, %Membrane.Buffer{payload: <<220, 255, 254>>, pts: nil, dts: nil, metadata: %{}}]]}} returned by callback Membrane.RTP.HeaderGenerator.handle_buffers_batch

[error] GenServer #PID<0.849.0> terminating
** (FunctionClauseError) no function clause matching in Ratio.mult/2
(ratio 2.4.2) lib/ratio.ex:418: Ratio.mult(nil, 48000)
(membrane_rtp_plugin 0.23.0) lib/membrane/rtp/header_generator.ex:71: Membrane.RTP.HeaderGenerator.handle_process/4
[error] <0.815.0>/:rtp/{:stream_send_bin, 1236}/:payloader/:header_generator Error handling action {:split, {:handle_buffer, [[:input, %Membrane.Buffer{payload: <<220, 255, 254>>, pts: nil, dts: nil, metadata: %{}}]]}} returned by callback Membrane.RTP.HeaderGenerator.handle_buffers_batch

[error] GenServer #PID<0.849.0> terminating
** (FunctionClauseError) no function clause matching in Ratio.mult/2
(ratio 2.4.2) lib/ratio.ex:418: Ratio.mult(nil, 48000)
(membrane_rtp_plugin 0.23.0) lib/membrane/rtp/header_generator.ex:71: Membrane.RTP.HeaderGenerator.handle_process/4
Does anyone have any tips on what I might be doing wrong?
6 replies