defmodule MyThumbnail do
use Membrane.Pipeline
import Membrane.ChildrenSpec
@impl true
def handle_init(_ctx, mp4_path) do
unless File.exists?(mp4_path), do: raise "File not found: #{mp4_path}"
structure = [
# Common source + demuxer
child(:source, %Membrane.File.Source{location: mp4_path, seekable?: true})
|> child(:demuxer, %Membrane.MP4.Demuxer.ISOM{optimize_for_non_fast_start?: true}),
# === VIDEO chain ===
get_child(:demuxer)
|> via_out(:output, options: [kind: :video])
|> child(:h264_parser_in, %Membrane.H264.Parser{
output_stream_structure: :annexb, output_alignment: :au
})
|> child(:h264_dec, Membrane.H264.FFmpeg.Decoder)
|> child(:h264_enc, %Membrane.H264.FFmpeg.Encoder{preset: :ultrafast})
|> child(:h264_to_avc1, %Membrane.H264.Parser{
output_stream_structure: :avc1, output_alignment: :au
})
|> get_child(:muxer),
# === AUDIO chain (passthrough AAC) ===
get_child(:demuxer)
|> via_out(:output, options: [kind: :audio])
|> child(:aac_parser_in, %Membrane.AAC.Parser{output_config: :esds})
|> get_child(:muxer),
# TODO: Extract thumbnail and store it
# === Mux + Sink ===
child(:muxer, %Membrane.MP4.Muxer.ISOM{})
|> child(:sink, %Membrane.File.Sink{
location: "/Users/Mauricio/Desktop/personal/vyvo/VYVO-APP/processed.mp4"
})
]
{[spec: structure], %{}}
end
end
defmodule MyThumbnail do
use Membrane.Pipeline
import Membrane.ChildrenSpec
@impl true
def handle_init(_ctx, mp4_path) do
unless File.exists?(mp4_path), do: raise "File not found: #{mp4_path}"
structure = [
# Common source + demuxer
child(:source, %Membrane.File.Source{location: mp4_path, seekable?: true})
|> child(:demuxer, %Membrane.MP4.Demuxer.ISOM{optimize_for_non_fast_start?: true}),
# === VIDEO chain ===
get_child(:demuxer)
|> via_out(:output, options: [kind: :video])
|> child(:h264_parser_in, %Membrane.H264.Parser{
output_stream_structure: :annexb, output_alignment: :au
})
|> child(:h264_dec, Membrane.H264.FFmpeg.Decoder)
|> child(:h264_enc, %Membrane.H264.FFmpeg.Encoder{preset: :ultrafast})
|> child(:h264_to_avc1, %Membrane.H264.Parser{
output_stream_structure: :avc1, output_alignment: :au
})
|> get_child(:muxer),
# === AUDIO chain (passthrough AAC) ===
get_child(:demuxer)
|> via_out(:output, options: [kind: :audio])
|> child(:aac_parser_in, %Membrane.AAC.Parser{output_config: :esds})
|> get_child(:muxer),
# TODO: Extract thumbnail and store it
# === Mux + Sink ===
child(:muxer, %Membrane.MP4.Muxer.ISOM{})
|> child(:sink, %Membrane.File.Sink{
location: "/Users/Mauricio/Desktop/personal/vyvo/VYVO-APP/processed.mp4"
})
]
{[spec: structure], %{}}
end
end