KinoMembrane
Mix.install([
{:kino, "~> 0.13", override: true},
{:kino_membrane, "~> 0.3"},
{:membrane_hackney_plugin, "~> 0.11"},
{:membrane_ffmpeg_swresample_plugin, "~> 0.20"},
{:membrane_mp3_mad_plugin, "~> 0.18"},
{:membrane_aac_fdk_plugin, "~> 0.18"},
{:membrane_audio_mix_plugin, "~> 0.16"},
{:membrane_tee_plugin, "~> 0.12"},
{:membrane_kino_plugin,
github: "membraneframework-labs/membrane_kino_plugin", tag: "v0.3.2"}
])
Play MP3
import Membrane.ChildrenSpec
alias Membrane.{
AAC,
AudioMixer,
Hackney,
MP3,
RawAudio,
RCPipeline,
Tee,
Time
}
alias Membrane.FFmpeg.SWResample.Converter
kino = Membrane.Kino.Player.new(audio: true)
base_repo_url = "https://raw.githubusercontent.com/membraneframework/membrane_demo/master"
source_url = "#{base_repo_url}/simple_pipeline/sample.mp3"
pipeline = RCPipeline.start_link!()
spec =
child(:hackney, %Hackney.Source{
location: source_url,
hackney_opts: [follow_redirect: true]
})
|> via_in(:input, auto_demand_size: 10)
|> child(:decoder, MP3.MAD.Decoder)
|> child(:converter, %Converter{
output_stream_format: %RawAudio{
sample_format: :s16le,
sample_rate: 48000,
channels: 2
}
})
|> child(:encoder_aac, AAC.FDK.Encoder)
|> via_in(:audio)
|> child(:player, %Membrane.Kino.Player.Sink{kino: kino})
RCPipeline.exec_actions(pipeline, spec: spec)
KinoMembrane.pipeline_dashboard(pipeline)
Membrane.Pipeline.terminate(pipeline)
Mixing audio files
beep_url = "#{base_repo_url}/livebooks/audio_mixer/assets/beep.aac"
beep_audio_input =
child(:beep_hackney, %Hackney.Source{
location: beep_url,
hackney_opts: [follow_redirect: true]
})
|> child({:beep_decoder_aac, :beep}, AAC.FDK.Decoder)
|> child(:beeps, Tee.PushOutput)
n_beeps = 30
beeps_split =
for i <- 1..n_beeps do
get_child(:beeps)
|> via_in(:input, options: [offset: Time.seconds(i)])
|> get_child(:mixer)
end
background_url = "#{base_repo_url}/livebooks/audio_mixer/assets/sample.mp3"
background_audio_input =
child(:background_hackney, %Hackney.Source{
location: background_url,
hackney_opts: [follow_redirect: true]
})
|> child(:background_decoder_mp3, MP3.MAD.Decoder)
|> child(:background_converter, %Converter{
input_stream_format: %RawAudio{channels: 2, sample_format: :s24le, sample_rate: 48_000},
output_stream_format: %RawAudio{channels: 1, sample_format: :s16le, sample_rate: 44_100}
})
|> get_child(:mixer)
mixer_kino = Membrane.Kino.Player.new(audio: true)
mixer_output =
child(:mixer, AudioMixer)
|> child(:mixer_encoder_aac, AAC.FDK.Encoder)
|> via_in(:audio)
|> child(:mixer_player, %Membrane.Kino.Player.Sink{kino: mixer_kino})
mixer_spec = beeps_split ++ [beep_audio_input, background_audio_input, mixer_output]
mixer_pipeline = RCPipeline.start_link!()
RCPipeline.exec_actions(mixer_pipeline, spec: mixer_spec)
KinoMembrane.pipeline_dashboard(mixer_pipeline)
Membrane.Pipeline.terminate(mixer_pipeline)