【问题标题】:Rotating videos with FFmpeg使用 FFmpeg 旋转视频
【发布时间】:2011-04-25 15:24:42
【问题描述】:

我一直在试图弄清楚如何使用 FFmpeg 旋转视频。我正在处理以纵向模式拍摄的 iPhone 视频。我知道如何使用MediaInfo(优秀的库,顺便说一句)确定当前的旋转度数,但我现在被困在 FFmpeg 上。

根据我的阅读,您需要使用 vfilter 选项。根据我看到的应该是这样的:

ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4

但是,我无法让它工作。首先,-vfilters 不再存在,现在只是 -vf。其次,我得到这个错误:

No such filter: 'rotate'
Error opening filters!

据我所知,我有一个全选项的 FFmpeg。运行 ffmpeg -filters 会显示:

Filters:
anull            Pass the source unchanged to the output.
aspect           Set the frame aspect ratio.
crop             Crop the input video to x:y:width:height.
fifo             Buffer input images and send them when they are requested.
format           Convert the input video to one of the specified pixel formats.
hflip            Horizontally flip the input video.
noformat         Force libavfilter not to use any of the specified pixel formats
 for the input to the next filter.
null             Pass the source unchanged to the output.
pad              Pad input image to width:height[:x:y[:color]] (default x and y:
 0, default color: black).
pixdesctest      Test pixel format definitions.
pixelaspect      Set the pixel aspect ratio.
scale            Scale the input video to width:height size and/or convert the i
mage format.
slicify          Pass the images of input video on to next video filter as multi
ple slices.
unsharp          Sharpen or blur the input video.
vflip            Flip the input video vertically.
buffer           Buffer video frames, and make them accessible to the filterchai
n.
color            Provide an uniformly colored input, syntax is: [color[:size[:ra
te]]]
nullsrc          Null video source, never return images.
nullsink         Do absolutely nothing with the input video.

拥有 vfliphflip 的选项非常棒,但它们无法将我带到我需要去的地方。我需要至少能够将视频旋转 90 度。 270 度也是一个很好的选择。旋转选项哪里去了?

【问题讨论】:

  • 对于任何搜索 180 度旋转的人:-vf "vflip,hflip"
  • 我想知道,如果这可以在不解码然后重新编码视频的情况下实现 - jpegtran 可以无损旋转 JPEG 图像的方式...
  • 旋转标志请参见此处:stackoverflow.com/questions/15335073/…
  • 另请参阅How to flip a video 180° (vertical/upside down) with FFmpeg? 的详细答案不要忘记重置任何现有的轮换元数据(请参阅链接)。
  • 我刚刚将“transpose=1,transpose=1”的 180° 旋转视频上传到 vimeo。即使我可以播放旋转的视频,它也被 vimeo 拒绝。 @OrangeDog 的方法 -vf "vflip,hflip" 很有魅力。

标签: ffmpeg rotation video-processing


【解决方案1】:

顺时针旋转 90:

ffmpeg -i in.mov -vf "transpose=1" out.mov

转置参数可以传入:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

使用-vf "transpose=2,transpose=2" 表示 180 度。

确保您使用最新的 ffmpeg 版本 from here(静态构建可以正常工作)。

请注意,这将重新编码音频和视频部分。您通常可以使用-c:a copy 复制音频而无需触摸它。要更改视频质量,请设置比特率(例如使用-b:v 1M)或查看H.264 encoding guide(如果您需要 VBR 选项)。

一个解决方案也是使用这个convenience script

【讨论】:

  • 视频仍然有方向信息,所以现在视频将在 iphone 上被遗漏。
  • 当我使用这个命令时,我得到一个低质量视频输出,除非——正如我刚刚发现的——我也使用这个参数:-vcodec libx264 .但是,如果我不需要查找要使用的编码,那就太好了,因为 ffmpeg 应该已经知道了。 有什么建议吗?
  • 和 Sadi 一样,有没有办法“复制”原始视频的质量?
  • 180 你可以使用-vf "transpose=2,transpose=2"
  • 当前文档指出“数字值已被弃用,应删除以支持符号常量。” ffmpeg.org/ffmpeg-filters.html#transpose 因此cclock_flipclockcclockclock_flip 而不是0123
