ffmpegmakefileffmpeg-wasm

FFmpeg WASM Custom build : defining custom flags


I wish to create custom ffmpeg.wasm build

Now the official GUIDE show four commands "make dev" "make prd" etc

So I cloned THE REPO and ran "make prd". It did build, but obviously, this build was with default settings, whatever exactly they made be.

So pardon my stupidity, as I cannot figure out how / where / what do I edit to set the custom flags about what I want to be included / excluded in the build?


Solution

  • For anyone else wondering about this, I got my custom build. Here is what I did

    1. This is more of a prerequisite but just in case : Im on windows so I have Docker Desktop running and WSL 2 enabled and running. I boot up my Ubuntu installation and run commands there. (Tried directly from windows but was a headache and I did not get it to work)

    2. I only needed webm muxers. 0 encoders / 0 decoders

    3. I removed most of the stuff from Dockerfile

    this is my Dockerfile

    # syntax=docker/dockerfile-upstream:master-labs
    
    # Stage 1: Base Emscripten environment
    FROM emscripten/emsdk:3.1.40 AS emsdk-base
    ARG EXTRA_CFLAGS
    ARG EXTRA_LDFLAGS
    ENV INSTALL_DIR=/opt
    ENV FFMPEG_VERSION=n5.1.4
    ENV CFLAGS="-I$INSTALL_DIR/include $CFLAGS $EXTRA_CFLAGS"
    ENV CXXFLAGS="$CFLAGS"
    ENV LDFLAGS="-L$INSTALL_DIR/lib $LDFLAGS $CFLAGS $EXTRA_LDFLAGS"
    ENV EM_PKG_CONFIG_PATH=$EM_PKG_CONFIG_PATH:$INSTALL_DIR/lib/pkgconfig:/emsdk/upstream/emscripten/system/lib/pkgconfig
    ENV EM_TOOLCHAIN_FILE=$EMSDK/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake
    ENV PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$EM_PKG_CONFIG_PATH
    RUN apt-get update && \
        apt-get install -y pkg-config autoconf automake libtool ragel
    
    # Stage 2: Build zlib
    FROM emsdk-base AS zlib-builder
    ENV ZLIB_BRANCH=v1.2.11
    ADD https://github.com/ffmpegwasm/zlib.git#$ZLIB_BRANCH /src
    COPY build/zlib.sh /src/build.sh
    RUN bash -x /src/build.sh
    
    # Stage 3: Base FFmpeg image with source code and zlib
    FROM emsdk-base AS ffmpeg-base
    RUN embuilder build sdl2 sdl2-mt
    ADD https://github.com/FFmpeg/FFmpeg.git#$FFMPEG_VERSION /src
    COPY --from=zlib-builder $INSTALL_DIR $INSTALL_DIR
    
    # Stage 4: Build FFmpeg with specified configuration
    FROM ffmpeg-base AS ffmpeg-builder
    COPY build/ffmpeg.sh /src/build.sh
    RUN bash -x /src/build.sh \
        --disable-all \
        --enable-protocol=file \
        --enable-avcodec \
        --enable-avformat \
        --enable-avfilter \
        --enable-demuxer=concat,matroska \
        --enable-muxer=matroska \
        --enable-parser=vp8,vp9,opus,vorbis
    
    # Stage 5: Build FFmpeg WebAssembly module
    FROM ffmpeg-builder AS ffmpeg-wasm-builder
    COPY src/bind /src/src/bind
    COPY src/fftools /src/src/fftools
    COPY build/ffmpeg-wasm.sh /src/build.sh
    RUN mkdir -p /src/dist/umd && bash -x /src/build.sh \
        -o dist/umd/ffmpeg-core.js
    RUN mkdir -p /src/dist/esm && bash -x /src/build.sh \
        -sEXPORT_ES6 \
        -o dist/esm/ffmpeg-core.js
    
    # Stage 6: Export the built files
    FROM scratch AS exportor
    COPY --from=ffmpeg-wasm-builder /src/dist /dist
    

    4. Needed to also edit ffmpeg.sh and ffmpeg-wasm.sh in the "build" folder

    this is -wasm.sh

    #!/bin/bash
    # `-o <OUTPUT_FILE_NAME>` must be provided when using this build script.
    # ex:
    #     bash ffmpeg-wasm.sh -o ffmpeg.js
    
    set -euo pipefail
    
    EXPORT_NAME="createFFmpegCore"
    
    CONF_FLAGS=(
      -I. 
      -I./src/fftools 
      -I$INSTALL_DIR/include 
      -L$INSTALL_DIR/lib 
      libavfilter/libavfilter.a
      libavformat/libavformat.a
      libavcodec/libavcodec.a
      libavutil/libavutil.a
      -Wno-deprecated-declarations 
      $LDFLAGS 
      -sENVIRONMENT=worker
      -sWASM_BIGINT
      -sUSE_SDL=2
      -sMODULARIZE
      ${FFMPEG_MT:+ -sINITIAL_MEMORY=1024MB}
      ${FFMPEG_MT:+ -sPTHREAD_POOL_SIZE=32}
      ${FFMPEG_ST:+ -sINITIAL_MEMORY=32MB -sALLOW_MEMORY_GROWTH}
      -sEXPORT_NAME="$EXPORT_NAME"
      -sEXPORTED_FUNCTIONS=$(node src/bind/ffmpeg/export.js)
      -sEXPORTED_RUNTIME_METHODS=$(node src/bind/ffmpeg/export-runtime.js)
      -lworkerfs.js
      --pre-js src/bind/ffmpeg/bind.js
      src/fftools/cmdutils.c 
      src/fftools/ffmpeg.c 
      src/fftools/ffmpeg_filter.c  # For filter function definitions
      src/fftools/ffmpeg_hw.c      # For hardware functions
      src/fftools/ffmpeg_mux.c 
      src/fftools/ffmpeg_opt.c 
      src/fftools/opt_common.c 
      src/fftools/ffprobe.c        # Added for ffprobe functionality
    )
    
    emcc "${CONF_FLAGS[@]}" $@
    

    and this is ffmpeg.sh

    #!/bin/bash
    
    set -euo pipefail
    
    CONF_FLAGS=(
      --target-os=none              # Disable target specific configs
      --arch=x86_32                 # Use x86_32 arch
      --enable-cross-compile        # Use cross compile configs
      --disable-asm                 # Disable asm
      --disable-stripping           # Disable stripping as it won't work
      # --disable-programs          # Removed to allow building programs like ffprobe
      --disable-doc                 # Disable doc build
      --disable-debug               # Disable debug mode
      --disable-runtime-cpudetect   # Disable cpu detection
      --disable-autodetect          # Disable env auto detect
      --enable-avcodec              # Enable avcodec
      --enable-avformat             # Enable avformat
      --enable-avfilter             # Enable avfilter
    
      # Assign toolchains and extra flags
      --nm=emnm
      --ar=emar
      --ranlib=emranlib
      --cc=emcc
      --cxx=em++
      --objcc=emcc
      --dep-cc=emcc
      --extra-cflags="$CFLAGS"
      --extra-cxxflags="$CXXFLAGS"
    
      # Disable thread when FFMPEG_ST is NOT defined
      ${FFMPEG_ST:+ --disable-pthreads --disable-w32threads --disable-os2threads}
    )
    
    emconfigure ./configure "${CONF_FLAGS[@]}" $@
    emmake make -j
    

    Now to say that I completely understand whats going on would be a lie :D
    I did some notorious "vibe-coding" with Grok to reach this.

    By the end, after running "make prd" I got my .wasm and .js
    Original 30mb now 1.06mb

    Everything works on the frontend.