使用FFmpeg旋转视频


417

我一直在尝试找出如何使用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度也是一个极好的选择。旋转选项哪里去了?


更新了我的答案。好像该过滤器是上个月才添加到源中的。
rwilliams

76
对于正在寻找180度旋转的任何人:-vf "vflip,hflip"
OrangeDog 2012年

4
我想知道,是否可以在不解码然后重新编码视频的情况下实现这一目标-jpegtran可以无损旋转JPEG图像的方式……
Mikhail T.


1
我刚刚将180度旋转的视频“ transpose = 1,transpose = 1”上传到了vimeo。即使我可以播放旋转的视频,它也被vimeo拒绝。@OrangeDog的方法很有-vf "vflip,hflip"魅力。
Besi 2016年

Answers:


682

顺时针旋转90:

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

对于transpose参数,您可以传递:

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

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

确保您从此处使用最新的ffmpeg版本(静态构建可以正常使用)。

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

一个解决方案就是使用此便捷脚本


8
该视频仍将具有方向信息,因此现在该视频将在iphone上错过校正。
srcspider

25
当我使用此命令时,我会得到低质量的视频输出,除非-正如我刚刚发现的-我也使用了此参数:-vcodec libx264。但是如果我不需要查找用作ffmpeg的编码应该已经知道的话,那就太好了。有什么建议么?
2013年

8
与Sadi一样,是否有办法“复制”原始视频的质量?
亚历克·雅各布森

58
180可以使用-vf "transpose=2,transpose=2"
Alex Pliutau 2013年

23
当前文档指出“不赞成使用数值,而应放弃使用符号常量。” ffmpeg.org/ffmpeg-filters.html#transpose因此cclock_flipclockcclockclock_flip代替的0123
l --marc l

149

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

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

11
怎么样用先检查旋转元数据ffmpeg -i input.m4v 2>&1 | grep rotate
lidaobing

60
到目前为止,这是最好的答案。但是有一点点要做。为避免丢失视频上剩余的元数据(如日期,摄像机)ffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v。这样,输入文件上的所有全局元数据将作为全局元数据复制到输出文件,并且仅旋转元数据被更改。
migle

11
如果您有纵向模式视频,并且只想“不旋转”它具有标准的1920x1080,那么您可能想要rotate=0
mivk

1
尝试过-metadata:s:v rotate="180",没有用。那应该起作用吗?
OndraŽižka17年

7
IMHO最佳解决方案,因为不需要重新编码,并且大多数视频播放器支持元数据旋转。还有云服务,例如Google Photos。但是,请记住,ffmpeg不一定会复制原始文件中的所有元数据!因此,我建议明确指定要复制原始文件中的所有其他元数据:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
Andreas

83

你有尝试过transpose吗?喜欢(来自其他答案)

 ffmpeg -i input -vf transpose=2 output

如果您使用的是旧版本,则要更新ffmpeg才能使用转置功能(该功能是2011年10月添加的)。

FFmpeg 下载页面提供了静态构建,您无需编译即可直接执行。


1
不我没有。我不知道它的存在。我会试一试。
jocull 2010年

我的任何FFmpeg版本中似乎都没有转置滤波器。我应该如何添加它?
jocull


6
感觉像我因在接受答案的1.5年之前提供有用的答案而受到惩罚。
威廉

1
@JonasB用逗号分隔过滤器。见stackoverflow.com/questions/6195872/...
rwilliams

19

我在寻找相同答案时遇到了该页面。距最初提出要求已经六个月了,自那时以来,该版本已多次更新。但是,我想为遇到此信息的其他人添加答案。

我正在从那些存储库中使用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

谢谢(你的)信息!我从来没有真正能够做到这一点,因为我通常无法从源代码构建。我可能会看看现在是否可以再次使用它。
jocull

transpose = 3导致图像镜像
Daniel Kobe

对于我的270旋转视频,transpose = 2无需镜像即可工作
Daniel Kobe

17

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

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

对于逆时针,角度必须为负

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

转置滤镜在90度角下同样可以很好地工作,但对于其他角度,这是一个更快的选择。


2
这很棒。我发现有可能获得更精确的弧度分辨率,因为它*表现为乘法:(ffmpeg -i in.avi -vf "rotate=-8*PI/40" -q 1 out.avi 比-PI / 4 = -10 * PI / 40小得多的旋转)
eqzx

12
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,然后它将起作用
patrick

2
“以弧度表示的任意角度旋转视频。” 文档:ffmpeg.org/ffmpeg-filters.html#rotate因此,弧度rotate=PI/2还是rotate=90*PI/180必需的
l --marc l

这太棒了
Tessaracter19年

7

如果您遇到“编解码器处于实验状态,但未启用实验性编解码器”错误,请使用以下命令:

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

和我一起发生了一些带有AAC音频的.mov文件。


这是唯一对我有用的示例,但是质量太差了,而且非常笨拙。此外,它还将1080x1920的视频尺寸缩小到352x640。我想我缺少一两个开关。有什么建议么?
LOlliffe 2013年

1
@LOlliffe add-sameq
Andrew Schleifer

2
@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,但仍然有效。
LOlliffe 2013年

3

该脚本将在“ 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

2
哎呀,这可能有用,但是非常可怕。首先,shell编程的一般规则是:在管道中,您只需要grep,cut,awk或sed中的一个即可。sed或awk都可以执行任何grep。然后,更具体地说,可以要求exiftool仅输出所需的标记-因此,除了过滤掉Rotation外,还只需“ exiftool -Rotation”即可。第三,您不需要那么多的“小样”,并且为了提高可读性和效率,应将“ if test ...”替换为$ ROTATION大小写。祝好运!
Mikhail T.

没有骰子:[Parsed_pad_2 @ 0x7f8b15c3a580] Input area -420:0:1500:1080 not within the padded area 0:0:1080:1080 or zero-sized\ [Parsed_pad_2 @ 0x7f8b15c3a580] Failed to configure input pad on Parsed_pad_2Error reinitializing filters!Failed to inject frame into filter network: Invalid argumentError while processing the decoded data for stream #0:0Conversion failed!
n`

2

Alexy的答案几乎对我有用,除了我遇到以下错误:

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

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

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

如果您正在寻找“ NTSC胶片”帧速率,那24000/1001将更加准确。
Reino

2

与上述解决方案不同的另一种解决方案是检查相机驱动程序是否支持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用户提供帮助。
JM

1

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

您需要使用avidemux或其他一些编辑器来达到​​相同的效果。

以编程方式,建议使用编码器。


1
您是说“ ffmpeg的Ubuntu版本支持视频过滤器”吗?
user1438038'1

2
仅供参考:“ FFmpeg已在Ubuntu 15.04 Vivid Vervet中返回。” 或可以为Ubuntu编译。-> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
l --marc l

avconv确实(在14.04中),并且似乎完全一样。(但对于更高版本,请
务必

1

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

要将其发送到网络侧,它是左侧90度(逆时针,横向格式)。

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

可以。我又恢复了垂直格式

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.