Help with RTMP Plugin

Hi everyone! First of all, thank you for the amazing work on Membrane. The framework has been incredibly helpful for us while building a media streaming service. I'm currently facing an issue when trying to compile membrane_rtmp_plugin with:
mix deps.compile
mix deps.compile
The error indicates that Bundlex can’t download the precompiled FFmpeg dependency:
Bundlex: Couldn't load OS dependency :ffmpeg

Cannot download file from:
https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2023-11-30-12-55/ffmpeg-n6.0.1-linux64-gpl-shared-6.0.tar.xz

Response status: 404


It then attempts to use pkg_config, but fails to find libavformat and libavutil.
Bundlex: Couldn't load OS dependency :ffmpeg

Cannot download file from:
https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2023-11-30-12-55/ffmpeg-n6.0.1-linux64-gpl-shared-6.0.tar.xz

Response status: 404


It then attempts to use pkg_config, but fails to find libavformat and libavutil.
I’m currently using:
{:membrane_rtmp_plugin, "~> 0.29"}
{:membrane_rtmp_plugin, "~> 0.29"}
And here is my full mix.exs (dependencies section):
{:membrane_core, "~> 1.0"},
{:membrane_framerate_converter_plugin, "~> 0.8"},
{:membrane_ffmpeg_swscale_plugin, "~> 0.15"},
{:membrane_h264_ffmpeg_plugin, "~> 0.31"},
{:membrane_http_adaptive_stream_plugin, "~> 0.18"},
{:membrane_rtmp_plugin, "~> 0.29"},
{:membrane_tee_plugin, "~> 0.12"}
{:membrane_core, "~> 1.0"},
{:membrane_framerate_converter_plugin, "~> 0.8"},
{:membrane_ffmpeg_swscale_plugin, "~> 0.15"},
{:membrane_h264_ffmpeg_plugin, "~> 0.31"},
{:membrane_http_adaptive_stream_plugin, "~> 0.18"},
{:membrane_rtmp_plugin, "~> 0.29"},
{:membrane_tee_plugin, "~> 0.12"}
Has anyone encountered this recently? It looks like the FFmpeg URL may no longer be valid — is there a recommended fix or an updated release for membrane_rtmp_plugin that changes the Bundlex config? Any guidance is greatly appreciated! Thanks in advance
29 Replies
varsill
varsill2mo ago
Hello! It looks as if FFmpeg 6.0 is no more available at the prebuilds repository we use. I think it should be safe to update the FFmpeg's dependency in membrane_rtmp_plugin's bundlex.exs to 6.1, but I will check on that.
Adriano Santos
Adriano SantosOP2mo ago
Thank you for your response. I will await your confirmation before proceeding.
varsill
varsill2mo ago
Sure, no problem! Could try setting membrane_precompiled_dependencies_provider to point to a fix branch by adding the following entry to the deps list in your mix.exs:
{:membrane_precompiled_dependency_provider, github: "membraneframework/membrane_precompiled_dependency_provider", branch: "update_ffmpeg_linux_link"},
{:membrane_precompiled_dependency_provider, github: "membraneframework/membrane_precompiled_dependency_provider", branch: "update_ffmpeg_linux_link"},
? If it helps, we will release membrane_precompiled_dependencies_provider v0.2.2 and you will be able to remove that entry and just do mix deps.update membrane_precompiled_dependencies_provider
Adriano Santos
Adriano SantosOP2mo ago
I need to set override: true but now server is up and running
Adriano Santos
Adriano SantosOP2mo ago
No description
Adriano Santos
Adriano SantosOP2mo ago
Thank you @varsill
varsill
varsill2mo ago
I need to set override: true but now server is up and running
You are right, override: true is also needed! I've already released membrane_precompiled_dependencies_provider v0.2.2 so now you should be able to remove the overriden entry and just do mix deps.update mmembrane_precompiled_dependencies_provider
Adriano Santos
Adriano SantosOP2mo ago
membrane_precompiled_dependencies_provider not found in hex but I tried {:membrane_precompiled_dependency_provider, "~> 0.2.2"}
Resolving Hex dependencies...
Resolution completed in 0.088s
Because the lock depends on membrane_ffmpeg_swscale_plugin 0.15.1 which depends on membrane_precompiled_dependency_provider ~> 0.1.0, the lock requires membrane_precompiled_dependency_provider ~> 0.1.0.
And because your app depends on the lock, membrane_precompiled_dependency_provider ~> 0.1.0 is required.
So, because your app depends on membrane_precompiled_dependency_provider ~> 0.2.2, version solving failed.
Resolving Hex dependencies...
Resolution completed in 0.088s
Because the lock depends on membrane_ffmpeg_swscale_plugin 0.15.1 which depends on membrane_precompiled_dependency_provider ~> 0.1.0, the lock requires membrane_precompiled_dependency_provider ~> 0.1.0.
And because your app depends on the lock, membrane_precompiled_dependency_provider ~> 0.1.0 is required.
So, because your app depends on membrane_precompiled_dependency_provider ~> 0.2.2, version solving failed.
mix.exs
{:membrane_core, "~> 1.0"},
{:membrane_framerate_converter_plugin, "~> 0.8"},
{:membrane_ffmpeg_swscale_plugin, "~> 0.15"},
{:membrane_h264_ffmpeg_plugin, "~> 0.31"},
{:membrane_http_adaptive_stream_plugin, "~> 0.18"},
{:membrane_rtmp_plugin, "~> 0.29"},
{:membrane_tee_plugin, "~> 0.12"},
{:membrane_precompiled_dependency_provider, "~> 0.2.2"}
{:membrane_core, "~> 1.0"},
{:membrane_framerate_converter_plugin, "~> 0.8"},
{:membrane_ffmpeg_swscale_plugin, "~> 0.15"},
{:membrane_h264_ffmpeg_plugin, "~> 0.31"},
{:membrane_http_adaptive_stream_plugin, "~> 0.18"},
{:membrane_rtmp_plugin, "~> 0.29"},
{:membrane_tee_plugin, "~> 0.12"},
{:membrane_precompiled_dependency_provider, "~> 0.2.2"}
Then I set override: true and works. Thank you again, I think for now we can close this thread. But before I go on, I wanted to ask another question. I'm using the adaptive HLS example as a basis for my project, but I'd like to export the incoming RTMP stream to other formats besides HLS, such as re-exporting RTMP and WebRTC, but I'm not quite sure how I could do this. Do you have any tips? So basically I want to have the ability to expose the input stream in different formats simultaneously, so that different types of clients can benefit from it.
varsill
varsill2mo ago
Oh, I see - it fails because membrane_precompiled_dependency_provider is not supposed to be a direct dependency of your project (I just suggested overriding it to make sure that the fix works, but in a normal setup you shouldn't have any {:membrane_precompiled_dependency_provider, in your project's mix.exs).
membrane_precompiled_dependency_provider is a direct dependency of e.g. membrane_rtmp_plugin and that's why your project indirectly depends on it as well (you can find it in your mix.lock). Here is how that dependency is defined in membrane_rtmp_plugin's mix.exs: https://github.com/membraneframework/membrane_rtmp_plugin/blob/27c14affa14adc4a8ca89a4f3f5cfeb87bfd6d00/mix.exs#L43 As you can see, it uses ~> syntax, allowing to bump the patch version with mix deps.update. So if you remove {:membrane_precompiled_dependency_provider, "~> 0.2.2", override: true} from you project's mix.exs and run mix deps.update membrane_precompiled_dependency_provider it should bump membrane_precompiled_dependency_provider to v0.2.2 (and therefore change your mix.lock)
GitHub
membrane_rtmp_plugin/mix.exs at 27c14affa14adc4a8ca89a4f3f5cfeb87bf...
RTMP server & client. Contribute to membraneframework/membrane_rtmp_plugin development by creating an account on GitHub.
Adriano Santos
Adriano SantosOP2mo ago
If I do this:
Downgraded:
membrane_precompiled_dependency_provider 0.2.2 => 0.1.2 (minor)
* Updating membrane_precompiled_dependency_provider (Hex package)
Downgraded:
membrane_precompiled_dependency_provider 0.2.2 => 0.1.2 (minor)
* Updating membrane_precompiled_dependency_provider (Hex package)
I think the rtmp_plugin will need to be updated, but for me the fix (override) worked for now.
varsill
varsill2mo ago
So basically I want to have the ability to expose the input stream in different formats simultaneously, so that different types of clients can benefit from it.
To do so you would need to connect different types of outputs to the :tee_video element. So for the ones you mentioned, you would need to connect: - Membrane.RTMP.Sink from membrane_rtmp_plugin - Membrane.WebRTC.Sink from membrane_webrtc_plugin You might also need to preprocess the stream before passing it to the sinks as different sinks require different input stream formats. So e.g. for RTMP, between the :tee_video and Membrane.RTMP.Sink you would need to put Membrane.H264.Parser{output_stream_structure: :avc3} to convert the stream structure for H.264 stream. Accepted formats for input pads should help you figure out what is the desired format of the stream - but feel free to ask if it's unclear how to convert given format into another!
Adriano Santos
Adriano SantosOP2mo ago
Thanks for answer. My actual pipeline is:
varsill
varsill2mo ago
I think the rtmp_plugin will need to be updated, but for me the fix (override) worked for now.
I think that's because you have membrane_rtmp_plugin v0.29.0 locked in you project, and it depends on membrane_precompiled_dependency_provider ~> 0.1.1 - doing mix deps.update membrane_rtmp_plugin (or even mix deps.update --all, as there might be some other deps with locked old versions) should solve it So concerning your pipeline - you can connect other sinks in the spec returned by handle_init . The HLS Sinks are connected in handle_info because in handle_init we don't know yet what are the desired resolutions, but for the sinks you mentioned I think we have all the necessary info available in handle_init
Adriano Santos
Adriano SantosOP2mo ago
hmm... sorry I new to Membrane, I would have to do something: |> child(:webrtc_sink, %Membrane.WebRTC.Sink{signaling: signaling}) in the end of handle_init pipeline?
varsill
varsill2mo ago
Sure, no problem, everybody is "new" at some point! Indeed, to support RTMP you would need to add something like the following entry to the spec list you create in handle_init() callback of your pipeline:
spec = [
...,
get_child(:tee_video)
|> child(:rtmp_h264_parser, %Membrane.H264.Parser{output_stream_structure: :avc3})
|> via_in(:video)
|> child(:rtmp_sink, %Membrane.RTMP.Sink{rtmp_url: <your URL>, tracks: [:video]})
]
spec = [
...,
get_child(:tee_video)
|> child(:rtmp_h264_parser, %Membrane.H264.Parser{output_stream_structure: :avc3})
|> via_in(:video)
|> child(:rtmp_sink, %Membrane.RTMP.Sink{rtmp_url: <your URL>, tracks: [:video]})
]
Adriano Santos
Adriano SantosOP2mo ago
Nice, thank you. rtmp_url in this case is a own server url right, because rtmp server is also in the pipeline Never mind, I misspoke. In your example, rtmp is a client for another rtmp server.
varsill
varsill2mo ago
Yeah, that's right - this rtmp_url is the URL of the server you would like to stream to (the Sink acts as a client). The Source you already had in your pipeline acts as a server.
Adriano Santos
Adriano SantosOP2mo ago
In the case of webrtc then:
spec = [
...,
get_child(:tee_video)
|> child(:rtmp_h264_parser, %Membrane.H264.Parser{output_stream_structure: :avc3})
|> via_in(:video)
|> |> child(:webrtc_sink, %Membrane.WebRTC.Sink{signaling: signaling})
]
spec = [
...,
get_child(:tee_video)
|> child(:rtmp_h264_parser, %Membrane.H264.Parser{output_stream_structure: :avc3})
|> via_in(:video)
|> |> child(:webrtc_sink, %Membrane.WebRTC.Sink{signaling: signaling})
]
varsill
varsill2mo ago
Almost, and that's because WebRTC.Sink has different pad names and expects different input stream formats (you can inspect it here) So you would need to do sth like:
spec = [
...,
get_child(:tee_video)
|> child(:webrtc_h264_parser, %Membrane.H264.Parser{output_stream_structure: :annexb, output_alignment: :nalu})
|> via_in(:input, options: [kind: :video])
|> child(:webrtc_sink, %Membrane.WebRTC.Sink{signaling: signaling})
]
spec = [
...,
get_child(:tee_video)
|> child(:webrtc_h264_parser, %Membrane.H264.Parser{output_stream_structure: :annexb, output_alignment: :nalu})
|> via_in(:input, options: [kind: :video])
|> child(:webrtc_sink, %Membrane.WebRTC.Sink{signaling: signaling})
]
Adriano Santos
Adriano SantosOP2mo ago
cool, Thank you for your guidance, I will try to follow it and update you on my progress. Another problem:
Adriano Santos
Adriano SantosOP2mo ago
the problem return 😭
varsill
varsill2mo ago
Hmm that's strange, https://github.com/BtbN/FFmpeg-Builds/releases/latest/download/ffmpeg-master-latest-linux64-gpl-shared.tar.xz seems to be a valid link - could you try running it again? Perhaps there was some server issue back when you ran it.
Adriano Santos
Adriano SantosOP2mo ago
In fact. Now works fine
Adriano Santos
Adriano SantosOP4w ago
Is there anything I can do to overcome these limitations? 👆 Hi @varsill
varsill
varsill4w ago
Hello! What version of membrane_ffmpeg_swscale_plugin do you have in your mix.lock?
Adriano Santos
Adriano SantosOP4w ago
"membrane_ffmpeg_swscale_plugin": {:hex, :membrane_ffmpeg_swscale_plugin, "0.16.1", "df82dda3c52c4260d7a3613753d1d2d23248713dfef80b8b9647dd0e601e3606", [:mix], [{:bundlex, "~> 1.2", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.16.0", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.1", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_precompiled_dependency_provider, "~> 0.1.0", [hex: :membrane_precompiled_dependency_provider, repo: "hexpm", optional: false]}, {:membrane_raw_video_format, "~> 0.3.0", [hex: :membrane_raw_video_format, repo: "hexpm", optional: false]}], "hexpm", "d75ee0e663e8446d84f26edca44b923d898317b2d68a2f5b4841ae56ec8d0f11"},
"membrane_ffmpeg_swscale_plugin": {:hex, :membrane_ffmpeg_swscale_plugin, "0.16.1", "df82dda3c52c4260d7a3613753d1d2d23248713dfef80b8b9647dd0e601e3606", [:mix], [{:bundlex, "~> 1.2", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.16.0", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.1", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_precompiled_dependency_provider, "~> 0.1.0", [hex: :membrane_precompiled_dependency_provider, repo: "hexpm", optional: false]}, {:membrane_raw_video_format, "~> 0.3.0", [hex: :membrane_raw_video_format, repo: "hexpm", optional: false]}], "hexpm", "d75ee0e663e8446d84f26edca44b923d898317b2d68a2f5b4841ae56ec8d0f11"},
varsill
varsill4w ago
Could you bump it to v0.16.3 (mix deps.update membrane_ffmpeg_swscale_plugin)? Generally speaking I think that bumping to the newest patch should resolve most of these precompiled dependencies problems (we recently added ability to specify a particular dependency version in bundlex.exs and the version and patched all the dependent plugins)

Did you find this page helpful?