Skip to content

Commit

Permalink
Add usage example. Deprecate AAC.Filler (#45)
Browse files Browse the repository at this point in the history
* Add simple usage example

* Use buffer's pts or dts fields instead of custom current_timestamp field in the buffer's metadata 

* Deprecate Membrane.AAC.Filler
---------

Co-authored-by: Mateusz Front <[email protected]>
  • Loading branch information
varsill and mat-hek authored Sep 20, 2024
1 parent c00550e commit 5c575ab
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 23 deletions.
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

0 comments on commit 5c575ab

Please sign in to comment.