FFMPEG:在不损失质量的情况下裁剪视频

时间:2015-10-27 21:12:19

标签: video ffmpeg

我有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进行无损视频裁剪,但裁剪后视频质量下降。

有谁知道如何裁剪视频而不会失去的质量?

4 个答案:

答案 0 :(得分:24)

在编码为有损格式时,您无法在不降低质量的情况下执行任何过滤,但您有一些选择。

使用播放器裁剪

可能的解决方案是在播放期间裁剪,因此您甚至不需要重新编码。预览作物也很有用。

使用ffplaycrop filter

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

使用vlc(或cvlc):

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

或者您可以使用VLC GUI裁剪:工具>效果&过滤器>视频效果>作物。

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

使用无损格式

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

接受一些质量损失

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

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

如果您的输入是MJPEG

Stream copy the individual images with ffmpeg,使用jpegtran无损地裁剪它们,然后使用ffmpeg将它们重新混合。这将导致不会丢失,但您将被限制在古老的MJPEG格式中。

答案 1 :(得分:4)

在基本级别,您无法使用有损编码,然后在解码然后再次编码时期望它不会丢失质量。唯一有效的方法是使用无损编解码器,例如使用动画编解码器的Quicktime。这只是数字视频制作的基本事实,你只需将命令行选项传递给ffmpeg就无法解决。

答案 2 :(得分:3)

使用ffmpeg无法做到这一点。

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

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

答案 3 :(得分:2)

至少对于某些视频格式而言,通过使用libavcodec的 bitstream 过滤器,也可以使用FFmpeg基于元数据 的软解决方案,例如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中也是如此。 las,我自己尚未测试过,不能说有关软件和硬件播放器支持的任何内容。 (不过,第一次简单的检查却失败了。)

有关更多详细信息,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_offsetframe_crop_right_offsetframe_crop_top_offsetframe_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 )的范围内(包括两端)。

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 )是指定亮度的帧坐标 样本。

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