Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add usage example. Deprecate AAC.Filler #45

Merged
merged 14 commits into from
Sep 20, 2024
2 changes: 1 addition & 1 deletion .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
inputs: [
"{lib,test,config}/**/*.{ex,exs}",
"{lib,test,config,examples}/**/*.{ex,exs}",
".formatter.exs",
"*.exs"
],
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,5 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk

output.mp4
# End of https://www.gitignore.io/api/c,vim,linux,macos,elixir,windows,visualstudiocode
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,25 @@ The package can be installed by adding `membrane_aac_plugin` to your list of dep
```elixir
def deps do
[
{:membrane_aac_plugin, "~> 0.18.1"}
{:membrane_aac_plugin, "~> 0.18.2"}
]
end
```

## Usage example
You can find examples of usage in the `examples/` directory.

TODO
To see how the parser can be used to payload AAC stream so that it can be put in the MP4 container, run:
```
elixir examples/add_and_put_in_mp4.exs
```

When the script terminates, you can play the result .mp4 file with the following command:
```
ffplay output.mp4
```

The docs can be found at [Hex Docs](https://hexdocs.pm/membrane_aac_plugin).
The documentation can be found at [Hex Docs](https://hexdocs.pm/membrane_aac_plugin).

## Copyright and License

Expand Down
46 changes: 46 additions & 0 deletions examples/parse_and_put_in_mp4.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Mix.install([
:membrane_hackney_plugin,
:membrane_mp4_plugin,
:membrane_file_plugin,
{:membrane_aac_plugin, path: Path.expand("./"), override: true}
])

defmodule MP4MuxingPipeline do
use Membrane.Pipeline

alias Membrane.{AAC, File, Hackney, MP4}

@impl true
def handle_init(_ctx, _opts) do
spec =
child(:source, %Hackney.Source{
location:
"https://raw.githubusercontent.com/membraneframework/static/gh-pages/samples/test-audio.aac",
hackney_opts: [follow_redirect: true]
})
|> child(:parser, %AAC.Parser{out_encapsulation: :none, output_config: :esds})
|> child(:muxer, %MP4.Muxer.ISOM{})
|> child(:sink, %File.Sink{location: "output.mp4"})

{[spec: spec], %{}}
end

# When end of stream arrives, terminate the pipeline
@impl
def handle_element_end_of_stream(:sink, _pad, _ctx, state) do
{[terminate: :normal], state}
end

@impl true
def handle_element_end_of_stream(_child, _pad, _ctx, state) do
{[], state}
end
end

{:ok, _supervisor, pid} = Membrane.Pipeline.start_link(MP4MuxingPipeline)
monitor_ref = Process.monitor(pid)

receive do
{:DOWN, ^monitor_ref, :process, _pid, _reason} ->
:ok
end
25 changes: 20 additions & 5 deletions lib/membrane/aac/filler.ex
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
defmodule Membrane.AAC.Filler do
@moduledoc deprecated:
"Please use `Membrane.AudioFiller` from the `:membrane_audio_filler_plugin` to fill gaps in raw audio stream with silence."
@moduledoc """

Element that fills gaps in AAC stream with silent frames.
"""
use Membrane.Filter
require Membrane.Logger
alias Membrane.{Buffer, Time}

# Silence frame per channel configuration
@silent_frames %{
1 => <<222, 2, 0, 76, 97, 118, 99, 53, 56, 46, 53, 52, 46, 49, 48, 48, 0, 2, 48, 64, 14>>,
1 => <<222, 2, 0, 76, 97, 118, 99, 54, 48, 46, 51, 49, 46, 49, 48, 50, 0, 2, 48, 64, 14>>,
2 =>
<<255, 241, 80, 128, 3, 223, 252, 222, 2, 0, 76, 97, 118, 99, 53, 56, 46, 57, 49, 46, 49,
48, 48, 0, 66, 32, 8, 193, 24, 56>>
Expand Down Expand Up @@ -50,6 +54,11 @@ defmodule Membrane.AAC.Filler do

@impl true
def handle_init(_ctx, _opts) do
Membrane.Logger.warning("""
`#{__MODULE__}` element is deprecated now.
Please use `Membrane.AudioFiller` from the `:membrane_audio_filler_plugin` to fill gaps in raw audio stream with silence.
""")

{[], %State{frame_duration: nil}}
end

Expand All @@ -60,7 +69,9 @@ defmodule Membrane.AAC.Filler do

@impl true
def handle_stream_format(:input, stream_format, _ctx, state) do
new_duration = stream_format.samples_per_frame / stream_format.sample_rate * Time.second()
new_duration =
stream_format.samples_per_frame / stream_format.sample_rate * Time.second()

state = %State{state | frame_duration: new_duration, channels: stream_format.channels}

{[forward: stream_format], state}
Expand All @@ -70,7 +81,7 @@ defmodule Membrane.AAC.Filler do
def handle_buffer(:input, buffer, _ctx, state) do
use Numbers, overload_operators: true, comparison: true

%{timestamp: current_timestamp} = buffer.metadata
current_timestamp = buffer.pts || buffer.dts
%{expected_timestamp: expected_timestamp, frame_duration: frame_duration} = state
expected_timestamp = expected_timestamp || current_timestamp

Expand All @@ -82,8 +93,12 @@ defmodule Membrane.AAC.Filler do

buffers =
Enum.map(silent_frames_timestamps, fn timestamp ->
%Buffer{buffer | payload: silent_frame_payload}
|> Bunch.Struct.put_in([:metadata, :timestamp], timestamp)
%Buffer{
buffer
| payload: silent_frame_payload,
pts: round(timestamp),
dts: round(timestamp)
}
end) ++ [buffer]

expected_timestamp = expected_timestamp + length(buffers) * frame_duration
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Membrane.AAC.MixProject do
use Mix.Project

@version "0.18.1"
@version "0.18.2"
@github_url "https://github.com/membraneframework/membrane_aac_plugin"

def project do
Expand Down
18 changes: 9 additions & 9 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
%{
"bimap": {:hex, :bimap, "1.3.0", "3ea4832e58dc83a9b5b407c6731e7bae87458aa618e6d11d8e12114a17afa4b3", [:mix], [], "hexpm", "bf5a2b078528465aa705f405a5c638becd63e41d280ada41e0f77e6d255a10b4"},
"bunch": {:hex, :bunch, "1.6.0", "4775f8cdf5e801c06beed3913b0bd53fceec9d63380cdcccbda6be125a6cfd54", [:mix], [], "hexpm", "ef4e9abf83f0299d599daed3764d19e8eac5d27a5237e5e4d5e2c129cfeb9a22"},
"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.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [: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", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"},
"credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [: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", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
"dialyxir": {:hex, :dialyxir, "1.4.2", "764a6e8e7a354f0ba95d58418178d486065ead1f69ad89782817c296d0d746a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "516603d8067b2fd585319e4b13d3674ad4f314a5902ba8130cd97dc902ce6bbd"},
"earmark_parser": {:hex, :earmark_parser, "1.4.38", "b42252eddf63bda05554ba8be93a1262dc0920c721f1aaf989f5de0f73a2e367", [:mix], [], "hexpm", "2cd0907795aaef0c7e8442e376633c5b3bd6edc8dbbdc539b22f095501c1cdb6"},
"earmark_parser": {:hex, :earmark_parser, "1.4.41", "ab34711c9dc6212dda44fcd20ecb87ac3f3fce6f0ca2f28d4a00e4154f8cd599", [:mix], [], "hexpm", "a81a04c7e34b6617c2792e291b5a2e57ab316365c2644ddc553bb9ed863ebefa"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.30.9", "d691453495c47434c0f2052b08dd91cc32bc4e1a218f86884563448ee2502dd2", [: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", "d7aaaf21e95dc5cddabf89063327e96867d00013963eadf2c6ad135506a8bc10"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"},
"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"},
"ex_doc": {:hex, :ex_doc, "0.34.2", "13eedf3844ccdce25cfd837b99bea9ad92c4e511233199440488d217c92571e8", [: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", "5ce5f16b41208a50106afed3de6a2ed34f4acfd65715b82a0b84b49d995f95c1"},
"file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [: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", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.1", "c7f58c120b2b5aa5fd80d540a89fdf866ed42f1f3994e4fe189abebeab610839", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "8a89a1eeccc2d798d6ea15496a6e4870b75e014d1af514b1b71fa33134f57814"},
"membrane_aac_format": {:hex, :membrane_aac_format, "0.8.0", "515631eabd6e584e0e9af2cea80471fee6246484dbbefc4726c1d93ece8e0838", [:mix], [{:bimap, "~> 1.1", [hex: :bimap, repo: "hexpm", optional: false]}], "hexpm", "a30176a94491033ed32be45e51d509fc70a5ee6e751f12fd6c0d60bd637013f6"},
"membrane_core": {:hex, :membrane_core, "1.0.0", "1b543aefd952283be1f2a215a1db213aa4d91222722ba03cd35280622f1905ee", [:mix], [{:bunch, "~> 1.6", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}, {:ratio, "~> 3.0", [hex: :ratio, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "352c90fd0a29942143c4bf7a727cc05c632e323f50a1a4e99321b1e8982f1533"},
"membrane_file_plugin": {:hex, :membrane_file_plugin, "0.16.0", "7917f6682c22b9bcfc2ca20ed960eee0f7d03ad31fd5f59ed850f1fe3ddd545a", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "b0727998f75a9b4dab8a2baefdfc13c3eac00a04e061ab1b0e61dc5566927acc"},
Expand Down
8 changes: 4 additions & 4 deletions test/membrane/aac/filler_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule Membrane.AAC.FillerTest do
state: state,
current_timestamp: current_timestamp
} do
current_buffer = %Buffer{metadata: %{timestamp: current_timestamp}, payload: ""}
current_buffer = %Buffer{pts: current_timestamp, payload: ""}

assert {actions, new_state} = Filler.handle_buffer(:input, current_buffer, nil, state)

Expand All @@ -35,7 +35,7 @@ defmodule Membrane.AAC.FillerTest do
skipped_frames = 10

current_buffer = %Buffer{
metadata: %{timestamp: current_timestamp + skipped_frames},
pts: current_timestamp + skipped_frames,
payload: ""
}

Expand Down Expand Up @@ -64,7 +64,7 @@ defmodule Membrane.AAC.FillerTest do
|> Enum.map(
&%Membrane.Buffer{
payload: &1,
metadata: %{timestamp: &1}
pts: &1
}
)

Expand Down Expand Up @@ -118,7 +118,7 @@ defmodule Membrane.AAC.FillerTest do
state = %{state | channels: channels}

buffer = %Buffer{
metadata: %{timestamp: current_timestamp + skipped_frames},
pts: current_timestamp + skipped_frames,
payload: ""
}

Expand Down