【问题标题】:FFMPEG: crop a video without losing the qualityFFMPEG:在不损失质量的情况下裁剪视频
【发布时间】:2016-01-27 11:43:23
【问题描述】:

我有1920x1080 的mp4 视频。我想将视频裁剪为480x270不损失质量

我正在使用以下命令:

ffmpeg -i input.mp4 -filter:v "crop=480:270:200:200" -crf 23 output.mp4

我也试过了:

ffmpeg -i input.mp4 -filter:v "crop=480:270:200:100" -c:a copy -qp 0 output.mp4

我使用-crf 23-qp 0 进行无损视频裁剪,但裁剪后视频质量下降。

有谁知道我如何在不损失质量的情况下裁剪视频?

【问题讨论】:

  • 请显示您的ffmpeg 命令的完整控制台输出。
  • 在这里你可以找到控制台输出:dropbox.com/s/1r4pdgdmtj9ilnm/consol-output.rtf?dl=0Thanks
  • 您应该编辑您的问题以包含控制台输出。您可以在播放期间进行裁剪。这会是一个可以接受的解决方案吗?
  • 在播放过程中裁剪?我为此命令添加了什么外壳?
    ffmpeg -i input.mp4 -filter:v "crop=480:270:200:100" -c:a copy -qp 0 output.mp4
  • H.264 没有无损裁剪,您正在重新编码内容。因此,质量损失。

标签: video ffmpeg


【解决方案1】:

当编码为有损格式时,您无法执行任何过滤而不损失质量,但您有一些选择。

使用播放器裁剪

一种可能的解决方案是在播放期间进行裁剪,这样您甚至不需要重新编码。预览裁剪也很有用。

此方法不会创建输出文件。这将使用您的视频播放器在播放时进行裁剪。如果您需要输出文件,请参阅下面的其他方法之一。

使用ffplaycrop filter

ffplay -vf "crop=480:270:200:100" input.mp4

使用vlc(或cvlc):

vlc input.mp4 --crop=480x270+200+100

或者您可以使用 VLC GUI 进行裁剪:工具 → 效果和滤镜 → 视频效果 → 裁剪。

接受一些质量损失(您甚至可能没有注意到差异)

给它足够的位,您可能无法分辨出质量差异:

ffmpeg -i input -vf "crop=480:270:200:100" -c:v libx264 -crf 17 -c:a copy ouput.mp4

请参阅FFmpeg Wiki: H.264 Video Encoding Guide 了解更多信息。

使用比特流过滤器

h264_metadatahevc_metadata 比特流过滤器可以在不修改视频本身的情况下设置裁剪尺寸。

注意:您的播放器可能不支持此方法。

H.264 视频示例:

ffmpeg -i input.mp4 -c copy -bsf:v h264_metadata=crop_left=100:crop_right=20:crop_top=10:crop_bottom=10 output.mp4
  • 在 SPS 中设置帧裁剪偏移量。如果流已被裁剪,这些值将替换当前值。

  • 这些字段以像素为单位。请注意,如果对色度进行二次采样或对流进行隔行扫描,则某些尺寸可能无法表示(请参阅 H.264 第 7.4.2.1.1 节)。

使用无损格式

ffmpeg 可以使用多种无损编码器进行编码:ffv1、huffyuv、ffvhuff、utvideo、libx264(使用-crf 0-qp 0)。输出将是无损的,但输出文件会很大。

注意:您的播放器可能不支持此方法。

ffmpeg -i input.mp4 -vf "crop=480:270:200:100" -c:v ffv1 -c:a copy output.mkv

ffmpeg -i input.mp4 -vf "crop=480:270:200:100" -c:v libx264 -crf 0 -c:a copy output.mp4

如果您的输入是 MJPEG

Stream copy the individual images with ffmpeg,使用jpegtran 无损裁剪它们,然后使用ffmpeg 重新组合它们。这不会造成任何损失,但您将被限制为古老的 MJPEG 格式。

【讨论】:

  • 在我的 Mac 中我已经安装了 ffmpeg,我不确定如何使用 ffplay?
  • 我使用 Homebrew。据我记得我遵循了这些说明:trac.ffmpeg.org/wiki/CompilationGuide/MacOSX 谢谢
  • 是的,我知道,但我总是收到 ffplay not found 消息:Masuds-MacBook-Pro:golf masudrana$ cd selected Masuds-MacBook-Pro:selected masudrana$ ffplay -vf "crop=480:270:200:100" golf.mp4 -bash: ffplay: command not found
  • @MasudRana 也许它没有安装或者它不在你的PATH 中。我不熟悉 OS X,所以我不能推荐其他任何东西。尝试搜索 ffplay 二进制文件。或者,从evermeet.cx/ffmpeg 获取ffplay
  • 在 mplayer 中播放新视频时使用比特流过滤器效果很好,但在 VLC (3.0.9.2) 和 Kodi (18) 中都会搞砸。
【解决方案2】:

在基本级别上,您不能使用有损编码,然后在解码然后再次编码时期望它不会降低质量。唯一可行的方法是使用无损编解码器,例如带有动画编解码器的 Quicktime。这只是数字视频制作的一个基本事实,您无法仅通过将命令行选项传递给 ffmpeg 来解决。

