diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/additional_media.ex b/lib/membrane_rtmp_plugin/rtmp/messages/additional_media.ex index 58e0b2a3..b60b3872 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/additional_media.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/additional_media.ex @@ -13,8 +13,10 @@ defmodule Membrane.RTMP.Messages.AdditionalMedia do media: binary() } + @names ["additionalMedia", "@additionalMedia"] + @impl true - def from_data(["additionalMedia", %{"id" => id, "media" => media}]) do + def from_data([name, %{"id" => id, "media" => media}]) when name in @names do %__MODULE__{id: id, media: media} end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/anonymous.ex b/lib/membrane_rtmp_plugin/rtmp/messages/anonymous.ex index 4abd99ca..e57d13da 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/anonymous.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/anonymous.ex @@ -14,6 +14,11 @@ defmodule Membrane.RTMP.Messages.Anonymous do tx_id: non_neg_integer() | nil } + @impl true + def from_data(["@" <> event, properties]) do + from_data([event, properties]) + end + @impl true def from_data([name, tx_id | properties]) when is_binary(name) do %__MODULE__{name: name, tx_id: tx_id, properties: properties} diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/command/connect.ex b/lib/membrane_rtmp_plugin/rtmp/messages/command/connect.ex index 485da485..722223d9 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/command/connect.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/command/connect.ex @@ -52,10 +52,10 @@ defmodule Membrane.RTMP.Messages.Connect do @attributes_to_keys Map.new(@keys_to_attributes, fn {key, attribute} -> {attribute, key} end) - @name "connect" + @names ["connect", "@connect"] @impl true - def from_data([@name, tx_id, properties]) do + def from_data([name, tx_id, properties]) when name in @names do # We take keys according to RFC, but preserve all extra ones # https://github.com/melpon/rfc/blob/master/rtmp.md#7211-connect {rfc, extra} = Map.split(properties, Map.keys(@attributes_to_keys)) diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/command/create_stream.ex b/lib/membrane_rtmp_plugin/rtmp/messages/command/create_stream.ex index 95670655..5290f7a3 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/command/create_stream.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/command/create_stream.ex @@ -11,10 +11,10 @@ defmodule Membrane.RTMP.Messages.CreateStream do tx_id: non_neg_integer() } - @name "createStream" + @names ["createStream", "@createStream"] @impl true - def from_data([@name, tx_id, :null]) do + def from_data([name, tx_id, :null]) when name in @names do %__MODULE__{tx_id: tx_id} end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/command/delete_stream.ex b/lib/membrane_rtmp_plugin/rtmp/messages/command/delete_stream.ex index 560ad041..19b0f576 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/command/delete_stream.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/command/delete_stream.ex @@ -14,10 +14,10 @@ defmodule Membrane.RTMP.Messages.DeleteStream do stream_id: non_neg_integer() } - @name "deleteStream" + @names ["deleteStream", "@deleteStream"] @impl true - def from_data([@name, tx_id, :null, stream_id]) do + def from_data([name, tx_id, :null, stream_id]) when name in @names do %__MODULE__{tx_id: tx_id, stream_id: stream_id} end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/command/fc_publish.ex b/lib/membrane_rtmp_plugin/rtmp/messages/command/fc_publish.ex index 622a3f8c..75fa7ba3 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/command/fc_publish.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/command/fc_publish.ex @@ -13,10 +13,10 @@ defmodule Membrane.RTMP.Messages.FCPublish do tx_id: non_neg_integer() } - @name "FCPublish" + @names ["FCPublish", "@FCPublish"] @impl true - def from_data([@name, tx_id, :null, stream_key]) do + def from_data([name, tx_id, :null, stream_key]) when name in @names do %__MODULE__{tx_id: tx_id, stream_key: stream_key} end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/command/publish.ex b/lib/membrane_rtmp_plugin/rtmp/messages/command/publish.ex index fa9ec165..373897e7 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/command/publish.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/command/publish.ex @@ -17,14 +17,14 @@ defmodule Membrane.RTMP.Messages.Publish do tx_id: non_neg_integer() } - @name "publish" + @names ["publish", "@publish"] @impl true - def from_data([@name, tx_id, :null, stream_key, publish_type]) do + def from_data([name, tx_id, :null, stream_key, publish_type]) when name in @names do %__MODULE__{tx_id: tx_id, stream_key: stream_key, publish_type: publish_type} end - def from_data([@name, tx_id, :null, stream_key]) do + def from_data([name, tx_id, :null, stream_key]) when name in @names do %__MODULE__{tx_id: tx_id, stream_key: stream_key} end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/command/release_stream.ex b/lib/membrane_rtmp_plugin/rtmp/messages/command/release_stream.ex index 84db9f61..2db3f994 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/command/release_stream.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/command/release_stream.ex @@ -15,10 +15,10 @@ defmodule Membrane.RTMP.Messages.ReleaseStream do tx_id: non_neg_integer() } - @name "releaseStream" + @names ["releaseStream", "@releaseStream"] @impl true - def from_data([@name, tx_id, :null, stream_key]) do + def from_data([name, tx_id, :null, stream_key]) when name in @names do %__MODULE__{tx_id: tx_id, stream_key: stream_key} end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/on_expect_additional_media.ex b/lib/membrane_rtmp_plugin/rtmp/messages/on_expect_additional_media.ex index b0e7306c..25500878 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/on_expect_additional_media.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/on_expect_additional_media.ex @@ -27,8 +27,10 @@ defmodule Membrane.RTMP.Messages.OnExpectAdditionalMedia do processing_intents: [String.t()] } + @names ["onExpectAdditionalMedia", "@onExpectAdditionalMedia"] + @impl true - def from_data(["@setDataFrame", "onExpectAdditionalMedia", properties]) do + def from_data(["@setDataFrame", name, properties]) when name in @names do new(properties) end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/on_meta_data.ex b/lib/membrane_rtmp_plugin/rtmp/messages/on_meta_data.ex index fcf0284e..15599cbb 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/on_meta_data.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/on_meta_data.ex @@ -35,8 +35,10 @@ defmodule Membrane.RTMP.Messages.OnMetaData do audio_data_rate: number() } + @names ["onMetaData", "@onMetaData"] + @impl true - def from_data(["onMetaData", properties]) do + def from_data([name, properties]) when name in @names do new(properties) end diff --git a/lib/membrane_rtmp_plugin/rtmp/messages/set_data_frame.ex b/lib/membrane_rtmp_plugin/rtmp/messages/set_data_frame.ex index 186a4f01..9bd8c5a7 100644 --- a/lib/membrane_rtmp_plugin/rtmp/messages/set_data_frame.ex +++ b/lib/membrane_rtmp_plugin/rtmp/messages/set_data_frame.ex @@ -57,6 +57,11 @@ defmodule Membrane.RTMP.Messages.SetDataFrame do OnExpectAdditionalMedia.from_data(data) end + @impl true + def from_data(["@setDataFrame", "@" <> event, properties]) do + from_data(["@setDataFrame", event, properties]) + end + @spec new([{String.t(), any()}]) :: t() def new(options) do params = diff --git a/test/membrane_rtmp_plugin/rtmp_messages_test.exs b/test/membrane_rtmp_plugin/rtmp_messages_test.exs new file mode 100644 index 00000000..59277dbe --- /dev/null +++ b/test/membrane_rtmp_plugin/rtmp_messages_test.exs @@ -0,0 +1,105 @@ +defmodule Membrane.RTMP.MessagesTest do + use ExUnit.Case, async: true + + alias Membrane.RTMP.Messages.AdditionalMedia + alias Membrane.RTMP.Messages.Anonymous + alias Membrane.RTMP.Messages.Connect + alias Membrane.RTMP.Messages.CreateStream + alias Membrane.RTMP.Messages.DeleteStream + alias Membrane.RTMP.Messages.FCPublish + alias Membrane.RTMP.Messages.OnExpectAdditionalMedia + alias Membrane.RTMP.Messages.OnMetaData + alias Membrane.RTMP.Messages.Publish + alias Membrane.RTMP.Messages.ReleaseStream + alias Membrane.RTMP.Messages.SetDataFrame + + test "Connect accepts @connect alias" do + props = %{"app" => "live", "tcUrl" => "rtmp://localhost/live", "custom" => "value"} + + assert Connect.from_data(["@connect", 1, props]) == Connect.from_data(["connect", 1, props]) + end + + test "CreateStream accepts @createStream alias" do + assert CreateStream.from_data(["@createStream", 2, :null]) == + CreateStream.from_data(["createStream", 2, :null]) + end + + test "DeleteStream accepts @deleteStream alias" do + assert DeleteStream.from_data(["@deleteStream", 3, :null, 10]) == + DeleteStream.from_data(["deleteStream", 3, :null, 10]) + end + + test "FCPublish accepts @FCPublish alias" do + assert FCPublish.from_data(["@FCPublish", 4, :null, "stream_key"]) == + FCPublish.from_data(["FCPublish", 4, :null, "stream_key"]) + end + + test "Publish accepts @publish alias with publish type" do + assert Publish.from_data(["@publish", 5, :null, "stream_key", "live"]) == + Publish.from_data(["publish", 5, :null, "stream_key", "live"]) + end + + test "Publish accepts @publish alias without publish type" do + assert Publish.from_data(["@publish", 6, :null, "stream_key"]) == + Publish.from_data(["publish", 6, :null, "stream_key"]) + end + + test "ReleaseStream accepts @releaseStream alias" do + assert ReleaseStream.from_data(["@releaseStream", 7, :null, "stream_key"]) == + ReleaseStream.from_data(["releaseStream", 7, :null, "stream_key"]) + end + + test "AdditionalMedia accepts @additionalMedia alias" do + props = %{"id" => "track-1", "media" => <<1, 2, 3>>} + + assert AdditionalMedia.from_data(["@additionalMedia", props]) == + AdditionalMedia.from_data(["additionalMedia", props]) + end + + test "Anonymous strips @ prefix" do + props = %{"level" => "status"} + + assert Anonymous.from_data(["@onStatus", props]) == + Anonymous.from_data(["onStatus", props]) + end + + test "OnMetaData accepts @onMetaData alias" do + props = %{"duration" => 12.0, "width" => 1920.0} + + assert OnMetaData.from_data(["@onMetaData", props]) == + OnMetaData.from_data(["onMetaData", props]) + end + + test "SetDataFrame accepts nested @onMetaData alias" do + props = %{"duration" => 12.0, "width" => 1920.0} + + assert SetDataFrame.from_data(["@setDataFrame", "@onMetaData", props]) == + SetDataFrame.from_data(["@setDataFrame", "onMetaData", props]) + end + + test "SetDataFrame accepts nested @onExpectAdditionalMedia alias" do + props = %{ + "additionalMedia" => %{"id" => "track-1"}, + "defaultMedia" => %{"id" => "track-0"}, + "processingIntents" => ["transcode"] + } + + assert SetDataFrame.from_data(["@setDataFrame", "@onExpectAdditionalMedia", props]) == + SetDataFrame.from_data(["@setDataFrame", "onExpectAdditionalMedia", props]) + end + + test "OnExpectAdditionalMedia accepts nested @onExpectAdditionalMedia alias" do + props = %{ + "additionalMedia" => %{"id" => "track-1"}, + "defaultMedia" => %{"id" => "track-0"}, + "processingIntents" => ["transcode"] + } + + assert OnExpectAdditionalMedia.from_data(["@setDataFrame", "@onExpectAdditionalMedia", props]) == + OnExpectAdditionalMedia.from_data([ + "@setDataFrame", + "onExpectAdditionalMedia", + props + ]) + end +end