-
Notifications
You must be signed in to change notification settings - Fork 5
Implement bin #68
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
Implement bin #68
Conversation
4fdcd93
to
e3055ba
Compare
80db650
to
7909366
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, let's add the docs ;)
lib/boombox/bin.ex
Outdated
@type input() :: | ||
(path_or_uri :: String.t()) | ||
| {:mp4, location :: String.t(), transport: :file | :http} | ||
| {:webrtc, Boombox.webrtc_signaling()} | ||
| {:whip, uri :: String.t(), token: String.t()} | ||
| {:rtmp, (uri :: String.t()) | (client_handler :: pid)} | ||
| {:rtsp, url :: String.t()} | ||
| {:rtp, Boombox.in_rtp_opts()} | ||
| {:stream, pid(), Boombox.in_stream_opts()} | ||
|
||
@type output :: | ||
(path_or_uri :: String.t()) | ||
| {path_or_uri :: String.t(), [Boombox.force_transcoding()]} | ||
| {:mp4, location :: String.t()} | ||
| {:mp4, location :: String.t(), [Boombox.force_transcoding()]} | ||
| {:webrtc, Boombox.webrtc_signaling()} | ||
| {:webrtc, Boombox.webrtc_signaling(), [Boombox.force_transcoding()]} | ||
| {:whip, uri :: String.t(), [{:token, String.t()} | {bandit_option :: atom(), term()}]} | ||
| {:hls, location :: String.t()} | ||
| {:hls, location :: String.t(), [Boombox.force_transcoding()]} | ||
| {:rtp, Boombox.out_rtp_opts()} | ||
| {:stream, pid(), Boombox.out_stream_opts()} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does it differ from Boombox.input()
/output()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boombox has {:stream, options}
Boombox.Bin has {:stream, pid(), options}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we spoke, let's create a private bin to handle this
lib/boombox/bin.ex
Outdated
def handle_playing(_ctx, state), do: {[], state} | ||
|
||
@impl true | ||
def handle_pad_added(pad_ref, ctx, state) when state.input == :membrane_pad do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's throw a readable error when someone specifies a different input and links some pads
I would add the docs after adding output pads, maybe the API will change till then and I hope I will have a better idea how to fix issue with passing |
lib/boombox.ex
Outdated
opts | ||
|> Enum.split_with(fn {key, _value} -> key == :force_transcoding end) | ||
end | ||
defp resolve_stream_endpoint(endpont, _parent), do: endpont |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defp resolve_stream_endpoint(endpont, _parent), do: endpont | |
defp resolve_stream_endpoint(endpoint, _parent), do: endpoint |
test/boombox_bin_test.exs
Outdated
if video_format != nil do | ||
Compare.compare(out_file, "test/fixtures/ref_bun10s_aac.mp4", | ||
kinds: [:video], | ||
subject_tracks_number: tracks_number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's quite long, but how about:
subject_tracks_number: tracks_number | |
expected_subject_tracks_number: tracks_number |
?
lib/boombox/pad.ex
Outdated
raise """ | ||
Boombox.Bin pad #{inspect(pad_ref)} was added while the Boombox.Bin playback \ | ||
is already :playing. All Boombox.Bin pads have to be linked before it enters \ | ||
:playing playback. To achieve so, link all pads of Boombox.Bin in the same spec \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:playing playback. To achieve so, link all pads of Boombox.Bin in the same spec \ | |
:playing playback. To achieve it, link all the pads of Boombox.Bin in the same spec \ |
lib/boombox/pad.ex
Outdated
@spec create_input(CallbackContext.t()) :: Ready.t() | Wait.t() | no_return() | ||
def create_input(ctx) when ctx.playback == :playing and ctx.pads == %{} do | ||
raise """ | ||
Cannot create input of type #{inspect(__MODULE__)}, while there are no pads. \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cannot create input of type #{inspect(__MODULE__)}, while there are no pads. \ | |
Cannot create input of type #{inspect(__MODULE__)}, as there are no pads available. \ |
lib/boombox/bin.ex
Outdated
:ok = maybe_log_transcoding_related_warning(state.input, state.output) | ||
|
||
with :membrane_pad <- state.input, {:stream, _pid, _opts} <- state.output do | ||
raise "Boombox bin cannot have pad input and stream output at the same time" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, please remember to change these raise messages once the code is separated into public bin and private bin
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As always, add some examples to examples.livemd
lib/boombox/bin.ex
Outdated
pads | ||
|> Enum.find(fn {Pad.ref(name, _id), %{options: options}} -> | ||
name == :output and | ||
(Bunch.listify(options.codec) -- @codecs[options.kind]) -- [nil] != [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this hard to read, maybe refactor to Enum.all?
test/support/compare.ex
Outdated
# <<<<<<< HEAD | ||
# assert abs(length(ref_audio_bufs) - length(sub_audio_bufs)) <= 1 | ||
|
||
# Enum.zip(sub_audio_bufs, ref_audio_bufs) | ||
# |> Enum.each(fn {sub, ref} -> | ||
# # The results differ between operating systems | ||
# # and subsequent runs due to transcoding. | ||
# # The threshold here is obtained empirically and may need | ||
# # to be adjusted, or a better metric should be used. | ||
# boundary = options[:audio_error_bounadry] || 30_000 | ||
# assert samples_min_squared_error(sub.payload, ref.payload, 16) < boundary | ||
# end) | ||
# ======= | ||
# assert samples_min_squared_error(sub_audio, ref_audio, 16) < 30_000 | ||
# >>>>>>> origin/master |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔
lib/boombox/bin.ex
Outdated
If you use it as a Membrane Source, you have to specify `:input` option. | ||
If you use it as a Membrane Sink, you have to specify `:output` option. | ||
Boombox.Bin cannot be used as both Source and Sink at the same time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mention what pads they need to link too, and provide some example, like child(%Boombox.Bin{input: "file.mp4"}) |> via_out(:output, options: [kind: :video]) |> ...
lib/boombox/internal_bin.ex
Outdated
@type input() :: | ||
(path_or_uri :: String.t()) | ||
| {:mp4, location :: String.t(), transport: :file | :http} | ||
| {:webrtc, Boombox.webrtc_signaling()} | ||
| {:whip, uri :: String.t(), token: String.t()} | ||
| {:rtmp, (uri :: String.t()) | (client_handler :: pid)} | ||
| {:rtsp, url :: String.t()} | ||
| {:rtp, Boombox.in_rtp_opts()} | ||
| {:stream, pid(), Boombox.in_stream_opts()} | ||
| :membrane_pad | ||
|
||
@type output :: | ||
(path_or_uri :: String.t()) | ||
| {path_or_uri :: String.t(), [Boombox.transcoding_policy()]} | ||
| {:mp4, location :: String.t()} | ||
| {:mp4, location :: String.t(), [Boombox.transcoding_policy()]} | ||
| {:webrtc, Boombox.webrtc_signaling()} | ||
| {:webrtc, Boombox.webrtc_signaling(), [Boombox.transcoding_policy()]} | ||
| {:whip, uri :: String.t(), [{:token, String.t()} | {bandit_option :: atom(), term()}]} | ||
| {:hls, location :: String.t()} | ||
| {:hls, location :: String.t(), [Boombox.transcoding_policy()]} | ||
| {:rtp, Boombox.out_rtp_opts()} | ||
| {:stream, pid(), Boombox.out_stream_opts()} | ||
| :membrane_pad |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still duplicated
Co-authored-by: Mateusz Front <[email protected]>
lib/boombox/bin.ex
Outdated
If set to `:always`, the media stream will be decoded and/or encoded, even if the | ||
format of the stream arriving at the #{inspect(__MODULE__)} endpoint matches the \ | ||
output pad codec. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding some example when :always
is helpful, i.e. when we want to "fix" the stream or support the keyframe requests? (We have a similar examples for the :never
option)
lib/boombox/bin.ex
Outdated
#{inspect(__MODULE__)} cannot accept input and output options at the same time, but both were provided.\ | ||
Input: #{inspect(opts.input)}, output: #{inspect(opts.output)}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That message only describes a situation when nil_opts_number == 0
, how about nil_opts_number == 2
?
@@ -4,18 +4,18 @@ defmodule Boombox.HLS do | |||
import Membrane.ChildrenSpec | |||
|
|||
require Membrane.Pad, as: Pad | |||
alias Boombox.Pipeline.Ready | |||
alias Boombox.InternalBin.Ready |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure Ready
and Wait
should be in InternalBin
, since they are use outside of the InternalBin
namespace as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are used only by modules that are used only inside internal bin
I can move these modules inside internal_bin
directory to make it more clear
closes #8