Videoları FFmpeg ile döndürme


417

FFmpeg ile videoları nasıl döndüreceğimizi anlamaya çalışıyorum. Portre modunda çekilen iPhone videolarıyla çalışıyorum. MediaInfo (mükemmel kütüphane, btw) kullanarak mevcut dönme dereceleri belirlemek nasıl biliyorum ama şimdi FFmpeg üzerinde sıkışmış.

Okuduğum kadarıyla, kullanmanız gereken bir vfilter seçeneğidir. Gördüğüm göre, şöyle görünmeli:

ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4

Ancak, bunu işe alamıyorum. İlk olarak, -vfilters artık mevcut değil, şimdi sadece -vf . İkincisi, bu hatayı alıyorum:

No such filter: 'rotate'
Error opening filters!

Bildiğim kadarıyla, FFmpeg'in tüm seçenekleri olan bir yapım var. Ffmpeg -filters'ı çalıştırmak şunu gösterir:

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 ve hflip için seçeneklere sahip olmak harika ve hepsi, ama sadece gitmem gereken yere ulaşamıyorlar . Videoları en azından 90 derece döndürme yeteneğine ihtiyacım var. 270 derece de sahip olmak için mükemmel bir seçenek olacaktır. Döndürme seçenekleri nereye gitti?


Cevabım güncellendi. Görünüşe göre bu filtre geçen ay kaynağa eklenmiş.
rwilliams

76
180 derece dönüş arayan herkes için:-vf "vflip,hflip"
OrangeDog

4
Merak ediyorum, bu videonun kodunu çözmeden ve daha sonra yeniden kodlamadan başarılabilirse - jpegtran'ın JPEG görüntülerini kayıpsız bir şekilde döndürme şekli ...
Mikhail T.

2
Rotasyon bayrağı için buraya bakın: stackoverflow.com/questions/15335073/…
Davor Josipovic

1
Ben sadece vimeo "transpose = 1, transpose = 1" ile 180 ° döndürülmüş bir video yükledi. Döndürülen videoyu oynatabilsem de, vimeo tarafından reddedildi. @ OrangeDog'un yaklaşımı -vf "vflip,hflip"bir cazibe gibi çalışıyor.
Besi

Yanıtlar:


682

Saat yönünde 90 döndürün:

ffmpeg -i in.mov -vf "transpose=1" out.mov

Transpose parametresi için şunları iletebilirsiniz:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

-vf "transpose=2,transpose=2"180 derece kullanın .

Buradan yeni bir ffmpeg sürümü kullandığınızdan emin olun (statik bir yapı düzgün çalışır).

Bunun ses ve video parçalarını yeniden kodlayacağını unutmayın. Sesi kullanarak, dokunmadan genellikle kopyalayabilirsiniz -c:a copy. Video kalitesini değiştirmek için bit hızını ayarlayın (örneğin ile -b:v 1M) veya VBR seçeneklerini istiyorsanız H.264 kodlama kılavuzuna bakın .

Bir çözüm de bu kolaylık komut dosyasını kullanmaktır .


8
Video hala yönlendirme bilgilerine sahip olacak, bu yüzden şimdi video iphone'da düzeltilecek.
srcspider

25
Ben bu komutu kullandığınızda, ben olsun düşük kaliteli video çıkışını : - Sadece keşfettim olarak - Ben de bu parametreyi kullanmazsanız, -vcodec libx264. Ama ffmpeg olarak kullanmak için hangi kodlamayı zaten bilmeli bakmam gerekmiyorsa harika olurdu. Herhangi bir öneri?
Sadi

8
Sadi ile aynı satırlar boyunca, orijinal videonun kalitesini "kopyalamanın" bir yolu var mı?
Alec Jacobson

58
180 için kullanabilirsiniz-vf "transpose=2,transpose=2"
Alex Pliutau

