FFmpeg 480p 转码失败但 1080p/720p 正常的坑

前言

最近在开发一个 B 站视频项目时,遇到了一个诡异的问题:视频转码功能里,1080p 和 720p 都能稳定正常转码,唯独 480p 持续转码失败。排查了很久才找到根因,今天把这个问题、分析过程和最终解决方案完整记录下来,帮大家避开这个 FFmpeg 坑。

问题描述

项目的视频处理系统,需要用 FFmpeg 将用户上传的视频转码为 HLS 流媒体格式,同时生成三种分辨率的版本:

  • ✅ 1080p (1920x1080) ------ 转码完全正常
  • ✅ 720p (1280x720) ------ 转码完全正常
  • ❌ 480p (854x480) ------ 转码直接失败

故障表现:转码进程异常退出,FFmpeg 日志没有打印明确的错误原因,只能定位到 480p 转码命令执行失败。

代码分析

先看项目中核心的 FFmpeg 转码工具类代码,问题就藏在这里:

java

运行

复制代码
// FFmpegUtils.java
public boolean transcodeToHLS(String inputPath, String outputDir, String playlistName, int width, int height) {
    ProcessBuilder builder = new ProcessBuilder(
        "ffmpeg",
        "-i", inputPath,
        // 问题核心代码
        "-vf", "scale=" + width + ":-2",  
        "-c:v", "libx264",
        "-preset", "fast",
        "-b:v", "2000k",
        "-c:a", "aac",
        "-b:a", "128k",
        "-hls_time", "10",
        "-hls_list_size", "0",
        "-hls_segment_filename", outputDir + File.separator + "%03d.ts",
        "-y",
        m3u8Path
    );
}

执行 480p 转码时,scale参数会拼接成 scale=854:-2,这就是失败的导火索。

深入分析:问题的根本原因

1. -2 参数的隐藏陷阱

FFmpeg 的scale=宽度:-2语法中,-2表示:自动计算高度,且高度必须是 2 的倍数 。这个设计是为了适配 x264 编码器对视频尺寸的偶数要求,但它不会保持视频原始宽高比,也不会做比例校验。

当源视频和目标分辨率比例不匹配时,自动计算的高度会偏离预期,直接导致转码异常。

2. 缺少关键的宽高比保护逻辑

对比项目中另一个正常运行的 PowerShell 转码脚本,能一眼看出差距:

powershell

复制代码
# 正常可用的缩放参数
scale=w=$($q.scale):force_original_aspect_ratio=decrease
# 480p对应参数:scale=w=854:480:force_original_aspect_ratio=decrease

而 Java 代码里只用了scale=854:-2缺失两个核心配置

  1. 没有显式指定目标高度(480);
  2. 没有添加force_original_aspect_ratio=decrease(保持原始宽高比)。

3. 为什么偏偏 480p 会出问题?

这是 480p 分辨率的特殊性导致的:

表格

分辨率 宽度 高度 比例特性
1080p 1920 1080 标准 16:9,兼容性拉满
720p 1280 720 标准 16:9,极少异常
480p 854 480 非标准 16:9,兼容性极差

标准 480p 是 640x480,而常用的 854x480 是适配 16:9 的非标分辨率。一旦源视频是竖屏、宽银幕、非标比例,-2自动计算的高度就会完全错乱,直接触发转码失败。

解决方案

只需要修改 FFmpeg 的 scale 滤镜参数,就能彻底解决问题。

修复后的代码

java

运行

复制代码
// 原错误写法
"-vf", "scale=" + width + ":-2"

// 修复后写法(推荐)
"-vf", "scale=w=" + width + ":h=" + height + ":force_original_aspect_ratio=decrease"

保守兼容写法

java

运行

复制代码
"-vf", "scale=w=854:h=480:force_original_aspect_ratio=decrease"

参数核心解释

  • w=854:强制视频宽度为 854;
  • h=480:强制视频高度为 480;
  • force_original_aspect_ratio=decrease保持原始宽高比,只缩小不放大,彻底避免视频拉伸、变形、尺寸异常。

修改后重新执行转码,480p、720p、1080p 全部正常输出,无任何异常。

总结

这个问题本质是FFmpeg scale 滤镜参数使用不规范 导致的。scale=宽度:-2是一个 "偷懒写法",在标准 16:9 的 1080p/720p 下能侥幸运行,但在非标 480p 分辨率下会直接暴露缺陷。

核心经验总结

  1. 视频缩放必须显式指定宽高 :不要依赖-2自动计算,避免尺寸错乱;
  2. 强制保留原始宽高比 :必加force_original_aspect_ratio=decrease,防止视频拉伸;
  3. 480p 需特殊处理:854x480 是非标分辨率,转码时一定要做严格的比例校验。

如果你也在做视频转码相关开发,遇到高低分辨率正常、唯独 480p 失败的情况,优先检查scale参数,90% 的概率是这个问题!

相关技术:Java | FFmpeg | HLS | 视频转码 | 流媒体开发

相关推荐
REDcker14 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
沐禾安信20 小时前
AVI 视频打不开?2026 四款转 MP4 工具封神
音视频·电脑录屏
兵叔物联1 天前
基于FFmpeg的短视频自动剪辑工具
ffmpeg·音视频
AORUO奥偌1 天前
从“拼凑”到“集成”:音视频系统如何重塑弱电智能化建设逻辑
音视频·公共广播系统·音视频系统·多媒体会议与ip广播系统·多媒体会议系统
禹亮科技1 天前
大型国企会议室音视频集成实战:3间120㎡空间Poly G7500+LED大屏+讯飞多语言会议系统落地方案
音视频·视频会议系统集成·上海禹亮科技·讯飞听见多语言会议系统·poly g7500
音视频牛哥1 天前
SmartMediaKit macOS版RTSP/RTMP低延迟播放器:技术架构、核心能力与应用实践
音视频·低延迟rtsp播放器·macos直播播放器·macos rtsp播放器·macos rtmp播放器·rtsp播放器mac版·rtmp播放器mac版
潜创微科技1 天前
沁恒CH9339:USB3.0超高速对拷,两台电脑一根线共享一切
音视频
Cxiaomu1 天前
从 TRTC Demo 到独立音视频服务:React + TRTC Web SDK 服务化实践
前端·react.js·音视频
EasyGBS1 天前
政务视频资源汇聚:国标GB28181视频平台EasyGBS在“一网统管”中的定位和落地路径
网络·音视频·政务
蝉蜕日记2 天前
视频压缩 v1.1.31:高效压缩,无损画质,释放存储空间
音视频·生活·视频编解码·视频·软件需求