Skip to content

Commit 3374365

Browse files
committed
Split new option into two
1 parent f4ccbfc commit 3374365

File tree

10 files changed

+77
-56
lines changed

10 files changed

+77
-56
lines changed

lib/boombox.ex

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ defmodule Boombox do
8686
| {:stream, out_stream_opts()}
8787

8888
@typep procs :: %{pipeline: pid(), supervisor: pid()}
89-
@typep opts_map :: %{input: input(), output: output(), enforce_transcoding?: boolean()}
89+
@typep opts_map :: %{
90+
input: input(),
91+
output: output(),
92+
enforce_video_transcoding?: boolean(),
93+
enforce_audio_transcoding?: boolean()
94+
}
9095

9196
@doc """
9297
Runs boombox with given input and output.
@@ -103,23 +108,36 @@ defmodule Boombox do
103108
If the input is `{:stream, opts}`, a `Stream` or other `Enumerable` is expected
104109
as the first argument.
105110
106-
If `:enforce_transcoding?` options is set to `true`, boombox will perform audio and/or video
107-
transcoding, even if it is not necessary. By default this option is set to `false`.
111+
If `:enforce_audio_transcoding?` or `:enforce_video_transcoding?` option is set to `true`,
112+
boombox will perform audio and/or video transcoding, even if it is not necessary. By default
113+
both options are set to `false`.
108114
109115
```
110-
Boombox.run(input: "path/to/file.mp4", output: {:webrtc, "ws://0.0.0.0:1234"}, enforce_transcoding?: true)
116+
Boombox.run(
117+
input: "path/to/file.mp4",
118+
output: {:webrtc, "ws://0.0.0.0:1234"},
119+
enforce_video_transcoding?: true,
120+
enforce_audio_transcoding?: true
121+
)
111122
```
112123
"""
113124
@spec run(Enumerable.t() | nil,
114125
input: input(),
115126
output: output(),
116-
enforce_transcoding?: boolean()
117-
) :: :ok | Enumerable.t()
127+
enforce_video_transcoding?: boolean(),
128+
enforce_audio_transcoding?: boolean()
129+
) :: :ok | Enumerable.t()
118130
@endpoint_opts [:input, :output]
119131
def run(stream \\ nil, opts) do
120132
opts =
121133
opts
122-
|> Keyword.validate!(@endpoint_opts ++ [enforce_transcoding?: false])
134+
|> Keyword.validate!(
135+
@endpoint_opts ++
136+
[
137+
enforce_video_transcoding?: false,
138+
enforce_audio_transcoding?: false
139+
]
140+
)
123141
|> Map.new(fn
124142
{key, value} when key in @endpoint_opts -> {key, parse_endpoint_opt!(key, value)}
125143
{key, value} -> {key, value}
@@ -250,12 +268,12 @@ defmodule Boombox do
250268
@spec maybe_log_transcoding_related_warning(opts_map()) :: :ok
251269
def maybe_log_transcoding_related_warning(opts) do
252270
if is_webrtc_endpoint(opts.output) and not is_webrtc_endpoint(opts.input) and
253-
not opts.enforce_transcoding? do
271+
not opts.enforce_video_transcoding? do
254272
Logger.warning("""
255273
Boombox output protocol is WebRTC, while Boombox input doesn't support keyframe requests. This \
256274
might lead to issues with the output video if the output stream isn't sent only by localhost. You \
257-
can solve this by setting `:enforce_transcoding?` option to `true`, but be aware that it will \
258-
increase Boombox CPU usage.
275+
can solve this by setting `:enforce_audio_transcoding?` option to `true`, but be aware that it \
276+
will increase Boombox CPU usage.
259277
""")
260278
end
261279

lib/boombox/elixir_stream.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule Boombox.ElixirStream do
55
require Membrane.Pad, as: Pad
66

77
alias __MODULE__.{Sink, Source}
8-
alias Boombox.Pipeline.Ready
8+
alias Boombox.Pipeline.{Ready, State}
99

1010
@options_audio_keys [:audio_format, :audio_rate, :audio_channels]
1111

@@ -41,9 +41,9 @@ defmodule Boombox.ElixirStream do
4141
options :: Boombox.out_stream_opts(),
4242
Boombox.Pipeline.track_builders(),
4343
Membrane.ChildrenSpec.t(),
44-
boolean()
44+
State.t()
4545
) :: Ready.t()
46-
def link_output(consumer, options, track_builders, spec_builder, enforce_transcoding?) do
46+
def link_output(consumer, options, track_builders, spec_builder, state) do
4747
options = parse_options(options, :output)
4848

