From c575b5c76162d139ce3906348cc0ea665300802c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Mon, 9 Dec 2024 16:16:25 +0100 Subject: [PATCH 1/9] Update credo and fix credo warnings --- lib/transcoder/video.ex | 4 ---- mix.lock | 8 ++++---- test/integration_test.exs | 2 +- test/support/preprocessors.ex | 8 ++++++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/transcoder/video.ex b/lib/transcoder/video.ex index 9cf43cc..c4cd7be 100644 --- a/lib/transcoder/video.ex +++ b/lib/transcoder/video.ex @@ -66,7 +66,6 @@ defmodule Membrane.Transcoder.Video do end defp maybe_plug_parser_and_decoder(builder, %VP8{}) do - # todo: maybe specify framerate in decoder options builder |> child(:vp8_decoder, %VP8.Decoder{}) end @@ -75,7 +74,6 @@ defmodule Membrane.Transcoder.Video do end defp maybe_plug_encoder_and_parser(builder, %H264{} = h264) do - # todo: specify different preset in eg. mp4 builder |> child(:h264_encoder, %H264.FFmpeg.Encoder{preset: :ultrafast}) |> child(:h264_output_parser, %H264.Parser{ @@ -85,7 +83,6 @@ defmodule Membrane.Transcoder.Video do end defp maybe_plug_encoder_and_parser(builder, %H265{} = h265) do - # todo: specify different preset in eg. mp4 builder |> child(:h265_encoder, %H265.FFmpeg.Encoder{preset: :ultrafast}) |> child(:h265_output_parser, %H265.Parser{ @@ -95,7 +92,6 @@ defmodule Membrane.Transcoder.Video do end defp maybe_plug_encoder_and_parser(builder, %VP8{}) do - # todo: check if no option is required builder |> child(:vp8_encoder, %VP8.Encoder{}) end diff --git a/mix.lock b/mix.lock index 1ccd076..6f2bca4 100644 --- a/mix.lock +++ b/mix.lock @@ -3,19 +3,19 @@ "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"}, "bundlex": {:hex, :bundlex, "1.5.3", "35d01e5bc0679510dd9a327936ffb518f63f47175c26a35e708cc29eaec0890b", [: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", "debd0eac151b404f6216fc60222761dff049bf26f7d24d066c365317650cd118"}, - "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, - "credo": {:hex, :credo, "1.7.0", "6119bee47272e85995598ee04f2ebbed3e947678dee048d10b5feca139435f75", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "6839fcf63d1f0d1c0f450abc8564a57c43d644077ab96f2934563e68b8a769d7"}, + "credo": {:hex, :credo, "1.7.10", "6e64fe59be8da5e30a1b96273b247b5cf1cc9e336b5fd66302a64b25749ad44d", [: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", "71fbc9a6b8be21d993deca85bf151df023a3097b01e09a2809d460348561d8cd"}, "dialyxir": {:hex, :dialyxir, "1.4.1", "a22ed1e7bd3a3e3f197b68d806ef66acb61ee8f57b3ac85fc5d57354c5482a93", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "84b795d6d7796297cca5a3118444b80c7d94f7ce247d49886e7c291e1ae49801"}, "earmark_parser": {:hex, :earmark_parser, "1.4.35", "437773ca9384edf69830e26e9e7b2e0d22d2596c4a6b17094a3b29f01ea65bb8", [:mix], [], "hexpm", "8652ba3cb85608d0d7aa2d21b45c6fad4ddc9a1f9a1f1b30ca3a246f0acc33f6"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "ex_doc": {:hex, :ex_doc, "0.30.6", "5f8b54854b240a2b55c9734c4b1d0dd7bdd41f71a095d42a70445c03cf05a281", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bd48f2ddacf4e482c727f9293d9498e0881597eae6ddc3d9562bd7923375109f"}, - "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, + "file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"}, "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"}, "heap": {:hex, :heap, "2.0.2", "d98cb178286cfeb5edbcf17785e2d20af73ca57b5a2cf4af584118afbcf917eb", [:mix], [], "hexpm", "ba9ea2fe99eb4bcbd9a8a28eaf71cbcac449ca1d8e71731596aace9028c9d429"}, "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [: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", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, diff --git a/test/integration_test.exs b/test/integration_test.exs index 92cce55..6f0a3bf 100644 --- a/test/integration_test.exs +++ b/test/integration_test.exs @@ -3,7 +3,7 @@ defmodule Membrane.Transcoder.IntegrationTest do import Membrane.Testing.Assertions import Membrane.ChildrenSpec - alias Membrane.{H264, H265, VP8, RawVideo, AAC, Opus, RawAudio} + alias Membrane.{AAC, H264, H265, Opus, RawAudio, RawVideo, VP8} alias Membrane.Testing.Pipeline alias Membrane.Transcoder.Support.Preprocessors diff --git a/test/support/preprocessors.ex b/test/support/preprocessors.ex index fb0fde9..dc416ab 100644 --- a/test/support/preprocessors.ex +++ b/test/support/preprocessors.ex @@ -1,4 +1,5 @@ defmodule Membrane.Transcoder.Support.Preprocessors do + @moduledoc false import Membrane.ChildrenSpec @raw_audio_stream_format %Membrane.RawAudio{ @@ -7,6 +8,7 @@ defmodule Membrane.Transcoder.Support.Preprocessors do sample_format: :s16le } + @spec decode_h264(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def decode_h264(link_builder) do child(link_builder, %Membrane.H264.Parser{ output_alignment: :au, @@ -16,6 +18,7 @@ defmodule Membrane.Transcoder.Support.Preprocessors do |> child(%Membrane.H264.FFmpeg.Decoder{}) end + @spec parse_h264(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def parse_h264(link_builder) do child(link_builder, %Membrane.H264.Parser{ output_alignment: :au, @@ -24,6 +27,7 @@ defmodule Membrane.Transcoder.Support.Preprocessors do }) end + @spec parse_h265(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def parse_h265(link_builder) do child(link_builder, %Membrane.H265.Parser{ output_alignment: :au, @@ -32,10 +36,12 @@ defmodule Membrane.Transcoder.Support.Preprocessors do }) end + @spec parse_vp8(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def parse_vp8(link_builder) do child(link_builder, Membrane.IVF.Deserializer) end + @spec parse_raw_audio(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def parse_raw_audio(link_builder) do child(link_builder, %Membrane.RawAudioParser{ stream_format: @raw_audio_stream_format, @@ -43,10 +49,12 @@ defmodule Membrane.Transcoder.Support.Preprocessors do }) end + @spec parse_aac(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def parse_aac(link_builder) do child(link_builder, %Membrane.AAC.Parser{out_encapsulation: :ADTS}) end + @spec parse_opus(Membrane.ChildrenSpec.builder()) :: Membrane.ChildrenSpec.builder() def parse_opus(link_builder) do child(link_builder, %Membrane.Opus.Parser{ input_delimitted?: true, From e009c00235cfa4e86d090e0610d8abed58a6706b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 10:51:01 +0100 Subject: [PATCH 2/9] Add docs to the Membrane.Transcoder --- lib/transcoder.ex | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/transcoder.ex b/lib/transcoder.ex index 658a3f3..fc3bdab 100644 --- a/lib/transcoder.ex +++ b/lib/transcoder.ex @@ -1,5 +1,20 @@ defmodule Membrane.Transcoder do - @moduledoc false + @moduledoc """ + Provides transcoding capabilities for audio and video streams in Membrane. + The bin takes an incoming stream on its input and converts it into the desired one + as specified by the option. Transcoding is applied only if it is neccessary. + The following video stream formats are supported: + * `Membrane.H264` + * `Membrane.H265` + * `Membrane.VP8` + * `Membrane.RawVideo` + + The following audio stream formats are supported: + * `Membrane.AAC` + * `Membrane.Opus` + * `Membrane.RawAudio` + * `Membrane.RemoteStream{content_type: Membrane.Opus}` + """ use Membrane.Bin require __MODULE__.Audio @@ -9,6 +24,9 @@ defmodule Membrane.Transcoder do alias __MODULE__.{Audio, ForwardingFilter, Video} alias Membrane.{AAC, Funnel, H264, H265, Opus, RawAudio, RawVideo, RemoteStream, VP8} + @typedoc """ + Describes stream formats acceptable on the bin's input and output. + """ @type stream_format :: H264.t() | H265.t() @@ -19,8 +37,14 @@ defmodule Membrane.Transcoder do | RemoteStream.t() | RawAudio.t() + @typedoc """ + Describes stream format modules that can be used to define inputs and outputs of the bin. + """ @type stream_format_module :: H264 | H265 | VP8 | RawVideo | AAC | Opus | RawAudio + @typedoc """ + Describes a function which can be used to provide output format based on the input format. + """ @type stream_format_resolver :: (stream_format() -> stream_format() | stream_format_module()) def_input_pad :input, @@ -30,7 +54,16 @@ defmodule Membrane.Transcoder do accepted_format: format when Audio.is_audio_format(format) or Video.is_video_format(format) def_options output_stream_format: [ - spec: stream_format() | stream_format_module() | stream_format_resolver() + spec: stream_format() | stream_format_module() | stream_format_resolver(), + description: """ + An option specifying desired output format. + Can be either: + * a struct being a Membrane stream format, + * a module in which Membrane stream format struct is defined, + * a `t:stream_format_resolver()` which is a function which receives + input stream format as an input argument and is supposed to return + the desired output stream format. + """ ] @impl true From 9bfad610d699e90f98aa6baaa6e42d3a888457f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 11:21:22 +0100 Subject: [PATCH 3/9] Add usage example and describe it in the README --- README.md | 12 ++++++++++++ examples/vp8_to_h264.exs | 30 ++++++++++++++++++++++++++++++ lib/transcoder.ex | 8 +++++--- 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 examples/vp8_to_h264.exs diff --git a/README.md b/README.md index 4f48cfc..30acfc7 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,18 @@ def deps do end ``` +## Usage +In the `examples/vp8_to_h264.exs` file there is and example showing how to use +the `Membrane.Transcoder` to convert video encoded with VP8 into H264 encoded video. +You can run it with the following command: +``` +elixir vp8_to_h264.exs +``` + +Then you can inspect the format of the output file with e.g. `ffprobe` and confirm that it stores video encoded with H.264: +``` +ffprobe tmp/video.ivf +``` ## Copyright and License Copyright 2020, [Software Mansion](https://swmansion.com/?utm_source=git&utm_medium=readme&utm_campaign=membrane_template_plugin) diff --git a/examples/vp8_to_h264.exs b/examples/vp8_to_h264.exs new file mode 100644 index 0000000..a307f50 --- /dev/null +++ b/examples/vp8_to_h264.exs @@ -0,0 +1,30 @@ +Mix.install([ + :membrane_file_plugin, + :membrane_ivf_plugin, + {:membrane_transcoder_plugin, path: __DIR__ |> Path.join("..") |> Path.expand()} +]) + +defmodule Example do +alias Membrane.RCPipeline +require Membrane.RCPipeline, as: RCPipeline +import Membrane.ChildrenSpec + + def convert(input_file, output_file) do + pipeline = RCPipeline.start_link!() + + spec = + child(%Membrane.File.Source{ + location: input_file + }) + |> child(:deserializer, Membrane.IVF.Deserializer) + |> child(:transcoder, %Membrane.Transcoder{output_stream_format: Membrane.H264}) + |> child(:sink, %Membrane.File.Sink{location: output_file}) + + RCPipeline.subscribe(pipeline, _any) + RCPipeline.exec_actions(pipeline, spec: spec) + RCPipeline.await_end_of_stream(pipeline, :sink) + RCPipeline.terminate(pipeline) + end +end +File.mkdir("tmp") +Example.convert(Path.join("./test/fixtures", "video.ivf"), Path.join("./tmp", "video.h264")) diff --git a/lib/transcoder.ex b/lib/transcoder.ex index fc3bdab..c5af701 100644 --- a/lib/transcoder.ex +++ b/lib/transcoder.ex @@ -1,6 +1,7 @@ defmodule Membrane.Transcoder do @moduledoc """ Provides transcoding capabilities for audio and video streams in Membrane. + The bin takes an incoming stream on its input and converts it into the desired one as specified by the option. Transcoding is applied only if it is neccessary. The following video stream formats are supported: @@ -14,6 +15,8 @@ defmodule Membrane.Transcoder do * `Membrane.Opus` * `Membrane.RawAudio` * `Membrane.RemoteStream{content_type: Membrane.Opus}` + + Please note that not all the conversions are possible! """ use Membrane.Bin @@ -60,9 +63,8 @@ defmodule Membrane.Transcoder do Can be either: * a struct being a Membrane stream format, * a module in which Membrane stream format struct is defined, - * a `t:stream_format_resolver()` which is a function which receives - input stream format as an input argument and is supposed to return - the desired output stream format. + * a function which receives input stream format as an input argument + and is supposed to return the desired output stream format. """ ] From 6d7b32719dd89fee781a530332ddd5daf5c42972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 11:22:29 +0100 Subject: [PATCH 4/9] Update ex_cdoc --- mix.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mix.lock b/mix.lock index 6f2bca4..db8c7d6 100644 --- a/mix.lock +++ b/mix.lock @@ -7,19 +7,19 @@ "coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm", "b44a691700f7a1a15b4b7e2ff1fa30bebd669929ac8aa43cffe9e2f8bf051cf1"}, "credo": {:hex, :credo, "1.7.10", "6e64fe59be8da5e30a1b96273b247b5cf1cc9e336b5fd66302a64b25749ad44d", [: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", "71fbc9a6b8be21d993deca85bf151df023a3097b01e09a2809d460348561d8cd"}, "dialyxir": {:hex, :dialyxir, "1.4.1", "a22ed1e7bd3a3e3f197b68d806ef66acb61ee8f57b3ac85fc5d57354c5482a93", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "84b795d6d7796297cca5a3118444b80c7d94f7ce247d49886e7c291e1ae49801"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.35", "437773ca9384edf69830e26e9e7b2e0d22d2596c4a6b17094a3b29f01ea65bb8", [:mix], [], "hexpm", "8652ba3cb85608d0d7aa2d21b45c6fad4ddc9a1f9a1f1b30ca3a246f0acc33f6"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"}, "elixir_uuid": {:hex, :elixir_uuid, "1.2.1", "dce506597acb7e6b0daeaff52ff6a9043f5919a4c3315abb4143f0b00378c097", [:mix], [], "hexpm", "f7eba2ea6c3555cea09706492716b0d87397b88946e6380898c2889d68585752"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.30.6", "5f8b54854b240a2b55c9734c4b1d0dd7bdd41f71a095d42a70445c03cf05a281", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bd48f2ddacf4e482c727f9293d9498e0881597eae6ddc3d9562bd7923375109f"}, + "ex_doc": {:hex, :ex_doc, "0.35.1", "de804c590d3df2d9d5b8aec77d758b00c814b356119b3d4455e4b8a8687aecaf", [:mix], [{:earmark_parser, "~> 1.4.39", [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", "2121c6402c8d44b05622677b761371a759143b958c6c19f6558ff64d0aed40df"}, "file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"}, "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"}, "heap": {:hex, :heap, "2.0.2", "d98cb178286cfeb5edbcf17785e2d20af73ca57b5a2cf4af584118afbcf917eb", [:mix], [], "hexpm", "ba9ea2fe99eb4bcbd9a8a28eaf71cbcac449ca1d8e71731596aace9028c9d429"}, "hpax": {:hex, :hpax, "1.0.0", "28dcf54509fe2152a3d040e4e3df5b265dcb6cb532029ecbacf4ce52caea3fd2", [:mix], [], "hexpm", "7f1314731d711e2ca5fdc7fd361296593fc2542570b3105595bb0bc6d0fad601"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "logger_backends": {:hex, :logger_backends, "1.0.0", "09c4fad6202e08cb0fbd37f328282f16539aca380f512523ce9472b28edc6bdf", [:mix], [], "hexpm", "1faceb3e7ec3ef66a8f5746c5afd020e63996df6fd4eb8cdb789e5665ae6c9ce"}, - "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [: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", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"}, + "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"}, "membrane_aac_fdk_plugin": {:hex, :membrane_aac_fdk_plugin, "0.18.9", "1bf4ee0e5fc5bae3eae1b8f2d100d71e41f2bfaaa366ac3c6267572f6bd71f24", [: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", "aed8f58eac2c465d1e2731179f81969cb212990163c6fdf1aa27679658969be0"}, "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"}, @@ -48,7 +48,7 @@ "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"}, "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.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "numbers": {:hex, :numbers, "5.2.4", "f123d5bb7f6acc366f8f445e10a32bd403c8469bdbce8ce049e1f0972b607080", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "eeccf5c61d5f4922198395bf87a465b6f980b8b862dd22d28198c5e6fab38582"}, "qex": {:hex, :qex, "0.5.1", "0d82c0f008551d24fffb99d97f8299afcb8ea9cf99582b770bd004ed5af63fd6", [:mix], [], "hexpm", "935a39fdaf2445834b95951456559e9dc2063d0a055742c558a99987b38d6bab"}, From 94d20be1f561879a59c04f5d21665c35c721809a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 17:06:30 +0100 Subject: [PATCH 5/9] Update lib/transcoder.ex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Feliks PobiedziƄski <38541925+FelonEkonom@users.noreply.github.com> --- lib/transcoder.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/transcoder.ex b/lib/transcoder.ex index c5af701..dedb656 100644 --- a/lib/transcoder.ex +++ b/lib/transcoder.ex @@ -64,7 +64,7 @@ defmodule Membrane.Transcoder do * a struct being a Membrane stream format, * a module in which Membrane stream format struct is defined, * a function which receives input stream format as an input argument - and is supposed to return the desired output stream format. + and is supposed to return the desired output stream format or its module. """ ] From ab28c6714711bfe5e7dd0d9663fb57436b493004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 17:07:24 +0100 Subject: [PATCH 6/9] Format examples file --- examples/vp8_to_h264.exs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/vp8_to_h264.exs b/examples/vp8_to_h264.exs index a307f50..29f590e 100644 --- a/examples/vp8_to_h264.exs +++ b/examples/vp8_to_h264.exs @@ -5,9 +5,9 @@ Mix.install([ ]) defmodule Example do -alias Membrane.RCPipeline -require Membrane.RCPipeline, as: RCPipeline -import Membrane.ChildrenSpec + alias Membrane.RCPipeline + require Membrane.RCPipeline, as: RCPipeline + import Membrane.ChildrenSpec def convert(input_file, output_file) do pipeline = RCPipeline.start_link!() @@ -26,5 +26,6 @@ import Membrane.ChildrenSpec RCPipeline.terminate(pipeline) end end + File.mkdir("tmp") Example.convert(Path.join("./test/fixtures", "video.ivf"), Path.join("./tmp", "video.h264")) From 9aa9605134730b479f277a30506d5035324de7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 17:08:38 +0100 Subject: [PATCH 7/9] Implement CR suggestion --- lib/transcoder.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/transcoder.ex b/lib/transcoder.ex index c5af701..ceaa510 100644 --- a/lib/transcoder.ex +++ b/lib/transcoder.ex @@ -14,7 +14,7 @@ defmodule Membrane.Transcoder do * `Membrane.AAC` * `Membrane.Opus` * `Membrane.RawAudio` - * `Membrane.RemoteStream{content_type: Membrane.Opus}` + * `Membrane.RemoteStream{content_type: Membrane.Opus}` (only as input stream) Please note that not all the conversions are possible! """ From e4cc6dd9189629de65026dbf1d27ee0ab3193e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Tue, 10 Dec 2024 17:08:57 +0100 Subject: [PATCH 8/9] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Feliks PobiedziƄski <38541925+FelonEkonom@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30acfc7..4f7f03e 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ end ``` ## Usage -In the `examples/vp8_to_h264.exs` file there is and example showing how to use +In the `examples/vp8_to_h264.exs` file there is an example showing how to use the `Membrane.Transcoder` to convert video encoded with VP8 into H264 encoded video. You can run it with the following command: ``` From 51fc266d988fe79113744c977e018bffbfc1762e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Kita?= Date: Wed, 11 Dec 2024 11:23:59 +0100 Subject: [PATCH 9/9] Implement CR suggestion --- .formatter.exs | 2 +- lib/transcoder.ex | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.formatter.exs b/.formatter.exs index 4c3febe..e88289c 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,6 +1,6 @@ [ inputs: [ - "{lib,test,config}/**/*.{ex,exs}", + "{lib,test,config,examples}/**/*.{ex,exs}", ".formatter.exs", "*.exs" ], diff --git a/lib/transcoder.ex b/lib/transcoder.ex index 4a55931..4c25934 100644 --- a/lib/transcoder.ex +++ b/lib/transcoder.ex @@ -14,9 +14,7 @@ defmodule Membrane.Transcoder do * `Membrane.AAC` * `Membrane.Opus` * `Membrane.RawAudio` - * `Membrane.RemoteStream{content_type: Membrane.Opus}` (only as input stream) - - Please note that not all the conversions are possible! + * `Membrane.RemoteStream{content_type: Membrane.Opus}` (only as an input stream) """ use Membrane.Bin