58

У меня есть видео, которое было повернуто на 180 ° при записи. Можно ли это исправить с помощью FFmpeg?

7 ответов7

90

оригиналповернутый


ТЛ; др

ffmpeg автоматически повернет видео, если:

  • Ваш вход не содержит метаданных поворота
  • ваш ffmpeg слишком стар

Метаданные ротации

Некоторые видео, например с iPhone, физически не переворачиваются, но содержат данные на стороне матрицы отображения видеопотока или метаданные поворота. Некоторые игроки игнорируют эти метаданные, а некоторые нет. Обратитесь к выводу консоли 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 автоматически физически поворачивает видео в соответствии с любыми существующими метаданными ротации видеопотока.

Чтобы использовать функцию автоповорота, вам нужна сборка, включающая фиксацию 1630224 от 2 мая 2015 года.

пример

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

Чтобы отключить это поведение, используйте параметр -noautorotate .


Если входные данные не содержат метаданных или если ваш ffmpeg старый

Вам придется использовать фильтр для поворота видео, и если существуют какие-либо метаданные поворота, их нужно будет удалить, как показано в примерах ниже:

Примеры

Используя ffmpeg вы можете выбрать один из трех способов использования видеофильтров для поворота на 180 °.

hflip и vflip

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

Вы можете использовать градусы вместо. Один градус равен π /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 билинейная интерполяция должна быть отключена (при использовании bilinear=0) для углов, кратных 90, в противном случае она может выглядеть размытой.


Заметки

  • Фильтрация требует кодирования. Эти примеры делают видеовыходы H.264. См. Руководство по кодированию видео FFmpeg H.264 для получения рекомендаций по получению желаемого качества.

  • Chroma subampling. Я включил format=yuv420p поскольку ffmpeg попытается минимизировать или избежать подвыборки цветности (в зависимости от кодера, входа, версии ffmpeg и т.д.). Это хорошее поведение в чисто техническом смысле, но большинство игроков несовместимы с более "продвинутыми" схемами подвыборки цветности. Это то же самое, что и -pix_fmt yuv420 , но удобно расположено в цепочке фильтров.

  • Скопируйте аудио. Опция -codec:a copy будет транслировать (повторно мультиплексировать) вместо кодирования. Нет смысла перекодировать аудио, если вы просто хотите манипулировать только видео (если вы не хотите конвертировать в другой аудиоформат). Это сэкономит время, так как кодирование занимает много времени, и оно сохранит качество звука.


Повернуть при воспроизведении

В качестве альтернативы вы можете вращать при воспроизведении и избежать перекодирования. ffplay будет автоматически вращаться:

ffplay input.mp4

Если нет данных стороны displaymatrix или метаданных поворота, вы можете использовать фильтры:

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

... или обратитесь к вашему любимому игроку. Большинство игроков, которые стоит использовать, например VLC, имеют такую возможность.


Получение ffmpeg

Старые сборки ffmpeg не включают возможности фильтрации. См. Страницу загрузки FFmpeg для нескольких вариантов, включая удобные сборки для Linux, OS X и Windows, или обратитесь к FFmpeg Wiki для пошаговых руководств по компиляции ffmpeg.

6

FFMPEG изменил поведение по умолчанию для автоматического поворота источников входного видео с метаданными "поворота" в версии v2.7 в 2015 году.

Если вы знаете, что ваш скрипт или команда никогда не будут запускаться в выпусках ffmpeg старше 2.7, самое простое решение - удалить любой пользовательский поворот на основе метаданных.

В других случаях вы можете рассчитывать на будущее, сохранив свой собственный код ротации и добавив флаг -noautorotate (это поддерживается в более старых версиях, которые все еще поддерживались в то время).

2

Медиаплееры, которые используют ffmpeg в качестве бэкенда для декодирования, также могут использовать все свои фильтры. Смотрите этот скриншот с фильтром «Смещение и переворот».

В качестве альтернативы, если вы хотите перекодировать видео, проверьте вращение видео с помощью FFmpeg в Stackoverflow.

1

Ниже приведен скрипт bash, который выведет файлы со структурой каталогов в "fixedFiles". Он преобразует и вращает видео iOS и перекодирует AVI. Сценарий основан на установке exiftool и ffmpeg.

#!/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
1

