diff --git a/examples.livemd b/examples.livemd index 83c661d..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 @@ -509,7 +513,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 = diff --git a/test/browser_test.exs b/test/browser_test.exs index c2cf394..33d285a 100644 --- a/test/browser_test.exs +++ b/test/browser_test.exs @@ -150,6 +150,49 @@ defmodule Boombox.BrowserTest do end end + 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 0000000..205e83b Binary files /dev/null and b/test/fixtures/logo.png differ