Обертові відео з FFmpeg


417

Я намагався розібратися, як обертати відео за допомогою FFmpeg. Я працюю з відеозаписами iPhone, знятими в портретному режимі. Я знаю, як визначити поточний ступінь обертання за допомогою MediaInfo (відмінна бібліотека, btw), але я зараз затримався на 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 градусів було б і відмінним варіантом. Куди пішли параметри обертання?


Оновлено мою відповідь. Схоже, що цей фільтр був доданий минулого місяця до джерела.
rwilliams

76
Для тих, хто шукає обертання на 180 градусів:-vf "vflip,hflip"
OrangeDog

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

2
Дивіться тут прапор обертання: stackoverflow.com/questions/15335073/…
Давор Йосипович

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

Відповіді:


682

Поверніть на 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

25
Коли я використовую цю команду, я отримую вихід низької якості відео , якщо - як я тільки що дізнався , - я використовую цей параметр , а також: -vcodec libx264. Але було б чудово, якби мені не потрібно було шукати, яке кодування використовувати як ffmpeg, я вже повинен це знати. Будь-які пропозиції?
Саді

8
Як і Саді, чи є спосіб "скопіювати" якість оригінального відео?
Алек Якобсон

58
Для 180 можна скористатися-vf "transpose=2,transpose=2"
Алекс Плютау

23
Поточні документи відзначають, що "Чисельні значення застаріли, і їх слід скасувати на користь символічних констант." ffmpeg.org/ffmpeg-filters.html#transpose Таким чином cclock_flip, clock, cclockабо clock_flipзамість 0, 1, 2або 3.
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", не вийшло. Це має працювати?
Ондра Жижка

7
Найкраще рішення IMHO, оскільки не потрібно перекодування, і більшість відеоплеєрів підтримують обертання метаданих. Також хмарні сервіси, такі як Google Photos. Однак пам’ятайте, що ffmpeg не обов'язково копіює всі метадані з вихідного файлу! Тому я рекомендую чітко вказати, щоб скопіювати всі інші метадані з оригінального файлу:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
Андреас

83

Ви transposeще пробували ? Як (з іншої відповіді)

 ffmpeg -i input -vf transpose=2 output

Якщо ви використовуєте стару версію, вам потрібно оновити ffmpeg, якщо ви хочете використовувати функцію транспонування, як вона була додана в жовтні 2011 року.

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


1
Ні я не маю. Я не знав, що воно існує. Я дам це постріл.
jocull

Схоже, фільтр транспозиції не існує в жодній з моїх конструкцій FFmpeg. Як я повинен додати його?
Jocull

У версії Документів станом на 2011-05-15 правильне посилання тепер ffmpeg.org/ffmpeg-doc.html#SEC93
Пітер Хансен

6
Схоже, я був покараний за те, що запропонував корисну відповідь за 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, тоді він спрацює
patrick

2
"Обертати відео на довільний кут, виражений у радіанах ." Документація: ffmpeg.org/ffmpeg-filters.html#rotate Отже, радіани rotate=PI/2чи rotate=90*PI/180потрібні
l --marc l

Це фантастично
Tessaracter

7

Якщо ви отримуєте помилку "Кодек експериментальний, але експериментальні кодеки не ввімкнено", скористайтеся цією помилкою:

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

Зі мною трапився якийсь файл .mov з аудіо Aac.


Це був єдиний приклад, який працював на мене, але якість була жахлива, і дуже блокована. Крім того, він зменшив 1080x1920 відео до 352x640. Я думаю, мені не вистачає перемикача чи двох. Будь-які пропозиції?
LOlliffe

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

3

Цей скрипт, який виведе файли зі структурою каталогу в розділі "fixFiles". На даний момент зафіксовано файли 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
Так ... Це може спрацювати, але це абсолютно огидно. Перш за все, загальне правило програмування оболонок: вам ніколи не потрібно більше, ніж один з греп, різання, буксирування або сідання в трубу. Будь-яка греп | різання sed може виконуватись як з sed, так і з awk. Потім, більш конкретно, exiftool можна попросити вивести потрібний тег (и), тому замість фільтрування Rotation просто "exiftool -Rotation". По-третє, вам не потрібно стільки "evals", а ваш "if test ..." слід замінити на корпус $ 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

Відповідь Алексі майже працювала для мене, за винятком того, що я отримував цю помилку:

часова база 1/90000 не підтримується стандартом MPEG 4, максимальне допустиме значення для знаменника часової бази - 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 і вертикаль_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

На жаль, версія Ubuntu ffmpeg підтримує відеофільтри.

Для досягнення такого ж ефекту потрібно використовувати avidemux або інший редактор.

Програмно рекомендовано введення mencoder.


1
Ви мали на увазі "Версія Ubuntu ffmpeg не підтримує відеофільтри"?
користувач1438038

2
FYI: "FFmpeg повернувся в Ubuntu 15.04 Vivid Vervet." або можуть бути складені для Ubuntu. -> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
l --marc l

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 Авторські права (c) 2000-2019 розробники FFmpeg

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.