简介:面向需要在Linux环境快速部署FFmpeg的用户,这份自动安装脚本省去了手动下载源码、逐个安装依赖和编译配置的繁琐流程,尤其适合对编译过程不熟悉或需要重复部署的开发者。压缩包共1个文件,类型为shell脚本,体积仅2KB,便于携带和快速分发;脚本会依次执行更新系统包列表、安装依赖库、拉取FFmpeg源码、按需配置编译选项、编译安装并自动清理临时文件。使用时只需赋予执行权限并运行脚本,即可获得可直接调用的FFmpeg环境,实现视频转码、视频剪辑、视频合并、音频提取以及RTMP/HLS等流媒体处理能力,编译后的二进制也适合批处理任务与自动化运维场景。目前已有553人学习下载,是轻量实用的入门级部署工具,也让后续多媒体处理变得更加顺畅高效。
1. 为什么要写一个自动安装脚本
先聊个我自己的经历。几年前我第一次在服务器上装 ffmpeg,天真地以为就是一个yum install ffmpeg的事,结果折腾了大半天,又是找源、又是编译依赖、又是处理各种兼容性报错,最后还得手动配 PATH。后来换了新机器,又从头来一遍,那种感觉真的是"同样的坑踩两次"。从那时候起,我就决定把安装过程固化成脚本,以后不管是自己新开服务器,还是帮同事搭环境,一条命令搞定,省下来的时间干点啥不好。
很多人觉得装 ffmpeg 很简单,下载个二进制包解压就能用。这话对 Windows 来说基本成立,但放到 Linux 服务器上,事情就没那么单纯了。apt-get install ffmpeg或者yum install ffmpeg装的版本往往比较老,有些项目对编码器(比如 libx264、libvpx)和滤镜有特定要求,老版本根本满足不了。自己编译源码又绕不开一堆依赖问题,而且编译耗时少则十几分钟,多则半小时起步。写一个自动安装脚本,本质上是把"下载、依赖处理、编译/解压、环境配置、验证"这套流程全部固化下来,让环境部署变成一件可重复、可预期的事。
这个脚本适合谁来用?我觉得至少有三类人很需要它。第一类是像我这样要频繁部署服务器的运维或后端开发,脚本化安装能保证每台机器的环境一致。第二类是刚接触 ffmpeg 的初学者,与其在安装环节劝退,不如直接用脚本把环境拉起来,把精力花在学命令上。第三类是需要在内网环境离线部署的人,脚本配上离线包,就能在没有外网的机器上快速搭好环境。下面我把 Linux 和 Windows 两个平台的方案都拆开讲,挑一个适合你的场景直接用。
2. Linux 平台自动安装脚本实现
2.1 方案选型:静态二进制包 vs 源码编译
写脚本之前先得想明白一个问题:走静态二进制包还是源码编译?这两种方式没有绝对的好坏,关键看你的使用场景。
静态二进制包的好处是省事、快,解压即用,不依赖系统里的动态库。比较有名的是 John Van Sickle 提供的静态构建版本,包含几乎所有常用编码器和滤镜。缺点是版本更新需要手动去网站上看,而且如果你要加一个非常冷门的第三方库,静态包是不支持的。源码编译的优点是灵活性拉满,想编什么进去就编什么进去,还能针对 CPU 指令集做优化;缺点是慢,依赖多,而且对新手来说,光是把依赖理清楚就能劝退一片。
我在脚本里默认采用"先试静态包,需要自定义再走源码编译"的策略,这样大多数场景一条命令就能搞定,少数有特殊需求的人在脚本里加个参数切换模式就行。这个思路在你的自动安装脚本里同样适用——把默认路径选成最简单可靠的,把复杂路径留作扩展。
2.2 核心脚本结构拆解
下面给出一个我用了很久的安装脚本核心逻辑,你根据自己的系统稍微调整就能用。这个脚本针对 CentOS/RHEL 系的系统,Debian/Ubuntu 系改一下包管理器就行。
#!/bin/bash # ffmpeg 自动安装脚本(CentOS/RHEL 系) set -e # ---------- 配置区 ---------- INSTALL_DIR="/usr/local/ffmpeg" BUILD_MODE="static" # static 或 source FFMPEG_VERSION="6.1" DOWNLOAD_BASE="https://johnvansickle.com/ffmpeg/releases" # ---------- 配置区结束 ---------- # 检查 root 权限 if [[ $EUID -ne 0 ]]; then echo "请以 root 权限运行此脚本" exit 1 fi # 安装基础依赖 yum install -y wget tar xz # Debian/Ubuntu 用:apt-get install -y wget tar xz if [[ "$BUILD_MODE" == "static" ]]; then # ---------- 静态包安装模式 ---------- ARCH=$(uname -m) if [[ "$ARCH" == "x86_64" ]]; then PKG_NAME="ffmpeg-${FFMPEG_VERSION}-amd64-static.tar.xz" elif [[ "$ARCH" == "aarch64" ]]; then PKG_NAME="ffmpeg-${FFMPEG_VERSION}-arm64-static.tar.xz" else echo "不支持的架构: $ARCH" exit 1 fi wget -q "${DOWNLOAD_BASE}/${PKG_NAME}" -O "/tmp/${PKG_NAME}" tar -xf "/tmp/${PKG_NAME}" -C /tmp # 解压出来的目录名通常带版本号,这里用通配符匹配 mv /tmp/ffmpeg-${FFMPEG_VERSION}-*-static ${INSTALL_DIR} # 建立软链接 ln -sf ${INSTALL_DIR}/ffmpeg /usr/local/bin/ffmpeg ln -sf ${INSTALL_DIR}/ffprobe /usr/local/bin/ffprobe else # ---------- 源码编译模式 ---------- yum install -y gcc make yasm pkg-config # Debian/Ubuntu 需要额外装 libx264-dev libx265-dev libvpx-dev 等 cd /tmp wget "https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.gz" tar -xf "ffmpeg-${FFMPEG_VERSION}.tar.gz" cd "ffmpeg-${FFMPEG_VERSION}" ./configure --prefix=${INSTALL_DIR} \ --enable-gpl \ --enable-libx264 \ --enable-libx265 \ --enable-libvpx \ --enable-libmp3lame make -j$(nproc) make install ln -sf ${INSTALL_DIR}/bin/ffmpeg /usr/local/bin/ffmpeg ln -sf ${INSTALL_DIR}/bin/ffprobe /usr/local/bin/ffprobe fi # 验证安装结果 ffmpeg -version 2>/dev/null | head -n 1 echo "ffmpeg 安装完成,路径: $(which ffmpeg)"这段脚本有几个关键的细节,我觉得值得单独拿出来说。
2.3 每个关键步骤为什么这么做
权限检查那段,很多人会忽略。ffmpeg 装到/usr/local下面,普通用户没有写权限,如果你用普通用户跑了脚本,装到一半就报错,还得 sudo 重新来。脚本直接在一开始就拦住这个情况,报错信息明确,省得浪费时间。这个思路适用于所有安装类脚本——早失败比晚失败好。
架构检测那步,uname -m的结果在不同机器上可能不一样。x86_64 对应 amd64 包,aarch64 对应 arm64 包。很多树莓派、ARM 服务器用户第一次跑脚本会忽略这个,直接下载 amd64 的包,结果自然是 "Exec format error"。脚本里用变量去拼下载地址,这个细节就是给这些场景兜底的。
CPU 核数那行,make -j$(nproc)里的nproc会自动检测 CPU 逻辑核心数。如果是 16 核的机器,编译速度能快接近 16 倍;如果你写死make -j4,可能浪费了新机器一大半的性能,而写死make -j32在 4 核小机器上又容易 OOM。nproc这个命令就是干这个的,脚本里用上它,编译效率会提升很多。
软链接而不是直接复制二进制,这个是我踩过坑后的经验。如果直接cp,以后版本升级时旧文件还留在系统里,which ffmpeg指向的路径很容易搞混。用ln -sf把/usr/local/ffmpeg下的二进制软链到/usr/local/bin,升级时只需要把新包解压覆盖到/usr/local/ffmpeg,软链接自动指向新版本,改了实现,不改接口。
注意:如果你的系统里之前装过 ffmpeg,建议装完后执行
hash -r刷新一下 shell 的命令缓存,否则可能还是指向旧的路径。
3. Windows 平台自动安装脚本实现
3.1 为什么 Windows 也要脚本化
Windows 装 ffmpeg 的常规教程是让用户去官网下载 ZIP 包,解压后手动把bin目录加到系统 PATH。听起来不难,但实际执行起来问题不少。第一,很多用户根本不知道"把路径加到 PATH"是什么意思,环境变量窗口打开后看着一堆变量名就头大。第二,下载的版本和系统架构不匹配的情况太常见了,下了个 64 位包结果系统是 32 位,或者反过来。第三,手动改 PATH 改错了,把原来的路径覆盖了,后面一堆程序起不来。
所以 Windows 端的自动安装脚本,核心就干三件事:自动下载对应架构的包、自动解压到固定目录、自动配置环境变量。顺便把版本验证一起做了。
3.2 PowerShell 脚本实现
Windows 下我推荐用 PowerShell,因为从 Windows 10 开始,PowerShell 就是系统自带的,不需要额外装环境。脚本如下:
# ffmpeg 自动安装脚本(Windows PowerShell) # 以管理员身份运行 $ErrorActionPreference = "Stop" # ---------- 配置区 ---------- $InstallDir = "C:\ffmpeg" $BaseUrl = "https://www.gyan.dev/ffmpeg/builds/" $BuildVer = "ffmpeg-release-essentials.zip" # ---------- 配置区结束 ---------- # 检查管理员权限 $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host "请以管理员身份运行此脚本" -ForegroundColor Red exit 1 } # 创建安装目录 New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null # 下载 $zipPath = "$env:TEMP\ffmpeg.zip" Write-Host "正在下载 ffmpeg..." Invoke-WebRequest -Uri ($BaseUrl + $BuildVer) -OutFile $zipPath # 解压 Write-Host "正在解压..." Expand-Archive -Path $zipPath -DestinationPath $InstallDir -Force # 解压后目录名带版本号,获取实际目录 $ffmpegDir = Get-ChildItem -Path $InstallDir -Directory | Select-Object -First 1 $binPath = $ffmpegDir.FullName + "\bin" # 更新 PATH $currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine") if ($currentPath -notlike "*$binPath*") { [Environment]::SetEnvironmentVariable("Path", "$currentPath;$binPath", "Machine") Write-Host "已添加 PATH: $binPath" -ForegroundColor Green } else { Write-Host "PATH 中已存在 ffmpeg 路径,跳过" -ForegroundColor Yellow } # 验证 $ffmpegExe = Join-Path $binPath "ffmpeg.exe" if (Test-Path $ffmpegExe) { & $ffmpegExe -version | Select-Object -First 1 Write-Host "ffmpeg 安装成功" -ForegroundColor Green } else { Write-Host "ffmpeg 安装失败,未找到可执行文件" -ForegroundColor Red exit 1 }这个脚本有几个细节值得说一下。PowerShell 里检查管理员权限那段代码,是WindowsPrincipal加IsInRole的组合,看起来有点绕,但这是判断当前进程权限最可靠的方式,比net session这类老办法要规范得多。设置 PATH 的时候注意用"Machine"这个作用域,它写入的是系统级环境变量,对所有用户生效;如果只对当前用户生效,那换了个用户登录又得装一次。
3.3 版本管理上的小技巧
Windows 这个脚本在解压时,Get-ChildItem拿到的是解压出来的第一个目录,这个目录名里带了完整版本号,比如ffmpeg-6.1-essentials_build。这么设计的好处是,每次升级只需要重新跑一遍脚本,旧的版本目录还在,只不过 PATH 指向了新的 bin 路径。如果你想回滚到旧版本,改 PATH 指回去就行。这个"目录带版本号 + PATH 指向当前版本"的思路,本质上就是一个极简版的版本管理方案,比覆盖安装要安全得多。
注意:Windows 改完 PATH 之后,已经打开的终端窗口不会立即生效。你需要重新打开一个新的 PowerShell 窗口,再执行
ffmpeg -version验证。这个坑我踩过不是一次两次了,每次改完 PATH 都以为脚本出问题了。
4. 安装完成后的核心应用实操
4.1 用-vframes 1正确截图,而不是乱传参数
装好 ffmpeg 之后,第一个要练手的功能多半就是截图。网上不少人在视频里截图会遇到一个奇葩问题——命令里写了add("-vframes:v 1")之类的内容,然后 ffmpeg 报错 "the specified filename does not exist" 或者直接不干活。这个问题的根源是把别的编程语言(比如 Java 的 JavaFX)里的写法混到 ffmpeg 命令行里了。ffmpeg 的命令行没有这种面向对象式的写法,正确格式是:
ffmpeg -i input.mp4 -vframes 1 -ss 00:01:23 output.jpg那条热词说白了就是这个:-vframes 1表示只取一帧,-ss表示跳转到第 1 分 23 秒的位置。注意-ss放在-i后面是精确跳转,放在-i前面是快速跳转。快速跳转速度快但定位可能差几帧,精确跳转慢但帧准确,截图场景我推荐把-ss放在-i前面,因为大部分时候你只需要"差不多这个时间点"的画面。
4.2 M3U8 转 MP4 的完整命令
M3U8 转 MP4 是另一个高频需求,尤其在看视频缓存、下载课程录像这类场景下。M3U8 本质是一个索引文件,里面列了一堆.ts分片文件的地址。ffmpeg 可以直接读取这个索引并合并输出:
ffmpeg -i playlist.m3u8 -c copy output.mp4-c copy的意思是直接复制音视频流,不做重新编码,速度非常快,而且画质无损。但有个前置条件:源文件的编码格式必须是 MP4 容器兼容的,比如 H.264 + AAC。如果源文件是 H.265(HEVC),直接-c copy出来的 MP4 在某些播放器上可能打不开,这时候就得换成重新编码:
ffmpeg -i playlist.m3u8 -c:v libx264 -c:a aac output.mp4实测下来,-c copy的速度基本是秒完成(取决于文件大小),重新编码则慢很多,好在画质可控。如果你的网络不够稳定,下载的 TS 分片可能有缺失,合并时可能会出现花屏或音画不同步,这种情况建议加一个-err_detect ignore_err参数,让 ffmpeg 尽量忽略错误继续处理。
4.3 推流命令与常见参数解析
推流是 ffmpeg 的另一个大用途,把本地视频推送到 RTMP 服务器(比如部署了 SRS 或者用 ZLMediaKit 搭建的流媒体服务)。基本命令是:
ffmpeg -re -i input.mp4 -c:v libx264 -preset veryfast -b:v 2500k -c:a aac -b:a 128k -f flv rtmp://your-server/live/stream_key这里有一个特别容易忽略的参数:-re。它的意思是按原始帧率读取输入文件,也就是模拟实时推流。如果不加这个参数,ffmpeg 会以最快速度处理完整个视频然后瞬间推完,直播流就直接结束了。对新手来说,漏掉-re是最常见的推流失败原因之一,表现出来就是"直播只持续了几秒钟就断了"。
-preset veryfast是编码速度和压缩率的折中,veryfast保证了 CPU 占用不高的同时画质损失可以接受。-b:v 2500k是视频码率,这个值要根据你的上行带宽来定,一般 1080p 在 4Mbps 上下,720p 在 2.5Mbps 左右。
提示:如果你要推流的是摄像头 RTSP 流,用
-rtsp_transport tcp可以避免因网络抖动导致的画面卡顿。这个参数在 ZLMediaKit 拉取 RTSP 流的场景里尤其管用,很多用 ZLMediaKit 的人说"拉流老是断",多半就是没指定 TCP 传输。
5. 常见问题与排查技巧实录
5.1 问题速查表
我在实际使用和帮别人排查的过程中,整理了一批高频问题,直接做成表格供你对照:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
ffmpeg: error while loading shared libraries | 动态链接库路径不对 | 源码编译后执行ldconfig,或设置LD_LIBRARY_PATH指向安装目录的 lib |
CentOS 7 报glibc版本过低 | 新版静态包要求较高的 glibc | 换用针对旧版 glibc 编译的静态包,或改为源码编译 |
提示Unknown encoder 'libx264' | 编译时没开启 libx264 | 源码编译记得加--enable-libx264 --enable-gpl |
截图命令报filename does not exist | 参数写错或文件路径没引号 | 检查命令格式,路径含空格必须加引号 |
Windows 下ffmpeg 不是内部或外部命令 | PATH 配置失败或终端未重开 | 重开终端;确认系统环境变量里已有 ffmpeg 的 bin 路径 |
| 推流几秒就断开 | 忘记加-re参数 | 加上-re,按原始码率实时推流 |
5.2 三个容易忽略的坑
第一个坑是版本和系统的兼容性。静态编译包虽然省事,但像是 CentOS 7 这种老系统,系统自带的 glibc 版本偏低,最新版 ffmpeg 静态包跑起来会直接报version \GLIBC_2.29' not found。这时候别急着怀疑脚本,先查系统 glibc:ldd --version`。如果确实太低,两个办法,要么找老版本的静态包(比如 4.x 的),要么走源码编译。
第二个坑是编译时缺少 libx264 导致功能不全。很多人装完 ffmpeg,处理 MP4 文件时提示编码器不支持,就是因为编译配置里没带上 libx264。源码编译时,--enable-gpl和--enable-libx264必须同时出现,少一个都不行。另外,还要确保系统先装了libx264-dev(Debian/Ubuntu)或通过其他方式编译安装。脚本里如果加了这些参数但系统没装对应开发库,./configure阶段就会报错,这一步的日志信息非常关键,别跳过不看。
第三个坑是win 环境变量修改后不生效。Windows 下脚本提示"安装成功",但新开的终端里输入ffmpeg -version还是提示找不到。这大概率是 PATH 里的路径没生效。验证方法是运行echo $env:Path看里面有没有 ffmpeg 的 bin 目录;如果有,再确认是不是终端开得不够新——PowerShell 窗口需要在修改环境变量之后重新启动才能读到新的值。如果确认路径也在、终端也重开了,检查一下是不是被杀毒软件拦截了,有少数安全软件会静默阻止写入系统环境变量。
5.3 脚本可扩展的两个方向
这个自动安装脚本用顺手之后,不妨再往上叠两个能力。第一个是版本检测与升级,脚本里加上远程版本比对逻辑,比如从官网接口拿最新版本号,和本地的ffmpeg -version输出对比,不一致就提示更新。第二个是多平台支持,用一个统一的入口脚本,自动识别操作系统然后调用对应的子脚本,这样团队里的 Windows 和 Linux 用户都能用同一条命令完成部署。我在公司内部就是这么做的,统一入口、平台分流、日志输出规范,运维同学再也不用一对一教人装环境了。
我个人在实际操作中的体会是,脚本的价值不在于代码本身有多炫酷,而在于它把你从重复劳动里解放出来,让你有更多精力去研究 ffmpeg 本身的能力边界。自动安装脚本是第一步,装上之后怎么用好它才是真正的长期课题。
本文还有配套的精品资源,点击获取