【讨论】:

  • 一定有什么办法,因为我不是压缩视频而是裁剪它。
  • 但您正在压缩视频。压缩格式的视频不能修改。就像任何其他压缩内容一样,例如 zip 文件。它必须解压缩、修改(裁剪),然后再次压缩。话虽如此,但在足够高的比特率下,您不应该损失太多质量。
  • Masud,如果您要忽略答案,为什么还要问一个问题?背景信息请见:howtogeek.com/142174/…
  • @MoDJ 对不起,我是 stackoverflow 的新手
  • 请注意,此答案涉及“解码然后再次编码”。 OP 似乎不知道裁剪需要去编码。这是必要的,因为裁剪会更改图像数据(如果您想删除未使用的数据)。
【解决方案3】:

这在使用 ffmpeg 时是不可能的。

作为替代方案,您可以将视频嵌入到 Matroska (.mkv) 容器和 set a cropping tag in the file header,但 it must be supported by your player

据说,对于H264编码的视频H264info也可以使用,但我还需要弄清楚如何使用它......

【讨论】:

  • 这也应该可以通过 FFmpeg 比特流过滤器实现,请参阅我的回答(最初是对这个问题的评论)。
【解决方案4】:

至少对于某些视频格式,基于元数据的软解决方案应该也可以使用 FFmpeg 以及使用 libavcodec 中的 bitstream 过滤器,例如hevc_metadatah264_metadata

cropcropdetect 等过滤器不同,这不需要解码。但是,语法略有不同,因为您只能设置四个边缘的裁剪量,而不是目标矩形大小。对于 1920×1080 全高清帧中左上角位置 (200,200) 的 OP 的 480×270 区域,我们得到:

  • ffmpeg -i input.mp4 -codec copy -bsf:v h264_metadata=crop_left=200:crop_right=1240:crop_top=200:crop_bottom=610 output.mp4

因为这是编解码器元数据,所以无论容器格式如何,它应该都可以工作,即不仅在 MP4 中,在 MKV 或 AVI 中也是如此。唉,我自己还没有测试过,也不能说任何关于软件和硬件播放器的支持。 (不过,第一次简单的检查失败了。)

有关更详细的信息,FFmpeg 的文档分别参考了 H.265 和 H.264 规范的第 7.4.3.2.1 和 7.4.2.1.1 节,它们可从 ITU 免费获得并且基本上是等效的:

  • frame_cropping_flag 等于 1 表示帧裁剪偏移参数在序列参数集中紧随其后。 frame_cropping_flag 等于 0 表示不存在帧裁剪偏移参数。
  • frame_crop_left_offset, frame_crop_right_offset, frame_crop_top_offset, frame_crop_bottom_offset 指定解码过程输出的编码视频序列中图片的样本,以矩形形式表示 在帧坐标中指定的区域用于输出。 变量CropUnitXCropUnitY派生如下:

    – 如果 ChromaArrayType 等于 0,则 CropUnitX 和 CropUnitY 派生为: CropUnitX = 1 CropUnitY = 2 − frame_mbs_only_flag – 否则(ChromaArrayType 等于 1、2 或 3),CropUnitXCropUnitY 派生为: CropUnitX = SubWidthC CropUnitY = SubHeightC * ( 2 − frame_mbs_only_flag )

帧裁剪矩形包含亮度样本,其水平帧坐标来自 CropUnitX * frame_crop_left_offset to PicWidthInSamplesL − ( CropUnitX * frame_crop_right_offset + 1 ) 和垂直框架坐标 CropUnitY * frame_crop_top_offset to ( 16 * FrameHeightInMbs ) − ( CropUnitY * frame_crop_bottom_offset + 1 ),包括在内。

frame_crop_left_offset 的值应在 0 范围内 至( PicWidthInSamplesL / CropUnitX ) − ( frame_crop_right_offset + 1 ),含; frame_crop_top_offset的取值范围为0~( 16 * FrameHeightInMbs / CropUnitY ) − ( frame_crop_bottom_offset + 1 ),含0。

frame_cropping_flag等于0时,frame_crop_left_offsetframe_crop_right_offsetframe_crop_top_offsetframe_crop_bottom_offset的值将被推断为等于0。

ChromaArrayType不等于0时,两个色度数组对应的指定样本为帧坐标为( x / SubWidthC, y / SubHeightC )的样本,其中( x, y )为指定亮度的帧坐标 样本。

对于解码字段,解码字段的指定样本是落在帧坐标中指定的矩形内的样本。

【讨论】:

  • 这是一个不错的解决方案。它真的不会重新编码 h264 视频。我用我的一个视频文件尝试了这个,但它在不同的视频播放器之间不能可靠地工作。我正在使用 VLC Player,它解释crop_left 和crop_top 错误,视频已从右侧和底部裁剪。然后我尝试了 Windows Media Player,并且从顶部和左侧按预期裁剪了相同的视频。我需要在所有播放器中以相同的方式裁剪视频,因此我无法使用此选项。
猜你喜欢
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 2013-03-15
  • 2015-04-04
相关资源
最近更新 更多