#!/usr/bin/env bash # ============================================================================ # Baut ein MINIMALES, CODEC-LOSES LGPL-ffmpeg fuer Konjo Trading Journal. # # Nur Container-Remux (Stream-Copy) -> KEIN Video-/Audio-Codec enthalten. # => LGPL v2.1+ (kein --enable-gpl/--enable-nonfree) UND patentrechtlich sauber # (es wird kein H.264/H.265-Codec ausgeliefert oder ausgefuehrt). # # Ausfuehren in GIT BASH auf Windows (hat git + curl). Portable Toolchain # (w64devkit) wird heruntergeladen -> KEINE Installation, kein Admin. # # Ergebnis -> vendor/ffmpeg/ : # ffmpeg.exe, ffprobe.exe, LICENSE.txt, BUILD_INFO.txt # Die .spec bindet diese automatisch ein (bin/ + licenses/ffmpeg/). # # Wichtig: gebaut wird in C:\tj_ffmpeg_build (OHNE Leerzeichen im Pfad -- ffmpeg's # Build vertraegt keine Leerzeichen; der Projektpfad enthaelt eins). # ============================================================================ set -euo pipefail FFMPEG_TAG="${FFMPEG_TAG:-n7.1}" ROOT="$(cd "$(dirname "$0")/.." && pwd)" PY="$ROOT/.venv/Scripts/python.exe" BUILD="${TJ_FFBUILD:-/c/tj_ffmpeg_build}" OUT="$ROOT/vendor/ffmpeg" mkdir -p "$BUILD" "$OUT" # ---- 1) Portable Toolchain (w64devkit) ------------------------------------- cd "$BUILD" # Neuere w64devkit-Releases (>= 2.0.0) sind selbst-entpackende .7z.exe. # Wir pinnen die letzte reine ZIP-Version (1.23.0, GCC 14) und laden sie direkt # -> keine 7z-Extraktion noetig, deterministisch. W64_VER="${W64_VER:-1.23.0}" if [ ! -x "w64devkit/bin/gcc.exe" ]; then echo ">> w64devkit $W64_VER (portable MinGW-w64, ZIP) holen ..." URL="https://github.com/skeeto/w64devkit/releases/download/v${W64_VER}/w64devkit-${W64_VER}.zip" echo " $URL" curl -fSL -o w64devkit.zip "$URL" # -f: bei HTTP-Fehler abbrechen statt Fehlertext speichern # Frisch geladene Archive werden von Windows Defender kurz gescannt/gesperrt # -> warten, bis die Datei wirklich lesbar ist (bis ~40s). for _i in $(seq 1 20); do if "$PY" -c "open('w64devkit.zip','rb').read(4)" 2>/dev/null; then break; fi echo " warte auf Datei-Freigabe (Virenscanner?) ..."; sleep 2 done sz=$("$PY" -c "import os;print(os.path.getsize('w64devkit.zip'))" 2>/dev/null || echo 0) [ "$sz" -gt 1000000 ] || { echo "FEHLER: Download unlesbar/zu klein ($sz Bytes)."; exit 1; } # --- Integritaet: SHA-256 gegen GitHubs eigenen Digest (schliesst Manipulation/MITM aus) --- GOT="$("$PY" -c "import hashlib;print(hashlib.sha256(open('w64devkit.zip','rb').read()).hexdigest())")" EXPECT="$("$PY" - "$W64_VER" <<'PYEOF' import sys, json, urllib.request ver = sys.argv[1] try: req = urllib.request.Request( "https://api.github.com/repos/skeeto/w64devkit/releases/tags/v%s" % ver, headers={"User-Agent": "konjo-build"}) data = json.load(urllib.request.urlopen(req, timeout=30)) want = "w64devkit-%s.zip" % ver for a in data.get("assets", []): if a.get("name") == want: d = a.get("digest") or "" print(d.split(":", 1)[1] if d.startswith("sha256:") else "") break except Exception: print("") PYEOF )" echo " SHA-256 (lokal): $GOT" if [ -n "$EXPECT" ]; then echo " SHA-256 (GitHub): $EXPECT" [ "$GOT" = "$EXPECT" ] || { echo "FEHLER: Hash weicht von GitHub ab -> NICHT vertrauen, Abbruch."; exit 1; } echo " OK: Datei ist byte-genau die offizielle GitHub-Version." else echo " (Kein GitHub-Digest verfuegbar -> obigen Hash zusaetzlich auf virustotal.com pruefen.)" fi echo ">> entpacke w64devkit ($((sz/1024/1024)) MB) ..." "$PY" -c "import zipfile; zipfile.ZipFile('w64devkit.zip').extractall('.')" fi W64="$BUILD/w64devkit" # ---- 2) ffmpeg-Quellcode (LGPL 'corresponding source', Tag gepinnt) -------- if [ ! -d ffmpeg ]; then echo ">> ffmpeg $FFMPEG_TAG klonen ..." git clone --depth 1 -b "$FFMPEG_TAG" https://git.ffmpeg.org/ffmpeg.git fi # ---- 3) Konfigurieren (CODEC-LOS) + bauen ---------------------------------- # demuxer mov = mp4/mov/m4a; matroska = mkv/webm. muxer mp4/mov/matroska/webm. # parser+bsf noetig, damit Stream-Copy Timestamps/Extradata korrekt schreibt. # BEWUSST KEIN --enable-decoder / --enable-encoder. CFG='./configure --target-os=mingw32 --arch=x86_64 --cc=gcc --disable-everything --disable-gpl --disable-nonfree --disable-doc --disable-htmlpages --disable-manpages --disable-txtpages --disable-network --disable-autodetect --disable-debug --disable-ffplay --disable-x86asm --disable-inline-asm --enable-small --enable-protocol=file,pipe --enable-demuxer=mov,matroska --enable-muxer=mp4,mov,matroska,webm --enable-parser=h264,hevc,vp9,av1,aac,vorbis,opus,mpegaudio,mpeg4video --enable-bsf=h264_mp4toannexb,hevc_mp4toannexb,aac_adtstoasc,extract_extradata,vp9_superframe,av1_metadata --enable-ffprobe' CFG_ONELINE="$(echo "$CFG" | tr '\n' ' ' | tr -s ' ')" echo ">> configure + make (w64devkit-gcc via PATH, in Git Bash) ..." # ANHAENGEN (nicht voranstellen): Git-Bash-Coreutils (ln/rm/mktemp) behalten Vorrang # -> kein busybox-ln-Rechteproblem; gcc/make/binutils kommen von w64devkit (hat Git Bash nicht). export PATH="$PATH:$W64/bin" export TMPDIR="$BUILD/tmp"; mkdir -p "$TMPDIR" # Temp in den AV-ausgenommenen Ordner ( cd "$BUILD/ffmpeg" && eval "$CFG_ONELINE" && make -j4 ) # ---- 4) Ergebnisse + LGPL-Pflichtdateien einsammeln ------------------------ cp -f "$BUILD/ffmpeg/ffmpeg.exe" "$OUT/ffmpeg.exe" cp -f "$BUILD/ffmpeg/ffprobe.exe" "$OUT/ffprobe.exe" if [ -f "$BUILD/ffmpeg/COPYING.LGPLv2.1" ]; then cp -f "$BUILD/ffmpeg/COPYING.LGPLv2.1" "$OUT/LICENSE.txt" else cp -f "$BUILD/ffmpeg/LICENSE.md" "$OUT/LICENSE.txt" fi { echo "FFmpeg fuer Konjo Trading Journal -- LGPL corresponding source" echo "quelle: https://git.ffmpeg.org/ffmpeg.git tag: $FFMPEG_TAG" echo "toolchain: w64devkit (portable MinGW-w64)" echo "lizenz: LGPL v2.1+ (OHNE --enable-gpl / --enable-nonfree)" echo "hinweis: codec-los -- nur Demuxer/Muxer/Parser/BSF fuer Stream-Copy" echo "configure: $CFG_ONELINE" } > "$OUT/BUILD_INFO.txt" echo ">> FERTIG. Inhalt vendor/ffmpeg/:" ls -lh "$OUT" "$OUT/ffmpeg.exe" -hide_banner -version | head -1 echo ">> Encoder (sollte LEER sein):" "$OUT/ffmpeg.exe" -hide_banner -encoders 2>/dev/null | grep -iE 'h264|hevc|aac' || echo " (keine Codecs -- korrekt)"