Skip to content

Instantly share code, notes, and snippets.

@gyk
Last active April 24, 2024 09:24
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save gyk/49dc80c58691a21a1c5f5e16926beaa6 to your computer and use it in GitHub Desktop.
Save gyk/49dc80c58691a21a1c5f5e16926beaa6 to your computer and use it in GitHub Desktop.

FFmpeg Minimal Build for RTMP Streaming

This tutorial will work you through steps of configuring an FFmpeg build tailored for RTMP streaming on macOS. At first I think of making it support general live streaming, with additional protocols like HLS, but to keep things simple let's stick with RTMP for now. (Anyway, I do include HLS in the protocol list as well as some related bitstream filters but it's untested.)

Goal

The built FFmpeg executable should

  • Be able to pull/push RTMP streams, either by forwarding the stream from rtmp:// address or serving media files.
  • Be capable of extracting metadata from A/V packets, e.g., parsing the SPS/PPS of H.264 header, but not the encoding/decoding part (will always use -vcodec copy). Supported codecs: H.264 for video, AAC/MP3 for audio.
  • Be able to transmux common container formats (FLV, MP4, MPEG-2 TS).
  • Optimized for binary size.

Strictly speaking it's not a really "minimal" build for RTMP, it's just small enough without losing core functionality.

Steps

List options marked as "[autodetect]" and disable them

cd $FFMPEG
./configure -h \
    | rg '\[autodetect\]' \
    | rg -o -e '--[^ ]+' \
    | rg -e '--(enable|disable)' -r '--disable'

which outputs:

--disable-pthreads
--disable-w32threads
--disable-os2threads
--disable-alsa
--disable-appkit
--disable-avfoundation
--disable-bzlib
--disable-coreimage
--disable-iconv
--disable-libxcb
--disable-libxcb-shm
--disable-libxcb-xfixes
--disable-libxcb-shape
--disable-lzma
--disable-sndio
--disable-sdl2
--disable-xlib
--disable-zlib
--disable-amf
--disable-audiotoolbox
--disable-cuda
--disable-cuvid
--disable-d3d11va
--disable-dxva2
--disable-nvdec
--disable-nvenc
--disable-v4l2-m2m
--disable-vaapi
--disable-vdpau
--disable-videotoolbox

Join these lines and we obtain DISABLE_AUTODETECT_LIST.

List "everything"

Here "everything" refers to all available small components (demuxers, decoders, parsers, ...) that we can turn on and off when building FFmpeg.

./configure -h | rg -e '--list-'

The command above generates a meta list of --list-*s, each of which can be passed to configure to query all available components in a specific subcategory. If we simply pass --disable-everything, all the components from the big meta list will be disabled.

Based on our use case, we obtain the "everything" list as

EVERYTHING_LIST="
    --disable-everything \
    --enable-decoder=h264,aac,mp3 \
    --enable-encoder=aac,libmp3lame \
    --enable-parser=h264,aac,mp3 \
    --enable-demuxer=flv,mov,mpegts,h264,aac,mp3,live_flv \
    --enable-muxer=flv,mov,mpegts \
    --enable-protocol=file,rtmp,pipe,hls \
    --enable-bsf=aac_adtstoasc,h264_mp4toannexb"

