随机
Enter 搜索 ↑↓ 切换 Esc 清空

fan-video-tr-build

命令

fan-video-tr 完整开发-编译-发布-部署教程

补充说明

本教程介绍 fan-video-tr 从源码编译、发布 GitHub Release 到目标服务器一键安装、升级的完整流程,适用于个人设备视频转码自建发布链路。

项目:fan-video-tr|视频转码工具(基于 FFmpeg,单二进制 + 原生前端内嵌,无账号密码的内网工具) 仓库:https://github.com/meimolihan/fan-video-tr 编译发布主机:fnOS(Debian,本机 Go/make 环境齐全) 部署测试主机:Debian Linux(amd64/arm64) 运行环境:Go 1.25+(go.mod 指定 go 1.25.0)

重要规则

  1. GitHub 不允许直接覆盖已发布 Release,正式环境版本号单向递增;内测可删除重建同名 tag。
  2. install.sh 使用 releases/latest/download,脚本不需要硬编码版本号。
  3. 编译机器 ≠ 业务运行机器;fnOS 只做编译发布,业务跑在目标主机。
  4. 前端为原生 HTML/CSS/JS(internal/embedded/web),已通过 go:embed 内嵌二进制,无 Node/React 构建步骤;改前端必须重新编译二进制。
  5. 发布脚本的 TAG 必须带 v 前缀(vX.Y.Z),例如 ./scripts/build-and-push.sh v1.0.1;传 1.0.1 会被正则 ^v[0-9]+\.[0-9]+\.[0-9]+$ 直接拒绝。
  6. 发布脚本会校验工作区无未提交改动、且本地 main 与远端一致,发版前先 git add/git pull。
  7. 二进制通过外部命令调用 ffmpeg / ffprobe(不是静态内嵌 ffmpeg 库),目标机需安装;容器镜像内已 apk add ffmpeg。
  8. 二进制为纯 Go(CGO_ENABLED=0),不含 cgo 依赖,amd64/arm64 产物行为一致。

一、编译发布机(fnOS)环境准备

1.1 安装依赖

apt update
apt install git curl build-essential

Go 1.25+(本机 /usr/local/go/bin/go,确保 go version 正常),Make,python3(发布脚本用它改写 internal/version/version.go)。 本机跑服务调试时另需 ffmpeg(目标机由 install.sh 自动安装):

apt install -y ffmpeg

1.2 安装 gh 命令行工具并授权 GitHub

gh auth login

选择 GitHub.com → SSH → 网页授权登录,务必勾选 repo 权限。 触发发布流水线还需要 workflow 权限(gh workflow run 会用到)。

校验授权结果

gh auth status

输出必须包含:Token scopes: admin:public_key, gist, read:org, repo, workflow

1.3 拉取源码

git clone git@github.com:meimolihan/fan-video-tr.git
cd fan-video-tr
go mod download

项目目录结构

fan-video-tr/
├── scripts/install.sh            # 远程一键安装脚本(systemd,无 systemd 回退后台运行)
├── scripts/uninstall.sh          # 卸载脚本
├── scripts/build-and-push.sh     # 升版+打tag+推代码+触发 release.yml
├── scripts/build-release.sh      # 本地交叉编译 dist/(amd64+arm64+sha256+脚本)
├── internal/version/version.go   # 版本号(唯一来源,ldflags 注入)
├── internal/embedded/web/        # 前端(原生 HTML/CSS/JS,go:embed 内嵌)
├── internal/{config,ffmpeg,handler,logger,service}/  # 后端
├── main.go / server.go           # 入口与 Web 服务
├── cli_ui.go / cli_style.go      # CLI 子命令与终端样式
├── status_cmd.go / service_cmd.go / uninstall_cmd.go  # status/start|stop|restart/uninstall
├── Makefile                      # build/build-all/run/test/docker/docker-push/install/uninstall
├── Dockerfile                    # 多阶段构建,运行镜像内置 ffmpeg
├── docker/entrypoint.sh          # 容器入口:权限自愈 + su-exec 降权到 fvt
├── docker-compose.yml            # 本地一键 Compose 部署
├── config.example.yaml           # 配置示例(FVT_ 环境变量映射)
└── .github/workflows/            # ci.yaml(push/PR)+ release.yml(workflow_dispatch 发版)

二、配置一键安装脚本

确认 scripts/install.sh 头部常量(无需改动,默认已正确定义):

