У меня есть видео, которое было повернуто на 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 для получения рекомендаций по получению желаемого качества.
Chroma subampling. Я включил, 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 за пошаговыми руководствами по компиляции 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, который выводит файлы со структурой каталогов в «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
Меня попросили отредактировать это, чтобы предисловие к тексту, указывая, что решение, которое я в конце концов нашел, было в конце текста. Итак, в конце вы найдете две последовательные команды 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
Вот шаги:
Сначала откройте видеофайл в QuickTime. Вы можете сначала запустить QuickTime, перейти в «Файл», а затем - «Открыть файл». Или вы можете щелкнуть правой кнопкой мыши сам файл, выбрать «Открыть с помощью», а затем выбрать QuickTime.
Когда видео откроется, нажмите «Редактировать», и вы сразу найдете варианты поворота и переворачивания.
После того, как вы заблокировали нужную ориентацию, вам нужно будет экспортировать видео с новыми добавленными изменениями. Вы найдете пункт «Экспорт» в меню «Файл» в QuickTime.
Выберите настройки файла, которые вы хотите экспортировать, и нажмите «ОК», чтобы начать экспорт.
Когда операция экспорта будет завершена, вы найдете свой новый файл, где бы вы ни выбрали, чтобы сохранить его с правильной ориентацией!
Все это исправление заняло у меня менее 5 минут, но в зависимости от продолжительности видео, это может занять гораздо больше времени (или короче, опять же, оно варьируется).