From f2e30d0df2e96894199deb463a8512cfd79e1a35 Mon Sep 17 00:00:00 2001 From: "feliks.pobiedzinski@swmansion.com" Date: Thu, 20 Feb 2025 11:43:51 +0100 Subject: [PATCH 1/4] Bump WebRTC plugin --- examples.livemd | 2 +- lib/boombox.ex | 4 ++-- lib/boombox/webrtc.ex | 10 +++++----- mix.exs | 3 +-- mix.lock | 22 +++++++++++----------- test/boombox_test.exs | 18 +++++++++--------- 6 files changed, 29 insertions(+), 30 deletions(-) diff --git a/examples.livemd b/examples.livemd index 83c661d..b55b691 100644 --- a/examples.livemd +++ b/examples.livemd @@ -509,7 +509,7 @@ System.shell("ffplay #{out_dir}/rtmp_to_mp4.mp4") ## Stream MP4 via WebRTC, receive it and record to MP4 again ```elixir -signaling = Membrane.WebRTC.SignalingChannel.new() +signaling = Membrane.WebRTC.Signaling.new() t = Task.async(fn -> diff --git a/lib/boombox.ex b/lib/boombox.ex index c987219..bc0769b 100644 --- a/lib/boombox.ex +++ b/lib/boombox.ex @@ -8,7 +8,7 @@ defmodule Boombox do alias Membrane.RTP - @type webrtc_signaling :: Membrane.WebRTC.SignalingChannel.t() | String.t() + @type webrtc_signaling :: Membrane.WebRTC.Signaling.t() | String.t() @type in_stream_opts :: [ {:audio, :binary | boolean()} | {:video, :image | boolean()} @@ -186,7 +186,7 @@ defmodule Boombox do {:mp4, location} when is_binary(location) and direction == :output -> {:mp4, location} - {:webrtc, %Membrane.WebRTC.SignalingChannel{}} -> + {:webrtc, %Membrane.WebRTC.Signaling{}} -> value {:webrtc, uri} when is_binary(uri) -> diff --git a/lib/boombox/webrtc.ex b/lib/boombox/webrtc.ex index d6b58c4..463d01e 100644 --- a/lib/boombox/webrtc.ex +++ b/lib/boombox/webrtc.ex @@ -89,8 +89,8 @@ defmodule Boombox.WebRTC do if webrtc_input?(state) do # let's spawn websocket server for webrtc source before the source starts {:webrtc, input_signaling} = state.input - signaling_channel = resolve_signaling(input_signaling, :input, ctx.utility_supervisor) - state = %{state | input: {:webrtc, signaling_channel}} + signaling = resolve_signaling(input_signaling, :input, ctx.utility_supervisor) + state = %{state | input: {:webrtc, signaling}} {%Wait{actions: [spec: spec]}, state} else @@ -188,7 +188,7 @@ defmodule Boombox.WebRTC do end defp resolve_signaling( - %WebRTC.SignalingChannel{} = signaling, + %WebRTC.Signaling{} = signaling, _direction, _utility_supervisor ) do @@ -202,7 +202,7 @@ defmodule Boombox.WebRTC do end defp resolve_signaling({:whip, uri, opts}, :output, utility_supervisor) do - signaling = WebRTC.SignalingChannel.new() + signaling = WebRTC.Signaling.new() Membrane.UtilitySupervisor.start_link_child( utility_supervisor, @@ -221,7 +221,7 @@ defmodule Boombox.WebRTC do end defp setup_whip_server(opts, utility_supervisor) do - signaling = WebRTC.SignalingChannel.new() + signaling = WebRTC.Signaling.new() clients_cnt = :atomics.new(1, []) {valid_token, opts} = Keyword.pop(opts, :token) diff --git a/mix.exs b/mix.exs index 1cc0c8e..20504fa 100644 --- a/mix.exs +++ b/mix.exs @@ -48,8 +48,7 @@ defmodule Boombox.Mixfile do [ {:membrane_core, "~> 1.1"}, {:membrane_transcoder_plugin, "~> 0.1.2"}, - # {:membrane_webrtc_plugin, "~> 0.23.2"}, - {:membrane_webrtc_plugin, github: "membraneframework/membrane_webrtc_plugin"}, + {:membrane_webrtc_plugin, "~> 0.24.0"}, {:membrane_mp4_plugin, "~> 0.35.2"}, {:membrane_realtimer_plugin, "~> 0.9.0"}, {:membrane_http_adaptive_stream_plugin, "~> 0.18.5"}, diff --git a/mix.lock b/mix.lock index 6368563..ba102b2 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "bandit": {:hex, :bandit, "1.6.6", "f2019a95261d400579075df5bc15641ba8e446cc4777ede6b4ec19e434c3340d", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "ceb19bf154bc2c07ee0c9addf407d817c48107e36a66351500846fc325451bf9"}, + "bandit": {:hex, :bandit, "1.6.7", "42f30e37a1c89a2a12943c5dca76f731a2313e8a2e21c1a95dc8241893e922d1", [:mix], [{:hpax, "~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "551ba8ff5e4fc908cbeb8c9f0697775fb6813a96d9de5f7fe02e34e76fd7d184"}, "bimap": {:hex, :bimap, "1.3.0", "3ea4832e58dc83a9b5b407c6731e7bae87458aa618e6d11d8e12114a17afa4b3", [:mix], [], "hexpm", "bf5a2b078528465aa705f405a5c638becd63e41d280ada41e0f77e6d255a10b4"}, "bunch": {:hex, :bunch, "1.6.1", "5393d827a64d5f846092703441ea50e65bc09f37fd8e320878f13e63d410aec7", [:mix], [], "hexpm", "286cc3add551628b30605efbe2fca4e38cc1bea89bcd0a1a7226920b3364fe4a"}, "bunch_native": {:hex, :bunch_native, "0.5.0", "8ac1536789a597599c10b652e0b526d8833348c19e4739a0759a2bedfd924e63", [:mix], [{:bundlex, "~> 1.0", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm", "24190c760e32b23b36edeb2dc4852515c7c5b3b8675b1a864e0715bdd1c8f80d"}, @@ -15,21 +15,21 @@ "crc": {:hex, :crc, "0.10.5", "ee12a7c056ac498ef2ea985ecdc9fa53c1bfb4e53a484d9f17ff94803707dfd8", [:mix, :rebar3], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3e673b6495a9525c5c641585af1accba59a1eb33de697bedf341e247012c2c7f"}, "credo": {:hex, :credo, "1.7.11", "d3e805f7ddf6c9c854fd36f089649d7cf6ba74c42bc3795d587814e3c9847102", [: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", "56826b4306843253a66e47ae45e98e7d284ee1f95d53d1612bb483f88a8cf219"}, "dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.42", "f23d856f41919f17cd06a493923a722d87a2d684f143a1e663c04a2b93100682", [:mix], [], "hexpm", "6915b6ca369b5f7346636a2f41c6a6d78b5af419d61a611079189233358b8b8b"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.43", "34b2f401fe473080e39ff2b90feb8ddfeef7639f8ee0bbf71bb41911831d77c5", [:mix], [], "hexpm", "970a3cd19503f5e8e527a190662be2cee5d98eed1ff72ed9b3d1a3d466692de8"}, "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "esbuild": {:hex, :esbuild, "0.8.2", "5f379dfa383ef482b738e7771daf238b2d1cfb0222bef9d3b20d4c8f06c7a7ac", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "558a8a08ed78eb820efbfda1de196569d8bfa9b51e8371a1934fbb31345feda7"}, - "ex_doc": {:hex, :ex_doc, "0.36.1", "4197d034f93e0b89ec79fac56e226107824adcce8d2dd0a26f5ed3a95efc36b1", [:mix], [{:earmark_parser, "~> 1.4.42", [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", "d7d26a7cf965dacadcd48f9fa7b5953d7d0cfa3b44fa7a65514427da44eafd89"}, - "ex_dtls": {:hex, :ex_dtls, "0.15.2", "6c8c0f8eb67525216551bd3e0322ab33c9d851d56ef3e065efab4fd277a8fbb9", [:mix], [{:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "6b852bc926bbdc9c1b9c4ecc6cfc73a89d4e106042802cefea2c1503072a9f2a"}, - "ex_ice": {:hex, :ex_ice, "0.8.5", "65de6fa7516f767a8eef4145d66cbd1ed0af10999ecfd1e4c698e90d3c2b7f86", [:mix], [{:elixir_uuid, "~> 1.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}, {:ex_turn, "~> 0.1.0", [hex: :ex_turn, repo: "hexpm", optional: false]}], "hexpm", "cc52cdf531288959dc8a4353602079188d88319fe1635ea1619fa612d31b8b3b"}, + "ex_doc": {:hex, :ex_doc, "0.37.2", "2a3aa7014094f0e4e286a82aa5194a34dd17057160988b8509b15aa6c292720c", [:mix], [{:earmark_parser, "~> 1.4.42", [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", "4dfa56075ce4887e4e8b1dcc121cd5fcb0f02b00391fd367ff5336d98fa49049"}, + "ex_dtls": {:hex, :ex_dtls, "0.16.0", "3ae38025ccc77f6db573e2e391602fa9bbc02253c137d8d2d59469a66cbe806b", [:mix], [{:bundlex, "~> 1.5.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:unifex, "~> 1.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2a4e30d74c6ddf95cc5b796423293c06a0da295454c3823819808ff031b4b361"}, + "ex_ice": {:hex, :ex_ice, "0.9.4", "793121989164e49d8dc64b82bcb7842a4c2e0d224a2f00379ab415293a78c8e7", [:mix], [{:elixir_uuid, "~> 1.0", [hex: :elixir_uuid, repo: "hexpm", optional: false]}, {:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}, {:ex_turn, "~> 0.2.0", [hex: :ex_turn, repo: "hexpm", optional: false]}], "hexpm", "fc328ed721c558440266def81a2cd5138d163164218ebe449fa9a10fcda72574"}, "ex_libsrtp": {:hex, :ex_libsrtp, "0.7.2", "211bd89c08026943ce71f3e2c0231795b99cee748808ed3ae7b97cd8d2450b6b", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_precompiled_dependency_provider, "~> 0.1.0", [hex: :membrane_precompiled_dependency_provider, repo: "hexpm", optional: false]}, {:unifex, "~> 1.1", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "2e20645d0d739a4ecdcf8d4810a0c198120c8a2f617f2b75b2e2e704d59f492a"}, "ex_rtcp": {:hex, :ex_rtcp, "0.4.0", "f9e515462a9581798ff6413583a25174cfd2101c94a2ebee871cca7639886f0a", [:mix], [], "hexpm", "28956602cf210d692fcdaf3f60ca49681634e1deb28ace41246aee61ee22dc3b"}, "ex_rtp": {:hex, :ex_rtp, "0.4.0", "1f1b5c1440a904706011e3afbb41741f5da309ce251cb986690ce9fd82636658", [:mix], [], "hexpm", "0f72d80d5953a62057270040f0f1ee6f955c08eeae82ac659c038001d7d5a790"}, "ex_sdp": {:hex, :ex_sdp, "1.1.1", "1a7b049491e5ec02dad9251c53d960835dc5631321ae978ec331831f3e4f6d5f", [:mix], [{:bunch, "~> 1.3", [hex: :bunch, repo: "hexpm", optional: false]}, {:elixir_uuid, "~> 1.2", [hex: :elixir_uuid, repo: "hexpm", optional: false]}], "hexpm", "1b13a72ac9c5c695b8824dbdffc671be8cbb4c0d1ccb4ff76a04a6826759f233"}, "ex_stun": {:hex, :ex_stun, "0.2.0", "feb1fc7db0356406655b2a617805e6c712b93308c8ea2bf0ba1197b1f0866deb", [:mix], [], "hexpm", "1e01ba8290082ccbf37acaa5190d1f69b51edd6de2026a8d6d51368b29d115d0"}, - "ex_turn": {:hex, :ex_turn, "0.1.1", "e796b6c27aaf39e24ab9bad2044b426ed41ecc5ee8515087fe64f8ec9967e41b", [:mix], [{:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}], "hexpm", "832f2bba6f200a859e14cb8658b0932f841b0cf290491cca10cccf5367152547"}, - "ex_webrtc": {:hex, :ex_webrtc, "0.4.1", "834054e38630f91a1c62e5d77ecf3394c0be64e9fd94be45e3021ea53baef6f9", [:mix], [{:crc, "~> 0.10", [hex: :crc, repo: "hexpm", optional: false]}, {:ex_dtls, "~> 0.15.0", [hex: :ex_dtls, repo: "hexpm", optional: false]}, {:ex_ice, "~> 0.8.0", [hex: :ex_ice, repo: "hexpm", optional: false]}, {:ex_libsrtp, "~> 0.7.1", [hex: :ex_libsrtp, repo: "hexpm", optional: false]}, {:ex_rtcp, "~> 0.4.0", [hex: :ex_rtcp, repo: "hexpm", optional: false]}, {:ex_rtp, "~> 0.4.0", [hex: :ex_rtp, repo: "hexpm", optional: false]}, {:ex_sdp, "~> 1.0", [hex: :ex_sdp, repo: "hexpm", optional: false]}], "hexpm", "be81984cf1624ccd1b50fa257558829db967764786e47ecc3da0cacbdcf1448d"}, + "ex_turn": {:hex, :ex_turn, "0.2.0", "4e1f9b089e9a5ee44928d12370cc9ea7a89b84b2f6256832de65271212eb80de", [:mix], [{:ex_stun, "~> 0.2.0", [hex: :ex_stun, repo: "hexpm", optional: false]}], "hexpm", "08e884f0af2c4a147e3f8cd4ffe33e3452a256389f0956e55a8c4d75bf0e74cd"}, + "ex_webrtc": {:hex, :ex_webrtc, "0.8.1", "e507d1b3d89e9c8b74e3fef5f4070d57e20a3f77061b7439b1af1877d6577793", [:mix], [{:crc, "~> 0.10", [hex: :crc, repo: "hexpm", optional: false]}, {:ex_dtls, "~> 0.16.0", [hex: :ex_dtls, repo: "hexpm", optional: false]}, {:ex_ice, "~> 0.9.0", [hex: :ex_ice, repo: "hexpm", optional: false]}, {:ex_libsrtp, "~> 0.7.1", [hex: :ex_libsrtp, repo: "hexpm", optional: false]}, {:ex_rtcp, "~> 0.4.0", [hex: :ex_rtcp, repo: "hexpm", optional: false]}, {:ex_rtp, "~> 0.4.0", [hex: :ex_rtp, repo: "hexpm", optional: false]}, {:ex_sctp, "0.1.2", [hex: :ex_sctp, repo: "hexpm", optional: true]}, {:ex_sdp, "~> 1.0", [hex: :ex_sdp, repo: "hexpm", optional: false]}], "hexpm", "2c5563cdaf998b5beed3c79b0feeaa1430f30118b21ab59dd18289d72177adf0"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [: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", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "gun": {:hex, :gun, "1.3.3", "cf8b51beb36c22b9c8df1921e3f2bc4d2b1f68b49ad4fbc64e91875aa14e16b4", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "3106ce167f9c9723f849e4fb54ea4a4d814e3996ae243a1c828b256e749041e0"}, @@ -42,7 +42,7 @@ "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, - "makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, "membrane_aac_fdk_plugin": {:hex, :membrane_aac_fdk_plugin, "0.18.11", "6bdcde2eaeafcce136f21fb17effdcdaf9c73107771c8d2a661ca5d0b616ea12", [:mix], [{:bunch, "~> 1.4", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 1.3", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_aac_format, "~> 0.8.0", [hex: :membrane_aac_format, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.16.0", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [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_audio_format, "~> 0.12.0", [hex: :membrane_raw_audio_format, repo: "hexpm", optional: false]}, {:unifex, "~> 1.1", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "dac3f0c839f33603dc2fdad8b9fbebd5ca578c9ca28ea65249ebb15c96c0fd31"}, "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.0", "58a15efaaa4f2cc91b968464cfd269244e035efdd983aac2e3ddeb176fcf0585", [: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", "eb7e786e650608ee205f4eebff4c1df3677e545acf09802458f77f64f9942fe9"}, @@ -89,11 +89,11 @@ "membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"}, "membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"}, "membrane_vpx_plugin": {:hex, :membrane_vpx_plugin, "0.3.0", "60404d1b1511b4c62ba6bbf7b6212570f1732ba477015c4072e0aa33e18a8809", [:mix], [{:membrane_core, "~> 1.0", [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.4.0", [hex: :membrane_raw_video_format, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vp9_format, "~> 0.5.0", [hex: :membrane_vp9_format, repo: "hexpm", optional: false]}, {:unifex, "~> 1.2", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm", "effa7762bbf73efd8d21d0978bce79538414719284194db97672afbce665b56a"}, - "membrane_webrtc_plugin": {:git, "https://github.com/membraneframework/membrane_webrtc_plugin.git", "8c1567c212f6ce4dfb06b6d5ed183b37d435336f", []}, + "membrane_webrtc_plugin": {:hex, :membrane_webrtc_plugin, "0.24.0", "20606f4f7082690598f2f30e0097f7708f46098b2d84cc8f98977e4341e510c1", [:mix], [{:bandit, "~> 1.2", [hex: :bandit, repo: "hexpm", optional: false]}, {:corsica, "~> 2.0", [hex: :corsica, repo: "hexpm", optional: false]}, {:ex_webrtc, "~> 0.8.0", [hex: :ex_webrtc, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.1", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_rtp_h264_plugin, "~> 0.20.1", [hex: :membrane_rtp_h264_plugin, repo: "hexpm", optional: false]}, {:membrane_rtp_opus_plugin, "~> 0.10.0", [hex: :membrane_rtp_opus_plugin, repo: "hexpm", optional: false]}, {:membrane_rtp_plugin, "~> 0.30.0", [hex: :membrane_rtp_plugin, repo: "hexpm", optional: false]}, {:membrane_rtp_vp8_plugin, "~> 0.9.4", [hex: :membrane_rtp_vp8_plugin, repo: "hexpm", optional: false]}, {:membrane_timestamp_queue, "~> 0.2.0", [hex: :membrane_timestamp_queue, repo: "hexpm", optional: false]}, {:req, "~> 0.5", [hex: :req, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.0", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "25e88a0d7ce8298dcf8cd1155d77efc55fffb20d0ae844cd80b20300d1875d04"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, - "mint": {:hex, :mint, "1.6.2", "af6d97a4051eee4f05b5500671d47c3a67dac7386045d87a904126fd4bbcea2e", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "5ee441dffc1892f1ae59127f74afe8fd82fda6587794278d924e4d90ea3d63f9"}, + "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "mockery": {:hex, :mockery, "2.3.3", "3dba87bd0422a513e6af6e0d811383f38f82ac6be5d3d285a5fcca9c299bd0ac", [:mix], [], "hexpm", "17282be00613286254298117cd25e607a39f15ac03b41c631f60e52f5b5ec974"}, "nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, @@ -113,7 +113,7 @@ "sweet_xml": {:hex, :sweet_xml, "0.7.5", "803a563113981aaac202a1dbd39771562d0ad31004ddbfc9b5090bdcd5605277", [:mix], [], "hexpm", "193b28a9b12891cae351d81a0cead165ffe67df1b73fe5866d10629f4faefb12"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "telemetry_metrics": {:hex, :telemetry_metrics, "1.1.0", "5bd5f3b5637e0abea0426b947e3ce5dd304f8b3bc6617039e2b5a008adc02f8f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e7b79e8ddfde70adb6db8a6623d1778ec66401f366e9a8f5dd0955c56bc8ce67"}, - "thousand_island": {:hex, :thousand_island, "1.3.9", "095db3e2650819443e33237891271943fad3b7f9ba341073947581362582ab5a", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "25ab4c07badadf7f87adb4ab414e0ed374e5f19e72503aa85132caa25776e54f"}, + "thousand_island": {:hex, :thousand_island, "1.3.10", "a9971ebab1dfb36e2710a86b37c3f54973fbc9470d892035334415521fb53328", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "17ab1f1b13aadb1f4b4c8e5b59c06874d701119fed082884c9c6d38addad254f"}, "typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, "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"}, diff --git a/test/boombox_test.exs b/test/boombox_test.exs index 47aa5df..035d3ab 100644 --- a/test/boombox_test.exs +++ b/test/boombox_test.exs @@ -66,7 +66,7 @@ defmodule BoomboxTest do @tag :file_webrtc async_test "mp4 file -> webrtc -> mp4 file", %{tmp_dir: tmp} do output = Path.join(tmp, "output.mp4") - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() t = Task.async(fn -> Boombox.run(input: @bbb_mp4, output: {:webrtc, signaling}) end) Boombox.run(input: {:webrtc, signaling}, output: output) Task.await(t) @@ -90,7 +90,7 @@ defmodule BoomboxTest do @tag :http_webrtc async_test "http mp4 -> webrtc -> mp4 file", %{tmp_dir: tmp} do output = Path.join(tmp, "output.mp4") - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() t = Task.async(fn -> Boombox.run(input: @bbb_mp4_url, output: {:webrtc, signaling}) end) Boombox.run(input: {:webrtc, signaling}, output: output) Task.await(t) @@ -100,7 +100,7 @@ defmodule BoomboxTest do @tag :webrtc_audio async_test "mp4 -> webrtc -> mp4 audio", %{tmp_dir: tmp} do output = Path.join(tmp, "output.mp4") - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() t = Task.async(fn -> Boombox.run(input: @bbb_mp4_a, output: {:webrtc, signaling}) end) @@ -113,7 +113,7 @@ defmodule BoomboxTest do @tag :webrtc_video async_test "mp4 -> webrtc -> mp4 video", %{tmp_dir: tmp} do output = Path.join(tmp, "output.mp4") - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() t = Task.async(fn -> Boombox.run(input: @bbb_mp4_v, output: {:webrtc, signaling}) end) @@ -126,8 +126,8 @@ defmodule BoomboxTest do @tag :webrtc2 async_test "mp4 -> webrtc -> webrtc -> mp4", %{tmp_dir: tmp} do output = Path.join(tmp, "output.mp4") - signaling1 = Membrane.WebRTC.SignalingChannel.new() - signaling2 = Membrane.WebRTC.SignalingChannel.new() + signaling1 = Membrane.WebRTC.Signaling.new() + signaling2 = Membrane.WebRTC.Signaling.new() t1 = Task.async(fn -> Boombox.run(input: @bbb_mp4, output: {:webrtc, signaling1}) end) @@ -198,7 +198,7 @@ defmodule BoomboxTest do async_test "rtmp -> webrtc -> mp4", %{tmp_dir: tmp} do output = Path.join(tmp, "output.mp4") url = "rtmp://localhost:5002/app/stream_key" - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() t1 = Task.async(fn -> Boombox.run(input: url, output: {:webrtc, signaling}) end) @@ -279,7 +279,7 @@ defmodule BoomboxTest do async_test "rtsp -> webrtc -> mp4", %{tmp_dir: tmp} do rtsp_port = 8556 output = Path.join(tmp, "output.mp4") - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() Membrane.SimpleRTSPServer.start_link(@bbb_mp4, port: rtsp_port) @@ -314,7 +314,7 @@ defmodule BoomboxTest do @tag :bouncing_bubble_webrtc_mp4 async_test "bouncing bubble -> webrtc -> mp4", %{tmp_dir: tmp} do - signaling = Membrane.WebRTC.SignalingChannel.new() + signaling = Membrane.WebRTC.Signaling.new() Task.async(fn -> overlay = From c86dea44e3bcab27b541418598f2fc49155fbe6f Mon Sep 17 00:00:00 2001 From: "feliks.pobiedzinski@swmansion.com" Date: Thu, 20 Feb 2025 12:14:34 +0100 Subject: [PATCH 2/4] Add bouncing logo test --- examples.livemd | 6 +++++- test/browser_test.exs | 44 +++++++++++++++++++++++++++++++++++++++++ test/fixtures/logo.png | Bin 0 -> 8857 bytes 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/logo.png diff --git a/examples.livemd b/examples.livemd index b55b691..f6d65db 100644 --- a/examples.livemd +++ b/examples.livemd @@ -12,6 +12,7 @@ System.put_env("PATH", "/opt/homebrew/bin:#{System.get_env("PATH")}") # MIX_INSTALL_CONFIG_BEGIN boombox = {:boombox, github: "membraneframework/boombox"} + # This livebook uses boombox from the master branch. If any examples happen to not work, the latest stable version of this livebook # can be found on https://hexdocs.pm/boombox/examples.html or in the latest github release. # MIX_INSTALL_CONFIG_END @@ -90,7 +91,10 @@ To send the stream, visit http://localhost:1234/whip.html. Note: don't stop this cell to finish recording - click 'disconnect' or close the browser tab instead, so the recording is finalized properly. ```elixir -Boombox.run(input: {:whip, "http://localhost:8829", token: "whip_it!"}, output: "#{out_dir}/webrtc_to_mp4.mp4") +Boombox.run( + input: {:whip, "http://localhost:8829", token: "whip_it!"}, + output: "#{out_dir}/webrtc_to_mp4.mp4" +) ``` ```elixir diff --git a/test/browser_test.exs b/test/browser_test.exs index c2cf394..82a1938 100644 --- a/test/browser_test.exs +++ b/test/browser_test.exs @@ -150,6 +150,50 @@ defmodule Boombox.BrowserTest do end end + @tag :xd + test "boombox -> browser (bouncing logo)", %{browser: browser} do + overlay = + __DIR__ + |> Path.join("fixtures/logo.png") + |> Image.open!() + + bg = Image.new!(640, 480, color: :light_gray) + max_x = Image.width(bg) - Image.width(overlay) + max_y = Image.height(bg) - Image.height(overlay) + + stream = + Stream.iterate({_x = 300, _y = 0, _dx = 1, _dy = 2, _pts = 0}, fn {x, y, dx, dy, pts} -> + dx = if (x + dx) in 0..max_x, do: dx, else: -dx + dy = if (y + dy) in 0..max_y, do: dy, else: -dy + pts = pts + div(Membrane.Time.seconds(1), _fps = 60) + {x + dx, y + dy, dx, dy, pts} + end) + |> Stream.map(fn {x, y, _dx, _dy, pts} -> + img = Image.compose!(bg, overlay, x: x, y: y) + %Boombox.Packet{kind: :video, payload: img, pts: pts} + end) + + boombox_task = + Task.async(fn -> + stream + |> Boombox.run( + input: {:stream, video: :image, audio: false}, + output: {:webrtc, "ws://localhost:8830"} + ) + end) + + page = start_page(browser, "webrtc_to_browser") + + seconds = 10 + Process.sleep(seconds * 1000) + + assert_page_connected(page) + assert_frames_decoded(page, seconds) + + close_page(page) + Task.shutdown(boombox_task) + end + defp start_page(browser, page) do url = "http://localhost:#{@port}/#{page}.html" do_start_page(browser, url) diff --git a/test/fixtures/logo.png b/test/fixtures/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..205e83be2c53826f7e9e9f8a2e5b0ff45e08e4ad GIT binary patch literal 8857 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 Date: Thu, 20 Feb 2025 12:20:15 +0100 Subject: [PATCH 3/4] mix format --- test/browser_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/browser_test.exs b/test/browser_test.exs index 82a1938..8378b41 100644 --- a/test/browser_test.exs +++ b/test/browser_test.exs @@ -151,7 +151,7 @@ defmodule Boombox.BrowserTest do end @tag :xd - test "boombox -> browser (bouncing logo)", %{browser: browser} do + test "boombox -> browser (bouncing logo)", %{browser: browser} do overlay = __DIR__ |> Path.join("fixtures/logo.png") From a376c5a94888585ca9539fb61090ef53cc479040 Mon Sep 17 00:00:00 2001 From: "feliks.pobiedzinski@swmansion.com" Date: Thu, 20 Feb 2025 12:33:18 +0100 Subject: [PATCH 4/4] Remove leftover --- test/browser_test.exs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/browser_test.exs b/test/browser_test.exs index 8378b41..33d285a 100644 --- a/test/browser_test.exs +++ b/test/browser_test.exs @@ -150,7 +150,6 @@ defmodule Boombox.BrowserTest do end end - @tag :xd test "boombox -> browser (bouncing logo)", %{browser: browser} do overlay = __DIR__