The bitstream filter "aac_adtstoasc" is necessary for transmuxing AAC audio in ADTS format (for MPEG-2 TS) into RTMP audio packet, so is ["h264_mp4toannexb"] (https://ffmpeg.org/ffmpeg-bitstream-filters.html#h264_005fmp4toannexb) for transmuxing H.264 video in AvcC (for RTMP/FLV, MP4, etc.) into Annex. B format (for MPEG-2 TS).

FFmpeg can either use its built-in RTMP implementation (see the libavformat/rtmp.*.(h|c) source files) or depend on RTMPDump's librtmp via libavformat/librtmp.c. The latter has more complete protocol support (e.g. RTMPE, RTMPS, etc). You can optionally pass --enable-librtmp to switch to external RTMP dependency.

The final command

mkdir build
cd build
../configure \
    ${DISABLE_AUTODETECT_LIST} \
    ${EVERYTHING_LIST} \
    --disable-avdevice --disable-swscale --disable-postproc --disable-doc \
    --disable-runtime-cpudetect \
    --enable-pthreads --enable-gpl --enable-version3 \
    --enable-avcodec --enable-avformat --enable-swresample --enable-avfilter \
    --disable-programs --enable-ffmpeg --enable-small
make -j4

(FIXME: Do we need --enable-swresample?)

Sample output:

install prefix            /usr/local
C compiler                gcc
C library
ARCH                      x86 (generic)
big-endian                no
runtime cpu detection     no
standalone assembly       yes
x86 assembler             yasm
MMX enabled               yes
MMXEXT enabled            yes
3DNow! enabled            yes
3DNow! extended enabled   yes
SSE enabled               yes
SSSE3 enabled             yes
AESNI enabled             yes
AVX enabled               yes
AVX2 enabled              yes
AVX-512 enabled           yes
XOP enabled               yes
FMA3 enabled              yes
FMA4 enabled              yes
i686 features enabled     yes
CMOV is fast              yes
EBX available             yes
EBP available             yes
debug symbols             yes
strip symbols             yes
optimize for size         yes
optimizations             yes
static                    yes
shared                    no
postprocessing support    no
network support           yes
threading support         pthreads
safe bitstream reader     yes
texi2html enabled         no
perl enabled              yes
pod2man enabled           yes
makeinfo enabled          yes
makeinfo supports HTML    no

External libraries:
librtmp        securetransport

External libraries providing hardware acceleration:

Libraries:
avcodec        avfilter         avformat       avutil         swresample

Programs:
ffmpeg

Enabled decoders:
aac        h264           mp3

Enabled encoders:
aac

Enabled hwaccels:

Enabled parsers:
aac        h264           mpegaudio

Enabled demuxers:
aac        h264           mov      mpegts
flv        live_flv         mp3

Enabled muxers:
adts         flv            latm       mov          mpegts

Enabled protocols:
file         hls            rtmp      pipe

Enabled filters:
aformat        anull          atrim      format         null           trim

Enabled bsfs:
aac_adtstoasc      null      h264_mp4toannexb

Enabled indevs:

Enabled outdevs:

The built ffmpeg executable is less than 2.5MB, with the following shared library usage:

$ otool -L ./ffmpeg
./ffmpeg:
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1445.12.0)
	/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (compatibility version 1.2.0, current version 1.5.0)
	/System/Library/Frameworks/CoreMedia.framework/Versions/A/CoreMedia (compatibility version 1.0.0, current version 1.0.0)

Troubleshooting

  • "nasm/yasm not found or too old."

    Easy, brew install yasm

  • "ERROR: librtmp not found using pkg-config"

    This happens only if --enable-librtmp is passed. By checking ./ffbuild/config.log you will find it is libssl that is missing. It is actually a macOS High Sierra issue, and can be fixed by export PKG_CONFIG_PATH=/usr/local/opt/openssl/lib/pkgconfig.

References

@ioppermann
Copy link

On macOS, the rg tool is not available by default. Use this command to obtain the "disable [autodetect]" list by only using tools that are available by default:

./configure -h \
    | grep '\[autodetect\]' \
    | grep -Eo -e '--[^ ]+' \
    | sed 's/--enable/--disable/g'

The same for the "list everything" command:

./configure -h | grep -e '--list-'

@thegobot
Copy link

For mingw\msys2

--extra-ldflags=-static \
--extra-cflags=-static \

otherwise there may be an error with libwinpthread-1.dll

@serg06
Copy link

serg06 commented Apr 11, 2023

Can DISABLE_AUTODETECT_LIST be replaced with --disable-autodetect?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment