cuda 配置未使用问题排查
CUDA 检查
确认 NVDEC 支持:在部署机运行 ffmpeg -decoders | grep -i nvdec 或 ./scripts/check_nvdec_support.sh。没有任何 NVDEC 编码器就说明 FFmpeg 没编译进 CUDA/NVDEC,Light 只能退回 CPU。
配置启用:在 /etc/light/light.ini 的 [hardware] 段把 hw_accel_enabled = true,hw_accel_device 为空或填 0/cuda (line 0),然后重启(systemd/PM2)。未设置就不会尝试 GPU。
查看日志:journalctl -u light -f 或 PM2 日志中搜索:
成功时会有 [Stream …] Initialized CUDA hwdevice...。
无 CUDA 时会出现 hw_accel_enabled=true but this build of FFmpeg lacks CUDA/NVDEC support。
初始化失败会有具体错误(Failed to create CUDA hwdevice: ...),按提示检查驱动/权限。
确认 FFmpeg/驱动:nvidia-smi 看驱动是否加载,Light 使用的 FFmpeg 库路径是否指向包含 CUDA 的版本(LD_LIBRARY_PATH/FFMPEG_DIR 设置正确)。
运行态验证:可用 nvidia-smi 观察进程是否占用 GPU,或在日志里看每个 stream 是否记录 NVDEC hardware decode requested/active。
逐条排查(FFmpeg 编译选项 → 配置开关 → 驱动 → 日志诊断)即可找出 CUDA 未启用的原因。
Light 使用的 FFmpeg 库路径是否指向包含 CUDA 的版本(LD_LIBRARY_PATH/FFMPEG_DIR 设置正确)。 怎么看
确认运行时链接的 FFmpeg 库:在部署机运行:
ldd /usr/local/bin/light | grep -E "avcodec|avformat|avutil|swscale"
看输出里的路径是否指向你编译的带 CUDA/NVDEC 的 FFmpeg(比如 /usr/local/ffmpeg-cuda/lib/libavcodec.so);如果显示的是系统默认 /usr/lib/x86_64-linux-gnu/libavcodec.so,就代表还在用不带 CUDA 的版本。
如果你使用了自定义 FFmpeg 路径,确保在运行 Light 的进程前设置 LD_LIBRARY_PATH=/path/to/ffmpeg/lib:$LD_LIBRARY_PATH,或在 systemd/PM2 的环境配置里加上这项。CMake 构建时也要指定 FFMPEG_DIR,可以在构建目录里 grep FFMPEG 确认 FFMPEG_INCLUDE_DIRS/FFMPEG_LIBRARIES 指向正确目录。
运行 env | grep LD_LIBRARY_PATH / env | grep FFMPEG 查看当前进程环境变量。如果 light 是由 systemd 启动,unit 文件里已经有 Environment="LD_LIBRARY_PATH=...";若你用 PM2,则在启动命令前设置 LD_LIBRARY_PATH,比如:
LD_LIBRARY_PATH=/opt/ffmpeg-cuda/lib:$LD_LIBRARY_PATH pm2 start /usr/local/bin/light ...
只要 ldd 结果指向你带 CUDA 的库,Light 就会真正加载那套 FFmpeg。若还是系统默认库,就需要调整环境变量或把自定义库安装到系统标准路径。
解决办法:
scripts/build.sh 并没有写死 FFmpeg 路径,而是临时生成 cmake/modules/FindFFmpeg.cmake,让 CMake 去 ${FFMPEG_DIR} 及其 include、lib 子目录查找头文件/库(脚本中间那段 find_path/find_library 就是)。运行脚本时如果设置 FFMPEG_DIR=/opt/ffmpeg-cuda(或通过 FFMPEG_CMAKE_OPTIONS 传参),CMake 就会在相应目录下寻找 libavcodec、libavformat 等。
构建完成后想确认 Light 运行时是否真的链接到带 CUDA 的 FFmpeg,可以执行 ldd /usr/local/bin/light | grep avcodec 等命令。如果输出还是 /usr/lib/x86_64-linux-gnu/libavcodec.so 这种系统默认库,就说明环境变量/安装路径还没指向你自定义的 FFmpeg,需要调整 LD_LIBRARY_PATH 或把 CUDA 版安装到默认路径。
关于ffmpeg-cuda配置了环境不生效的办法
LD_LIBRARY_PATH=/usr/local/ffmpeg:$LD_LIBRARY_PATH 这个已经加到 .bashrc里面了
.bashrc 只在交互式 shell 中生效,systemd 服务或 PM2 守护进程启动时不会读取它,所以 Light 运行时仍看不到你设置的 LD_LIBRARY_PATH。把环境变量写到真正启动 Light 的环境里才能生效:
systemd: 在 /etc/systemd/system/light.service 的 [Service] 段加/覆盖 Environment="LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:/usr/local/lib:/usr/lib:/lib",然后 sudo systemctl daemon-reload && sudo systemctl restart light。
PM2: 启动命令前显式设置:LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:$LD_LIBRARY_PATH pm2 start /usr/local/bin/light --name light -- -c /etc/light/light.ini,保存后 pm2 save。
这样进程启动时才会真正加载 /usr/local/ffmpeg/lib 下的 FFmpeg,ldd 输出也会随之改变。
PM2: 启动命令前显式设置:LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:$LD_LIBRARY_PATH pm2 start /usr/local/bin/light --name light -- -c /etc/light/light.ini,保存后 pm2 save。每次都要这样启动吗,有没有全局或者更好的办法
PM2 不会读取 .bashrc 之类的交互式环境,所以在命令前手动加 LD_LIBRARY_PATH=... 当然可行,但每次都敲确实麻烦。更好的做法是让这个变量写进 PM2 的配置里,让 PM2 启动 Light时自动带上:
运行 pm2 init simple(或直接创建 ecosystem.config.js),在里面配置:
module.exports = {
apps: [{
name: 'light',
script: '/usr/local/bin/light',
args: '-c /etc/light/light.ini',
env: {
LD_LIBRARY_PATH: '/usr/local/ffmpeg/lib:/usr/local/lib:/usr/lib:/lib'
}
}]
}
然后 pm2 start ecosystem.config.js --only light,确认 pm2 status 正常后执行 pm2 save。之后 PM2 重启/开机恢复时都会带着同样的环境变量。
如果你不想用 ecosystem,也可以写一个简单的 wrapper 脚本,比如 lightn-pm2.sh:
!/bin/bash
export LD_LIBRARY_PATH=/usr/local/ffmpeg/lib:${LD_LIBRARY_PATH}
exec /usr/local/bin/light -c /etc/light/light.ini
给它执行权限后 pm2 start /path/to/light-pm2.sh --name light 即可。
两种方式都能让 LD_LIBRARY_PATH(以及其他自定义变量)持久化,不需要每次手动敲。
浙公网安备 33010602011771号