23
Mevcut dokümanlar "Sayısal değerlerin kullanımdan kaldırıldığını ve sembolik sabitler lehine bırakılması gerektiğini" belirtir. ffmpeg.org/ffmpeg-filters.html#transpose Böylece cclock_flip, clock, cclockya da clock_flipyerine 0, 1, 2ya da 3.
l --marc l

149

Videonuzu yeniden kodlamak istemiyorsanız VE oynatıcınız rotasyon meta verilerini işleyebilir ffmpeg kullanarak meta verilerdeki rotasyonu değiştirebilirsiniz:

ffmpeg -i input.m4v -metadata:s:v rotate="90" -codec copy output.m4v

11
ilk önce döndürme meta verilerini kontrol etmeye ne dersinizffmpeg -i input.m4v 2>&1 | grep rotate
lidaobing

60
Bu en iyi cevap. Ancak yapılacak küçük bir gelişme var. Videoda kalan meta verileri (tarih, kamera gibi) kaybetmemek için bunu yapın ffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v. Bu şekilde girdi dosyasındaki tüm global meta veriler çıktı dosyasına global meta veri olarak kopyalanır ve yalnızca döndürme meta verileri değiştirilir.
Ağustos'ta migle

11
Dikey modlu bir videonuz varsa ve standart bir 1920x1080 değerine sahip olmak için videonun "UN döndürülmesini" istiyorsanız, muhtemelen istersiniz rotate=0.
mivk

1
Denedim -metadata:s:v rotate="180", işe yaramadı. Bunun işe yaraması gerekiyor mu?
Ondra Žižka

7
IMHO en iyi çözümü çünkü yeniden kodlama gerekli değildir ve çoğu video oynatıcı meta veri döndürmeyi destekler. Ayrıca Google Fotoğraflar gibi bulut hizmetleri. Ancak, ffmpeg'in tüm meta verileri orijinal dosyadan kopyalaması gerekmediğini unutmayın! Bu nedenle, diğer tüm meta verileri orijinal dosyadan açıkça kopyalamayı belirtmenizi öneririm:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
Andreas

83

transposeHenüz denedin mi? Beğen (diğer cevaptan)

 ffmpeg -i input -vf transpose=2 output

Eski bir sürüm kullanıyorsanız, transpoze özelliğini kullanmak istiyorsanız ffmpeg'i Ekim 2011'de eklendiği gibi güncellemelisiniz.

FFmpeg indirme sayfası, derlemek zorunda kalmadan doğrudan yürütebileceğiniz statik yapıları sunar.


1
Hayır bende yok. Var olduğunu bilmiyordum. Ben bir şans vereceğim.
jocull

Geçiş filtresi, FFmpeg sürümlerimin hiçbirinde yok gibi görünüyor. Nasıl eklemem gerekiyor?
jocull

2011-05-15 tarihi itibariyle dokümanların sürümünde artık doğru bağlantı ffmpeg.org/ffmpeg-doc.html#SEC93
Peter Hansen

6
Kabul edilen cevaptan 1,5 yıl önce yararlı bir cevap verdiğim için cezalandırıldım gibi geliyor.
rwilliams

1
@JonasB Filtreleri virgülle ayırın. Bkz. Stackoverflow.com/questions/6195872/…
rwilliams

19

Aynı cevabı ararken bu sayfaya rastladım. Başlangıçta sorulduğundan bu yana altı ay geçti ve yapılar o zamandan beri birçok kez güncellendi. Ancak, buraya gelen ve bu bilgiyi arayan herkes için bir cevap eklemek istedim.

Bu depolardan Debian Squeeze ve FFmpeg sürümünü kullanıyorum .

Ffmpeg için MAN sayfası aşağıdaki kullanımı belirtir

ffmpeg -i inputfile.mpg -vf "transpose=1" outputfile.mpg

Anahtar, bir derece değişkeni değil, MAN sayfasından önceden tanımlanmış bir ayar değişkeni kullanmanızdır.

0=90CounterCLockwise and Vertical Flip  (default) 
1=90Clockwise 
2=90CounterClockwise 
3=90Clockwise and Vertical Flip