【解决方案2】:

如果您不想重新编码您的视频并且您的播放器可以处理旋转元数据,您可以使用 ffmpeg 更改元数据中的旋转:

ffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v

【讨论】:

  • 先用ffmpeg -i input.m4v 2>&1 | grep rotate检查旋转元数据如何?
  • 这是迄今为止最好的答案。但是有一点小改进要做。为避免丢失视频中剩余的元数据(例如日期、相机),请执行ffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v。这样,输入文件上的所有全局元数据都将作为全局元数据复制到输出文件,并且仅更改旋转元数据。
  • 如果您有一个纵向模式的视频,并且只想“取消旋转”它以获得标准 1920x1080,那么您可能需要rotate=0
  • 试过-metadata:s:v rotate="180",没用。这应该有效吗?
  • 恕我直言最好的解决方案,因为不需要重新编码并且大多数视频播放器都支持元数据轮换。还有像谷歌照片这样的云服务。但是,请记住,ffmpeg 不一定会从原始文件中复制所有元数据!因此,我建议明确指定从原始文件中复制所有其他元数据:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
【解决方案3】:

你试过transpose了吗?喜欢(来自另一个答案)

 ffmpeg -i input -vf transpose=2 output

如果你使用的是旧版本,如果你想使用转置功能,你必须更新 ffmpeg,因为它是在 2011 年 10 月添加的。

FFmpeg download 页面提供静态构建,您可以直接执行而无需编译它们。

【讨论】:

  • 不,我没有。我不知道它存在。我会试一试。
  • 我的任何 FFmpeg 版本中似乎都不存在转置过滤器。我应该如何添加它?
  • 感觉就像我在接受答案前 1.5 年提供了一个有用的答案而受到了惩罚。
  • @JonasB 用逗号分隔过滤器。见stackoverflow.com/questions/6195872/…
  • @rwilliams 虽然这是一个很好的答案,比 Alexy 的答案早了 1.5 年,但它的缺点是它没有包含关于转置功能或如何使用它的尽可能多的信息。您链接到它很好,但链接到相关信息的缺点是(在这种情况下)链接不再指向正确的文档。如果不出意外,我将提交修改以修复链接。
【解决方案4】:

要顺时针旋转图片,您可以使用旋转滤镜,以弧度表示正角度。 90 度等于 PI/2,你可以这样做:

ffmpeg -i in.mp4 -vf "rotate=PI/2" out.mp4

逆时针方向的角度必须为负

ffmpeg -i in.mp4 -vf "rotate=-PI/2" out.mp4

转置过滤器同样适用于 90 度,但对于其他角度,这是更快或唯一的选择。

【讨论】:

  • 这很棒。我发现可以获得更细粒度的弧度分辨率,因为* 表现为乘法:ffmpeg -i in.avi -vf "rotate=-8*PI/40" -q 1 out.avi(比 -PI/4 = -10*PI/40 旋转略小)
【解决方案5】:

我在搜索相同的答案时遇到了这个页面。从最初提出这个问题到现在已经六个月了,从那时起,这些版本已经更新了很多次。但是,我想为遇到此信息的其他人添加一个答案。

我正在使用来自这些存储库的 Debian Squeeze 和 FFmpeg 版本。

ffmpeg 的 MAN 页面说明了以下用途

ffmpeg -i inputfile.mpg -vf "transpose=1" outputfile.mpg

关键是您不要使用度数变量,而是使用 MAN 页面中预定义的设置变量。

0=90CounterCLockwise and Vertical Flip  (default) 
1=90Clockwise 
2=90CounterClockwise 
3=90Clockwise and Vertical Flip

【讨论】:

  • 感谢您的信息!我从来没有真正让这个工作,因为我通常很难从源代码构建。我可能会看看我现在是否可以让它再次工作。
  • transpose=3 导致图像镜像
  • transpose=2 没有镜像我的 270 个旋转视频
