总结

总结

我的视频在录制时旋转了 180°。可以使用 FFmpeg 纠正这个问题吗?

答案1

原来的旋转


总结

ffmpeg将自动旋转视频,除非:

  • 您的输入不包含旋转元数据
  • ffmpeg太老了

旋转元数据

有些视频(例如来自 iPhone 的视频)没有进行物理翻转,但包含视频流 displaymatrix 端数据或旋转元数据。有些播放器会忽略这些元数据,有些则不会。请参阅ffmpeg控制台输出以查看您的输入是否具有此类元数据:

$ ffmpeg -i input.mp4
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Duration: 00:00:05.00, start: 0.000000, bitrate: 43 kb/s
    Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 39 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      rotate          : 180
    Side data:
      displaymatrix: rotation of -180.00 degrees

自动旋转

ffmpeg将根据任何现有的视频流旋转元数据自动物理旋转视频。

您需要一个包含 2015 年 5 月 2 日提交 1630224 的版本才能使用自动旋转功能。

例子

ffmpeg -i input.mp4 -c:a copy output.mp4

要禁用此行为,请使用该-noautorotate选项。


如果输入不包含元数据,或者您的输入ffmpeg是旧的

您必须使用过滤器来旋转视频,并且如果存在任何旋转元数据,则必须将其删除,如以下示例所示:

例子

您可以ffmpeg选择三种方法来使用视频滤镜进行 180° 旋转。

hflipvflip

ffmpeg -i input.mp4 -vf "hflip,vflip,format=yuv420p" -metadata:s:v rotate=0 \
-codec:v libx264 -codec:a copy output.mkv

transpose

ffmpeg -i input.mp4 -vf "transpose=2,transpose=2,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

rotate

此滤镜可以旋转到任意角度,并使用弧度而不是度作为单位。此示例将旋转 π/1 弧度,即 180°:

ffmpeg -i input.mp4 -vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

您可以使用度数来代替。1 度等于 π/180 弧度。因此,如果您想旋转 45°:

ffmpeg -i input.mp4 -vf "rotate=45*(PI/180),format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

使用过滤器时rotate,对于可被 90 整除的角度,应关闭双线性插值(通过使用bilinear=0),否则可能会看起来很模糊。


笔记

  • 过滤需要编码。这些示例制作 H.264 视频输出。请参阅FFmpeg H.264 视频编码指南以获得您想要的质量的指导。

  • 色度子采样。我包括了,format=yuv420p因为ffmpeg将尝试最小化或避免色度二次采样(取决于编码器、输入、ffmpeg版本等)。从纯技术意义上讲,这是良好的行为,但大多数播放器与更“高级”的色度二次采样方案不兼容。这与使用相同-pix_fmt yuv420,但位于过滤链

  • 复制音频。-codec:a copy选项将流复制(重新复用)而不是编码。如果您只想处理视频,则没有必要重新编码音频(除非您想转换为不同的音频格式)。这将节省时间,因为编码很耗时,并且可以保持音频的质量。


播放时旋转

或者,您可以在播放时旋转并避免重新编码。ffplay将自动旋转:

ffplay input.mp4

如果没有显示矩阵侧数据或旋转元数据,那么您可以使用过滤器:

ffplay -vf "hflip,vflip" -i input.mp4

...或者参考您最喜欢的播放器。大多数值得使用的播放器(如 VLC)都具有此功能。


获取ffmpeg

ffmpeg 的旧版本不包含过滤功能。请参阅FFmpeg 下载页面,了解包括 Linux、OS X 和 Windows 的便捷版本在内的多个选项,或者参考FFmpeg 维基为了一步一步的 ffmpeg 编译指南

答案2

FFmpeg 在 v2.7 版本中将默认行为更改为使用“旋转”元数据自动旋转输入视频源2015年

如果您知道您的脚本或命令永远不会在 FFmpeg 2.7 之前的版本上运行,最简单的解决方案是删除任何基于元数据的自定义旋转。

对于其他情况,您可以通过保留自定义轮换代码并添加标志来确保未来安全-noautorotate(这在当时仍维护的旧版本中受支持)。

答案3

ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4

对我来说很管用。我不确定为什么转置过滤器不提供一次旋转 180 度的可能性,但无论如何。

查看文档了解更多信息。

答案4

以下是一个 Bash 脚本,它将输出“fixedFiles”下具有目录结构的文件。它转换和旋转 iOS 视频并转码AVI文件。脚本依赖于已安装Exif工具和 FFmpeg。

#!/bin/bash

# Rotation by 90 degrees. It 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 resolution 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

相关内容