From 2443eed38038df51e13ce15ba38cd093f7f51917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Wed, 7 Jan 2026 14:20:45 +0100 Subject: [PATCH 01/12] Set no_duration_filesize flvflag. Update deps. --- c_src/membrane_rtmp_plugin/sink/rtmp_sink.c | 12 ++++++++++-- mix.lock | 18 +++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c index ebf0982d..de25fbae 100644 --- a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c +++ b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c @@ -90,9 +90,13 @@ UNIFEX_TERM init_video_stream(UnifexEnv *env, State *state, int width, bool ready = is_ready(state); if (ready && !state->header_written) { - if (avformat_write_header(state->output_ctx, NULL) < 0) { + AVDictionary *options = NULL; + av_dict_set(&options, "flvflags", "no_duration_filesize", 0); + if (avformat_write_header(state->output_ctx, &options) < 0) { + av_dict_free(&options); return unifex_raise(env, "Failed writing header"); } + av_dict_free(&options); state->header_written = true; } return init_video_stream_result_ok(env, ready, state); @@ -132,9 +136,13 @@ UNIFEX_TERM init_audio_stream(UnifexEnv *env, State *state, int channels, bool ready = is_ready(state); if (ready && !state->header_written) { - if (avformat_write_header(state->output_ctx, NULL) < 0) { + AVDictionary *options = NULL; + av_dict_set(&options, "flvflags", "no_duration_filesize", 0); + if (avformat_write_header(state->output_ctx, &options) < 0) { + av_dict_free(&options); return unifex_raise(env, "Failed writing header"); } + av_dict_free(&options); state->header_written = true; } return init_audio_stream_result_ok(env, ready, state); diff --git a/mix.lock b/mix.lock index 5547b0ea..37f25de5 100644 --- a/mix.lock +++ b/mix.lock @@ -5,13 +5,13 @@ "bundlex": {:hex, :bundlex, "1.5.4", "3726acd463f4d31894a59bbc177c17f3b574634a524212f13469f41c4834a1d9", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:req, ">= 0.4.0", [hex: :req, repo: "hexpm", optional: false]}, {:zarex, "~> 1.0", [hex: :zarex, repo: "hexpm", optional: false]}], "hexpm", "e745726606a560275182a8ac1c8ebd5e11a659bb7460d8abf30f397e59b4c5d2"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "certifi": {:hex, :certifi, "2.15.0", "0e6e882fcdaaa0a5a9f2b3db55b1394dba07e8d6d9bcad08318fb604c6839712", [:rebar3], [], "hexpm", "b147ed22ce71d72eafdad94f055165c1c182f61a2ff49df28bcc71d1d5b94a60"}, - "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, - "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, - "dialyxir": {:hex, :dialyxir, "1.4.6", "7cca478334bf8307e968664343cbdb432ee95b4b68a9cba95bdabb0ad5bdfd9a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "8cf5615c5cd4c2da6c501faae642839c8405b49f8aa057ad4ae401cb808ef64d"}, + "coerce": {:hex, :coerce, "1.0.2", "5ef791040c92baaa5dd344887563faaeac6e6742573a167493294f8af3672bbe", [:mix], [], "hexpm", "0b3451c729571234fdac478636c298e71d1f2ce1243abed5fa43fa3181b980eb"}, + "credo": {:hex, :credo, "1.7.15", "283da72eeb2fd3ccf7248f4941a0527efb97afa224bcdef30b4b580bc8258e1c", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "291e8645ea3fea7481829f1e1eb0881b8395db212821338e577a90bf225c5607"}, + "dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"}, "earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, - "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, - "ex_doc": {:hex, :ex_doc, "0.38.4", "ab48dff7a8af84226bf23baddcdda329f467255d924380a0cf0cee97bb9a9ede", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "f7b62346408a83911c2580154e35613eb314e0278aeea72ed7fedef9c1f165b2"}, + "erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"}, + "ex_doc": {:hex, :ex_doc, "0.39.3", "519c6bc7e84a2918b737aec7ef48b96aa4698342927d080437f61395d361dcee", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "0590955cf7ad3b625780ee1c1ea627c28a78948c6c0a9b0322bd976a079996e1"}, "ffmpex": {:hex, :ffmpex, "0.11.0", "70d2e211a70e1d8cc1a81d73208d5efedda59d82db4c91160c79e5461529d291", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:rambo, "~> 0.3.0", [hex: :rambo, repo: "hexpm", optional: false]}], "hexpm", "2429d67badc91957ace572b9169615619740904a58791289ba54d99e57a164eb"}, "file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"}, "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, @@ -25,7 +25,7 @@ "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, "membrane_aac_format": {:hex, :membrane_aac_format, "0.8.0", "515631eabd6e584e0e9af2cea80471fee6246484dbbefc4726c1d93ece8e0838", [:mix], [{:bimap, "~> 1.1", [hex: :bimap, repo: "hexpm", optional: false]}], "hexpm", "a30176a94491033ed32be45e51d509fc70a5ee6e751f12fd6c0d60bd637013f6"}, "membrane_aac_plugin": {:hex, :membrane_aac_plugin, "0.19.1", "29b9eecf75e3d60b16e7aac0861a501caa16f6d34f88e6d1d4140fdd4926292b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_aac_format, "~> 0.8.0", [hex: :membrane_aac_format, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "21158745f4d748eb15dd63e872d21a7deacb055294c0efb24b31960ad0400171"}, - "membrane_core": {:hex, :membrane_core, "1.2.4", "3f9fc78cef29b69acadd4f959c8ec23cbb1544c26c8e8474589b143ada9a0da2", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ec7a77b7ab457267c0243338383365f6ef5ace2686ddc129939e502a58eba546"}, + "membrane_core": {:hex, :membrane_core, "1.2.6", "22329f6a5ac1f56a58666e3bf48e07dcd0978143c23626226127f3baa3c89a95", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0 or ~> 4.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7bdee620f5c1fc492613b12566b1b95e7e09f5eb9364c0fed742fffb16266ab4"}, "membrane_file_plugin": {:hex, :membrane_file_plugin, "0.17.2", "650e134c2345d946f930082fac8bac9f5aba785a7817d38a9a9da41ffc56fa92", [:mix], [{:logger_backends, "~> 1.0", [hex: :logger_backends, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "df50c6040004cd7b901cf057bd7e99c875bbbd6ae574efc93b2c753c96f43b9d"}, "membrane_flv_plugin": {:hex, :membrane_flv_plugin, "0.12.0", "d715ad405af86dcaf4b2f479e34088e1f6738c7280366828e1066b39d2aa493a", [:mix], [{:membrane_aac_format, "~> 0.8.0", [hex: :membrane_aac_format, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_h264_format, "~> 0.6.1", [hex: :membrane_h264_format, repo: "hexpm", optional: false]}], "hexpm", "a317872d6d394e550c7bfd8979f12a3a1cc1e89b547d75360321025b403d3279"}, "membrane_funnel_plugin": {:hex, :membrane_funnel_plugin, "0.9.2", "2b2e840dbb232ce29aaff2d55bd329d9978766518dbeb6e8dba7aba7115fadcc", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "865ac9d84f86698e2cfeb7904d3b12ab74855a38ca651a880db1505965fa77cc"}, @@ -33,7 +33,7 @@ "membrane_h265_format": {:hex, :membrane_h265_format, "0.2.0", "1903c072cf7b0980c4d0c117ab61a2cd33e88782b696290de29570a7fab34819", [:mix], [], "hexpm", "6df418bdf242c0d9f7dbf2e5aea4c2d182e34ac9ad5a8b8cef2610c290002e83"}, "membrane_h26x_plugin": {:hex, :membrane_h26x_plugin, "0.10.5", "e9fa1ee9cda944259c4d2728c8b279bfe0152a3a6c1af187b07fa8411ca4e25e", [:mix], [{:bunch, "~> 1.4", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_h264_format, "~> 0.6.0", [hex: :membrane_h264_format, repo: "hexpm", optional: false]}, {:membrane_h265_format, "~> 0.2.0", [hex: :membrane_h265_format, repo: "hexpm", optional: false]}], "hexpm", "dd0287a6b6223e47bba30a8952d6ec53db35f6a3e33203b7ad786e995711f098"}, "membrane_hackney_plugin": {:hex, :membrane_hackney_plugin, "0.11.0", "54b368333a23394e7cac2f4d6b701bf8c5ee6614670a31f4ebe009b5e691a5c1", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:mockery, "~> 2.3", [hex: :mockery, repo: "hexpm", optional: false]}], "hexpm", "2b28fd1be3c889d5824d7d985598386c7673828c88f49a91221df3626af8a998"}, - "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.2.1", "d385afa61f9e30318d672960acdb951669bb911cd5ee98062d06c3b739a44a76", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "5470400b720581871efe688c9e446aef17085042ff80c7b8855f10de55d73c93"}, + "membrane_precompiled_dependency_provider": {:hex, :membrane_precompiled_dependency_provider, "0.2.2", "0fbff1eb651619ce95abd7f9d19dd636ce460adc01bea36a440c48d1a6572a95", [:mix], [{:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "60296232d613856d22494303b64487bfa141666544f2e83a97f1d2dd28c34453"}, "membrane_stream_plugin": {:hex, :membrane_stream_plugin, "0.4.0", "0c4ab72a4e13bf0faa0f1166fbaf68d2e34167dbec345aedb74ce1eb7497bdda", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "5a9a9c17783e18ad740e6ddfed364581bdb7ebdab8e61ba2c19a1830356f7eb8"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, @@ -48,11 +48,11 @@ "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, "rambo": {:hex, :rambo, "0.3.4", "8962ac3bd1a633ee9d0e8b44373c7913e3ce3d875b4151dcd060886092d2dce7", [:mix], [], "hexpm", "0cc54ed089fbbc84b65f4b8a774224ebfe60e5c80186fafc7910b3e379ad58f1"}, "ratio": {:hex, :ratio, "4.0.1", "3044166f2fc6890aa53d3aef0c336f84b2bebb889dc57d5f95cc540daa1912f8", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}, {:numbers, "~> 5.2.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm", "c60cbb3ccdff9ffa56e7d6d1654b5c70d9f90f4d753ab3a43a6bf40855b881ce"}, - "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, + "req": {:hex, :req, "0.5.17", "0096ddd5b0ed6f576a03dde4b158a0c727215b15d2795e59e0916c6971066ede", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0b8bc6ffdfebbc07968e59d3ff96d52f2202d0536f10fef4dc11dc02a2a43e39"}, "shmex": {:hex, :shmex, "0.5.1", "81dd209093416bf6608e66882cb7e676089307448a1afd4fc906c1f7e5b94cf4", [:mix], [{:bunch_native, "~> 0.5.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "c29f8286891252f64c4e1dac40b217d960f7d58def597c4e606ff8fbe71ceb80"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.1", "a48703a25c170eedadca83b11e88985af08d35f37c6f664d6dcfb106a97782fc", [:rebar3], [], "hexpm", "b3a917854ce3ae233619744ad1e0102e05673136776fb2fa76234f3e03b23642"}, "unifex": {:hex, :unifex, "1.2.1", "6841c170a6e16509fac30b19e4e0a19937c33155a59088b50c15fc2c36251b6b", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.4", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.5.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm", "8c9d2e3c48df031e9995dd16865bab3df402c0295ba3a31f38274bb5314c7d37"}, - "zarex": {:hex, :zarex, "1.0.5", "58239e3ee5d75f343262bb4df5cf466555a1c689f920e5d3651a9333972f7c7e", [:mix], [], "hexpm", "9fb72ef0567c2b2742f5119a1ba8a24a2fabb21b8d09820aefbf3e592fa9a46a"}, + "zarex": {:hex, :zarex, "1.0.6", "f657ed1187e6e90472e24c92b1fd5bf3f846e74bd240bd77276c13f336a8d168", [:mix], [], "hexpm", "b628a9b0bc312f278af2c288078c31fd4757224b82d768e91bcf3bedbe3a50e7"}, } From 3d7e71bfe79b633a3dfa892bd0947d97adf13048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 10:58:58 +0100 Subject: [PATCH 02/12] Fix warnings with struct update --- lib/membrane_rtmp_plugin/rtmp/header.ex | 2 +- lib/membrane_rtmp_plugin/rtmp/message_handler.ex | 8 ++++++-- lib/membrane_rtmp_plugin/rtmp/message_parser.ex | 8 ++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/membrane_rtmp_plugin/rtmp/header.ex b/lib/membrane_rtmp_plugin/rtmp/header.ex index b5eca2a8..5ccf4869 100644 --- a/lib/membrane_rtmp_plugin/rtmp/header.ex +++ b/lib/membrane_rtmp_plugin/rtmp/header.ex @@ -127,7 +127,7 @@ defmodule Membrane.RTMP.Header do <<@header_type_3::bitstring, chunk_stream_id::6, rest::binary>>, previous_headers ) do - previous_header = previous_headers[chunk_stream_id] + %__MODULE__{} = previous_header = previous_headers[chunk_stream_id] if previous_header.extended_timestamp? do with {timestamp_delta, _extended_timestamp?, rest} <- diff --git a/lib/membrane_rtmp_plugin/rtmp/message_handler.ex b/lib/membrane_rtmp_plugin/rtmp/message_handler.ex index bb75e253..58759af2 100644 --- a/lib/membrane_rtmp_plugin/rtmp/message_handler.ex +++ b/lib/membrane_rtmp_plugin/rtmp/message_handler.ex @@ -254,7 +254,11 @@ defmodule Membrane.RTMP.MessageHandler do } end - defp get_additional_media_events(rtmp_header, additional_media, %{header_sent?: true} = state) do + defp get_additional_media_events( + %Membrane.RTMP.Header{} = rtmp_header, + additional_media, + %{header_sent?: true} = state + ) do # NOTE: we are replacing the type_id from 18 to 8 (script data to audio data) as it carries the # additional audio track data = additional_media.media @@ -275,7 +279,7 @@ defmodule Membrane.RTMP.MessageHandler do Map.update!(state, :events, &[event | &1]) end - defp get_additional_media_events(rtmp_header, additional_media, state) do + defp get_additional_media_events(%Membrane.RTMP.Header{} = rtmp_header, additional_media, state) do data = additional_media.media header = %Membrane.RTMP.Header{rtmp_header | type_id: 8, body_size: byte_size(data)} diff --git a/lib/membrane_rtmp_plugin/rtmp/message_parser.ex b/lib/membrane_rtmp_plugin/rtmp/message_parser.ex index 34e17544..7931e2f8 100644 --- a/lib/membrane_rtmp_plugin/rtmp/message_parser.ex +++ b/lib/membrane_rtmp_plugin/rtmp/message_parser.ex @@ -100,7 +100,7 @@ defmodule Membrane.RTMP.MessageParser do def handle_packet( packet, - %{state_machine: :connected, buffer: buffer, chunk_size: chunk_size} = state + %__MODULE__{state_machine: :connected, buffer: buffer, chunk_size: chunk_size} = state ) do payload = buffer <> packet @@ -117,7 +117,7 @@ defmodule Membrane.RTMP.MessageParser do def handle_packet( packet, - %{state_machine: :handshake, buffer: buffer, handshake: handshake} = state + %__MODULE__{state_machine: :handshake, buffer: buffer, handshake: handshake} = state ) do payload = buffer <> packet @@ -161,7 +161,7 @@ defmodule Membrane.RTMP.MessageParser do def handle_packet( packet, - %{state_machine: :connecting, buffer: buffer, chunk_size: chunk_size} = state + %__MODULE__{state_machine: :connecting, buffer: buffer, chunk_size: chunk_size} = state ) do payload = buffer <> packet @@ -269,7 +269,7 @@ defmodule Membrane.RTMP.MessageParser do defp fsm_transition(:handshake), do: :connecting - defp update_state_with_message(state, header, message, rest) do + defp update_state_with_message(%__MODULE__{} = state, header, message, rest) do updated_headers = Map.put(state.previous_headers, header.chunk_stream_id, header) %__MODULE__{ From 17f9dc23be11df3ca1e7e76ff9d0276cc2d299b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 11:06:15 +0100 Subject: [PATCH 03/12] Fix credo warning --- lib/membrane_rtmp_plugin/rtmp/sink/sink.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex b/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex index e75211a2..b6536f82 100644 --- a/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex +++ b/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex @@ -75,7 +75,7 @@ defmodule Membrane.RTMP.Sink do options = %{options | tracks: Enum.uniq(options.tracks)} - unless length(options.tracks) > 0 and + unless options.tracks != [] and Enum.all?(options.tracks, &Kernel.in(&1, [:audio, :video])) do raise ArgumentError, "All track have to be either :audio or :video" end From 966aec1f650db7f89d0c44cb228740017282eb2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 11:13:38 +0100 Subject: [PATCH 04/12] Disable no_duration_filesize --- c_src/membrane_rtmp_plugin/sink/rtmp_sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c index de25fbae..16776a35 100644 --- a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c +++ b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c @@ -91,7 +91,7 @@ UNIFEX_TERM init_video_stream(UnifexEnv *env, State *state, int width, bool ready = is_ready(state); if (ready && !state->header_written) { AVDictionary *options = NULL; - av_dict_set(&options, "flvflags", "no_duration_filesize", 0); + av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); if (avformat_write_header(state->output_ctx, &options) < 0) { av_dict_free(&options); return unifex_raise(env, "Failed writing header"); From a7fa81217f416fa0a4218160e21be7d3680c8df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 11:16:27 +0100 Subject: [PATCH 05/12] Disable no_duration_filesize --- c_src/membrane_rtmp_plugin/sink/rtmp_sink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c index 16776a35..103334ba 100644 --- a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c +++ b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c @@ -137,7 +137,7 @@ UNIFEX_TERM init_audio_stream(UnifexEnv *env, State *state, int channels, bool ready = is_ready(state); if (ready && !state->header_written) { AVDictionary *options = NULL; - av_dict_set(&options, "flvflags", "no_duration_filesize", 0); + av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); if (avformat_write_header(state->output_ctx, &options) < 0) { av_dict_free(&options); return unifex_raise(env, "Failed writing header"); From 0ec05d2f4fb0744673a480e654ea942fae78790f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 11:18:51 +0100 Subject: [PATCH 06/12] Disable no_duration_filesize --- c_src/membrane_rtmp_plugin/sink/rtmp_sink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c index 103334ba..036c4068 100644 --- a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c +++ b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c @@ -91,7 +91,7 @@ UNIFEX_TERM init_video_stream(UnifexEnv *env, State *state, int width, bool ready = is_ready(state); if (ready && !state->header_written) { AVDictionary *options = NULL; - av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); + // av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); if (avformat_write_header(state->output_ctx, &options) < 0) { av_dict_free(&options); return unifex_raise(env, "Failed writing header"); @@ -137,7 +137,7 @@ UNIFEX_TERM init_audio_stream(UnifexEnv *env, State *state, int channels, bool ready = is_ready(state); if (ready && !state->header_written) { AVDictionary *options = NULL; - av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); + // av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); if (avformat_write_header(state->output_ctx, &options) < 0) { av_dict_free(&options); return unifex_raise(env, "Failed writing header"); From a69914cbbd83858fd857bf0ddb65ee631a04aaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 11:38:57 +0100 Subject: [PATCH 07/12] Update fixtures as new FFmpeg produces output with 1 byte less. Revoke no_duration_filesize --- c_src/membrane_rtmp_plugin/sink/rtmp_sink.c | 4 ++-- test/fixtures/bun33s.flv | Bin 3915839 -> 3915838 bytes test/fixtures/bun33s_audio.flv | Bin 551018 -> 551017 bytes test/fixtures/bun33s_video.flv | Bin 3364933 -> 3364932 bytes 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c index 036c4068..de25fbae 100644 --- a/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c +++ b/c_src/membrane_rtmp_plugin/sink/rtmp_sink.c @@ -91,7 +91,7 @@ UNIFEX_TERM init_video_stream(UnifexEnv *env, State *state, int width, bool ready = is_ready(state); if (ready && !state->header_written) { AVDictionary *options = NULL; - // av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); + av_dict_set(&options, "flvflags", "no_duration_filesize", 0); if (avformat_write_header(state->output_ctx, &options) < 0) { av_dict_free(&options); return unifex_raise(env, "Failed writing header"); @@ -137,7 +137,7 @@ UNIFEX_TERM init_audio_stream(UnifexEnv *env, State *state, int channels, bool ready = is_ready(state); if (ready && !state->header_written) { AVDictionary *options = NULL; - // av_dict_set(&options, "flvflags", "no_duration_filesize2", 0); + av_dict_set(&options, "flvflags", "no_duration_filesize", 0); if (avformat_write_header(state->output_ctx, &options) < 0) { av_dict_free(&options); return unifex_raise(env, "Failed writing header"); diff --git a/test/fixtures/bun33s.flv b/test/fixtures/bun33s.flv index 28e6012e561c370ea6a1beebfc1fc76ce5518016..e541c659cf18af72304fb8186b0e6423594573db 100644 GIT binary patch delta 11128 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 delta 10984 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 A^8f$< diff --git a/test/fixtures/bun33s_audio.flv b/test/fixtures/bun33s_audio.flv index 4e73260f4b0f6f04f1b29f95403fcc916da3936b..7f5df2335f0afcdc825804960f57ac3346378b29 100644 GIT binary patch delta 95 zcmaELLGk4UML{>8Fh&*z1_n+bW)NavI51Igi8_x@Vp*D*p`N*(p@9JdM_Oi1YH?;& tDubiKg-alH5ap*E@3!7$Y`x3WdY8HNE=%iO*4Ddht#{eC-sR{`2LSED9t;2g delta 96 zcmaEPLGjfEML{>8Fh&*z1_n+bW)NavI5<&oi3YDvVp*E0g`T;Yo}qyO14mkBPHJ&x uRVss{!i6g!g%I^;8t=5;VQjs_)Ov@x^$ttx9oE)6Y^`_Lx8C9CO$Pu4z#c^a diff --git a/test/fixtures/bun33s_video.flv b/test/fixtures/bun33s_video.flv index 6778aabc56a4640451fcfd40e7f10c13c85cc9d4..acc8a7b9ad38821c8ea6b577b47c5eb5d7d19e07 100644 GIT binary patch delta 10860 zcmYjXcU)9g({@+-!Zui73k&SR(sq|+4T23tVhbwr5=-nTV0_WPHKIbI5)CN& z87zq!8@TF?EsA18jj_gpQPlWiibh4z*uFb+*)#m%PoDdnnKS3ioS8WXj#Zu&)$som z-FpuZiCVR4<;nkRrEJxTD^Zw4OG^^-BD{NN=I6AHvnE*MY_?V&Ib+9VPaZoXyH#?p ztp*q@$Q&uT)JrUCbOehYiunJ_CeD@Vmc_Il>HOKTx%Dn29$%O190jh0VqoUDDfEs| zkCm+f)K^P%j;oS`E&!_LNp%i~{HQB}E+U;{x&IM&9JbL*=g8CB)l8-);T6a@syhaH zvf)kLI(jgW-d9E7ivd{xmQ{DuIow9oUZ>WvW?!Qc22_F7m1m1k4}w9LBgu?4H(S_r{`YWV{2sa! zX!ra#QV{>PN3*#)uG~%335Pu{73sMqsc0}0;yw)!2~x;?5-fU;xI+;lDWN}OMO_J{ zCW>%xINsb$`fTeZ>In$8j4MqSZD(NAU{NUp{-Z@3N$5tdD2-7)^F)V;3ZErH=b*mX z^F?Qf8oO9j2#Dh?FJt20e=Dk_F?pLreHeACQZ$38se45u8TG7MR7}*GT2XsK&o78Z z5z4n+Zp!aa8iRD3A+$SEoJ&7)PU7bwH443aZI6=l9 z7fFf}6ufi^>%jwVZ5LO!RQ`uD{s$d*tk_irh+lw~Yr5iE)Wr$b1h_5e<^)}bxgF~6 z1o{nbV;ETXhnpPqqJndA?te3xYg654wBs4HlABoNUet*p^&|I%of$f0^_Y;vBaUCs z0Qii`Hf;5HVsiq=O^6kdOk$5iBo^S%zz*ROPaP8*l`NSB6j$F(GL5uN z&6Jp##Nlj-h9q9hkxZwFmJ~|%l330#W|;p@Dc0vVdT-#Z@aJ1RML$vX}94?)}`@Anz_+S6wY1O8z?*8p&QI2!%g z`2Ic%U=b*Md4kU%nliP}=L|LxkH44cxcCYmgRgU7p2No-R0xr{@{~`7OrUh!z-vBM z3{p(%>+k!l6nYLgErb8@Nyig`p?Ipv$KnP`aHQW`A3Ji;8F5*z(z)0UVZ6AwOK-pi za`j%)hxo&Jsq`etaw_RdY=rR4{H&E?jS^01*Dz^M;xJ|vx29MYb|bv!6l zlicJZ(g5N%otDag!yIz?7ioK-IK_48Y?9c1OWKAc-Ze-wPy)K32@j<|ldFe5mySat z(4F`HmEObl7Q>+7jkFRuJS%&|vQ&YCt{~V|R)y0c_s~nW7C5fNN4A_qQj{_ksmu41 zrI5(4YMBeEd#RQ6AucOab{k_1Jv_=NOKrAZ%hg88zJ}UZhV#xCA$x&J5G@@gn}fbX z6gyVd9ytt*1-Y^YI2Rlr#1_`ha|hg7%QJrcAD_JS?+?R z1FEuHdwCKZ>@qy&qx#58o6oYAQw@`Q0mbo)(?TCFl*hpZ^7~Y5h8M}Fd4pzfdt<5m zDs=w{{#YwtD})F5a`P5>ix#(VmwcFTR=`rxL3trX%Xc;M4!FY@EpKb(d(ml#F8?AI zLKczt75QBV1djK`0t&FwTk`KIJ_g@w$-QfkU!akX{+545%FCb14-+@-h5RLzIKE6FWDlHZ=PHFK#tNcq>lN={piq0BZ&3sj*JhVONoe!|g>Z{NxqUT? z1ma|871+@WTBcl9L=ku3rs4xaVfPgVLRk+LiG=n&S8O8m`8$PhDa85SxhqGv;N;4c zgc8)s976j;mAwgtM=L7`-L)&16Z)ouGM3Pt6lIIqH}zKjLHknqp>h(9>@uw73_oNm z-zUy{ymAnsx%o=r7Km%O{+Y7H&Wjc()ig43iE<1eZf%+J5`A7)p&Uy{vsu}qrsh{E z@i{@*^t64-Jus3F87*fxs{CXcXe;U9dmg%N{5rd@@8n1)kWKa7<;Me|*RC)2?F79F z=G2aBeY2rqN1>mpd>f$A5ysV=@qNPdUA*OcLg>pNcmDX=_Yk!5D79Sbx0$t6gCqU6 zuqJP=fBYul^9DBc=ZE^eVDsMp#P0{8eSTf{#&)5-7==UR((!2!B^t{2y+icQHa`KK`71S-wEo45ClKi{R^76Nynum`7d== zkByIe`a6H-WEuWLp_1@R)NzZ3`ZsqSkgl$0`^Qj`F@EYlqw}6#GFhQ>DHaOsG772~H0sa&}k%a-v`s zlX0NJ606@hsH2)fA-|Ve4U6JRhNwHEVW{k3w)zsu-=3oG1JNk7^QndE%~&^aLCRwF zaEhhHW$Iw`DfX48x2XTa>R5-J>Z3RiU7$Opo`oji+2Ss!v4rEYc3x3m!qbTQH{4X` zGaZTd)E8iza9reH>Ly^g(5LD=_SNyPTEoDfB25nl`gv;N0hDEy81&qCa?KP*B?f8= z7&srS`J91IBQ$9Y)LAv_7+Bp_gGH4~PSTXJug|(^{tJN1?4$8(POUm_S%1w5He}i` zO$7sOvs=u3Zk%Q@V+!&#ISjljXu)imr&-OI>|)Jk2F%MeV;HC^*KiCJt`n@qo$K*~ z<{)DXJ2k5qxUpArlz{`)n)wWjIHj4+!1G@;|HnYpRn2||if(IeF|eSa1vBy=%_hc} zUTD5y;MzM4J_Vy~m)*53`i^Ru_6{3Y9UxF#Nw8Li2MlBNrwHvwgyL=507Cyw)Xpa4 zo~*SJ%IKxV$423He=J?A&VcB^^Za^)wmh9jyh&Ql@m#wz%?ajq*O?JOWd3C;lq zw(`9_A;YnUz-_2J8$t&FD4CPzPm1=wDJM8eYRai%XtrIEjr6&J$5!NW}XxpA}D`!(lx=R~s%u zkwEV!{$RK%+<+HAd0&1fvDZ1S+XXG1iijtv!reAvo|?cU*pk@vKmX;QpF9$XH5ps%+zU zsv&E0jajUo8fF+vAzFl3yt2wDJfoqjUR4=?Y#zwBU5AYW@ZexA>vq~W1FH@HP@9R< zqVZj>7}Xe*uxnGV8jaw0e%JWc_J2m07VQB`kNAeG(AgLr&rIRd5#jcH**<(=^ZK-VJ_!E= zw-M7yac+1S1|CXvSr8tEQW%DF%ftJlSg@3${p4%r14)3rMMHH4k;lsEKN_#QlbIMDVid_SHkaDu1A)PaFfA*M7u zV3?rKy=S@rD$tFG;!U|2gJ@OH1QR|M2?u9Td($Jd5nGk)B$FJi!ja2TOk%Rw(amI| zrwmc5srii!n&j4fP4j5o8$L9Z3Na6{J7|C@gyc$xnBKsA7#@`)Or=7Kg@IZ5rdL35 znKMk-Vxs>(nrG^bfr{IG^ea;kCQU?dOHDq6qAE-`r~n!^oB9#Abf>9?xJmm>orybF zW3m$p{@GN7h`)C7zft_vBqQ$mZBrB=F7yvmE&PBMdN!KY(U?b;Oak&m`7vg4v%O@ z=-QZwv4loWjF>{`>5OKJO48%>+}<4RnH}-y?2xbb_{qNJBgigx(^5 zV5B}A5SG84Gb3Z5z6&Y))#}KlSX%KMZQdQ(gQW(avypg(!MP&;7wL&Xjylp_^WCp= zvO)e)BeB3h$-5jKby2uu!4>#;a#RD$e5du0{`jiCP1ZgkJmZT9iS!JHRRU{XtX% z1{s?0=aZ;fETM2zFS zV73acj(O6YS@_>39gFz`BAE+47t;%i25Mhe7t=^#QT|s?b%6wn{VD96=gKj52otj$1p~>`R|7 z6quWYc!GrZzc0-PFcxs8>gDDK0tf0&erLXh9IoroHnX*P*L0lZC-V<1crTnZ2SGe= zk8hZJQ3MXUZ%(1r?tNiCPeyDKS+=t!<@s8Kbci#Xu*4gPzqHmEW*svw=RG;2rX&|_lu`2rpgbBU5QiiOItxAC*F%4Nh00ekM$st+}^P=;#Lfa z{T1Z6iKAo3!Dq~q|4xdnP38giG-Y>o#h!37$9KneU^hqo_1Kr}g8AO7*djg1VEw66 z+g4#8hv=Jl+Y)TE&>vkhY(vokOi2eu*{VPc6HD=ETQ0Ui*dqDm*cM^Kg#Fn5u{Pmp z3sKfYTZ=1r<#gM2JcpRBzp#CVJuN2Rz@@f$JdB8P%WWeFHEggI5Sp{Y_5q;>du_7` z71r415DGtM%O$k^T1z?qd$wfaraZJQCKUS8R!Hbr>$rn}aLd1y#$`8etd29ZiTe=} zIu^bco#V%!4haXTxy$0dC93n5h#>v)Wp8~$xpq9>pwDlxXP eV8ewGSeMeKHMozf@6!hVvP-xD6bxunEBb%Yn<>L`~ z)w&7$T#$Q8WGL<0DL^1*^i1OkCgC-(9H6K;SYP_*kV9IRNNLgZmHcixnZC4l{#hy0 zQ^G*2<$p*7(6HzwnD|PQzO=)(dj5=2=BxFk-|c&$asimWlj$*r&=H84K z%sF>ALiil;*jxCV`07tVuHJ_>?E3lAj%;X->(tv6sWNqMIDLybEhaDlE{GFgsv_hOLfWd3|br3qa zQ4A0B9vfX!9clORcJtiT!{Yf&2ajf+77rjKx+I2gd9Lt=_&4Ha-xc@q>|OR)ynub? z7QGVRa(}7g=6w`jOLu+iGDydLonA9O!2>R=t{K{Zt$%i*ro6uA+fbicN8>!;Lqe^r zmL9M$yVm!OJ)mn@Eorg`WWTLtZsP&vExi8M-UE)z^$JSyfLFhJ<+t#FZ-Z;kYV83@ z{cHdHi3fyks69jgMGtE$1l4Ebz5f+tu1xUGZs?KuqQrY{Qx6D!;ytIi2kf`|jBe%u zDIf<-d}_1qe@?;(YNrdoV0tXuKi;Y8oRl?+w5 zdN6mSy|06hhciUaDZBZ;2o^YFrtbsRp$c*t7d6)RHgT4@zEj-YOUE5t?7O0qYaxP^ zRpC3z%%oU9O-6#v98nb2Zi{|rJwX8$WdNJ_uv{@y{%zr0)z z|2&+6&1mlOm;Sxj#<){(?eqN4V827QSUp#7t-mpVaacL7)W0^gAT3w?;=fkTI1J;S zSN-iQNzoD4-Sc1R%P8dGXHWgRpgw?3zV^4(_ACte;O`Vtbg-9f1};ZP(VE_}>%xVI ztCGkrxZSDe9?4`|1r=p#*;{r!;#@|JL5X6UB(tn7`mE&Y7jN)8UBgxn^Gi3aI4<;1Pmidvf=NHL>=pbGNG8u94Yh|&-<$N!55ckV= z*<(87TXaj-nIt|ukadFu z65)%-va=NJzOQ5>U25%9CLQwEeD;*Ale7(aAd!l^QO;?Y^4pxj`m*3Zq=R>bPH`Y;GKV0kWr3S=K9Zv+kj%gdBMV08f{bEnHy!WEw@pCNyah4AL-Joy+_cx+)o zpLOy_!e(jf<@v~Vl$~F(e4$C;_MMXNqqZn+bk_M;lukZzjLpJ$R@ex;kOwP}8 z6!+Mq;ga$dOZ}K~1pmcy#T6_9`lm=yBqYzqEeg*C*uc%&t>`PHf7yOT9%amiql(5T z5m&}sM%0ixm(D5plm(LhuK1f0!SA{v6A0Y0TZ$iu`|OTl7I7aQC@v6s{I6mj?XdEN z;vjJo-YDJ@n*UxgoseCu{1gbeu)4PL5JCr(BT-fm%9bfF63SF5{|5v+#|0^Cl9pv! zWfgHd3`%~oK<68yas_4L_6X&2LW85KqadprA)Kdd$|(pnw4^syhCmL*SJ+g^&sf;f zpr!IK<4}A-t(8eg9t1HfMVZZ_!#(S&+<=%N9ZLHuw*g_%)HG!&LI~7(gmMod<2dDd zLVxEdj}tmELwSnOj=9P=gpMsy@{I)hl@uy{Y4FyfrMl`7t{%oqcg z_LDM!xV=ZKBiXM?{I_`&N991` zK6tBA2~AU|RuXEUQDqR?7q03+$Q+|uOXx4Bihsz2ol6_5;)ttAR`I)oEAF6rNPgMT zUBypCaLxNy-(gd_sugLGj#Bj|lsjIQohZzHF9CLkklYsD=>wsX+B3p~Y)e z!w6|Msj3axtP&OfwgDS-+NUaGE73l~kEljYWc>uqYHQI&NyGfU!}GLU)o+ z2q+C?2z~JO+<>OI#6YZZQ9wGo*F)p}l7I(v6FPDx;JKjj!mWT4xUxY9R~7IxyYWM6 zi7apv?m^hBPgLM$));vc69Yw1h`m~L4IIO_Ja+p(*Dvr5o+xn9x;HX#6T9JYuAaG* zy&{49fJK4MQ7*ubne86~z4@|a7xRlEwHdXCl2!YtebE$PUlXZ%UL=!4$=-LWZ!pfK zQqNU1P>1uC!;GlYOg$M3Vf(&x^=6m^G=02!9&75H3mwPv4RpUOR439LNZFx&4-UOP zQX|5|EkOBX=GfL`YRwrStSj6f|WpFnjj^iPL`mi7$WD> zH3n{rGiVatC!v|NY!h!zm$h+9+dI zh!5KcY4pvikS~x%h`VN8NCG<=l6K_IkT>uFJTl{SNIi>-;-~)QXCX~sEJ7RSrMW?- zM{6`YaHRnEDoT?i?AD`+Moc-7)lQ=kj<&V0#>8yoTnX`%#BXJ3IwBJ>!rJF)Hn9N; z)0J~I16T@iqYE^R;RmcawMEmFW?7?Mnj^?F#9sHaW(o{NJ(XS1+~jMGMWf_*%_SxW z-Ro~^#*>nSJDLl8t+9oXk2J4|Yw|+Vo48&7X|#kMinMJAb@tWPC$vtXoj@odM4LnC zT$uJNLZc$Joe5pHYu6DfY@n?+Y5O(PVsP^@s%)(tPAeyO)K;6ci+gBK5I3Q}b}ga$ z>D6sHJ3>33xa@J-3_>4rs&kuXXjc=LHdniekadZ62%(*;v>c(C>#CpOlg--w#D(wD z781I)S9^p|`62C0LIZx$P9pU3oc3EnJFjTV3C+2!y+tVRL3M86Q|(6LBHn115xVkG zi&xCNcQ1MCs@+u%%5{Iy%7ekxxvgQk7mVXvw}mWJC<>#VLl;bFSfXwk5c;7{k}j6G zuI+UE+e_r|(JneoH|cZK+`|bTY=EUPcPFyiewzn<^B3K ztlU_o7c}c)t<4pj)E{;~BRG?kghLMMhW4j$3{8QKeN3g=w-AoK*^ zU0Km(eF(h_kKoipy$w;Qc*t$n8U6=3=;SPhnM^0@xKDFKCE^0H5p4{^+)r(K?nQq? z5u?{ zMtRgb&(`Uk!4sr_( z;a6}l95c@z{*1INOAb$l9Jp8A!(Wn4-^_4ttmIQ=T6llY^Deh>Rrq1y0JHuIk89*P zz(u|Bc{DQwqx0`ijBW6C3Wl^DY`npS5P#`uIoeo7Pi*}r7`LKjV>3&RF_FcSugJ-Z zjN6a~ICz`Y#)}v=D2&9-Mt(vewVVfxpR&mYU#_`gEDZI4UayRQBl3t~Z>>qkc5|)M zbBjVvd ztjsT*X~;HlGyi-TcNEX8h{Lb*VCUg*CAKP(Xwl;~m*iX^EHw1n10c6w!;F z3jzDsE@C9Sh;+!$j3_|*L9F?#2s6ZxjJc~KdLS;asq%-27Vsj{qwBVae~^qopOr+M z;&1iL!ld01yWMY@^jyHc2nD(jj+t~QqRO3cdam!Sh%#17a8BIIh;kGb*7-;+jR_5^ zW9iJwjM-oCYdyjVw=KAy8T~ivpztdlx5L#ANTT z))t3QW@RZBytIQ+;!c(sbmsNlEz7YR{L!nYrH&xQE$eG}kKK?OI|o{pp*XQJb-d*r zICyn(wgtCaz7O@DVd=p4efDzp@H|T>Yoc7ma!WM2DW0-p)>^L8NDSX(`4k+~E!br_ zO5EsjOLOAR9?4?cjiXDlO}1<;nM!HVkn}@5nLq zb&(?S2NFrwM)G%cC{UUs-_XiPd*lFGxjrHC1aY&IB8L(uONl&3TvhkTA%t=VL^dRJ zWk}>OLIX!fW)XUx?Y0c=D*HOJ8RJk2%K4GL4pi@=UBYN2G z9TYtfGXyIy$3$O1=AdwoB}G3#<%2u@Y4kHpBGl@&!O`_uQFF>M(KfUdDDO8VT0~tT zXK6IwkfGrC+UQ4kmV+zKl}1aEdf?vfk3KIvkUTgS{T-4D@!N1U+Q|AJO5)Bx(GNhu zh=hdJ&UBgXhA>n4`kr*3h0qAgjMg9N+Vi{3x)v0UytI*Zp8JyJ znk`+dM_Ic-*9z-qjbg_~Skt>%ecTS!arvp%U-&V?u1BNutTz!pEFAHjwJVH=_8Z%+ zF>n@onE8q6X*ISy$8n7=cyx%r9ka5TqO`q6E(l%glYzu+9Ck z3%g{HJH+4s$${9-l+71T#_EwD z;QVgH+9)r3-HS~Yj{M`B*z;s$vBDYCC7s=35Y(HyO_>nYG%%=QUF zSX$J#=aST|rgo*EP}bSr1Qa4Rw3q#BK}s^z-k79PzqJ1s#U8vA2M-xhd8-F74(h!gQUJmjr-J1 z>A1IJ;!Y*;8|w;g?~Xg^`po~deSA+`BlfV#Bg3`0HyBK~gVcK$H^;y@-1Dw$9EJR2 z1{+gL>pK>(YZ%{-lDawic{VH9H`uX@G3YV*sg6wkp2XhP24pzqu#N)<>>K8o%j^Y6 z9qq8=T<9=6CONjF-1s*BwPPy!4Y=Tij{4w$hOcrABy@j+BZtseI~?r^J=p7*Mrh_y zM=l}rZ;nicxJ6eT8T7UKjw6ZCxW|t9gzCI?|49Uf5H65-{cw&ir)eba^kV^*ea^t(8bA!uW62FGHW<~Mw zjN?X^#`CX?ky29+#it1(WtZYNlEm?f_*DYMO|6VS2o4tZ6FZl%{N-GKuQv^bL)-i? zXAd$?6z|+X+>xfv)r{i?b#}g^ue19(-EYjlT{o+E~gX3$G{Ft%;ywj#PE5i@yuRx=B6jo)-Nd-4+6X From 5bf52335be7a4c1ece6d3aa6cf27af011dedda97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 11:59:24 +0100 Subject: [PATCH 08/12] Add no_duration_filesize in test scripts --- test/membrane_rtmp_plugin/rtmp_source_bin_test.exs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/membrane_rtmp_plugin/rtmp_source_bin_test.exs b/test/membrane_rtmp_plugin/rtmp_source_bin_test.exs index c05201d1..0325d846 100644 --- a/test/membrane_rtmp_plugin/rtmp_source_bin_test.exs +++ b/test/membrane_rtmp_plugin/rtmp_source_bin_test.exs @@ -276,6 +276,12 @@ defmodule Membrane.RTMP.SourceBin.IntegrationTest do use FFmpex.Options Logger.debug("Starting ffmpeg") + flv_flag = %FFmpex.Option{ + name: "-flvflags", + argument: "no_duration_filesize", + contexts: [:output] + } + command = FFmpex.new_command() |> add_global_option(option_y()) @@ -283,6 +289,7 @@ defmodule Membrane.RTMP.SourceBin.IntegrationTest do |> add_file_option(option_re()) |> add_output_file(stream_url) |> add_file_option(option_f("flv")) + |> add_file_option(flv_flag) |> add_file_option(option_vcodec("copy")) |> add_file_option(option_acodec("copy")) |> maybe_add_file_timestamps_offset(opts) From 63a08c5a2b8285df498a210ab4b86ddd5c828a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 14:01:05 +0100 Subject: [PATCH 09/12] Make socket_module/1 work with new OTP --- lib/membrane_rtmp_plugin/rtmp/message_handler.ex | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/membrane_rtmp_plugin/rtmp/message_handler.ex b/lib/membrane_rtmp_plugin/rtmp/message_handler.ex index 58759af2..d87b160c 100644 --- a/lib/membrane_rtmp_plugin/rtmp/message_handler.ex +++ b/lib/membrane_rtmp_plugin/rtmp/message_handler.ex @@ -340,6 +340,11 @@ defmodule Membrane.RTMP.MessageHandler do end @compile {:inline, socket_module: 1} - defp socket_module({:sslsocket, _1, _2}), do: :ssl - defp socket_module(_other), do: :gen_tcp + def socket_module(socket) when is_tuple(socket) and elem(socket, 0) == :sslsocket do + :ssl + end + + def socket_module(_socket) do + :gen_tcp + end end From bddcc27e83f07a5fcfb99bd6490337b5361b3370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 14:02:55 +0100 Subject: [PATCH 10/12] Make socket_module/1 private --- lib/membrane_rtmp_plugin/rtmp/message_handler.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/membrane_rtmp_plugin/rtmp/message_handler.ex b/lib/membrane_rtmp_plugin/rtmp/message_handler.ex index d87b160c..438a6790 100644 --- a/lib/membrane_rtmp_plugin/rtmp/message_handler.ex +++ b/lib/membrane_rtmp_plugin/rtmp/message_handler.ex @@ -340,11 +340,11 @@ defmodule Membrane.RTMP.MessageHandler do end @compile {:inline, socket_module: 1} - def socket_module(socket) when is_tuple(socket) and elem(socket, 0) == :sslsocket do + defp socket_module(socket) when is_tuple(socket) and elem(socket, 0) == :sslsocket do :ssl end - def socket_module(_socket) do + defp socket_module(_socket) do :gen_tcp end end From 2fd451c7be0ab5a12e2c311ff4aa16bc55edb1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Thu, 8 Jan 2026 14:06:49 +0100 Subject: [PATCH 11/12] Bump to v0.29.2 --- README.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aea37f5b..1554807e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The package can be installed by adding `membrane_rtmp_plugin` to your list of de ```elixir def deps do [ - {:membrane_rtmp_plugin, "~> 0.29.1"} + {:membrane_rtmp_plugin, "~> 0.29.2"} ] end ``` diff --git a/mix.exs b/mix.exs index 8f2249e2..1a599bd5 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule Membrane.RTMP.Mixfile do use Mix.Project - @version "0.29.1" + @version "0.29.2" @github_url "https://github.com/membraneframework/membrane_rtmp_plugin" def project do From c8a01aed58ca604e456cab2f61ffce8b81b7675b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Fri, 9 Jan 2026 10:54:17 +0100 Subject: [PATCH 12/12] Update lib/membrane_rtmp_plugin/rtmp/sink/sink.ex Co-authored-by: Mateusz Front --- lib/membrane_rtmp_plugin/rtmp/sink/sink.ex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex b/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex index b6536f82..2650cc5a 100644 --- a/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex +++ b/lib/membrane_rtmp_plugin/rtmp/sink/sink.ex @@ -75,8 +75,7 @@ defmodule Membrane.RTMP.Sink do options = %{options | tracks: Enum.uniq(options.tracks)} - unless options.tracks != [] and - Enum.all?(options.tracks, &Kernel.in(&1, [:audio, :video])) do + if Enum.any?(options.tracks, &(&1 not in [:audio, :video])) do raise ArgumentError, "All track have to be either :audio or :video" end