FFmpeg 实战小知识 | H264 转 MP4 播放时长异常问题

4 阅读3分钟

一、问题场景

今天有个朋友需要让我把车载记录仪的视频导给他看,我发现记录仪存储格式是h264,但是我朋友手机里不能看h264格式视频,那就用 FFmpeg 转成 MP4 给他,中间出现了一个小插曲,学到了不少知识。

记录仪导出的H264 格式视频,直接转 MP4 后出现时长仅 2 秒、画面极速倍速播放的问题。

经过大模型的帮助和实际测试,我不仅解决了问题,还掌握了H264 一点小知识,知道了裸流、FFmpeg 转换。这篇博客就把完整的踩坑、解题、原理梳理分享给大家,避免后续踩同样的坑。

二、首次尝试:错误命令导致播放异常

我第一时间想到用流复制(最快、不损画质)的方式转换,执行了命令:

ffmpeg -i input.h264 -c copy output.mp4

出现的问题

  1. 转换后的 MP4时长只有 2 秒

  2. 播放时视频飞快闪过,完全无法正常观看。


三、问题根源:为什么会播放异常?

1. 分清两个核心概念

  • .h264 = H264 编码裸流, 它只有视频画面的编码数据:没有任何封装信息,属于「纯视频码流」;

  • MP4 = 容器格式:除了视频数据,还必须存储帧率、时长、时间戳 等元数据,播放器才能正常播放。

2. 异常的本质:裸流缺少「时间信息」

我们的车载记录仪导出的纯 H264 裸流,没有自带帧率和时间戳! FFmpeg 处理这种无元数据的裸流时,无法识别视频的真实播放速度,只能用默认的错误参数生成 MP4,最终导致:

  • 总时长被严重压缩;
  • 画面没有正确的播放间隔,出现倍速快放。

四、方案一:手动指定帧率(无损极速转换)

既然问题是缺少帧率,我们手动告诉 FFmpeg 输入视频的真实帧率,就能修复时间戳问题。

车载记录仪 / 监控摄像头的标准帧率为 25/30fps,使用命令:

# 25帧率(车载/监控最常用,优先用这个)
ffmpeg -r 25 -i input.h264 -c copy output.mp4

# 30帧率(根据设备实际帧率选择)
ffmpeg -r 30 -i input.h264 -c copy output.mp4

参数说明

  • -r 25:给裸 H264 流指定25 帧帧率
  • -c copy无损快速封装,不转码、不损画质

五、方案二:自动重新编码(零配置,最省心)

如果不想手动猜帧率、指定参数,有没有全自动无脑转换的方案? 答案是:重新编码视频,让 FFmpeg 自动分析裸流并生成正确参数。

推荐命令

# 基础版(默认参数,自动适配)
ffmpeg -i input.h264 -c:v libx264 output.mp4

# 优化版(画质+速度平衡,日常首选)
ffmpeg -i input.h264 -c:v libx264 -crf 23 -preset fast output.mp4

参数解释

参数作用说明
-i 文件名指定输入文件FFmpeg 命令必填基础参数
-c:v libx264指定视频编码器通用 H264 编码器,兼容性拉满
-crf 23恒定画质因子0-51,23 为默认最优值(画质 / 体积平衡);数值越小画质越好
-preset fast编码速度预设控制编码速度与压缩比;fast 速度快,veryslow 体积更小