У мене є відео, яке під час запису поверталося на 180 °. Чи можна це виправити за допомогою FFmpeg?
У мене є відео, яке під час запису поверталося на 180 °. Чи можна це виправити за допомогою FFmpeg?
Відповіді:
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 для отримання вказівки щодо отримання бажаної якості.
Підсистема кольоровості. Я включив, format=yuv420p
оскільки ffmpeg
буду намагатися мінімізувати або уникнути підсистеми кольоровості (залежно від кодера, вводу, ffmpeg
версії тощо). Це хороша поведінка в чисто технічному сенсі, але більшість гравців несумісні з більш "просунутими" схемами підсимулювання кольоровості. Це те саме, що використовувати -pix_fmt yuv420
, але зручно розташований у ланцюзі фільтру .
Скопіюйте аудіо. -codec:a copy
Варіант буде текти копія (ре-MUX) замість того , щоб закодувати. Немає причин перекодувати звук, якщо ви просто хочете маніпулювати відео лише (якщо ви не хочете конвертувати в інший формат аудіо). Це заощадить час, оскільки кодування забирає багато часу, і це збереже якість звуку.
Крім того, ви можете обертатись під час відтворення та уникати повторного кодування. ffplay
автоматично обертається:
ffplay input.mp4
Якщо немає бічних даних displaymatrix або обертаються метадані, ви можете використовувати фільтри:
ffplay -vf "hflip,vflip" -i input.mp4
... або зверніться до улюбленого гравця. Більшість гравців, які варто використовувати, як VLC, мають цю можливість.
ffmpeg
Старі версії ffmpeg не включають можливості фільтрації. Див скачати FFmpeg сторінку кілька варіантів , включаючи зручні збірки для Linux, OS X і Windows, або зверніться до FFmpeg Wiki для кроку за кроком FFmpeg компіляції керівництва .
-vf vflip
і це спрацювало як шарм. Але це було перекодування. Я не впевнений, чи правильно я тебе читаю. Ви скажете -vf hflip,vflip
, що не перекодуватимуть повторно?
ffmpeg
вимагає перекодувати повторно, використовуючи відео- та аудіофільтри. Однак ffplay
можна також використовувати багато фільтрів під час відтворення, як показано в моєму другому прикладі.
-codec:v libx264
? Чи можна ffmpeg
просто використовувати одне і те ж кодування, не намагаючись його зрозуміти?
FFMPEG змінив поведінку за замовчуванням, щоб автоматично обертати джерела вхідних відеозаписів з "обертати" метадані у версії v2.7 у 2015 році .
Якщо ви знаєте, що ваш скрипт чи команда ніколи не працюватимуть у випусках ffmpeg, старших за 2.7, найпростішим рішенням є видалення будь-яких спеціальних поворотів на основі метаданих.
Для інших випадків ви можете бути впевненими у майбутньому, зберігаючи власний код обертання та додавши -noautorotate
прапор (це підтримується у старих версіях, які досі зберігалися).
Медіапрогравачі, які використовують ffmpeg як декодування декоду, також можуть використовувати всі його фільтри. Дивіться цей знімок екрана з фільтром "Зсув і перевертання".
Якщо ви хочете перекодувати відео, перегляньте відео, що обертається за допомогою FFmpeg на Stackoverflow.
transpose
фільтр, на який посилаються ротаційні відео з FFmpeg , не обертається на 180 °, наскільки я можу сказати.
transpose
фільтри разом для досягнення ефекту.
Далі йде сценарій bash, який виводить файли зі структурою каталогу під "fixFiles". Він перетворює та обертає відео з 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
Мене попросили відредагувати це, передмовити текст, вказуючи на те, що рішення, яке я врешті знайшов, було в кінці тексту. Отже, наприкінці ви знайдете дві послідовні команди 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
Оригінальний файл: Video 1920 x 1080 Codec 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 Авторські права (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
Наступний 2-етапний процес нарешті отримав те, що я хотів; вертикальний і горизонтальний, і перевернутий, і синхронізований звук, і формат, перетворений у MPEG-4 (Знову ж, це не помилка; я використовував hflip в обох командах):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
Ось такі кроки:
Спочатку відкрийте свій відеофайл у QuickTime. Ви можете спочатку запустити QuickTime, перейдіть до "Файл", а потім до "Відкрити файл". Або ви можете клацнути правою кнопкою миші сам файл, виберіть "Відкрити за допомогою", а потім виберіть QuickTime.
Після відкриття відео натисніть «Редагувати», після чого ви знайдете параметри обертання та перевертання прямо внизу
Після того як ви заблокували потрібну орієнтацію, вам доведеться експортувати своє відео з новими змінами, які ви додали. Ви знайдете опцію "Експорт" у меню "Файл" у QuickTime.
Виберіть параметри файлу, які потрібно експортувати, і натисніть "Ок", щоб почати експорт.
Коли операція експортування завершена, ви знайдете новий файл, куди не захочете його зберегти з правильною орієнтацією!
На все це виправлення пішло менше 5 хвилин, але залежно від тривалості відео це може зайняти набагато більше часу (або коротше, знову ж, воно змінюється).