如何用FFmpeg递归压缩指定目录下的MP4(实际为TS)文件并保留原路径
如何用FFmpeg递归压缩指定目录下的MP4文件并保留原路径
当然可以!这种零散分布在各级文件夹里的MP4压缩需求,用FFmpeg配合系统的递归遍历工具就能轻松搞定,不管你用的是Linux/macOS还是Windows,我都给你准备了现成的方案,还有实用的参数建议:
Linux/macOS(Bash/Zsh)方案
用find命令递归定位所有MP4文件,再逐个用FFmpeg压缩,同时做了错误处理避免文件损坏:
find /path/to/your/root/dir -type f -name "*.mp4" -exec sh -c ' for file do # 生成临时文件,避免压缩失败覆盖原文件 temp_file="${file%.mp4}_temp.mp4" # FFmpeg压缩核心命令,用H.265编码兼顾体积和质量 ffmpeg -i "$file" -c:v libx265 -crf 28 -c:a aac -b:a 128k "$temp_file" # 压缩成功就替换原文件,失败则清理临时文件 if [ $? -eq 0 ]; then mv "$temp_file" "$file" echo "✅ 压缩完成: $file" else echo "❌ 压缩失败: $file" rm -f "$temp_file" fi done ' sh {} +
参数说明:
-c:v libx265:用高效的H.265(HEVC)编码,比传统H.264能省30%-50%体积-crf 28:控制视频质量,数值越小质量越高,28是「质量可接受+体积大幅压缩」的常用值,可在24-30之间调整-c:a aac -b:a 128k:用AAC编码压缩音频,128kbit/s足够日常播放需求
Windows(PowerShell)方案
用PowerShell的递归文件查找功能,逻辑和Linux版一致,确保原路径不变:
Get-ChildItem -Path "C:\path\to\your\root\dir" -Recurse -Filter "*.mp4" | ForEach-Object { $tempFile = $_.FullName -replace '\.mp4$', '_temp.mp4' # 执行FFmpeg压缩 ffmpeg -i $_.FullName -c:v libx265 -crf 28 -c:a aac -b:a 128k $tempFile # 检查压缩状态并处理文件 if ($LASTEXITCODE -eq 0) { Move-Item -Path $tempFile -Destination $_.FullName -Force Write-Host "✅ 压缩完成: $($_.FullName)" } else { Write-Host "❌ 压缩失败: $($_.FullName)" Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue } }
重要注意事项
- 先备份!先备份!先备份!:压缩前务必把所有视频文件备份到其他位置,万一参数不合适或FFmpeg出错,能快速找回原文件
- 兼容老设备:如果你的播放设备不支持H.265,把
-c:v libx265换成-c:v libx264,-crf值改成23(H.264的平衡值) - 自定义优化:
- 想更快压缩:加
-preset fast(可选值:ultrafast、fast、medium、slow,越慢压缩率越高) - 缩小分辨率:加
-vf scale=1280:-1把视频宽度缩到1280,高度按比例自动适配
- 想更快压缩:加
- FFmpeg环境:确保你的系统已经安装了FFmpeg,Linux/macOS可以用包管理器安装,Windows可以下载官方编译包并添加到环境变量
备注:内容来源于stack exchange,提问作者Norhther
相关产品推荐
相关产品推荐

