%define _debugsource_template %{nil} %define debug_package %{nil} %global ffmpeg_version 8.1.2 %global fedora_ffmpeg_commit 567905bced8b89832247b1a3965d0b4df183e3f9 Name: ffmpegthumbnailer-minimal Version: 2.3.1 Release: 1%{?dist} Summary: Video thumbnailer without FFmpeg's network and desktop integrations License: GPL-2.0-or-later URL: https://github.com/dirkvdb/ffmpegthumbnailer Source0: %{url}/archive/refs/tags/v%{version}.tar.gz#/%{name}-%{version}.tar.gz Source1: https://ffmpeg.org/releases/ffmpeg-%{ffmpeg_version}.tar.xz Source2: https://src.fedoraproject.org/rpms/ffmpeg/raw/%{fedora_ffmpeg_commit}/f/enable_decoders#/ffmpeg-%{ffmpeg_version}-enable_decoders BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: make BuildRequires: binutils BuildRequires: cmake BuildRequires: pkgconf-pkg-config BuildRequires: pkgconfig(libjpeg) BuildRequires: pkgconfig(libpng) BuildRequires: pkgconfig(zlib) BuildRequires: pkgconfig(dav1d) BuildRequires: pkgconfig(openh264) BuildRequires: python3 %ifarch x86_64 %{ix86} BuildRequires: nasm %endif Provides: bundled(ffmpeg) = %{ffmpeg_version} Conflicts: ffmpegthumbnailer # H.264 is decoded through OpenH264, which stays a shared library; without it # nothing in an MP4 shot by a phone or a camera gets a thumbnail. Recommends: openh264%{?_isa} %description Generate PNG and JPEG video thumbnails with normal file-manager integration. Private static FFmpeg libraries avoid dependencies on system FFmpeg, Samba, network protocols, hardware acceleration, and unrelated external filters. The build uses Fedora's decoder allowlist, with dav1d for AV1 and OpenH264 for H.264 when the real OpenH264 library is installed. HEVC, VC-1 and VVC decoding are not included. This package replaces the ffmpegthumbnailer command, not the public libffmpegthumbnailer library. %prep %setup -q -n ffmpegthumbnailer-%{version} -a 1 # Link private FFmpeg archives with their transitive dependencies, while # keeping the C/C++ runtime and image/codec libraries dynamically linked. sed -i 's/set(FFMPEG_USE_STATIC_LIBS ${ENABLE_FULL_STATIC})/set(FFMPEG_USE_STATIC_LIBS ON)/' cmake/FindFFmpeg.cmake %build %set_build_flags ffmpeg_prefix="$PWD/ffmpeg-private" pushd ffmpeg-%{ffmpeg_version} ./configure \ --prefix="$ffmpeg_prefix" --libdir="$ffmpeg_prefix/lib" \ --enable-static --disable-shared --enable-pic --enable-gpl --enable-lto=auto \ --optflags="$CFLAGS" --extra-ldflags="$LDFLAGS" \ --disable-autodetect --disable-programs --disable-doc \ --disable-network --disable-protocols --enable-protocol=file,pipe \ --disable-avdevice --disable-swresample --disable-hwaccels \ --disable-v4l2-m2m --disable-vaapi --disable-vdpau --disable-vulkan \ --disable-encoders --disable-muxers --disable-decoders \ --enable-decoder="$(awk '!/^#/ && NF {printf "%s,", $1}' %{SOURCE2})" \ --disable-filters --enable-filter=buffer,buffersink,scale,format,yadif,rotate,transpose \ --enable-zlib --enable-libdav1d --enable-libopenh264 %make_build V=0 make install popd export PKG_CONFIG_PATH="$ffmpeg_prefix/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" %cmake \ -DCMAKE_PREFIX_PATH="$ffmpeg_prefix" \ -DCMAKE_SKIP_RPATH=ON \ -DENABLE_SHARED=OFF -DENABLE_STATIC=ON -DENABLE_FULL_STATIC=OFF \ -DENABLE_GIO=OFF -DENABLE_THUMBNAILER=ON -DENABLE_AUDIO_THUMBNAILER=OFF \ -DENABLE_TESTS=ON %cmake_build %install install -Dpm 0755 %{_vpath_builddir}/ffmpegthumbnailer %{buildroot}%{_bindir}/ffmpegthumbnailer install -Dpm 0644 man/ffmpegthumbnailer.1 %{buildroot}%{_mandir}/man1/ffmpegthumbnailer.1 install -Dpm 0644 dist/ffmpegthumbnailer.thumbnailer %{buildroot}%{_datadir}/thumbnailers/ffmpegthumbnailer.thumbnailer %check %ctest %{buildroot}%{_bindir}/ffmpegthumbnailer -i test/test_sample.flv -o thumbnail.png -s 128 %{buildroot}%{_bindir}/ffmpegthumbnailer -i test/test_sample.flv -o thumbnail.jpg -s 128 python3 - <<'PY' from pathlib import Path import struct import subprocess binary = "%{buildroot}%{_bindir}/ffmpegthumbnailer" png = Path("thumbnail.png").read_bytes() assert png[:8] == b"\x89PNG\r\n\x1a\n" assert max(struct.unpack(">II", png[16:24])) == 128 assert Path("thumbnail.jpg").read_bytes()[:3] == b"\xff\xd8\xff" assert subprocess.run([binary, "-i", "missing-video", "-o", "missing.png"], capture_output=True).returncode != 0 with Path("test/test_sample.flv").open("rb") as video: subprocess.run([binary, "-i", "-", "-o", "stdin.png", "-s", "128"], stdin=video, check=True, timeout=30) assert Path("stdin.png").read_bytes()[:8] == b"\x89PNG\r\n\x1a\n" needed = subprocess.check_output(["readelf", "-d", binary], text=True) assert "(RPATH)" not in needed and "(RUNPATH)" not in needed allowed = ("libc.so.", "libm.so.", "libgcc_s.so.", "libstdc++.so.", "libpng16.so.", "libjpeg.so.", "libz.so.", "libdav1d.so.", "libopenh264.so.", "libpthread.so.", "libdl.so.", "librt.so.", "ld-linux") for line in needed.splitlines(): if "(NEEDED)" in line: library = line.split("[", 1)[1].split("]", 1)[0] assert library.startswith(allowed), library PY %files %license COPYING ffmpeg-%{ffmpeg_version}/COPYING.GPLv2 ffmpeg-%{ffmpeg_version}/LICENSE.md %doc README %{_bindir}/ffmpegthumbnailer %{_mandir}/man1/ffmpegthumbnailer.1* %{_datadir}/thumbnailers/ffmpegthumbnailer.thumbnailer %changelog * Sun Sep 06 2026 sachesi - 2.3.1-1 - Package the thumbnailer with private FFmpeg libraries and minimal external integrations.