4949
{track_builders, to_ignore} =
@@ -58,7 +58,7 @@ defmodule Boombox.ElixirStream do
5858
builder
5959
|> child(:mp4_audio_transcoder, %Membrane.Transcoder{
6060
output_stream_format: Membrane.RawAudio,
61-
enforce_transcoding?: enforce_transcoding?
61+
enforce_transcoding?: state.enforce_audio_transcoding?
6262
})
6363
|> maybe_plug_resampler(options)
6464
|> via_in(Pad.ref(:input, :audio))
@@ -68,7 +68,7 @@ defmodule Boombox.ElixirStream do
6868
builder
6969
|> child(:elixir_stream_video_transcoder, %Membrane.Transcoder{
7070
output_stream_format: Membrane.RawVideo,
71-
enforce_transcoding?: enforce_transcoding?
71+
enforce_transcoding?: state.enforce_video_transcoding?
7272
})
7373
|> child(:elixir_stream_rgb_converter, %Membrane.FFmpeg.SWScale.Converter{
7474
format: :RGB

lib/boombox/hls.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ defmodule Boombox.HLS do
44
import Membrane.ChildrenSpec
55

66
require Membrane.Pad, as: Pad
7-
alias Boombox.Pipeline.Ready
7+
alias Boombox.Pipeline.{Ready, State}
88
alias Membrane.H264
99
alias Membrane.Time
1010

1111
@spec link_output(
1212
Path.t(),
1313
Boombox.Pipeline.track_builders(),
1414
Membrane.ChildrenSpec.t(),
15-
boolean()
15+
State.t()
1616
) :: Ready.t()
17-
def link_output(location, track_builders, spec_builder, enforce_transcoding?) do
17+
def link_output(location, track_builders, spec_builder, state) do
1818
{directory, manifest_name} =
1919
if Path.extname(location) == ".m3u8" do
2020
{Path.dirname(location), Path.basename(location, ".m3u8")}
@@ -46,7 +46,7 @@ defmodule Boombox.HLS do
4646
builder
4747
|> child(:hls_audio_transcoder, %Membrane.Transcoder{
4848
output_stream_format: Membrane.AAC,
49-
enforce_transcoding?: enforce_transcoding?
49+
enforce_transcoding?: state.enforce_audio_transcoding?
5050
})
5151
|> via_in(Pad.ref(:input, :audio),
5252
options: [encoding: :AAC, segment_duration: Time.milliseconds(2000)]
@@ -57,7 +57,7 @@ defmodule Boombox.HLS do
5757
builder
5858
|> child(:hls_video_transcoder, %Membrane.Transcoder{
5959
output_stream_format: %H264{alignment: :au, stream_structure: :avc3},
60-
enforce_transcoding?: enforce_transcoding?
60+
enforce_transcoding?: state.enforce_video_transcoding?
6161
})
6262
|> via_in(Pad.ref(:input, :video),
6363
options: [encoding: :H264, segment_duration: Time.milliseconds(2000)]

lib/boombox/mp4.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule Boombox.MP4 do
33

44
import Membrane.ChildrenSpec
55
require Membrane.Pad, as: Pad
6-
alias Boombox.Pipeline.{Ready, Wait}
6+
alias Boombox.Pipeline.{Ready, State, Wait}
77
alias Membrane.H264
88
alias Membrane.H265
99

@@ -55,9 +55,9 @@ defmodule Boombox.MP4 do
5555
String.t(),
5656
Boombox.Pipeline.track_builders(),
5757
Membrane.ChildrenSpec.t(),
58-
boolean()
58+
State.t()
5959
) :: Ready.t()
60-
def link_output(location, track_builders, spec_builder, enforce_transcoding?) do
60+
def link_output(location, track_builders, spec_builder, state) do
6161
spec =
6262
[
6363
spec_builder,
@@ -68,7 +68,7 @@ defmodule Boombox.MP4 do
6868
builder
6969
|> child(:mp4_audio_transcoder, %Membrane.Transcoder{
7070
output_stream_format: Membrane.AAC,
71-
enforce_transcoding?: enforce_transcoding?
71+
enforce_transcoding?: state.enforce_audio_transcoding?
7272
})
7373
|> child(:mp4_out_aac_parser, %Membrane.AAC.Parser{
7474
out_encapsulation: :none,
@@ -93,7 +93,7 @@ defmodule Boombox.MP4 do
9393
_not_h26x ->
9494
%H264{stream_structure: :avc3, alignment: :au}
9595
end,
96-
enforce_transcoding?: enforce_transcoding?
96+
enforce_transcoding?: state.enforce_video_transcoding?
9797
})
9898
|> via_in(Pad.ref(:input, :video))
9999
|> get_child(:mp4_muxer)

lib/boombox/pipeline.ex

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,14 @@ defmodule Boombox.Pipeline do
5353
defmodule State do
5454
@moduledoc false
5555

56-
@enforce_keys [:status, :input, :output, :parent, :enforce_transcoding?]
56+
@enforce_keys [
57+
:status,
58+
:input,
59+
:output,
60+
:parent,
61+
:enforce_video_transcoding?,
62+
:enforce_audio_transcoding?
63+
]
5764

5865
defstruct @enforce_keys ++
5966
[
@@ -96,7 +103,8 @@ defmodule Boombox.Pipeline do
96103
rtsp_state: Boombox.RTSP.state() | nil,
97104
parent: pid(),
98105
output_webrtc_state: Boombox.WebRTC.output_webrtc_state() | nil,
99-
enforce_transcoding?: boolean()
106+
enforce_video_transcoding?: boolean(),
107+
enforce_audio_transcoding?: boolean()
100108
}
101109
end
102110

@@ -106,7 +114,8 @@ defmodule Boombox.Pipeline do
106114
input: opts.input,
107115
output: opts.output,
108116
parent: opts.parent,
109-
enforce_transcoding?: opts.enforce_transcoding?,
117+
enforce_audio_transcoding?: opts.enforce_audio_transcoding?,
118+
enforce_video_transcoding?: opts.enforce_video_transcoding?,
110119
status: :init
111120
}
112121

@@ -359,25 +368,19 @@ defmodule Boombox.Pipeline do
359368
end
360369

361370
defp link_output({:mp4, location}, track_builders, spec_builder, _ctx, state) do
362-
Boombox.MP4.link_output(location, track_builders, spec_builder, state.enforce_transcoding?)
371+
Boombox.MP4.link_output(location, track_builders, spec_builder, state)
363372
end
364373

365374
defp link_output({:hls, location}, track_builders, spec_builder, _ctx, state) do
366-
Boombox.HLS.link_output(location, track_builders, spec_builder, state.enforce_transcoding?)
375+
Boombox.HLS.link_output(location, track_builders, spec_builder, state)
367376
end
368377

369378
defp link_output({:rtp, opts}, track_builders, spec_builder, _ctx, state) do
370-
Boombox.RTP.link_output(opts, track_builders, spec_builder, state.enforce_transcoding?)
379+
Boombox.RTP.link_output(opts, track_builders, spec_builder, state)
371380
end
372381

373382
defp link_output({:stream, opts}, track_builders, spec_builder, _ctx, state) do
374-
Boombox.ElixirStream.link_output(
375-
state.parent,
376-
opts,
377-
track_builders,
378-
spec_builder,
379-
state.enforce_transcoding?
380-
)
383+
Boombox.ElixirStream.link_output(state.parent, opts, track_builders, spec_builder, state)
381384
end
382385

383386
# Wait between sending the last packet

lib/boombox/rtp.ex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Boombox.RTP do
44

55
require Membrane.Pad
66

7-
alias Boombox.Pipeline.Ready
7+
alias Boombox.Pipeline.{Ready, State}
88
alias Membrane.RTP
99

1010
@supported_encodings [audio: [:AAC, :Opus], video: [:H264, :H265]]
@@ -123,9 +123,9 @@ defmodule Boombox.RTP do
123123
Boombox.out_rtp_opts(),
124124
Boombox.Pipeline.track_builders(),
125125
Membrane.ChildrenSpec.t(),
126-
boolean()
126+
State.t()
127127
) :: Ready.t()
128-
def link_output(opts, track_builders, spec_builder, enforce_transcoding?) do
128+
def link_output(opts, track_builders, spec_builder, state) do
129129
parsed_opts = validate_and_parse_options(:output, opts)
130130

131131
spec = [
@@ -138,29 +138,29 @@ defmodule Boombox.RTP do
138138
Enum.map(track_builders, fn {media_type, builder} ->
139139
track_config = parsed_opts.track_configs[media_type]
140140

141-
{output_stream_format, parser, payloader} =
141+
{output_stream_format, parser, payloader, enforce_transcoding?} =
142142
case track_config.encoding_name do
143143
:H264 ->
144144
{%Membrane.H264{stream_structure: :annexb, alignment: :nalu},
145145
%Membrane.H264.Parser{output_stream_structure: :annexb, output_alignment: :nalu},
146-
Membrane.RTP.H264.Payloader}
146+
Membrane.RTP.H264.Payloader, state.enforce_video_transcoding?}
147147

148148
:AAC ->
149149
{%Membrane.AAC{encapsulation: :none},
150150
%Membrane.AAC.Parser{out_encapsulation: :none},
151151
%Membrane.RTP.AAC.Payloader{
152152
mode: track_config.encoding_specific_params.aac_bitrate_mode,
153153
frames_per_packet: 1
154-
}}
154+
}, state.enforce_video_transcoding?}
155155

156156
:OPUS ->
157157
{Membrane.Opus, %Membrane.Opus.Parser{delimitation: :undelimit},
158-
Membrane.RTP.Opus.Payloader}
158+
Membrane.RTP.Opus.Payloader, state.enforce_audio_transcoding}
159159

