# ── Stage 1: Build FFmpeg with DeckLink + NVENC (HEVC/H264) support ───────── # All-Intra HEVC NVENC is the master codec for growing-file ingest (see # docs/design/2026-05-29-all-intra-hevc-ingest.md). This stage gets the # nv-codec-headers (header-only, no driver / no full CUDA toolkit needed) # so ffmpeg's configure can light up hevc_nvenc / h264_nvenc / cuvid. # At runtime, /dev/nvidia* + the host driver libs (via the NVIDIA Container # Toolkit) supply the actual encoder. FROM debian:bookworm AS ffmpeg-builder RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential nasm yasm pkg-config git ca-certificates python3 \ libssl-dev libx264-dev libx265-dev libvpx-dev libopus-dev \ libmp3lame-dev libsrt-openssl-dev \ libzmq3-dev zlib1g-dev libstdc++-12-dev \ && rm -rf /var/lib/apt/lists/* # Copy in BMD DeckLink SDK headers and patch script COPY sdk/ /decklink-sdk/ COPY patch_decklink.py /patch_decklink.py COPY decklink-sdk16.patch /decklink-sdk16.patch # nv-codec-headers — just the ffnvcodec public headers + a pkg-config file. # Pin to a tag known to work with FFmpeg 7.1 (n12.x series). RUN git clone --depth=1 --branch n12.1.14.0 https://github.com/FFmpeg/nv-codec-headers.git /nv-codec-headers \ && make -C /nv-codec-headers PREFIX=/usr/local install # Pull FFmpeg 7.1 source RUN git clone --depth=1 --branch release/7.1 https://git.ffmpeg.org/ffmpeg.git /ffmpeg # Patch FFmpeg DeckLink code for SDK 16.x API changes RUN python3 /patch_decklink.py WORKDIR /ffmpeg # NVENC adds: --enable-nvenc (encoder), --enable-cuvid (decoder), --enable-ffnvcodec. # We deliberately do NOT enable --enable-cuda-nvcc / --enable-libnpp here — those # require the full ~3GB CUDA toolkit and are only needed for GPU filters like # yadif_cuda / scale_cuda. If §5's GPU deinterlace stretch goal goes ahead, # rebuild this image off nvidia/cuda:12.x-devel and flip those flags on. RUN ./configure \ --prefix=/usr/local \ --pkg-config-flags="--static" \ --extra-cflags="-I/decklink-sdk -I/usr/local/include" \ --extra-ldflags="-L/usr/local/lib" \ --enable-gpl \ --enable-nonfree \ --enable-libx264 \ --enable-libx265 \ --enable-libvpx \ --enable-libopus \ --enable-libmp3lame \ --enable-libsrt \ --enable-libzmq \ --enable-decklink \ --enable-ffnvcodec \ --enable-nvenc \ --enable-cuvid \ --disable-doc \ --disable-debug \ --disable-ffplay \ && make -j$(nproc) \ && make install # Sanity-check: hevc_nvenc and h264_nvenc must be present in the encoder list, # otherwise the resulting image is useless for the All-Intra HEVC pipeline. RUN /usr/local/bin/ffmpeg -hide_banner -encoders 2>&1 | grep -E 'nvenc' \ || (echo 'FATAL: nvenc encoders missing from ffmpeg build' && exit 1) # ── Stage 2: Runtime image ─────────────────────────────────────────────────── FROM node:20-bookworm # Runtime deps for compiled ffmpeg libs RUN apt-get update && apt-get install -y --no-install-recommends \ libx264-164 libx265-199 libvpx7 libopus0 libmp3lame0 \ libsrt1.5-openssl libzmq5 libstdc++6 libc++1 libc++abi1 \ && rm -rf /var/lib/apt/lists/* # Copy compiled ffmpeg/ffprobe COPY --from=ffmpeg-builder /usr/local/bin/ffmpeg /usr/local/bin/ffmpeg COPY --from=ffmpeg-builder /usr/local/bin/ffprobe /usr/local/bin/ffprobe COPY --from=ffmpeg-builder /usr/local/lib/ /usr/local/lib/ # DeckLink runtime .so COPY lib/libDeckLinkAPI.so /usr/lib/libDeckLinkAPI.so COPY lib/libDeckLinkPreviewAPI.so /usr/lib/libDeckLinkPreviewAPI.so RUN ldconfig # Mount points the recorder lifecycle expects to exist. # /live — HLS preview output (bound from host LIVE_DIR by node-agent) # /growing — growing-file master output (bound from host /mnt/NVME/MAM/growing) RUN mkdir -p /live /growing WORKDIR /app COPY package*.json ./ RUN npm install --omit=dev COPY . . EXPOSE 3001 CMD ["node", "src/index.js"]