Вращающиеся видео с 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.

Наличие опций для vflip и hflip - это здорово и все, но они просто не приведут меня туда, куда мне нужно идти. Мне нужна возможность поворачивать видео на 90 градусов как минимум. 270 градусов было бы отличным вариантом, чтобы иметь. Куда делись опции поворота?


77
Для тех, кто ищет поворот на 180 градусов:-vf "vflip,hflip"
OrangeDog

4
Мне интересно, может ли это быть достигнуто без декодирования, а затем перекодирования видео - как jpegtran может без потерь вращать изображения JPEG ...
Михаил Т.

2
Смотрите здесь для флага поворота: stackoverflow.com/questions/15335073/…
Давор Йосипович

1
Также см. Подробный ответ в разделе Как перевернуть видео на 180 ° (по вертикали / вверх ногами) с помощью FFmpeg? Не забудьте сбросить все существующие метаданные ротации (см. Ссылку).
Llogan

1
Я только что загрузил видео с поворотом на 180 ° с помощью transpose = 1, transpose = 1 в vimeo. Хотя я могу воспроизвести повернутое видео, оно было отклонено vimeo. Подход @ OrangeDog -vf "vflip,hflip"работает как шарм.
Беси

Ответы:


683

Повернуть на 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 отсюда (статическая сборка будет работать нормально).

Обратите внимание, что это перекодирует аудио и видео части. Вы можете обычно копировать аудио, не касаясь его, используя -c:a copy. Чтобы изменить качество видео, установите битрейт (например, с помощью -b:v 1M) или посмотрите руководство по кодированию H.264, если вам нужны опции VBR.

Решением также является использование этого удобного сценария .


8
Видео будет по-прежнему иметь информацию об ориентации, поэтому теперь оно будет исправлено на iphone.
srcspider

26
Когда я использую эту команду, я получаю выход низкого качества видео , если - как я только что узнал , - я использую этот параметр , а также: -vcodec libx264. Но было бы замечательно, если бы мне не нужно было искать, какую кодировку использовать, так как ffmpeg уже должен это знать. Какие-либо предложения?
Сади

8
По аналогии с Sadi, есть ли способ «скопировать» качество оригинального видео?
Алек Джейкобсон,

58
За 180 можно использовать-vf "transpose=2,transpose=2"
Алекс Плютау

23
В текущих документах отмечается, что «числовые значения устарели, и их следует отбрасывать в пользу символических констант». ffmpeg.org/ffmpeg-filters.html#transpose Таким образом cclock_flip, clock, cclockили clock_flipвместо 0, 1, 2или 3.
1 марта

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. Таким образом, все глобальные метаданные во входном файле будут скопированы как глобальные метаданные в выходной файл, и изменятся только метаданные ротации.
Миг

11
Если у вас есть видео в портретном режиме и вы просто хотите «развернуть его», чтобы оно имело стандартное разрешение 1920x1080, то вы, вероятно, захотите rotate=0.
mivk

1
Попробовал -metadata:s:v rotate="180", не сработало. Это должно работать?
Ондра Жижка

7
ИМХО лучшее решение, потому что перекодирование не требуется, и большинство видеоплееров поддерживают ротацию метаданных. Также облачные сервисы, такие как 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 года.

Страница загрузки FFmpeg предлагает статические сборки, которые вы можете выполнять напрямую, не компилируя их.


1
Нет, у меня нет. Я не знал, что это существует. Я сделаю это.
Jocull

Фильтр транспонирования, кажется, не существует ни в одной из моих сборок FFmpeg. Как я должен добавить это?
2010 г.

В версии документов по состоянию на 2011-05-15 правильная ссылка теперь ffmpeg.org/ffmpeg-doc.html#SEC93
Питер Хансен,

7
Такое чувство, что я был наказан за предложение полезного ответа за 1,5 года до принятого ответа.
Rwilliams

1
@JonasB Разделите фильтры запятыми. См stackoverflow.com/questions/6195872/...
rwilliams

19

Я наткнулся на эту страницу во время поиска того же ответа. Прошло уже шесть месяцев с тех пор, как об этом изначально просили, и с тех пор сборки многократно обновлялись. Тем не менее, я хотел бы добавить ответ для всех, кто сталкивается здесь в поисках этой информации.