160160
:H265 ->
161161
{%Membrane.H265{stream_structure: :annexb, alignment: :nalu},
162162
%Membrane.H265.Parser{output_stream_structure: :annexb, output_alignment: :nalu},
163-
Membrane.RTP.H265.Payloader}
163+
Membrane.RTP.H265.Payloader, state.enforce_audio_transcoding}
164164
end
165165

166166
builder

lib/boombox/webrtc.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ defmodule Boombox.WebRTC do
149149
builder
150150
|> child(:mp4_audio_transcoder, %Membrane.Transcoder{
151151
output_stream_format: Membrane.Opus,
152-
enforce_transcoding?: state.enforce_transcoding?
152+
enforce_transcoding?: state.enforce_audio_transcoding?
153153
})
154154
|> child(:webrtc_out_audio_realtimer, Membrane.Realtimer)
155155
|> via_in(Pad.ref(:input, tracks.audio), options: [kind: :audio])
@@ -168,9 +168,9 @@ defmodule Boombox.WebRTC do
168168
&1,
169169
vp8_negotiated?,
170170
h264_negotiated?,
171-
state.enforce_transcoding?
171+
state.enforce_video_transcoding?
172172
),
173-
enforce_transcoding?: state.enforce_transcoding?
173+
enforce_transcoding?: state.enforce_video_transcoding?
174174
})
175175
|> via_in(Pad.ref(:input, tracks.video), options: [kind: :video])
176176
|> get_child(:webrtc_output)