【解决方案6】:
ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4 

即使使用最新的源也不行...

必须改变顺序:

ffmpeg -i input.mp4 -vf vflip output.mp4

工作正常

【讨论】:

  • 那是因为您将过滤器应用于错误的文件...尝试 ffmpeg -i input.mp4 -vf "rotate=90" output.mp4,然后它会起作用
  • "将视频旋转任意角度,以 弧度 表示。"文档:ffmpeg.org/ffmpeg-filters.html#rotate 所以,需要弧度 rotate=PI/2rotate=90*PI/180
【解决方案7】:

如果您收到“编解码器是实验性的,但未启用实验性编解码器”错误,请使用:

ffmpeg -i inputFile -vf "transpose=1" -c:a copy outputFile

我遇到了一些带有 aac 音频的 .mov 文件。

【讨论】:

  • 这是唯一对我有用的例子,但质量很糟糕,而且非常块状。此外,它将 1080x1920 视频缩小到 352x640。我想我缺少一两个开关。有什么建议吗?
  • @LOlliffe 添加-sameq
  • @AndrewSchleifer 谢谢。我试过了,但是 ffmpeg 向我抛出了Option 'sameq' was removed. If you are looking for an option to preserve the quality (which is not what -sameq was for), use -qscale 0 or an equivalent quality factor option. Failed to set value '1' for option 'sameq': Invalid argument -qscale 也给出了一个错误。 Please use -q:a or -q:v, -qscale is ambiguous,但仍然有效。
【解决方案8】:

此脚本将输出具有“fixedFiles”下目录结构的文件。目前已固定为 MOV 文件,并将根据视频的原始“旋转”执行许多转换。适用于运行 Mavericks 的 Mac 上的 iOS 捕获视频,但应该可以轻松导出。依赖于安装 exiftoolffmpeg

#!/bin/bash

# rotation of 90 degrees. Will have to concatenate.
#ffmpeg -i <originalfile> -metadata:s:v:0 rotate=0 -vf "transpose=1" <destinationfile>
#/VLC -I dummy -vvv <originalfile> --sout='#transcode{width=1280,vcodec=mp4v,vb=16384,vfilter={canvas{width=1280,height=1280}:rotate{angle=-90}}}:std{access=file,mux=mp4,dst=<outputfile>}\' vlc://quit

#Allowing blanks in file names
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

#Bit Rate
BR=16384

#where to store fixed files
FIXED_FILES_DIR="fixedFiles"
#rm -rf $FIXED_FILES_DIR
mkdir $FIXED_FILES_DIR

# VLC
VLC_START="/Applications/VLC.app/Contents/MacOS/VLC -I dummy -vvv"
VLC_END="vlc://quit"


#############################################
# Processing of MOV in the wrong orientation
for f in `find . -regex '\./.*\.MOV'` 
do
  ROTATION=`exiftool "$f" |grep Rotation|cut -c 35-38`
  SHORT_DIMENSION=`exiftool "$f" |grep "Image Size"|cut -c 39-43|sed 's/x//'`
  BITRATE_INT=`exiftool "$f" |grep "Avg Bitrate"|cut -c 35-38|sed 's/\..*//'`
  echo Short dimension [$SHORT_DIMENSION] $BITRATE_INT

  if test "$ROTATION" != ""; then
    DEST=$(dirname ${f})
    echo "Processing $f with rotation $ROTATION in directory $DEST"
    mkdir -p $FIXED_FILES_DIR/"$DEST"

    if test "$ROTATION" == "0"; then
      cp "$f" "$FIXED_FILES_DIR/$f"

    elif test "$ROTATION" == "180"; then