Меня попросили отредактировать это, чтобы предисловие к тексту, указав, что решение, которое я в конце концов нашел, было в конце текста. Итак, в конце вы найдете две последовательные команды ffmpeg, которые успешно повернули мое видео в правильную ориентацию. Предшествующий текст должен был дать как можно больше информации, как я видел другие сообщения, которые были отвергнуты из-за недостатка информации. В любом случае, я надеюсь, что это поможет другим, использующим ffmpeg. Мне кажется, что назначение hflip и vflip в ffmpeg, как минимум, сбивает с толку и противоречит тому, что я ожидал.

Файл merlin.mov представляет собой копию видео, которое я снял на своем iphone, сначала загрузил в Dropbox, а затем скачал на свой ноутбук с Ubuntu:

    $ uname -a
    Linux gazelle 3.13.0-135-generic #184-Ubuntu SMP
    Wed Oct 18 11:55:51 UTC 2017 x86_64 x86_64 x86_64
    GNU/Linux

Я знаю, что должен был смонтировать свой iphone через USB и напрямую скопировать файлы, но это не сработало; мой ноутбук распознал бы, что iphone был подключен, но не смонтировал его файловую систему, и у меня не было подсказки на моем iphone "доверять" ноутбуку.

Команда, которую я использовал для копирования из Dropbox на мой ноутбук, была такой:

    cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
            merlin.mov

Исходный файл: видео 1920 x 1080, кодек HEVC/H.265, частота кадров 30/ с, битрейт 8140 кбит / с, аудиокодек MPEG-4 AAC, аудиоканалы стерео, частота дискретизации 44100 Гц, битрейт 85 кбит / с. Когда я играю на своем iphone, он ориентируется правильно, и звук синхронизируется. Когда я играю его в Видео на моем ноутбуке, он переворачивается и переворачивается по горизонтали, и звук не синхронизируется. Вот частичный вывод из "ffmpeg -i merlin.mov":

    Metadata:
    rotate          : 180
    creation_time   : 2017-11-02T14:41:55.000000Z
    handler_name    : Core Media Data Handler
    encoder         : HEVC

Вот первая строка вывода «ffmpeg -version»:

ffmpeg версия 3.3.3 Copyright (c) 2000-2017 разработчики FFmpeg

Следующее оставило воспроизведение инвертированным как по вертикали, так и по горизонтали, хотя оно конвертировалось в видео MPEG-4 (видео /mp4) и синхронизировало звук:

    ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4

Следующее перевернуто по вертикали, поэтому воспроизведение выполняется в вертикальном положении, синхронизируется звук и конвертируется в MPEG-4, но оставлено горизонтальный неправильно перевернутый конец для конца (это не опечатка, я действительно указал 'hflip'):

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4

Следующее перевернуло горизонталь в правильную ориентацию, но оставило воспроизведение вверх ногами:

    ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4

Кажется, что следующее не имеет никакого эффекта:

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
    ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4

Я также попробовал это, основываясь на команде, которую нашел на superuser.com. Он успешно синхронизировал звук и преобразовал в MPEG-4, но как горизонтальная, так и вертикальная ориентация остались неверными:

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

Я также попробовал это, которое не работало ни с точки зрения исправления ориентации:

    ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4

Следующий двухэтапный процесс, наконец, получил то, что я хотел; вертикальный и горизонтальный, как перевернутый, синхронизированный звук, и формат, преобразованный в MPEG-4 (Опять же, это не опечатка; я использовал hflip в обеих командах):

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
    ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
0
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4

Сделал трюк для меня. Не уверен, почему транспонированный фильтр не дает возможности поворота на 180 градусов сразу, но как угодно. Проверьте документы для получения дополнительной информации.

0

Вот шаги:

  1. Сначала откройте видеофайл в QuickTime. Вы можете сначала запустить QuickTime, перейти в «Файл», а затем - «Открыть файл». Или вы можете щелкнуть правой кнопкой мыши сам файл, выбрать «Открыть с помощью», а затем выбрать QuickTime.

  2. Когда видео откроется, нажмите «Редактировать», и вы сразу найдете варианты поворота и переворачивания.

  3. После того, как вы заблокировали нужную ориентацию, вам нужно будет экспортировать видео с новыми изменениями, которые вы добавили. Вы найдете пункт «Экспорт» в меню «Файл» в QuickTime.

Выберите настройки файла, которые вы хотите экспортировать, и нажмите «ОК», чтобы начать экспорт.

Когда операция экспорта будет завершена, вы найдете свой новый файл, где бы вы ни выбрали, чтобы сохранить его с правильной ориентацией!

Все это исправление заняло у меня менее 5 минут, но в зависимости от продолжительности видео, это может занять гораздо больше времени (или короче, опять же, оно варьируется).

источник блога

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .