@@ -9,6 +9,8 @@ defmodule Boombox do
9
9
10
10
alias Membrane.RTP
11
11
12
+ @ type enforce_transcoding_value ( ) :: boolean ( ) | :audio | :video
13
+
12
14
@ type webrtc_signaling :: Membrane.WebRTC.Signaling . t ( ) | String . t ( )
13
15
@ type in_stream_opts :: [
14
16
{ :audio , :binary | boolean ( ) }
@@ -64,6 +66,7 @@ defmodule Boombox do
64
66
| { :address , :inet . ip_address ( ) | String . t ( ) }
65
67
| { :port , :inet . port_number ( ) }
66
68
| { :target , String . t ( ) }
69
+ | { :enforce_transcoding , enforce_transcoding_value ( ) }
67
70
]
68
71
69
72
@ type input ::
@@ -79,18 +82,19 @@ defmodule Boombox do
79
82
@ type output ::
80
83
( path_or_uri :: String . t ( ) )
81
84
| { :mp4 , location :: String . t ( ) }
85
+ | { :mp4 , location :: String . t ( ) , [ { :enforce_transcoding , enforce_transcoding_value ( ) } ] }
82
86
| { :webrtc , webrtc_signaling ( ) }
87
+ | { :webrtc , webrtc_signaling ( ) , [ { :enforce_transcoding , enforce_transcoding_value ( ) } ] }
83
88
| { :whip , uri :: String . t ( ) , [ { :token , String . t ( ) } | { bandit_option :: atom ( ) , term ( ) } ] }
84
89
| { :hls , location :: String . t ( ) }
90
+ | { :hls , location :: String . t ( ) , [ { :enforce_transcoding , enforce_transcoding_value ( ) } ] }
85
91
| { :rtp , out_rtp_opts ( ) }
86
92
| { :stream , out_stream_opts ( ) }
87
93
88
94
@ typep procs :: % { pipeline: pid ( ) , supervisor: pid ( ) }
89
95
@ typep opts_map :: % {
90
96
input: input ( ) ,
91
- output: output ( ) ,
92
- enforce_video_transcoding?: boolean ( ) ,
93
- enforce_audio_transcoding?: boolean ( )
97
+ output: output ( )
94
98
}
95
99
96
100
@ doc """
@@ -123,25 +127,15 @@ defmodule Boombox do
123
127
"""
124
128
@ spec run ( Enumerable . t ( ) | nil ,
125
129
input: input ( ) ,
126
- output: output ( ) ,
127
- enforce_video_transcoding?: boolean ( ) ,
128
- enforce_audio_transcoding?: boolean ( )
130
+ output: output ( )
129
131
) :: :ok | Enumerable . t ( )
130
132
@ endpoint_opts [ :input , :output ]
131
133
def run ( stream \\ nil , opts ) do
132
134
opts =
133
135
opts
134
- |> Keyword . validate! (
135
- @ endpoint_opts ++
136
- [
137
- enforce_video_transcoding?: false ,
138
- enforce_audio_transcoding?: false
139
- ]
140
- )
141
- |> Map . new ( fn
142
- { key , value } when key in @ endpoint_opts -> { key , parse_endpoint_opt! ( key , value ) }
143
- { key , value } -> { key , value }
144
- end )
136
+ |> Keyword . validate! ( @ endpoint_opts )
137
+ |> Map . new ( fn { key , value } -> { key , parse_endpoint_opt! ( key , value ) } end )
138
+ |> resolve_enforce_transcoding ( )
145
139
146
140
:ok = maybe_log_transcoding_related_warning ( opts )
147
141
@@ -224,12 +218,21 @@ defmodule Boombox do
224
218
{ :mp4 , location } when is_binary ( location ) and direction == :output ->
225
219
{ :mp4 , location }
226
220
221
+ { :mp4 , location , _opts } when is_binary ( location ) and direction == :output ->
222
+ value
223
+
227
224
{ :webrtc , % Membrane.WebRTC.Signaling { } } ->
228
225
value
229
226
227
+ { :webrtc , % Membrane.WebRTC.Signaling { } , _opts } when direction == :output ->
228
+ value
229
+
230
230
{ :webrtc , uri } when is_binary ( uri ) ->
231
231
value
232
232
233
+ { :webrtc , uri , _opts } when is_binary ( uri ) and direction == :output ->
234
+ value
235
+
233
236
{ :whip , uri } when is_binary ( uri ) ->
234
237
parse_endpoint_opt! ( direction , { :whip , uri , [ ] } )
235
238
@@ -244,6 +247,10 @@ defmodule Boombox do
244
247
{ :hls , location } when direction == :output and is_binary ( location ) ->
245
248
value
246
249
250
+ { :hls , location , opts }
251
+ when direction == :output and is_binary ( location ) and is_list ( opts ) ->
252
+ value
253
+
247
254
{ :rtsp , location } when direction == :input and is_binary ( location ) ->
248
255
value
249
256
@@ -268,12 +275,12 @@ defmodule Boombox do
268
275
@ spec maybe_log_transcoding_related_warning ( opts_map ( ) ) :: :ok
269
276
def maybe_log_transcoding_related_warning ( opts ) do
270
277
if is_webrtc_endpoint ( opts . output ) and not is_webrtc_endpoint ( opts . input ) and
271
- not opts . enforce_video_transcoding? do
278
+ opts . enforce_transcoding not in [ true , :video ] do
272
279
Logger . warning ( """
273
280
Boombox output protocol is WebRTC, while Boombox input doesn't support keyframe requests. This \
274
281
might lead to issues with the output video if the output stream isn't sent only by localhost. You \
275
- can solve this by setting `:enforce_audio_transcoding?` option to `true`, but be aware that it \
276
- will increase Boombox CPU usage.
282
+ can solve this by setting `:enforce_transcoding` output option to `true` or `:video` , but be aware \
283
+ that it will increase Boombox CPU usage.
277
284
""" )
278
285
end
279
286
@@ -413,4 +420,23 @@ defmodule Boombox do
413
420
raise ArgumentError , "Invalid transport: #{ inspect ( transport ) } "
414
421
end
415
422
end
423
+
424
+ defp resolve_enforce_transcoding ( opts ) do
425
+ maybe_keyword =
426
+ opts . output
427
+ |> Tuple . to_list ( )
428
+ |> List . last ( )
429
+
430
+ enforce_transcoding =
431
+ Keyword . keyword? ( maybe_keyword ) && Keyword . get ( maybe_keyword , :enforce_transcoding , false )
432
+
433
+ opts
434
+ |> Map . put ( :enforce_transcoding , enforce_transcoding )
435
+ |> Map . update! ( :output , fn
436
+ { :webrtc , signaling , _opts } -> { :webrtc , signaling }
437
+ { :hls , location , _opts } -> { :hls , location }
438
+ { :mp4 , location , _opts } -> { :mp4 , location }
439
+ other -> other
440
+ end )
441
+ end
416
442
end
0 commit comments