Bilgi için teşekkürler! Genelde kaynağından derlemede güçlük çektiğim için bu çalışmayı asla başaramadım. Şimdi tekrar işe alıp alamayacağımı görebilirim.
jocull

transpose = 3 görüntünün
Daniel Kobe

transpose = 2 270 döndürülmüş videom için yansıtma olmadan çalıştı
Daniel Kobe

17

Resmi saat yönünde döndürmek için, radyan cinsinden pozitif açıyı gösteren döndürme filtresini kullanabilirsiniz. PI / 2 ile eşit 90 derece ile bunu yapabilirsiniz:

ffmpeg -i in.mp4 -vf "rotate=PI/2" out.mp4

saat yönünün tersine açı negatif olmalıdır

ffmpeg -i in.mp4 -vf "rotate=-PI/2" out.mp4

Geçiş filtresi 90 derece eşit derecede iyi çalışır, ancak diğer açılar için bu daha hızlı veya tek bir seçimdir.


2
bu harika. *ffmpeg -i in.avi -vf "rotate=-8*PI/40" -q 1 out.avi
Radyanların daha hassas tanımlı çözünürlüğünü elde etmenin

12
ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4 

en son kaynakla bile çalışmayacak ...

sipariş değiştirmek gerekir:

ffmpeg -i input.mp4 -vf vflip output.mp4

iyi çalışıyor


filtreyi yanlış dosyaya uyguladığınızdan ... ffmpeg -i input.mp4 -vf "rotate = 90" output.mp4 deneyin, o zaman işe yarayacak
patrick

2
"İsteğe bağlı bir açı ile dönüşümlü bir video ifade radyan ." Belgeler: ffmpeg.org/ffmpeg-filters.html#rotate Yani, radyanlar rotate=PI/2ya rotate=90*PI/180da gerekli
l - marc l

Bu harika
Tessaracter

7

"Codec deneysel ancak deneysel codec bileşenleri etkin değil" hatası alıyorsanız şunu kullanın:

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

Aac ses içeren bazı .mov dosyaları için benimle oldu.


Bu benim için çalışan tek örnekti, ama kalitesi korkunç ve çok blokluydu. Ayrıca, 1080x1920 videoyu 352x640 boyutuna küçülttü. Sanırım bir veya iki anahtar eksik. Herhangi bir öneri?
LOlliffe

1
@LOlliffe add-sameq
Andrew Schleifer

2
@AndrewSchleifer Teşekkürler. Bunu denedim, ama ffmpeg bana geri attı- 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 de bir hata veriyor. Please use -q:a or -q:v, -qscale is ambiguous, ama yine de çalışıyor.
LOlliffe

3

"FixedFiles" altında dizin yapısına sahip dosyaları çıktısı Bu komut dosyası. Şu anda MOV dosyalarına sabitlenir ve videonun orijinal "döndürülmesine" bağlı olarak bir dizi dönüşüm gerçekleştirir. Mavericks çalıştıran bir Mac'te iOS ile çekilen videolarla çalışır, ancak kolayca dışa aktarılabilir olmalıdır. Her iki taktıktan Güveniyor ExifTool ve 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
Ah ... Bu işe yarayabilir, ama tamamen iğrenç. Her şeyden önce, kabuk programlamanın genel kuralı: bir boruda asla birden fazla grep, cut, awk veya sed'e ihtiyacınız yoktur. Herhangi bir grep | cut | sed tek başına sed veya awk ile yapılabilir. Daha sonra, daha spesifik olarak, exiftool'dan sadece istediğiniz etiket (ler) çıktısını almanız istenebilir - bu nedenle Rotasyonu filtrelemek yerine sadece "exiftool -Rotation". Üçüncüsü, hem okunabilirlik hem de verimlilik için çok fazla "evals" a ihtiyacınız yoktur ve "eğer test ..." durumunuz $ ROTATION durumuyla değiştirilmelidir. İyi şanslar!
Mikhail T.

