ffmpeg 转换不损失质量

Posted

技术标签:

【中文标题】ffmpeg 转换不损失质量【英文标题】:ffmpeg convert without loss quality 【发布时间】:2014-10-23 12:27:06 【问题描述】:

当文件类型不是 flv/mp4/webm 时,我需要将所有视频转换为我的视频播放器(在网站中)。

当我使用时:ffmpeg -i filename.mkv -sameq -ar 22050 filename.mp4

[h264 @ 0x645ee0] 解码 MB 22 1,字节流 (8786) 时出错

我的意思是,当我需要将文件类型:.mkv 和其他(jwplayer 不支持)转换为 flv/mp4 而不损失质量时,我应该怎么做。

【问题讨论】:

回答***.com/a/15052662/3102264解释如何不重新编码复制(ffmpeg -i input.mkv -c copy -map 0 output.mp4) @mpromonet 如果你想保留编解码器,-c copy 很好,但要转换编解码器并保持相同的质量,我必须使用 -qscale 0 就像我在答案中读到的那样。跨度> 【参考方案1】:

不要使用-sameq, it does not mean "same quality"

该选项已在不久前从 FFmpeg 中删除。这意味着您使用的是过时的版本。

使用 libx264 进行编码时,请改用 -crf 选项。这是ffmepg 使用的 H.264 视频编码器,如果可用,它是 MP4 输出的默认编码器。有关详细信息,请参阅FFmpeg H.264 Video Encoding Guide。

获取最近的ffmpeg

转到FFmpeg Download 页面并在那里进行构建。有适用于 Linux、OS X 和 Windows 的选项。或者您可以关注FFmpeg Compile Guides 之一。由于 FFmpeg 开发非常活跃,因此始终建议您使用适合您使用的最新版本。

你将不得不接受一些质量损失

您可以使用 libx264 生成无损输出,但这可能会创建绝对巨大的文件,并且可能无法被浏览器解码和/或被 JW Player 支持(我从未尝试过)。

好消息是,您可以制作大致无损的视频。同样,文件可能有点大,但您需要在质量和文件大小之间做出选择。

使用-crf 选择一个介于 18 到 29 之间的值。选择仍能提供可接受质量的最高数字。为您的视频使用该值。

其他事情

添加-movflags +faststart。这会将 moov atom 从文件末尾重新定位到开头。这将允许视频在下载时开始播放。否则必须完全下载整个视频才能开始播放。

添加-pix_fmt yuv420p。这将确保对所有播放器兼容的色度子采样。否则,ffmpeg 默认情况下会根据几个因素尝试最小化或避免色度二次采样,结果通常无法由非 FFmpeg 播放器播放。

【讨论】:

最好能澄清一下 CRF 是什么,它的作用以及如何使用这个参数。 CRF 代表恒定速率因子。来自 ffmpeg docs 的引用:“CRF 比例的范围是 0-51,其中 0 是无损的,23 是默认值,51 是可能的最差质量。较低的值通常会导致更高的质量,主观上合理的范围是 17 –28. 认为 17 或 18 在视觉上没有损失或几乎没有损失。”有用链接:ffmpeg docs、Understanding Rate Control Modes @AlexanderMosov 您在我的回答中引用的 wiki 有一个链接。【参考方案2】:

使用 -qscale 0 代替 -sameq(已被 FFMpeg 删除):文件大小会增加,但会保持质量。

【讨论】:

-qscale,或者更准确地说是-qscale:v,只能用于传统的 MPEG 系列:mjpeg、mpeg1video、mpeg2video、mpeg4 等。它被使用 @987654324 的 libx264 和 libx265 忽略而是@。 @LordNeckbeard 等等,如果您从 mpeg4(例如 mp4v)转换为 H.264,这两者都涉及到怎么办? @Michael 输入格式无关紧要:只有用于输出的编码器很重要。这是因为无论输入格式如何,ffmpeg 都会将输入分解为原始格式。然后编码器会将原始格式处理成输出。 (除非您使用-c copy 进行流式复制,否则不会发生重新编码)。 ffmpeg 4.2.1 在使用 -qscale 0 时抛出黄色“请使用 -q:a 或 -q:v,-qscale 不明确”消息【参考方案3】:

将所有mkv转成mp4而不损失质量(实际上只是重新打包):

for %a in ("*.mkv") do ffmpeg.exe -i "%a" -vcodec copy -acodec copy -scodec mov_text "%~na.mp4"

【讨论】:

对我来说,一个简单的ffmpeg -i input_file.mkv output_file.mp4 就可以了。 @ThiagoNegri 但是会重新编码所有内容;使用“复制”,您可以避免这样做【参考方案4】:

对我来说,这是转换它的最佳方式。

ffmpeg -i input -vcodec copy output

我正在用 python 编写一个脚本,将多个 .webm 文件附加到一个 .mp4 中。我花了 10 到 20 秒来转换一块 5 秒的时间:

ffmpeg -i input -qscale 0 copy output

有些文件夹的块数超过 500 个。

现在每个块只需要不到一秒的时间。我花了 5 分钟来转换一个 1:20:00 的长视频。

【讨论】:

以上是关于ffmpeg 转换不损失质量的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ffmpeg 将 MP4 转换为 WMV 以获得更好的质量?

如何用中等质量的ffmpeg将vob转换为wmv?

将Icon对象转换为byte []会导致质量损失

iOS:将 PNG 转换为 HEIF/HEIC + Alpha 而不会造成质量损失

ffmpeg转换视频格式的问题

ffmpeg 视频压缩/特定文件大小