Open anildigital opened 5 years ago
Since this element hasn't been published yet it is included as a dependency by git. Which commit you mix.lock is locked to? Which version of Elixir are you using? To which commit membrane core is locked to? (preferably paste here part of mix.lock relevant to membrane here)
Please try checking out this repo to "ignored-event"
You can do so by:
{:membrane_element_shout, github: "membraneframework/membrane-element-shout", branch: "ignored-event"}
Also when parsing mp3 make sure it does not contain id3 tags, because we don't support them yet.
@Hajto Do you know about this error
{:ok, #PID<0.709.0>}
iex(3)> Pipeline.play(pid)
:ok
iex(4)> [error] GenServer #PID<0.714.0> terminating
** (stop) exited in: :cannot_handle_message.invalid_caps({:message, {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, [for_pad: :input]}}, {:mode, :info})
** (EXIT) :error
Last message: {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, [for_pad: :input]}
State: %Membrane.Core.Element.State{controlling_pid: #PID<0.709.0>, delayed_demands: %{}, internal_state: %{consumer: %Membrane.Element.Shout.Sink.Consumer{guard: #PID<0.715.0>, native_ref: #Reference<0.2722255998.1430650885.61899>}, ringbuffer_size: 20}, module: Membrane.Element.Shout.Sink, name: :sink, pads: %{data: %{input: %Membrane.Element.Pad.Data{accepted_caps: Membrane.Caps.Audio.MPEG, availability: :always, caps: nil, current_id: nil, demand: 20, demand_unit: :buffers, direction: :input, end_of_stream?: false, input_buf: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, metric: Membrane.Buffer.Metric.Count, min_demand: 2, name: :sink, preferred_size: 10, q: #Qex<[]>, toilet: false}, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.713.0>, start_of_stream?: false, sticky_messages: []}}, dynamic_currently_linking: [], info: %{}}, playback: %Membrane.Core.Playback{async_state_change: false, pending_state: nil, state: :playing, target_locked?: false, target_state: :playing}, playback_buffer: %Membrane.Core.Element.PlaybackBuffer{q: #Qex<[]>}, terminating: false, type: :sink, watcher: #PID<0.709.0>}
** (EXIT from #PID<0.699.0>) shell process exited with reason: exited in: :cannot_handle_message.invalid_caps({:message, {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, [for_pad: :input]}}, {:mode, :info})
** (EXIT) :error```
Another thing is that this element has sink that defined his input pad as:
:input, caps: MPEG, demand_unit: :buffers
Which means that it expects data with MPEG caps. Currently you are feeding him RAW. So you need to encode it back to MPEG for example using lame (https://github.com/membraneframework/membrane-element-lame).
Also please keep in mind that this element is experimental and is not supported and will be deleted as soon as https://github.com/membraneframework/membrane-element-icecast is released.
Thanks!
Here is new error while starting
iex -S mix
Erlang/OTP 22 [erts-10.4.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
==> membrane_element_lame
Bundlex: Building natives: encoder
Package lame was not found in the pkg-config search path.
Perhaps you should add the directory containing `lame.pc'
to the PKG_CONFIG_PATH environment variable
No package 'lame' found
could not compile dependency :membrane_element_lame, "mix compile" failed. You can recompile this dependency with "mix deps.compile membrane_element_lame", update it with "mix deps.update membrane_element_lame" or clean it with "mix deps.clean membrane_element_lame"
** (MatchError) no match of right hand side value: {"", 1}
(bundlex) lib/bundlex/toolchain/common/unix.ex:87: Bundlex.Toolchain.Common.Unix.pkg_config/2
(bundlex) lib/bundlex/toolchain/common/unix.ex:9: Bundlex.Toolchain.Common.Unix.compiler_commands/4
(bundlex) lib/bundlex/native.ex:86: Bundlex.Native.resolve_native/4
(bunch) lib/bunch/enum.ex:248: Bunch.Enum.do_try_flat_map/3
(bundlex) lib/tasks/compile.bundlex.ex:38: Mix.Tasks.Compile.Bundlex.run/1
(mix) lib/mix/task.ex:331: Mix.Task.run_task/3
(mix) lib/mix/tasks/compile.all.ex:73: Mix.Tasks.Compile.All.run_compiler/2
(mix) lib/mix/tasks/compile.all.ex:53: Mix.Tasks.Compile.All.do_compile/4
I have lame
installed with homebrew on my mac. Wondering if it needs any other dependency.
@anildigital it's a known issue: https://github.com/membraneframework/membrane-element-lame/issues/18
The workaround is explained here: https://github.com/membraneframework/membrane-element-lame#compilation-on-unix-systems
Please let us know if you need more assistance.
@mspanc I am using macOS and homebrew where lame is installed at /usr/local/Cellar/lame
Do you have specific steps to compile NIF? Thanks
/usr/local/Cellar/lame/3.100
lame.pc
in some directory, e.g. YOUR_PROJECT_PATH/pkg-config
with the following contentsprefix=/usr/local/Cellar/lame/3.100
exec_prefix=/usr/local/Cellar/lame/3.100
libdir=/usr/local/Cellar/lame/3.100/lib
includedir=/usr/local/Cellar/lame/3.100/include
Name: lame
Description: MPEG Audio Encoder
Version: 3.100
Requires:
Conflicts:
Libs: -L/usr/local/Cellar/lame/3.100/lib -lmp3lame -lm
Cflags: -I/usr/local/Cellar/lame/3.100/include
please replace 3.100 with the version you have installed
(it should point to the directory that contains
lame.pc`)The most important paths are in lines with Libs and Cflags, rest is effectively unused.
PKG_CONFIG_PATH=YOUR_PROJECT_PATH/pkg-config pkg-config --cflags --libs lame
For example I created a file
/Users/marcin/aktivitis/lame/lame.pc
with the following contents:
prefix=/usr/local/Cellar/lame/3.100
exec_prefix=/usr/local/Cellar/lame/3.100
libdir=/usr/local/Cellar/lame/3.100/lib
includedir=/usr/local/Cellar/lame/3.100/include
Name: lame
Description: MPEG Audio Encoder
Version: 3.100
Requires:
Conflicts:
Libs: -L/usr/local/Cellar/lame/3.100/lib -lmp3lame -lm
Cflags: -I/usr/local/Cellar/lame/3.100/include
And if I call pkg-config
manually to test if it is being resolved (this is what happens internally while building membrane), this is the output:
$ PKG_CONFIG_PATH=/Users/marcin/aktivitis/lame pkg-config --cflags --libs lame
-I/usr/local/Cellar/lame/3.100/include -L/usr/local/Cellar/lame/3.100/lib -lmp3lame -lm
Thanks @mspanc
Here is my Pipeline code
defmodule Mp3Icecast.Pipeline do
use Membrane.Pipeline
def handle_init(path_to_mp3) do
children = [
# Stream from file
file_src: %Membrane.Element.File.Source{location: path_to_mp3},
# Decode frames
decoder: Membrane.Element.Mad.Decoder,
# Convert Raw :s24le to Raw :s16le
converter: %Membrane.Element.FFmpeg.SWResample.Converter{
output_caps: %Membrane.Caps.Audio.Raw{
format: :s16le,
sample_rate: 48000,
channels: 2
}
},
lame: Membrane.Element.Lame.Encoder,
# Stream data into PortAudio to play it on speakers.
sink: %Membrane.Element.Shout.Sink{
host: "localhost",
port: 8000,
password: "hackme",
mount: "/stream",
ringbuffer_size: 20
}
]
# Map that describes how we want data to flow
# It is formated as such
# {:child, :output_pad} => {:another_child, :input_pad}
links = %{
{:file_src, :output} => {:decoder, :input},
{:decoder, :output} => {:converter, :input},
{:converter, :output} => {:lame, :input},
{:lame, :output} => {:sink, :input}
}
spec = %Membrane.Pipeline.Spec{
children: children,
links: links
}
{{:ok, spec}, %{}}
end
end
I get following error
iex(1)> alias Mp3Icecast.Pipeline
Mp3Icecast.Pipeline
iex(2)> {:ok, pid} = Pipeline.start_link("sample.mp3")
{:ok, #PID<0.486.0>}
iex(3)> Pipeline.play(pid)
:ok
iex(4)> [error] GenServer #PID<0.491.0> terminating
** (stop) exited in: :cannot_handle_message.invalid_caps({:message, {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, [for_pad: :input]}}, {:mode, :info})
** (EXIT) :error
Last message: {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, [for_pad: :input]}
State: %Membrane.Core.Element.State{controlling_pid: #PID<0.486.0>, delayed_demands: %{}, internal_state: %{native: #Reference<0.2202141337.150339588.75004>, options: %Membrane.Element.Lame.Encoder{bitrate: 192, gapless_flush: true, quality: 5}, queue: "", raw_frame_size: 9216}, module: Membrane.Element.Lame.Encoder, name: :lame, pads: %{data: %{input: %Membrane.Element.Pad.Data{accepted_caps: {Membrane.Caps.Audio.Raw, [format: :s32le, sample_rate: 44100, channels: 2]}, availability: :always, caps: nil, current_id: nil, demand: 92160, demand_unit: :bytes, direction: :input, end_of_stream?: false, input_buf: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, metric: Membrane.Buffer.Metric.ByteSize, min_demand: 16384, name: :lame, preferred_size: 65536, q: #Qex<[]>, toilet: false}, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.490.0>, start_of_stream?: false, sticky_messages: []}, output: %Membrane.Element.Pad.Data{accepted_caps: {Membrane.Caps.Audio.MPEG, [channels: 2, sample_rate: 44100, layer: :layer3, version: :v1]}, availability: :always, caps: %Membrane.Caps.Audio.MPEG{bitrate: 192, channel_mode: nil, channels: 2, copyright: nil, crc_enabled: nil, emphasis_mode: nil, layer: :layer3, mode_extension: nil, original: nil, padding_enabled: nil, private: nil, sample_rate: 44100, version: :v1}, current_id: nil, demand: 10, demand_unit: nil, direction: :output, end_of_stream?: false, input_buf: nil, mode: :pull, options: {:ok, nil}, other_demand_unit: :buffers, other_ref: :input, pid: #PID<0.492.0>, start_of_stream?: false, sticky_messages: nil}}, dynamic_currently_linking: [], info: %{}}, playback: %Membrane.Core.Playback{async_state_change: false, pending_state: nil, state: :playing, target_locked?: false, target_state: :playing}, playback_buffer: %Membrane.Core.Element.PlaybackBuffer{q: #Qex<[]>}, terminating: false, type: :filter, watcher: #PID<0.486.0>}
** (EXIT from #PID<0.483.0>) shell process exited with reason: exited in: :cannot_handle_message.invalid_caps({:message, {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, [for_pad: :input]}}, {:mode, :info})
** (EXIT) :error
and with
links = %{
{:file_src, :output} => {:decoder, :input},
{:decoder, :output} => {:lame, :input},
{:lame, :output} => {:converter, :input},
{:converter, :output} => {:sink, :input}
}
I get
iex(1)> alias Mp3Icecast.Pipeline
Mp3Icecast.Pipeline
iex(2)> {:ok, pid} = Pipeline.start_link("file1.mp3")
{:ok, #PID<0.486.0>}
iex(3)> Pipeline.play(pid)
:ok
iex(4)> [error] GenServer #PID<0.490.0> terminating
** (stop) exited in: :cannot_handle_message.invalid_caps({:message, {Membrane.Core.Message, :change_playback_state, :playing, []}}, {:mode, :info})
** (EXIT) :error
Last message: {Membrane.Core.Message, :change_playback_state, :playing, []}
State: %Membrane.Core.Element.State{controlling_pid: #PID<0.486.0>, delayed_demands: %{}, internal_state: %{frames_per_buffer: 2048, input_caps: nil, native: nil, output_caps: %Membrane.Caps.Audio.Raw{channels: 2, format: :s16le, sample_rate: 48000}, queue: ""}, module: Membrane.Element.FFmpeg.SWResample.Converter, name: :converter, pads: %{data: %{input: %Membrane.Element.Pad.Data{accepted_caps: [{Membrane.Caps.Audio.Raw, [format: one_of([:u8, :s16le, :s32le, :f32le, :f64le]), channels: one_of([1, 2])]}, {Membrane.Caps.Audio.Raw, [format: :s24le, channels: one_of([1, 2])]}], availability: :always, caps: nil, current_id: nil, demand: 0, demand_unit: :bytes, direction: :input, end_of_stream?: false, input_buf: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, metric: Membrane.Buffer.Metric.ByteSize, min_demand: 16384, name: :converter, preferred_size: 65536, q: #Qex<[]>, toilet: false}, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.491.0>, start_of_stream?: false, sticky_messages: []}, output: %Membrane.Element.Pad.Data{accepted_caps: {Membrane.Caps.Audio.Raw, [format: one_of([:u8, :s16le, :s32le, :f32le, :f64le]), channels: one_of([1, 2])]}, availability: :always, caps: nil, current_id: nil, demand: 10, demand_unit: nil, direction: :output, end_of_stream?: false, input_buf: nil, mode: :pull, options: {:ok, nil}, other_demand_unit: :buffers, other_ref: :input, pid: #PID<0.492.0>, start_of_stream?: false, sticky_messages: nil}}, dynamic_currently_linking: [], info: %{}}, playback: %Membrane.Core.Playback{async_state_change: false, pending_state: nil, state: :playing, target_locked?: false, target_state: :playing}, playback_buffer: %Membrane.Core.Element.PlaybackBuffer{q: #Qex<[{Membrane.Core.Message, :demand, 10, [for_pad: :output]}, {Membrane.Core.Message, :caps, %Membrane.Caps.Audio.MPEG{bitrate: 192, channel_mode: nil, channels: 2, copyright: nil, crc_enabled: nil, emphasis_mode: nil, layer: :layer3, mode_extension: nil, original: nil, padding_enabled: nil, private: nil, sample_rate: 44100, version: :v1}, [for_pad: :input]}]>}, terminating: false, type: :filter, watcher: #PID<0.486.0>}
** (EXIT from #PID<0.483.0>) shell process exited with reason: exited in: :cannot_handle_message.invalid_caps({:message, {Membrane.Core.Message, :change_playback_state, :playing, []}}, {:mode, :info})
** (EXIT) :error
Here is my code if you want to check if I have done something wrong there
@mspanc Any update on this? Does this work?
@anildigital I've managed to fix your code:
mix.exs
without override flag, use membrane_element_shout
from master and run mix deps.get
links = %{
{:file_src, :output} => {:decoder, :input},
{:decoder, :output} => {:converter, :input},
{:converter, :output} => {:lame, :input},
{:lame, :output} => {:sink, :input}
}
:s32le
format and sample rate 44100 on input, so that's what converter has to output:
converter: %Membrane.Element.FFmpeg.SWResample.Converter{
output_caps: %Membrane.Caps.Audio.Raw{
format: :s32le,
sample_rate: 44100,
channels: 2
}
},
With these fixes I've managed to run the pipeline ;) Hope that helps, let us know if you have any other issues
@bblaszkow06
** (FunctionClauseError) no function clause matching in Membrane.Element.Shout.Sink.handle_event/4
(membrane_element_shout) lib/membrane_element_shout/sink.ex:39: Membrane.Element.Shout.Sink.handle_event(:input, %Membrane.Event.Discontinuity{duration: nil}, %Membrane.Element.CallbackContext.Event{pads: %{input: %Membrane.Element.Pad.Data{accepted_caps: Membrane.Caps.Audio.MPEG, availability: :always, buffer: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, demand_pid: #PID<0.4875.0>, linked_output_ref: :output, metric: Membrane.Buffer.Metric.Count, min_demand: 2, name: :sink, preferred_size: 10, q: #Qex<[]>, toilet: false}, caps: %Membrane.Caps.Audio.MPEG{bitrate: 192, channel_mode: nil, channels: 2, copyright: nil, crc_enabled: nil, emphasis_mode: nil, layer: :layer3, mode_extension: nil, original: nil, padding_enabled: nil, private: nil, sample_rate: 44100, version: :v1}, current_id: nil, demand: 20, demand_unit: :buffers, direction: :input, end_of_stream?: false, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.4875.0>, start_of_stream?: false, sticky_messages: []}}, playback_state: :playing}, %{consumer: %Membrane.Element.Shout.Sink.Consumer{guard: #PID<0.4877.0>, native_ref: #Reference<0.3139192917.2515140610.246631>}, ringbuffer_size: 20})
(membrane_core) lib/membrane/core/callback_handler.ex:59: Membrane.Core.CallbackHandler.exec_and_handle_callback/5
(membrane_core) lib/membrane/core/element/event_controller.ex:35: Membrane.Core.Element.EventController.exec_handle_event/4
(membrane_core) lib/membrane/core/element/message_dispatcher.ex:20: Membrane.Core.Element.MessageDispatcher.handle_message/3
(membrane_core) lib/membrane/element.ex:263: Membrane.Element.handle_info/2
(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {Membrane.Core.Message, :event, [%Membrane.Event.Discontinuity{duration: nil}, :input]}
State: %Membrane.Core.Element.State{controlling_pid: #PID<0.4870.0>, delayed_demands: %{}, internal_state: %{consumer: %Membrane.Element.Shout.Sink.Consumer{guard: #PID<0.4877.0>, native_ref: #Reference<0.3139192917.2515140610.246631>}, ringbuffer_size: 20}, module: Membrane.Element.Shout.Sink, name: :sink, pads: %{data: %{input: %Membrane.Element.Pad.Data{accepted_caps: Membrane.Caps.Audio.MPEG, availability: :always, buffer: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, demand_pid: #PID<0.4875.0>, linked_output_ref: :output, metric: Membrane.Buffer.Metric.Count, min_demand: 2, name: :sink, preferred_size: 10, q: #Qex<[]>, toilet: false}, caps: %Membrane.Caps.Audio.MPEG{bitrate: 192, channel_mode: nil, channels: 2, copyright: nil, crc_enabled: nil, emphasis_mode: nil, layer: :layer3, mode_extension: nil, original: nil, padding_enabled: nil, private: nil, sample_rate: 44100, version: :v1}, current_id: nil, demand: 20, demand_unit: :buffers, direction: :input, end_of_stream?: false, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.4875.0>, start_of_stream?: false, sticky_messages: []}}, dynamic_currently_linking: [], info: %{}}, parent_monitor: #Reference<0.3139192917.2515009538.246630>, playback: %Membrane.Core.Playback{async_state_change: false, pending_state: nil, state: :playing, target_locked?: false, target_state: :playing}, playback_buffer: %Membrane.Core.Element.PlaybackBuffer{q: #Qex<[]>}, type: :sink, watcher: #PID<0.4870.0>}
** (EXIT from #PID<0.4854.0>) shell process exited with reason: an exception was raised:
** (FunctionClauseError) no function clause matching in Membrane.Element.Shout.Sink.handle_event/4
(membrane_element_shout) lib/membrane_element_shout/sink.ex:39: Membrane.Element.Shout.Sink.handle_event(:input, %Membrane.Event.Discontinuity{duration: nil}, %Membrane.Element.CallbackContext.Event{pads: %{input: %Membrane.Element.Pad.Data{accepted_caps: Membrane.Caps.Audio.MPEG, availability: :always, buffer: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, demand_pid: #PID<0.4875.0>, linked_output_ref: :output, metric: Membrane.Buffer.Metric.Count, min_demand: 2, name: :sink, preferred_size: 10, q: #Qex<[]>, toilet: false}, caps: %Membrane.Caps.Audio.MPEG{bitrate: 192, channel_mode: nil, channels: 2, copyright: nil, crc_enabled: nil, emphasis_mode: nil, layer: :layer3, mode_extension: nil, original: nil, padding_enabled: nil, private: nil, sample_rate: 44100, version: :v1}, current_id: nil, demand: 20, demand_unit: :buffers, direction: :input, end_of_stream?: false, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.4875.0>, start_of_stream?: false, sticky_messages: []}}, playback_state: :playing}, %{consumer: %Membrane.Element.Shout.Sink.Consumer{guard: #PID<0.4877.0>, native_ref: #Reference<0.3139192917.2515140610.246631>}, ringbuffer_size: 20})
(membrane_core) lib/membrane/core/callback_handler.ex:59: Membrane.Core.CallbackHandler.exec_and_handle_callback/5
(membrane_core) lib/membrane/core/element/event_controller.ex:35: Membrane.Core.Element.EventController.exec_handle_event/4
(membrane_core) lib/membrane/core/element/message_dispatcher.ex:20: Membrane.Core.Element.MessageDispatcher.handle_message/3
(membrane_core) lib/membrane/element.ex:263: Membrane.Element.handle_info/2
(stdlib) gen_server.erl:637: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:711: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3```
For mix.lock
%{
"bimap": {:hex, :bimap, "1.0.1", "6c92d76d73ed1cf04b2b6e8548c732256da5fe9efe9ab64b90724db58bdc8f18", [:mix], [], "hexpm"},
"bunch": {:hex, :bunch, "1.2.0", "f26c6c84e2e5e245620c73a0a4560ca91a75b25744012537e055426568916ab7", [:mix], [], "hexpm"},
"bunch_native": {:hex, :bunch_native, "0.2.1", "0227d2a751a32f8c0b77dfec57c8dc7216351720c9c755c467e6d9387467fd1f", [:mix], [{:bundlex, "~> 0.2.7", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm"},
"bundlex": {:hex, :bundlex, "0.2.7", "8f46199bf4cf84a60cdfc142edeafbab37040167acc35dda8aa70433f2ff8162", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.5", [hex: :qex, repo: "hexpm", optional: false]}, {:secure_random, "~> 0.5", [hex: :secure_random, repo: "hexpm", optional: false]}], "hexpm"},
"calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"coerce": {:hex, :coerce, "1.0.1", "211c27386315dc2894ac11bc1f413a0e38505d808153367bd5c6e75a4003d096", [:mix], [], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"cowboy": {:hex, :cowboy, "2.6.3", "99aa50e94e685557cad82e704457336a453d4abcb77839ad22dbe71f311fcc06", [:rebar3], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
"cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm"},
"db_connection": {:hex, :db_connection, "2.1.1", "a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.8.0", "ca462e0d885f09a1c5a342dbd7c1dcf27ea63548c65a65e67334f4b61803822e", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.2.1", "a0f9af0fb50b19d3bb6237e512ac0ba56ea222c2bbea92e7c6c94897932c76ba", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_sql": {:hex, :ecto_sql, "3.2.0", "751cea597e8deb616084894dd75cbabfdbe7255ff01e8c058ca13f0353a3921b", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"file_system": {:hex, :file_system, "0.2.7", "e6f7f155970975789f26e77b8b8d8ab084c59844d8ecfaf58cbda31c494d14aa", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.17.0", "abe21542c831887a2b16f4c94556db9c421ab301aee417b7c4fbde7fbdbe01ec", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"membrane_caps_audio_mpeg": {:hex, :membrane_caps_audio_mpeg, "0.2.0", "9cf9a63f03e25b31cf31445325aa68e60a07d36ee1e759caa1422fa45df49367", [:mix], [], "hexpm"},
"membrane_caps_audio_raw": {:hex, :membrane_caps_audio_raw, "0.1.7", "419467f210b556b1790701383731c839393a8aec3ab3a4cbc9b971ef5bd521f4", [:mix], [{:bimap, "~> 1.0", [hex: :bimap, repo: "hexpm", optional: false]}, {:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_common_c": {:hex, :membrane_common_c, "0.2.3", "391c1a96b9434e1dea90845bfeafc197ce5f2a2507a5a7af06773e73e1e086e8", [:mix], [{:bundlex, "~> 0.2.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:shmex, "~> 0.2.0", [hex: :shmex, repo: "hexpm", optional: false]}, {:unifex, "~> 0.2.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_core": {:hex, :membrane_core, "0.3.2", "cdb45c2db4654485d4405443af6d78bda5fcdae06f9c5774478f77c51d43fc63", [:mix], [{:bunch, "~> 1.1", [hex: :bunch, repo: "hexpm", optional: false]}, {:qex, "~> 0.3", [hex: :qex, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_element_ffmpeg_swresample": {:hex, :membrane_element_ffmpeg_swresample, "0.2.3", "f6bd69381a8108cfe785122ad7d1b4ad3021d2c194e6cd7fdfd378c460a8e4ea", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.2.1", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_caps_audio_raw, "~> 0.1.0", [hex: :membrane_caps_audio_raw, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.2.0", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:mockery, "~> 2.1", [hex: :mockery, repo: "hexpm", optional: false]}, {:unifex, "~> 0.2.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_element_file": {:hex, :membrane_element_file, "0.2.3", "e8134811a730601b5096284aac4793ceb31f1755baf20ee2649db9e403d2ef46", [:mix], [{:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:mockery, "~> 2.2", [hex: :mockery, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_element_lame": {:hex, :membrane_element_lame, "0.3.3", "06cfa3d577244c474b3d1f032370d70ff79c9d24f1eb1f7d6d55cec672b4e2d3", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.2.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_caps_audio_mpeg, "~> 0.2.0", [hex: :membrane_caps_audio_mpeg, repo: "hexpm", optional: false]}, {:membrane_caps_audio_raw, "~> 0.1.0", [hex: :membrane_caps_audio_raw, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.2.0", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:unifex, "~> 0.2.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_element_mad": {:hex, :membrane_element_mad, "0.2.3", "3b3e19db830b62de803348d46f9e8c6e0c85deb3a1699032354ee2f2fa2cf2a3", [:mix], [{:bundlex, "~> 0.2.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_caps_audio_mpeg, "~> 0.2.0", [hex: :membrane_caps_audio_mpeg, repo: "hexpm", optional: false]}, {:membrane_caps_audio_raw, "~> 0.1.0", [hex: :membrane_caps_audio_raw, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.2.0", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:unifex, "~> 0.2.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_element_portaudio": {:hex, :membrane_element_portaudio, "0.2.3", "d27988283e641f888d2ac21a80aecea2a3ffe8e9e238b04449fd460634181062", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.2.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_caps_audio_raw, "~> 0.1.0", [hex: :membrane_caps_audio_raw, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.2.2", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}, {:mockery, "~> 2.1", [hex: :mockery, repo: "hexpm", optional: false]}, {:unifex, "~> 0.2.0", [hex: :unifex, repo: "hexpm", optional: false]}], "hexpm"},
"membrane_element_shout": {:git, "https://github.com/membraneframework/membrane-element-shout.git", "24fc6eece74fe3d545e049763fba4f80fb510109", [branch: "master"]},
"membrane_loggers": {:hex, :membrane_loggers, "0.2.5", "f0178a40d9f532e2ebcd838bd2327236dd65e416b19adba8738d6c44a479ad9f", [:mix], [{:bunch_native, "~> 0.2.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.2.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:membrane_common_c, "~> 0.2.2", [hex: :membrane_common_c, repo: "hexpm", optional: false]}, {:membrane_core, "~> 0.3.0", [hex: :membrane_core, repo: "hexpm", optional: false]}], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"},
"mockery": {:hex, :mockery, "2.3.0", "f1af3976916e7402427116f491e3038a251857de8f0836952c2fa24ad6de4317", [:mix], [], "hexpm"},
"numbers": {:hex, :numbers, "5.1.1", "1277dbee5dc73b0e1608bd6d318bd8338cbcba5b68cade65f24e4bb402676b5c", [:mix], [{:coerce, "~> 1.0", [hex: :coerce, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
"phoenix": {:hex, :phoenix, "1.4.10", "619e4a545505f562cd294df52294372d012823f4fd9d34a6657a8b242898c255", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.1", "274a4b07c4adbdd7785d45a8b0bb57634d0b4f45b18d2c508b26c0344bd59b8f", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_live_view": {:git, "https://github.com/phoenixframework/phoenix_live_view.git", "98249158878f26239803b8da0fc333fc7bf77f91", []},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm"},
"plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
"plug_cowboy": {:hex, :plug_cowboy, "2.1.0", "b75768153c3a8a9e8039d4b25bb9b14efbc58e9c4a6e6a270abff1cd30cbe320", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.15.1", "23ce3417de70f4c0e9e7419ad85bdabcc6860a6925fe2c6f3b1b5b1e8e47bf2f", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"qex": {:hex, :qex, "0.5.0", "5a3a9becf67d4006377c4c247ffdaaa8ae5b3634a0caadb788dc24d6125068f4", [:mix], [], "hexpm"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
"ratio": {:hex, :ratio, "2.2.2", "c26013b9af7d03cf451bbe11608046e4c9d06e127f5e387668ae97163e75a6dd", [:mix], [{:numbers, "~> 5.1.0", [hex: :numbers, repo: "hexpm", optional: false]}], "hexpm"},
"secure_random": {:hex, :secure_random, "0.5.1", "c5532b37c89d175c328f5196a0c2a5680b15ebce3e654da37129a9fe40ebf51b", [:mix], [], "hexpm"},
"shmex": {:hex, :shmex, "0.2.0", "2dc5e3919171e69993729fab2eee5bde6b679a4c7da91fd88e41c4254cc65fef", [:mix], [{:bunch_native, "~> 0.2.0", [hex: :bunch_native, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.2.4", [hex: :bundlex, repo: "hexpm", optional: false]}], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"},
"tzdata": {:hex, :tzdata, "1.0.1", "f6027a331af7d837471248e62733c6ebee86a72e57c613aa071ebb1f750fc71a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
"unifex": {:hex, :unifex, "0.2.5", "a279c09e0bc2a9a50b5fa0552c36783964601f803bb27813122bb17a03be4ebf", [:mix], [{:bunch, "~> 1.0", [hex: :bunch, repo: "hexpm", optional: false]}, {:bundlex, "~> 0.2.0", [hex: :bundlex, repo: "hexpm", optional: false]}, {:shmex, "~> 0.2.0", [hex: :shmex, repo: "hexpm", optional: false]}], "hexpm"},
}
and here is pipeline.ex
defmodule Mp3Icecast.Pipeline do
use Membrane.Pipeline
def handle_init(path_to_mp3) do
children = [
# Stream from file
file_src: %Membrane.Element.File.Source{location: path_to_mp3},
# Decode frames
decoder: Membrane.Element.Mad.Decoder,
# Convert Raw :s24le to Raw :s16le
converter: %Membrane.Element.FFmpeg.SWResample.Converter{
output_caps: %Membrane.Caps.Audio.Raw{
format: :s32le,
sample_rate: 44100,
channels: 2
}
},
lame: Membrane.Element.Lame.Encoder,
# Stream data into PortAudio to play it on speakers.
sink: %Membrane.Element.Shout.Sink{
host: "localhost",
port: 8000,
password: "hackme",
mount: "/stream",
ringbuffer_size: 20
}
]
# Map that describes how we want data to flow
# It is formated as such
# {:child, :output_pad} => {:another_child, :input_pad}
links = %{
{:file_src, :output} => {:decoder, :input},
{:decoder, :output} => {:converter, :input},
{:converter, :output} => {:lame, :input},
{:lame, :output} => {:sink, :input}
}
spec = %Membrane.Pipeline.Spec{
children: children,
links: links
}
{{:ok, spec}, %{}}
end
end
@anildigital It's not a bug, it's a feature :wink: It's caused by an mp3 file containing IDv3 tag(s) at the beginning and since there's no proper parser, the decoder will emit discontinuity events (assuming the file is broken). Anyway, I've merged a workaround for it (ignoring discontinuity in a shout sink), so you can update the element and the error should disappear. Another solution would be to use an mp3 file without tags
@bblaszkow06 I am still getting following after updating the code. Not sure if I am missing anything.
:ok
iex(5)> [error] GenServer #PID<0.585.0> terminating
** (FunctionClauseError) no function clause matching in Membrane.Element.Shout.Sink.handle_event/4
(membrane_element_shout) lib/membrane_element_shout/sink.ex:39: Membrane.Element.Shout.Sink.handle_event(:input, %Membrane.Event.Discontinuity{duration: nil}, %Membrane.Element.CallbackContext.Event{pads: %{input: %Membrane.Element.Pad.Data{accepted_caps: Membrane.Caps.Audio.MPEG, availability: :always, buffer: %Membrane.Core.InputBuffer{current_size: 0, demand: 0, demand_pid: #PID<0.584.0>, linked_output_ref: :output, metric: Membrane.Buffer.Metric.Count, min_demand: 2, name: :sink, preferred_size: 10, q: #Qex<[]>, toilet: false}, caps: %Membrane.Caps.Audio.MPEG{bitrate: 192, channel_mode: nil, channels: 2, copyright: nil, crc_enabled: nil, emphasis_mode: nil, layer: :layer3, mode_extension: nil, original: nil, padding_enabled: nil, private: nil, sample_rate: 44100, version: :v1}, current_id: nil, demand: 20, demand_unit: :buffers, direction: :input, end_of_stream?: false, mode: :pull, options: {:ok, nil}, other_demand_unit: nil, other_ref: :output, pid: #PID<0.584.0>, start_of_stream?: false, sticky_messages: []}}, playback_state: :playing}, %{consumer: %Membrane.Element.Shout.Sink.Consumer{guard: #PID<0.587.0>, native_ref: #Reference<0.3317838516.393347075.210970>}, ringbuffer_size: 20})
(membrane_core) lib/membrane/core/callback_handler.ex:59: Membrane.Core.CallbackHandler.exec_and_handle_callback/5
(membrane_core) lib/membrane/core/element/event_controller.ex:35: Membrane.Core.Element.EventController.exec_handle_event/4
(membrane_core) lib/membrane/core/element/message_dispatcher.ex:20: Membrane.Core.Element.MessageDispatcher.handle_message/3
Are you sure the latest master
of :membrane_element_shout
was used?
cat mix.lock | grep shout
should return:
"membrane_element_shout": {:git, "https://github.com/membraneframework/membrane-element-shout.git", "cb98e94f5c5793de0d0cdea50d3ab1b50338fc95", []},
To be sure, you can run mix deps.update membrane_element_shout
@anildigital any updates on this?
@mspanc It was not working well for me. I will check soon and update.
Getting this error
I have pipeline set like this