APP_NAME="fan-video-tr"
DEFAULT_PORT=8790
DEFAULT_INSTALL_DIR="/var/lib/fan-video-tr"
RECORD_FILE="/etc/fan-video-tr.conf"
SERVICE_FILE="/etc/systemd/system/fan-video-tr.service"
WRAPPER_FILE="/usr/local/bin/fan-video-tr"

Release 下载地址与流水线产物命名必须一致(fan-video-tr_linux_amd64 / fan-video-tr_linux_arm64):

REL_URL="https://github.com/meimolihan/fan-video-tr/releases/latest/download/fan-video-tr_linux_${REL_ARCH}"

提交推送至 main 分支

git add scripts/install.sh
git commit -m "chore: update install script"
git push origin main

三、构建与发布

3.1 本地构建与自测

make vet          # go vet ./...
make test         # go vet + go test(含 internal/ffmpeg、internal/service 单测)
make build        # 产物 bin/fan-video-tr,版本号/提交号/构建时间自动注入 ldflags
make run          # 本地启动(-port 8790 -media 当前目录 -data ./data)

本地运行验证

./bin/fan-video-tr -port 8790 -data ./data -media /vol2/1000/downloads/fan-video-tr
curl -s http://127.0.0.1:8790/api/health
curl -s http://127.0.0.1:8790/api/capabilities   # 确认软件编码族与硬件加速自检结果

3.2 一键发布(推荐,CI 出包)

./scripts/build-and-push.sh v1.0.1 --yes -m "本次新增 xxx"

内部流程:校验 TAG 格式 → CNB 同名仓库检测/创建(可选)→ 校验工作区干净 → python3 改写 internal/version/version.go → 生成 RELEASE_NOTES.md → git commit + 打 tag v1.0.1 → git push origin main + git push origin v1.0.1 → gh workflow run release.yml -f tag=v1.0.1 --ref v1.0.1 → 轮询并美化输出流水线状态。

3.3 Release 流水线(GitHub Actions)

release.yml(仅 workflow_dispatch 触发,日常 push/PR 不会触发发版)按顺序执行:

  1. build-binaries:ubuntu-24.04 构建 fan-video-tr_linux_amd64 / fan-video-tr_linux_arm64 + sha256sums.txt(先校验 tag 格式与 version.go 一致性)
  2. publish-release:创建/更新 GitHub Release 并上传上述附件(说明取 RELEASE_NOTES.md)
  3. build-docker:buildx 构建 linux/amd64,linux/arm64 镜像并推送
    • Docker Hub:mobufan/fan-video-tr:v1.0.1、mobufan/fan-video-tr:latest
    • GHCR:ghcr.io/meimolihan/fan-video-tr:v1.0.1、ghcr.io/meimolihan/fan-video-tr:1.0.1
  4. sync-cnb:同步镜像仓库到 cnb.cool/meimolihan/fan-video-tr(continue-on-error: true,失败不阻塞 Release)

所需 Secrets:DOCKERHUB_USERNAME、DOCKERHUB_TOKEN、CNB_ACCESS_TOKEN(未配置则跳过 CNB 同步)。

3.4 本地交叉编译 Release 产物(离线/自建发布)

bash scripts/build-release.sh            # amd64 + arm64
bash scripts/build-release.sh amd64      # 仅单架构

产物(dist/):

dist/
├── fan-video-tr_linux_amd64
├── fan-video-tr_linux_arm64
├── sha256sums.txt
├── install.sh
├── uninstall.sh
├── config.example.yaml
└── RELEASE_NOTES.md

或手工等价命令:

export VERSION=1.0.1
PKG=github.com/meimolihan/fan-video-tr
rm -rf dist && mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w -X ${PKG}/internal/version.Version=${VERSION}" -o dist/fan-video-tr_linux_amd64 .
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "-s -w -X ${PKG}/internal/version.Version=${VERSION}" -o dist/fan-video-tr_linux_arm64 .
sha256sum dist/fan-video-tr_linux_* > dist/sha256sums.txt

3.5 创建 GitHub Release 并上传二进制(离线模式)

VERSION=1.0.1
gh release create "v${VERSION}" \
  dist/fan-video-tr_linux_amd64 \
  dist/fan-video-tr_linux_arm64 \
  dist/sha256sums.txt \
  --title "v${VERSION}" \
  --notes "fan-video-tr - Local Video Transcode Tool"

校验 Release

