#!/usr/bin/env bash # ============================================================================= # 把环境改造成"项目内自包含"——Python、第三方库、模型全放进项目目录, # 之后整个项目文件夹可以【随便放到任意路径、任意用户】,不再依赖 /root 或固定路径。 # # 在【能联网】的机器上跑一次(已 setup_server.sh 装好 .venv 后): # bash make_portable.sh # 默认 ffmpeg 用 GPU 版(BtbN,含 cuda/nvdec,也兼容 CPU) # # 需运行机 glibc>=2.28;GPU 机器自动硬解、CPU 机器软解 # FFMPEG_VARIANT=cpu bash make_portable.sh # ffmpeg 用 CPU 版(johnvansickle,全静态,老 glibc 也能跑) # 之后: # bash pack.sh # 打包(此时只需打项目目录,已自包含) # # 离线机解压到【任意路径】即可: source activate.sh && python main.py ... # ============================================================================= set -euo pipefail cd "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" PROJ="$(pwd)" PIP_MIRROR="${PIP_MIRROR:-https://repo.huaweicloud.com/repository/pypi/simple}" log() { echo -e "\n\033[1;32m==> $*\033[0m"; } warn() { echo -e "\033[1;33m[警告] $*\033[0m"; } have() { command -v "$1" >/dev/null 2>&1; } [ -d .venv ] || { echo "没有 .venv,请先 bash setup_server.sh"; exit 1; } # shellcheck disable=SC1091 source .venv/bin/activate have uv || { echo "需要 uv(本机改造用,离线机不需要)"; exit 1; } # 0) 确保 bin/ffmpeg 可用。两种变体(用环境变量 FFMPEG_VARIANT 选): # cpu (默认) = johnvansickle 静态版,含 dav1d(CPU 软解 AV1),兼容老 glibc,哪都能跑。 # gpu = BtbN 版,含 cuda/nvdec(GPU 硬解),给 Ampere+ 卡的机器用;需较新 glibc(>=2.28)。 # 用法: FFMPEG_VARIANT=gpu bash make_portable.sh # 默认下 GPU 版(含 cuda/nvdec,也兼容 CPU 软解)。要纯 CPU 版用 FFMPEG_VARIANT=cpu。 FFMPEG_VARIANT="${FFMPEG_VARIANT:-gpu}" FF_NEED=1 if [ "$FFMPEG_VARIANT" = "gpu" ]; then FF_URL="${FFMPEG_GPU_URL:-https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl.tar.xz}" # GPU 版(BtbN)要 glibc>=2.28 才能运行;本机若太老仅警告(可能在给别的新机器打包) # 注意:管道里 head 会让前面命令 SIGPIPE,配合 set -e/pipefail 会误退出,故加 || true _glibc="$(ldd --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -1 || true)" if [ -n "$_glibc" ] && [ "$(printf '%s\n2.28\n' "$_glibc" | sort -V | head -1)" != "2.28" ]; then warn "本机 glibc=$_glibc < 2.28,GPU 版 ffmpeg 在本机跑不了(GLIBC_2.28 not found)。" warn "仅当打包给 glibc>=2.28 的机器时才用 GPU 版;本机自用请: FFMPEG_VARIANT=cpu bash make_portable.sh" fi # 用 grep(不带 -q)读完整输出再判,避免 grep -q 提前关管道触发 SIGPIPE+pipefail 误判 if [ -x "$PROJ/bin/ffmpeg" ] && "$PROJ/bin/ffmpeg" -hide_banner -hwaccels 2>/dev/null | grep -i cuda >/dev/null; then log "[0/4] bin/ffmpeg 已是 GPU 版(支持 cuda),跳过"; FF_NEED=0 else log "[0/4] 下载 GPU 版 ffmpeg (BtbN,含 cuda/nvdec) → ./bin" fi else FF_URL="${FFMPEG_STATIC_URL:-https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz}" if [ -x "$PROJ/bin/ffmpeg" ] && "$PROJ/bin/ffmpeg" -hide_banner -decoders 2>/dev/null | grep -iE 'dav1d|av1' >/dev/null; then log "[0/4] bin/ffmpeg 已支持 AV1(CPU 版),跳过"; FF_NEED=0 else log "[0/4] 下载 CPU 版 ffmpeg (johnvansickle,含 dav1d) → ./bin" fi fi if [ "$FF_NEED" -eq 1 ]; then mkdir -p "$PROJ/bin"; tmp="$(mktemp -d)" if have curl; then curl -L "$FF_URL" -o "$tmp/ff.tar.xz"; else wget -O "$tmp/ff.tar.xz" "$FF_URL"; fi tar xf "$tmp/ff.tar.xz" -C "$tmp" # johnvansickle 在