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

Initial implementation #1

Merged
merged 13 commits into from
Dec 9, 2024
7 changes: 6 additions & 1 deletion lib/transcoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,12 @@ defmodule Membrane.Transcoder do
end

@impl true
def handle_child_notification({:stream_format, format}, :forwarding_filter, _ctx, state) do
def handle_child_notification(
{:stream_format, format},
:forwarding_filter,
_ctx,
%{input_stream_format: nil} = state
) do
varsill marked this conversation as resolved.
Show resolved Hide resolved
state =
%{state | input_stream_format: format}
|> resolve_output_stream_format()
Expand Down
36 changes: 33 additions & 3 deletions lib/transcoder/audio.ex
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
defmodule Boombox.Transcoder.Audio do
defmodule Membrane.Transcoder.Audio do
@moduledoc false

import Membrane.ChildrenSpec
require Membrane.Logger
alias Membrane.{AAC, ChildrenSpec, Opus, RawAudio, RemoteStream}

@opus_sample_rate 48_000
@aac_sample_rates [
96_000,
88_200,
64_000,
48_000,
44_100,
32_000,
24_000,
22_050,
16_000,
12_000,
11_025,
8000
]

@type audio_stream_format :: AAC.t() | Opus.t() | RawAudio.t()

defguard is_audio_format(format)
when is_struct(format) and
(format.__struct__ in [AAC, Opus, RawAudio] or
(format.__struct__ == RemoteStream and format.content_format == Opus and
(format.__struct__ == RemoteStream and format.content_format in [Opus, AAC] and
varsill marked this conversation as resolved.
Show resolved Hide resolved
format.type == :packetized))

@spec plug_audio_transcoding(
Expand All @@ -34,7 +48,11 @@ defmodule Boombox.Transcoder.Audio do
end

defp do_plug_audio_transcoding(builder, %RemoteStream{content_format: Opus}, %Opus{}) do
builder |> child(:opus_parser, Opus.Parser)
builder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot remove plugging Opus.Parser, the output stream format will remain %RemoteStream{content_format: Opus} but it should be %Opus{}

end

defp do_plug_audio_transcoding(builder, %RemoteStream{content_format: AAC}, %AAC{}) do
builder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a parser here, to change stream format from RemoteStream to %AAC{}

end

defp do_plug_audio_transcoding(builder, input_format, output_format) do
Expand Down Expand Up @@ -72,6 +90,18 @@ defmodule Boombox.Transcoder.Audio do
})
end

defp maybe_plug_resampler(builder, %{sample_rate: sample_rate} = input_format, %AAC{})
when sample_rate not in @aac_sample_rates do
builder
|> child(:resampler, %Membrane.FFmpeg.SWResample.Converter{
output_stream_format: %RawAudio{
sample_format: :s16le,
sample_rate: 44_100,
channels: input_format.channels
}
})
end

defp maybe_plug_resampler(builder, _input_format, _output_format) do
builder
end
Expand Down