访问:https://github.com/meimolihan/fan-video-tr/releases/tag/v1.0.1

  1. 状态:Published,不是 Draft 草稿
  2. Assets 内必须存在 fan-video-tr_linux_amd64 与 fan-video-tr_linux_arm64,不要只看源码 zip/tar.gz。

测试下载链接有效性

curl -IL https://github.com/meimolihan/fan-video-tr/releases/latest/download/fan-video-tr_linux_amd64

返回 302 Found 正常;返回 404 代表附件缺失或没有已发布 Release。

四、本地构建 Docker 镜像

make docker        # docker build -t mobufan/fan-video-tr:$(VERSION) -t ...:latest .
make docker-push   # buildx --platform linux/amd64,linux/arm64 --push

或手工多架构构建

docker buildx build --platform linux/amd64,linux/arm64 \
  --build-arg FVT_VERSION=1.0.1 \
  --build-arg GOPROXY=https://goproxy.cn,direct \
  -t mobufan/fan-video-tr:1.0.1 -t mobufan/fan-video-tr:latest \
  --push .

镜像要点:golang:1.25-alpine 构建 → alpine:3.20 运行,apk add ffmpeg su-exec tzdata ca-certificates,内置 fvt(uid 1000) 用户、VOLUME /data、EXPOSE 8790、HEALTHCHECK /api/health,入口 docker/entrypoint.sh 负责卷权限自愈并 su-exec fvt 降权启动。

五、目标服务器远程一键安装

目标服务器需要 root 权限,已安装 curl。

5.1 预检查国内网络

curl -sSL https://raw.githubusercontent.com/meimolihan/fan-video-tr/main/scripts/install.sh

输出 shell 脚本内容 = 网络正常;卡住超时需要网络代理。 二进制下载走 GitHub Release,脚本已内置 ghfast.top / ghproxy.net / gh.xxooo.cf / githubproxy.cc 逐个回退。

5.2 执行一键安装

bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/fan-video-tr/main/scripts/install.sh)"

交互步骤:

  1. 请输入监听端口 [默认: 8790]: 回车使用默认,或填写自定义端口
  2. 请输入视频浏览根目录 [可选,留空浏览全盘]: 可指定媒体目录(如 /vol2/1000/downloads/fan-video-tr)
  3. 脚本检测/安装 ffmpeg,下载二进制(或使用本地 -b 产物),写入 /usr/local/bin/fan-video-tr 软链
  4. 写入安装记录 /etc/fan-video-tr.conf,生成 systemd 单元并 enable + restart
  5. 输出 Web 访问地址;无账号密码(内网工具)

静默安装

bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/fan-video-tr/main/scripts/install.sh)" -p 8790 -d /var/lib/fan-video-tr -s /vol2/1000/downloads/fan-video-tr -y

非 systemd 环境(容器/受限环境)脚本自动回退为 nohup 后台运行,日志写入 <数据目录>/fan-video-tr.log,重启后不会自动恢复。

部署后运维命令

systemctl status fan-video-tr
journalctl -u fan-video-tr -f
systemctl restart fan-video-tr
fan-video-tr status                     # PID / 端口 / 内存 / 健康检查
fan-video-tr --version

访问示例:http://10.10.10.251:8790(无账号密码)

六、一键卸载

bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/fan-video-tr/main/scripts/uninstall.sh)"

交互:

也可直接用二进制自带子命令:sudo fan-video-tr uninstall -y --purge

卸载完成:systemd 服务移除、二进制与 /usr/local/bin 软链删除、安装记录清除。

七、新版本发布两种模式

模式 1:递增新版本(正式环境,推荐)

不要复用旧 tag,版本号向上迭代,例如 v1.0.1 → v1.0.2

cd /vol1/1000/GitHub/fan-video-tr
./scripts/build-and-push.sh v1.0.2 --yes

目标服务器升级,直接重跑安装脚本,自动拉取 latest,覆盖二进制,systemd 自动重启

bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/fan-video-tr/main/scripts/install.sh)"
fan-video-tr --version

模式 2:删除重建同名 Release(仅限内测,无线上用户)

⚠️ 已有服务器依赖该版本绝对禁止执行,会造成旧版本下载 404。

cd /vol1/1000/GitHub/fan-video-tr
# 删除github release
gh release delete v1.0.1 --yes
# 删除本地与远端git tag
git tag -d v1.0.1
git push origin --delete v1.0.1

# 重新编译并重建release上传附件
export VERSION=1.0.1
PKG=github.com/meimolihan/fan-video-tr
rm -rf dist && mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w -X ${PKG}/internal/version.Version=${VERSION}" -o dist/fan-video-tr_linux_amd64 .
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "-s -w -X ${PKG}/internal/version.Version=${VERSION}" -o dist/fan-video-tr_linux_arm64 .

