Как повернуть видео на 180° с помощью FFmpeg?
У меня есть видео, которое было повернуто на 180° при записи. Можно ли это исправить с помощью FFmpeg?
8 ответов
ТЛ; др
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.
FFMPEG изменил поведение по умолчанию для автоматического поворота источников входного видео с метаданными "поворота" в версии v2.7 в 2015 году.
Если вы знаете, что ваш скрипт или команда никогда не будут выполняться в выпусках ffmpeg старше 2.7, самое простое решение - удалить любой пользовательский поворот на основе метаданных.
В других случаях вы можете ориентироваться на будущее, сохранив свой код поворота и добавив -noautorotate
флаг (это поддерживается в более старых версиях, которые все еще поддерживались в то время).
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4
Сделал трюк для меня. Не уверен, почему транспонированный фильтр не дает возможности вращаться на 180 градусов сразу, но как угодно. Проверьте документы для получения дополнительной информации.
Медиаплееры, которые используют ffmpeg в качестве бэкенда для декодирования, также могут использовать все свои фильтры. Смотрите этот скриншот с фильтром "Смещение и переворот".
В качестве альтернативы, если вы хотите перекодировать видео, проверьте вращение видео с помощью FFmpeg в Stackoverflow.
Меня попросили отредактировать это, чтобы предисловие к тексту, указав, что решение, которое я в конце концов нашел, было в конце текста. Итак, в конце вы найдете две последовательные команды 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
Я также попробовал это, основываясь на команде, которую нашел на usersuper.ru. Он успешно синхронизировал звук и преобразовал в 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
Ниже приведен скрипт 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
Вот шаги:
Сначала откройте видеофайл в QuickTime. Вы можете сначала запустить QuickTime, перейти в "Файл", а затем - "Открыть файл". Или вы можете щелкнуть правой кнопкой мыши сам файл, выбрать "Открыть с помощью", а затем выбрать QuickTime.
Когда видео откроется, нажмите "Редактировать", и вы сразу найдете варианты поворота и переворачивания.
После того, как вы заблокировали нужную ориентацию, вам нужно будет экспортировать видео с новыми добавленными изменениями. Вы найдете пункт "Экспорт" в меню "Файл" в QuickTime.
Выберите настройки файла, которые вы хотите экспортировать, и нажмите "ОК", чтобы начать экспорт.
Когда операция экспорта будет завершена, вы найдете свой новый файл, где бы вы ни выбрали, чтобы сохранить его с правильной ориентацией!
Все это исправление заняло у меня менее 5 минут, но в зависимости от продолжительности видео, это может занять гораздо больше времени (или короче, опять же, оно меняется).
Если ваше видео не имеет метаданных вращения, как описано в ответе llogan , вы можете добавить метаданные для поворота видео без перекодирования, и это должно работать в большинстве мест.
ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=180 output.mp4
(Команда скопирована из этого ответа на другой вопрос в StackOverflow)