Я использую Debian Squeeze и версию FFmpeg из этих репозиториев.

Страница MAN для ffmpeg гласит следующее использование

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 вызывает зеркальное отображение изображения
Даниэль Кобе

transpose = 2 работал без зеркалирования для моего повернутого видео 270
Даниэль Кобе

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, тогда он будет работать
Патрик

2
«Повернуть видео на произвольный угол, выраженный в радианах ». Документация: ffmpeg.org/ffmpeg-filters.html#rotate Итак, радианы rotate=PI/2или rotate=90*PI/180нужны
l

Это фантастика
Tessaracter

7

Если вы получаете сообщение об ошибке «Кодек экспериментальный, но экспериментальные кодеки не включены», используйте это:

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

Случилось со мной какой-то файл .mov с аудио aac.


Это был единственный пример, который работал для меня, но качество было ужасным и очень блочным. Кроме того, он уменьшил размер видео 1080x1920 до 352x640. Думаю, мне не хватает переключателя или двух. Какие-либо предложения?
Леллифф

1
@LOlliffe добавить-sameq
Эндрю Шлейфер

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, но все еще работает.
Лиллифф

3

Это скрипт, который будет выводить файлы со структурой каталогов в «fixedFiles». На данный момент фиксируется MOV-файл и будет выполняться ряд преобразований в зависимости от исходного «поворота» видео. Работает с видео, снятым iOS, на Mac под управлением Mavericks, но его легко экспортировать. Полагается на то, что установил 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

2
Ой ... Это может сработать, но это совершенно отвратительно. Прежде всего, общее правило программирования оболочки: вам никогда не нужно больше, чем один из grep, cut, awk или sed в трубе. Любой grep | cut | sed выполним с помощью sed или awk. Затем, более конкретно, exiftool можно попросить вывести только те теги, которые вы хотите - так что вместо фильтрации Rotation, просто "exiftool -Rotation". В-третьих, вам не нужно так много «уловок», и ваш «если тест ...» должен быть заменен регистром $ 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\ nConversion failed!
Слипп Д. Томпсон,

2

Ответ Алексия почти сработал для меня, за исключением того, что я получаю эту ошибку:

timebase 1/90000 не поддерживается стандартом MPEG 4, максимальное допустимое значение для знаменателя timebase составляет 65535

Мне просто нужно было добавить параметр (-r 65535/2733) в команду, и это сработало. Полная команда была таким:

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

Если вы ищете "NTSC-фильм" частоту кадров, то 24000/1001будет более точным.
Рейно

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

И если вам повезет, он поддерживает Horizontal_flip и vertical_flip .
Тогда все, что вам нужно сделать, это установить Horizontal_flip :

v4l2-ctl --set-ctrl horizontal_flip=1

или вертикальный_флип по:

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, если это помогает обеспечить какой-либо контекст :)
jocull

Я немного новичок в этом сообществе, и этот вопрос намного старше моего стажа здесь ... Я действительно считаю, что это хороший (и общий) вопрос, поэтому я считаю, что этот старый вопрос будет помогать многим пользователям FFmpeg.
JM

1

К сожалению, версия ffmpeg для Ubuntu поддерживает видеофильтры.

Вам нужно использовать avidemux или другой редактор для достижения того же эффекта.

В программном отношении, Mencoder был рекомендован.


1
Вы имели в виду "версия ffmpeg для Ubuntu не поддерживает видеофильтры"?
user1438038

2
К вашему сведению: «FFmpeg вернулся в Ubuntu 15.04 Vivid Vervet». или может быть скомпилировано для Ubuntu. -> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
1 марта

avconv делает (в 14.04), и, кажется, работает точно так же. (Но для более поздних версий обязательно используйте FFmpeg.)
SilverWolf - Восстановить Монику

1

Смартфон: записал видео в вертикальном формате

Хотите, чтобы отправить его на веб-сайт было 90 ° влево (против часовой стрелки, альбомный формат) хм.

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

Является ли. Я снова вернул вертикальный формат

debian buster: ffmpeg --version ffmpeg версия 4.1.4-1 ~ deb10u1 Copyright (c) 2000-2019 разработчики FFmpeg

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.