gh release create "v${VERSION}" \
  dist/fan-video-tr_linux_amd64 \
  dist/fan-video-tr_linux_arm64 \
  dist/sha256sums.txt \
  --title "v${VERSION}" \
  --notes "fan-video-tr - Local Video Transcode Tool"

八、故障排查表

现象 排查方案
发布脚本报「TAG 必须形如 vX.Y.Z」 补 v 前缀:./scripts/build-and-push.sh v1.0.1
发布脚本报「工作区存在未提交改动」 git add/git commit 或 git stash 后重试
发布脚本报「本地 main 与远端不一致」 git pull --rebase 后重试
gh workflow run 失败 gh auth login 重新授权,确保 token 含 workflow 权限;tag 已推送远端
流水线报「version.go 与 tag 不一致」 走 build-and-push.sh 升版发布,不要手动只打 tag
下载二进制返回 404 检查 Release 是否 Published,Assets 文件名严格匹配 fan-video-tr_linux_{arch}
下载内容被识别为非 ELF install.sh 校验魔数 7f454c46,说明下到的不是二进制(多为代理返回的 HTML)
raw.githubusercontent.com 卡住超时 国内网络限制,配置代理;install.sh 已内置 GitHub 加速镜像回退
服务启动失败 journalctl -u fan-video-tr -n 100;检查 ffmpeg 是否安装、端口占用、目录权限
界面硬件加速全部不可用 容器需映射 /dev/dri(VAAPI 还要 video/render 组),或设置 FVT_FFMPEG_ACCEL=none
AV1 + 双遍编码明确报错 本机 libsvtav1 仅单遍;用 libaom-av1 或改用单遍/码率模式
转码任务一直排队不执行 FVT_APP_WORKER 并发数为 1,确认无其他转码占用;查看日志是否 FFmpeg 报错
编译机本机执行 fan-video-tr: command not found 编译机没走 install.sh;测试运行用完整路径 ./bin/fan-video-tr
流水线 sync-cnb 报错 CNB 仓库未创建或 token 权限不足,属尽力而为同步,不影响 Release/Docker

九、前端 UI 修改流程

前端为原生 HTML/CSS/JS(internal/embedded/web/),无 Node 构建,修改后直接重新编译内嵌即可:

  1. 修改 internal/embedded/web/index.html / css/style.css / js/app.js / favicon.svg
  2. 重新构建:make build(改前端后必须重新编译,否则运行的仍是旧页面)
  3. 重新走发布流程:./scripts/build-and-push.sh v1.0.3 --yes 触发流水线
  4. 目标服务器重跑一键安装脚本升级生效(或本地 make install)

若需要覆盖内嵌资源,也可在配置里指定外部前端目录:

app:
  web_dir: "/opt/fan-video-tr/web"   # 留空使用二进制内嵌资源
  favicon: ""                        # 留空依次回退 <data_dir>/favicon.svg -> 内置图标

十、极简速查复制块

发布新版本速记

cd /vol1/1000/GitHub/fan-video-tr
git pull --rebase
./scripts/build-and-push.sh v1.0.2 --yes    # 自动:升版 version.go → 写 RELEASE_NOTES → commit → push main → tag → 触发 release.yml

# 或分步(离线模式):
# make test && make build
# git add . && git commit -m "chore: bump version to v1.0.2"
# git push origin main && git tag -a v1.0.2 -m v1.0.2 && git push origin v1.0.2
# gh workflow run release.yml -f tag=v1.0.2 --ref v1.0.2

export VERSION=1.0.2
PKG=github.com/meimolihan/fan-video-tr
rm -rf dist && mkdir -p dist
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w -X ${PKG}/internal/version.Version=${VERSION}" -o dist/fan-video-tr_linux_amd64 .
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -trimpath -ldflags "-s -w -X ${PKG}/internal/version.Version=${VERSION}" -o dist/fan-video-tr_linux_arm64 .
gh release create "v${VERSION}" dist/fan-video-tr_linux_amd64 dist/fan-video-tr_linux_arm64 --title "v${VERSION}" --notes "更新说明"

# 目标服务器升级
bash -c "$(curl -sSL https://raw.githubusercontent.com/meimolihan/fan-video-tr/main/scripts/install.sh)" -y
fan-video-tr status && fan-video-tr --version