Zar yok: [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!
Slipp D.Thompson

2

Alexy'nin yanıtı bu hatayı alıyorum dışında neredeyse benim için çalıştı:

Zaman tabanı 1/90000, MPEG 4 standardı tarafından desteklenmez, zaman tabanı paydası için kabul edilen maksimum değer 65535'tir.

Komuta bir parametre (-r 65535/2733) eklemek zorunda kaldım ve işe yaradı. Böylece tam komut şuydu:

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

Bir "NTSC-film" kare hızı arıyorsanız, o 24000/1001zaman daha doğru olur.
Reino

2

Son bahsedilen çözümlerden farklı bir yaklaşıma sahip ek bir çözüm, kamera sürücünüzün v4l2 kamera kontrollerini destekleyip desteklemediğini kontrol etmektir (çok yaygındır).
Terminalde şunu yazın:

v4l2-ctl -L

Kamera sürücünüz v4l2 kamera kontrollerini destekliyorsa, böyle bir şey almalısınız (aşağıdaki liste kamera sürücünüzün desteklediği kontrollere bağlıdır):

               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

Şanslıysanız, horizontal_flip ve vertical_flip'i destekler .
O zaman tek yapmanız gereken horizontal_flip öğesini şu şekilde ayarlamaktır :

v4l2-ctl --set-ctrl horizontal_flip=1

veya dikey_flip :

v4l2-ctl --set-ctrl vertical_flip=1

ardından yeni bir video çekmek için video cihazınızı arayabilirsiniz (aşağıdaki örneğe bakın) ve video döndürülür / çevrilir.

ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -vcodec libx264 -f mpegts input.mp4

Elbette, zaten mevcut bir videoyu işlemeniz gerekiyorsa, bu yöntemden daha fazla aradığınız çözüm değildir.

Bu yaklaşımdaki avantaj, görüntüyü sensör düzeyinde çevirmemizdir, bu nedenle sürücünün sensörü zaten bize döndürülmüş görüntüyü verir ve bu da uygulamayı (FFmpeg gibi) daha fazla ve gereksiz işlemeden kurtarır.


Burada v4l2 hakkında harika bilgiler. Kayıt zamanında doğru yöne döndürmek kesinlikle tercih edilir :) Bu neredeyse 10 yıllık soru (vay!) Aslında herhangi bir bağlam sağlamaya yardımcı olursa iOS cihazlarından yüklenen videolar hakkında sorulmuştur :)
jocull

Bu toplulukta biraz yeniyim ve bu soru buradaki kıdemimden çok daha eski ... Gerçekten iyi (ve ortak) bir soru olduğunu düşünüyorum, bu yüzden bu eski sorunun birçok FFmpeg kullanıcısına yardımcı olmaya devam edeceğine inanıyorum.
JM

1

Ne yazık ki, ffmpeg'in Ubuntu sürümü video filtreleri destekliyor.

Aynı etkiyi elde etmek için avidemux veya başka bir editör kullanmanız gerekir.

Programlı bir şekilde mencoder tavsiye edilmiştir.


1
Eğer "yok Ffmpeg Ubuntu sürümünü kastettiniz değil videofilters desteklemek"?
user1438038

2
Bilginize: "FFmpeg, Ubuntu 15.04 Canlı Vervet'e geri döndü." veya Ubuntu için derlenebilir. -> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
l --marc l

avconv (14.04'te) bunu yapıyor ve aynı şekilde çalışıyor gibi görünüyor. (Ancak sonraki sürümler için kesinlikle FFmpeg kullanın.)
SilverWolf - Reinstate Monica

1

Akıllı telefon: Bir videoyu dikey biçimde kaydetti

Bir web tarafına 90 ° sola (saat yönünün tersine, yatay format) hmm oldu.

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

yapar. Tekrar dikey format aldım

debian buster: ffmpeg --version ffmpeg sürüm 4.1.4-1 ~ deb10u1 Telif Hakkı (c) 2000-2019 FFmpeg geliştiricileri

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.