mix.exs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@ defmodule Boombox.Mixfile do
4747
defp deps do
4848
[
4949
{:membrane_core, "~> 1.1"},
50-
# {:membrane_transcoder_plugin, "~> 0.1.2"},
51-
{:membrane_transcoder_plugin,
52-
github: "membraneframework/membrane_transcoder_plugin",
53-
ref: "9a6fbbb2318b5ac4c2ecbd77c5845d3e0ca62531"},
50+
{:membrane_transcoder_plugin, "~> 0.1.3"},
5451
{:membrane_webrtc_plugin, "~> 0.24.0"},
5552
{:membrane_mp4_plugin, "~> 0.35.2"},
5653
{:membrane_realtimer_plugin, "~> 0.9.0"},

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
"membrane_tee_plugin": {:hex, :membrane_tee_plugin, "0.12.0", "f94989b4080ef4b7937d74c1a14d3379577c7bd4c6d06e5a2bb41c351ad604d4", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "0d61c9ed5e68e5a75d54200e1c6df5739c0bcb52fee0974183ad72446a179887"},
8585
"membrane_telemetry_metrics": {:hex, :membrane_telemetry_metrics, "0.1.1", "57917e72012f9ebe124eab54f29ca74c9d9eb3ae2207f55c95618ee51280eb4f", [:mix], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.1 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "69392966e6bd51937244758c2b3d835c5ff47d8953d25431a9d37059737afc11"},
8686
"membrane_timestamp_queue": {:hex, :membrane_timestamp_queue, "0.2.2", "1c831b2273d018a6548654aa9f7fa7c4b683f71d96ffe164934ef55f9d11f693", [:mix], [{:heap, "~> 2.0", [hex: :heap, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm", "7c830e760baaced0988421671cd2c83c7cda8d1bd2b61fd05332711675d1204f"},
87-
"membrane_transcoder_plugin": {:git, "https://github.com/membraneframework/membrane_transcoder_plugin.git", "9a6fbbb2318b5ac4c2ecbd77c5845d3e0ca62531", [ref: "9a6fbbb2318b5ac4c2ecbd77c5845d3e0ca62531"]},
87+
"membrane_transcoder_plugin": {:hex, :membrane_transcoder_plugin, "0.1.3", "cc8655a9a37d905551261b58623d10c34a91ab0a2b31206b70864a6179b94e3d", [:mix], [{:membrane_aac_fdk_plugin, "~> 0.18.0", [hex: :membrane_aac_fdk_plugin, repo: "hexpm", optional: false]}, {:membrane_aac_format, "~> 0.8.0", [hex: :membrane_aac_format, repo: "hexpm", optional: false]}, {:membrane_aac_plugin, "~> 0.19.0", [hex: :membrane_aac_plugin, repo: "hexpm", optional: false]}, {:membrane_core, "~> 1.1", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:membrane_ffmpeg_swresample_plugin, "~> 0.20.0", [hex: :membrane_ffmpeg_swresample_plugin, repo: "hexpm", optional: false]}, {:membrane_funnel_plugin, "~> 0.9.1", [hex: :membrane_funnel_plugin, repo: "hexpm", optional: false]}, {:membrane_h264_ffmpeg_plugin, "~> 0.32.0", [hex: :membrane_h264_ffmpeg_plugin, repo: "hexpm", optional: false]}, {:membrane_h264_format, "~> 0.6.1", [hex: :membrane_h264_format, repo: "hexpm", optional: false]}, {:membrane_h265_ffmpeg_plugin, "~> 0.4.2", [hex: :membrane_h265_ffmpeg_plugin, repo: "hexpm", optional: false]}, {:membrane_h265_format, "~> 0.2.0", [hex: :membrane_h265_format, repo: "hexpm", optional: false]}, {:membrane_h26x_plugin, "~> 0.10.0", [hex: :membrane_h26x_plugin, repo: "hexpm", optional: false]}, {:membrane_opus_format, "~> 0.3.0", [hex: :membrane_opus_format, repo: "hexpm", optional: false]}, {:membrane_opus_plugin, "~> 0.20.3", [hex: :membrane_opus_plugin, repo: "hexpm", optional: false]}, {:membrane_timestamp_queue, "~> 0.2.2", [hex: :membrane_timestamp_queue, repo: "hexpm", optional: false]}, {:membrane_vp8_format, "~> 0.5.0", [hex: :membrane_vp8_format, repo: "hexpm", optional: false]}, {:membrane_vpx_plugin, "~> 0.3.0", [hex: :membrane_vpx_plugin, repo: "hexpm", optional: false]}], "hexpm", "3bf08fbeddec340515c5816ba276b7e553f1f7ef7d95e1b0ae8b215707ddda4c"},
8888
"membrane_udp_plugin": {:hex, :membrane_udp_plugin, "0.14.0", "d533ee5f6fcdd0551ad690045cdb6c1a76307a155d9255cc4a4606f85774bc37", [:mix], [{:membrane_core, "~> 1.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:mockery, "~> 2.3.0", [hex: :mockery, repo: "hexpm", optional: false]}], "hexpm", "902d1a7aa228ec377482d53a605b100e20e0b6e59196f94f94147bb62b23c47e"},
8989
"membrane_vp8_format": {:hex, :membrane_vp8_format, "0.5.0", "a589c20bb9d97ddc9b717684d00cefc84e2500ce63a0c33c4b9618d9b2f9b2ea", [:mix], [], "hexpm", "d29e0dae4bebc6838e82e031c181fe626d168c687e4bc617c1d0772bdeed19d5"},
9090
"membrane_vp9_format": {:hex, :membrane_vp9_format, "0.5.0", "c6a4f2cbfc39dba5d80ad8287162c52b5cf6488676bd64435c1ac957bd16e66f", [:mix], [], "hexpm", "68752d8cbe7270ec222fc84a7d1553499f0d8ff86ef9d9e89f8955d49e20278e"},

test/browser_test.exs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,19 @@ defmodule Boombox.BrowserTest do
108108
end
109109

110110
for first <- [:ingress, :egress], transcoding? <- [true, false] do
111-
test "browser -> boombox -> browser, but #{first} browser page connects first and :enforce_transcoding? is set to #{transcoding?}",
111+
test "browser -> boombox -> browser, but #{first} browser page connects first and :enforce_audio/video_transcoding? is set to #{transcoding?}",
112112
%{
113113
browser: browser
114114
} do
115+
transcoding? = unquote(transcoding?)
116+
115117
boombox_task =
116118
Task.async(fn ->
117119
Boombox.run(
118120
input: {:webrtc, "ws://localhost:8829"},
119121
output: {:webrtc, "ws://localhost:8830"},
120-
enforce_transcoding?: unquote(transcoding?)
122+
enforce_video_transcoding?: transcoding?,
123+
enforce_audio_transcoding?: transcoding?
121124
)
122125
end)
123126

0 commit comments

Comments
 (0)