#      $(eval $VLC_START \"$f\" "--sout="\'"#transcode{vfilter={rotate{angle=-"$ROTATION"}},vcodec=mp4v,vb=$BR}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
      $(eval ffmpeg -i \"$f\" -vf hflip,vflip -r 30 -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\")

    elif test "$ROTATION" == "270"; then
      $(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=2,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )

    else
#      $(eval $VLC_START \"$f\" "--sout="\'"#transcode{scale=1,width=$SHORT_DIMENSION,vcodec=mp4v,vb=$BR,vfilter={canvas{width=$SHORT_DIMENSION,height=$SHORT_DIMENSION}:rotate{angle=-"$ROTATION"}}}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
      echo ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" 
      $(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )

    fi

  fi

echo 
echo ==================================================================
sleep 1
done

#############################################
# Processing of AVI files for my Panasonic TV
# Use ffmpegX + QuickBatch. Bitrate at 16384. Camera res 640x424
for f in `find . -regex '\./.*\.AVI'` 
do
  DEST=$(dirname ${f})
  DEST_FILE=`echo "$f" | sed 's/.AVI/.MOV/'`
  mkdir -p $FIXED_FILES_DIR/"$DEST"
  echo "Processing $f in directory $DEST"
  $(eval ffmpeg -i \"$f\" -r 20 -acodec libvo_aacenc -b:a 128k -vcodec mpeg4 -b:v 8M -flags +aic+mv4 \"$FIXED_FILES_DIR/$DEST_FILE\" )
echo 
echo ==================================================================

done

IFS=$SAVEIFS

【讨论】:

  • 哎哟......这可能有效,但它非常可怕。首先,shell 编程的一般规则:在管道中您永远不需要超过一个 grep、cut、awk 或 sed。任何 grep|cut|sed 都可以单独使用 sed 或 awk。然后,更具体地说,可以要求 exiftool 只输出您想要的标签——所以不要过滤掉旋转,只需“exiftool -Rotation”。第三,为了可读性和效率,您不需要太多的“评估”并且您的“if test...”应该用 case $ROTATION in 替换。祝你好运!
  • 无骰子:[Parsed_pad_2 @ 0x7f8b15c3a580] Input area -420:0:1500:1080 not within the padded area 0:0:1080:1080 or zero-sized\n ` [Parsed_pad_2 @ 0x7f8b15c3a580] Failed to configure input pad on Parsed_pad_2\n Error reinitializing filters!\n Failed to inject frame into filter network: Invalid argument\n Error while processing the decoded data for stream #0:0\n Conversion failed!
【解决方案9】:

另一个解决方案与最后提到的解决方案不同,它是检查您的相机驱动程序是否支持 v4l2 相机控件(这很常见)。
在终端输入:

v4l2-ctl -L

如果您的摄像头驱动程序支持 v4l2 摄像头控件,您应该会得到类似的内容(下面的列表取决于您的摄像头驱动程序支持的控件):

               contrast (int)    : min=0 max=255 step=1 default=0 value=0 flags=slider
             saturation (int)    : min=0 max=255 step=1 default=64 value=64 flags=slider
                    hue (int)    : min=0 max=359 step=1 default=0 value=0 flags=slider
white_balance_automatic (bool)   : default=1 value=1 flags=update
            red_balance (int)    : min=0 max=4095 step=1 default=0 value=128 flags=inactive, slider
           blue_balance (int)    : min=0 max=4095 step=1 default=0 value=128 flags=inactive, slider
               exposure (int)    : min=0 max=65535 step=1 default=0 value=885 flags=inactive, volatile
         gain_automatic (bool)   : default=1 value=1 flags=update
                   gain (int)    : min=0 max=1023 step=1 default=0 value=32 flags=inactive, volatile
        horizontal_flip (bool)   : default=0 value=0
          vertical_flip (bool)   : default=0 value=0

如果幸运的话,它还支持 horizo​​ntal_flipvertical_flip
那么您需要做的就是通过以下方式设置 horizo​​ntal_flip

v4l2-ctl --set-ctrl horizontal_flip=1

vertical_flip

v4l2-ctl --set-ctrl vertical_flip=1

然后你可以调用你的视频设备来捕捉一个新的视频(见下面的例子),视频将被旋转/翻转。

ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -vcodec libx264 -f mpegts input.mp4

当然,如果您需要处理已经存在的视频,那么这种方法不是您正在寻找的解决方案。

这种方法的优点是我们在传感器级别翻转图像,因此驱动程序的传感器已经为我们提供了翻转的图像,这为应用程序(如 FFmpeg)节省了任何进一步和不必要的处理。

【讨论】:

  • 这里有关于 v4l2 的重要信息。在录制时旋转到正确的方向显然更可取:) 这个近 10 年前的问题(哇!)最初是被问及从 iOS 设备上传的视频是否有助于提供任何上下文:)
  • 我在这个社区有点新,这个问题比我在这里的资历要老得多......我真的认为这是一个很好(和常见)的问题,所以我相信这个老问题会继续存在帮助许多 FFmpeg 用户。
【解决方案10】:

由于ffmpeg转置命令非常慢,使用下面的命令将视频顺时针旋转90度。

快速命令(无编码)-

ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=270 output.mp4

对于完整的视频编码(慢命令,进行编码)

ffmpeg -i inputFile -vf "transpose=1" -c:a copy outputFile

【讨论】:

  • 请注意,快速命令只是添加视频元数据,这可能已经存在于许多来源中。问题在于渲染视频的播放器是否尊重元数据标志:)
【解决方案11】:

Alexy 的回答几乎对我有用,只是我遇到了这个错误:

MPEG 4 标准不支持时基 1/90000,最大 时基分母的允许值为 65535

我只需要在命令中添加一个参数 (-r 65535/2733) 就可以了。完整的命令是:

ffmpeg -i in.mp4 -vf "transpose=1" -r 65535/2733 out.mp4

【讨论】:

  • 如果您正在寻找“NTSC 电影”帧率,那么24000/1001 会更准确。
【解决方案12】:

智能手机:以垂直格式录制视频

想将其发送到向左 90° 的网页(逆时针,横向格式)嗯。

ffmpeg -i input.mp4 -vf "rotate=0" output.mp4

做到了。我又恢复了垂直格式

debian buster: ffmpeg --version ffmpeg 版本 4.1.4-1~deb10u1 版权所有 (c) 2000-2019 FFmpeg 开发者

【讨论】:

    【解决方案13】:

    不幸的是,Ubuntu 版本的 ffmpeg 确实支持视频过滤器。

    你需要使用avidemux或者其他的编辑器来达到​​同样的效果。

    程序化的方式,推荐使用mencoder。

    【讨论】:

    • 您的意思是“Ubuntu 版本的 ffmpeg 支持视频过滤器”吗?
    • 仅供参考:“FFmpeg 已在 Ubuntu 15.04 Vivid Vervet 中回归。”或者可以为 Ubuntu 编译。 --> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
    • avconv 确实(在 14.04 中),并且似乎工作方式完全相同。 (但对于以后的版本,一定要用FFmpeg。)
    【解决方案14】:

    我遇到了与 OP 相同的问题,得到了 No such filter: 'rotate' 错误,即使旋转过滤器显示为 --filters 中的支持。我需要旋转任意角度,因此当前所有替代旋转 90 度的答案都不起作用。我发现-vf的语法需要在标记周围有空格,这与official docs相反。

    改变:

    -vf 'rotate=1.23'

    -vf 'rotate = 1.23' 让它为我工作。

    完整示例:

    ffmpeg.exe -i input.mp4 -vf "rotate = 3.0 , crop = 1920:1080" out.mp4

    FWIW 这是 ffmpeg 版本 4.3.2

    【讨论】:

      【解决方案15】:

      对我来说是这样的

      顺时针旋转

       ffmpeg -i "path_source_video.mp4" -filter:v "transpose=1" "path_output_video.mp4"
      

      逆时针旋转

       ffmpeg -i "path_source_video.mp4" -filter:v "transpose=0,transpose=1,transpose=0" -acodec copy "path_output_video.mp4"
      

      我使用的包zeranoe

      【讨论】:

        猜你喜欢
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-13
        • 2016-07-19
        • 1970-01-01
        • 1970-01-01
        • 2017-12-20
        相关资源
        最近更新 更多