Create thumbnail from mp4 video

Hello! I am a bit new with membrane framework, and i read about it and it looks amazing, so i have been trying it out. Now, i want to implement it in a personal project, where i need to extract a thumbnail from a video. I investigated a lot, and i can't find a reference in how to do this, i investigated the process and it looked like Parsing the MP4 video, demuxing it, redirecting the H264 file to a chain, and then decoding it. I was using this plugins, but failed successfully 🙂 {:membrane_file_plugin, "~> 0.16"}, {:membrane_mp4_plugin, "~> 0.29"}, {:membrane_h264_ffmpeg_plugin, "~> 0.28"}, {:membrane_h264_plugin, "~> 0.9"}, This is my current code
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
Can someone help me with this task?, or just give me an idea
1 Reply
Feliks
Feliks•4w ago
Hi, do you want to have just a single image being a thumbnail? Or maybe you want to generate a video stream that will be displayed as a thumbnail?

Did you find this page helpful?