generated from membraneframework/membrane_template_plugin
-
Notifications
You must be signed in to change notification settings - Fork 12
/
sink.exs
80 lines (67 loc) · 2.54 KB
/
sink.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Before running this example, make sure that target RTMP server is live.
# If you are streaming to eg. Youtube, you don't need to worry about it.
# If you want to test it locally, you can run the FFmpeg server with:
# ffmpeg -y -listen 1 -f flv -i rtmp://localhost:1935 -c copy dest.flv
Logger.configure(level: :info)
Mix.install([
:membrane_realtimer_plugin,
:membrane_hackney_plugin,
:membrane_h264_plugin,
:membrane_aac_plugin,
{:membrane_rtmp_plugin, path: __DIR__ |> Path.join("..") |> Path.expand()}
])
defmodule Example do
use Membrane.Pipeline
@samples_url "https://raw.githubusercontent.com/membraneframework/static/gh-pages/samples/big-buck-bunny/"
@video_url @samples_url <> "bun33s_480x270.h264"
@audio_url @samples_url <> "bun33s.aac"
@impl true
def handle_init(_ctx, destination: destination) do
structure = [
child(:video_source, %Membrane.Hackney.Source{
location: @video_url,
hackney_opts: [follow_redirect: true]
})
|> child(:video_parser, %Membrane.H264.Parser{
generate_best_effort_timestamps: %{framerate: {25, 1}},
output_stream_structure: :avc1
})
|> child(:video_realtimer, Membrane.Realtimer)
|> via_in(Pad.ref(:video, 0))
|> child(:rtmp_sink, %Membrane.RTMP.Sink{rtmp_url: destination}),
child(:audio_source, %Membrane.Hackney.Source{
location: @audio_url,
hackney_opts: [follow_redirect: true]
})
|> child(:audio_parser, %Membrane.AAC.Parser{
out_encapsulation: :none
})
|> child(:audio_realtimer, Membrane.Realtimer)
|> via_in(Pad.ref(:audio, 0))
|> get_child(:rtmp_sink)
]
{[spec: structure], %{streams_to_end: 2}}
end
# The rest of the example module is only used for self-termination of the pipeline after processing finishes
@impl true
def handle_element_end_of_stream(:rtmp_sink, _pad, _ctx, %{streams_to_end: 1} = state) do
{[terminate: :shutdown], %{state | streams_to_end: 0}}
end
@impl true
def handle_element_end_of_stream(:rtmp_sink, _pad, _ctx, state) do
{[], %{state | streams_to_end: 1}}
end
@impl true
def handle_element_end_of_stream(_child, _pad, _ctx, state) do
{[], state}
end
end
destination = System.get_env("RTMP_URL", "rtmp://localhost:1935")
# Initialize the pipeline and start it
{:ok, _supervisor, pipeline} = Membrane.Pipeline.start_link(Example, destination: destination)
monitor_ref = Process.monitor(pipeline)
# Wait for the pipeline to finish
receive do
{:DOWN, ^monitor_ref, :process, _pid, _reason} ->
:ok
end