Memutar video dengan FFmpeg

417

Saya telah mencoba mencari cara memutar video dengan FFmpeg. Saya bekerja dengan video iPhone yang diambil dalam mode potret. Saya tahu cara menentukan derajat rotasi saat ini menggunakan MediaInfo (pustaka bagus, btw) tapi saya terjebak di FFmpeg sekarang.

Dari apa yang saya baca, apa yang perlu Anda gunakan adalah opsi vfilter . Menurut apa yang saya lihat, seharusnya terlihat seperti ini:

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

Namun, saya tidak bisa membuatnya bekerja. Pertama, -vfilters tidak ada lagi, sekarang hanya -vf . Kedua, saya mendapatkan kesalahan ini:

No such filter: 'rotate'
Error opening filters!

Sejauh yang saya tahu, saya memiliki FFmpeg versi all-options-on. Menjalankan ffmpeg -filters menunjukkan ini:

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.

Memiliki opsi untuk vflip dan hflip sangat bagus dan semuanya, tetapi mereka tidak akan membawa saya ke tempat yang harus saya tuju. Saya perlu kemampuan untuk memutar video setidaknya 90 derajat. 270 derajat akan menjadi pilihan yang sangat baik untuk dimiliki. Ke mana perginya opsi rotate?

jocull
sumber
77
Bagi siapa pun yang mencari rotasi 180 derajat:-vf "vflip,hflip"
OrangeDog
4
Saya bertanya-tanya, apakah ini dapat dicapai tanpa decoding dan kemudian kembali encoding video - cara jpegtran dapat memutar gambar JPEG tanpa kehilangan ...
Mikhail T.
2
Lihat di sini untuk bendera rotasi: stackoverflow.com/questions/15335073/…
Davor Josipovic
1
Lihat juga jawaban terperinci di Cara membalik video 180 ° (vertikal / terbalik) dengan FFmpeg? Jangan lupa untuk mengatur ulang metadata rotasi yang ada (lihat tautan).
llogan
1
Saya baru saja mengunggah video diputar 180 ° dengan "transpose = 1, transpose = 1" ke vimeo. Meskipun saya dapat memutar ulang video yang diputar, namun ditolak oleh Vimeo. Pendekatan @ OrangeDog -vf "vflip,hflip"bekerja seperti pesona.
Besi

Jawaban:

683

Putar 90 searah jarum jam:

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

Untuk parameter transpose, Anda dapat meneruskan:

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

Gunakan -vf "transpose=2,transpose=2"untuk 180 derajat.

Pastikan Anda menggunakan versi ffmpeg terbaru dari sini (build statis akan berfungsi dengan baik).

Perhatikan bahwa ini akan menyandikan ulang bagian audio dan video. Anda biasanya dapat menyalin audio tanpa menyentuhnya, dengan menggunakan -c:a copy. Untuk mengubah kualitas video, atur bitrate (misalnya dengan -b:v 1M) atau lihat panduan pengkodean H.264 jika Anda menginginkan opsi VBR.

Solusi juga menggunakan skrip kenyamanan ini .

Alexy
sumber
8
Video masih akan memiliki informasi orientasi sehingga sekarang video akan hilang diperbaiki pada iphone.
srcspider
26
Ketika saya menggunakan perintah ini, saya mendapatkan output video berkualitas rendah , kecuali - seperti yang saya baru saja menemukan - saya menggunakan parameter ini juga: -vcodec libx264. Tetapi akan lebih bagus jika saya tidak perlu mencari encoding yang harus digunakan sebagai ffmpeg yang seharusnya sudah mengetahuinya. Ada saran?
Sadi
8
Sejalan dengan Sadi, apakah ada cara untuk "menyalin" kualitas video asli?
Alec Jacobson
58
Untuk 180 Anda dapat menggunakan-vf "transpose=2,transpose=2"
Alex Pliutau
23
Dokumen saat ini mencatat bahwa "Nilai numerik sudah usang, dan harus dibuang demi konstanta simbolik." ffmpeg.org/ffmpeg-filters.html#transpose demikian cclock_flip, clock, cclockatau clock_flipbukan 0, 1, 2atau 3.
l --marc l
149

Jika Anda tidak ingin menyandikan ulang video Anda DAN pemain Anda dapat menangani metadata rotasi, Anda bisa mengubah rotasi dalam metadata menggunakan ffmpeg:

ffmpeg -i input.m4v -metadata:s:v rotate="90" -codec copy output.m4v
Rodrigo Polo
sumber
11
bagaimana dengan memeriksa metadata rotate terlebih dahulu denganffmpeg -i input.m4v 2>&1 | grep rotate
lidaobing
60
Ini adalah jawaban terbaik sejauh ini. Tetapi ada sedikit perbaikan yang harus dilakukan. Untuk menghindari kehilangan meta-data yang tersisa (seperti tanggal, kamera) pada video, lakukan ffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v. Dengan cara ini semua metadata global pada file input akan disalin sebagai metadata global ke file output dan hanya meta-data rotasi yang diubah.
migle
11
Jika Anda memiliki video mode potret dan hanya ingin "UN-rotate" untuk memiliki standar 1920x1080, maka Anda mungkin ingin rotate=0.
mivk
1
Sudah mencoba -metadata:s:v rotate="180", tidak berhasil. Apakah itu seharusnya berhasil?
Ondra Žižka
7
Solusi terbaik IMHO karena tidak diperlukan lagi reencoding dan sebagian besar pemutar video mendukung rotasi metadata. Juga layanan Cloud seperti Foto Google. Namun, ingatlah bahwa ffmpeg tidak perlu menyalin semua metadata dari file asli! Oleh karena itu, saya akan merekomendasikan untuk secara eksplisit menentukan untuk menyalin semua metadata lain dari file asli:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
Andreas
83

Sudahkah Anda mencoba transpose? Suka (dari jawaban lain)

 ffmpeg -i input -vf transpose=2 output

Jika Anda menggunakan versi lama, Anda harus memperbarui ffmpeg jika Anda ingin menggunakan fitur transpos, seperti yang ditambahkan pada Oktober 2011.

Halaman unduhan FFmpeg menawarkan build statis yang dapat Anda jalankan secara langsung tanpa harus mengompilasinya.

rwilliams
sumber
1
Tidak saya tidak punya. Saya tidak tahu itu ada. Saya akan mencobanya.
jocull
Filter transpos tampaknya tidak ada di build FFmpeg saya. Bagaimana saya menambahkannya?
jocull
Dalam versi dokumen pada 2011-05-15 tautan yang benar adalah ffmpeg.org/ffmpeg-doc.html#SEC93
Peter Hansen
6
Rasanya saya dihukum karena menawarkan jawaban yang bermanfaat 1,5 tahun sebelum jawaban yang diterima.
rwilliams
1
@JonasB Pisahkan filter dengan koma. Lihat stackoverflow.com/questions/6195872/…
rwilliams
19

Saya menemukan halaman ini sambil mencari jawaban yang sama. Sekarang enam bulan sejak ini awalnya diminta dan build telah diperbarui berkali-kali sejak itu. Namun, saya ingin menambahkan jawaban untuk orang lain yang datang ke sini mencari informasi ini.

Saya menggunakan versi Squian Debian dan FFmpeg dari repositori tersebut.

Halaman MAN untuk ffmpeg menyatakan penggunaan berikut ini

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

Kuncinya adalah bahwa Anda tidak menggunakan variabel derajat, tetapi variabel pengaturan yang telah ditentukan dari halaman MAN.

0=90CounterCLockwise and Vertical Flip  (default) 
1=90Clockwise 
2=90CounterClockwise 
3=90Clockwise and Vertical Flip
Zonjai
sumber
Terimakasih atas infonya! Saya tidak pernah benar-benar bisa mendapatkan ini berfungsi, karena saya biasanya kesulitan membangun dari sumber. Saya mungkin melihat apakah saya bisa membuatnya bekerja lagi sekarang.
jocull
transpose = 3 menyebabkan gambar menjadi mirror
Daniel Kobe
transpose = 2 bekerja tanpa mirroring untuk 270 video yang diputar
Daniel Kobe
17

Untuk memutar gambar searah jarum jam, Anda dapat menggunakan filter putar, yang menunjukkan sudut positif dalam radian. Dengan menyamakan 90 derajat dengan PI / 2, Anda dapat melakukannya seperti ini:

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

untuk berlawanan arah jarum jam sudutnya harus negatif

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

Filter transpos akan bekerja sama baiknya untuk 90 derajat, tetapi untuk sudut lain ini adalah pilihan yang lebih cepat atau satu-satunya.

Bijou Trouvaille
sumber
2
ini bagus. Saya menemukan bahwa mungkin untuk mendapatkan resolusi radian yang lebih halus, karena *berperilaku sebagai multiplikasi: ffmpeg -i in.avi -vf "rotate=-8*PI/40" -q 1 out.avi (sedikit lebih sedikit rotasi daripada -PI / 4 = -10 * PI / 40)
eqzx
12
ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4 

tidak akan berfungsi, bahkan dengan sumber terbaru ...

harus mengubah urutan:

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

bekerja dengan baik

nano
sumber
itu karena Anda menerapkan filter ke file yang salah ... coba ffmpeg -i input.mp4 -vf "rotate = 90" output.mp4, maka itu akan berfungsi
patrick
2
"Putar video dengan sudut sewenang-wenang yang dinyatakan dalam radian ." Dokumentasi: ffmpeg.org/ffmpeg-filters.html#rotate Jadi, radian rotate=PI/2atau rotate=90*PI/180diperlukan
l --marc l
Ini fantastis
Tessaracter
7

Jika Anda mendapatkan "Codec eksperimental tetapi codec eksperimental tidak diaktifkan" gunakan kesalahan ini:

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

Terjadi dengan saya untuk beberapa file .mov dengan audio aac.

sabujp
sumber
Ini adalah satu-satunya contoh yang berhasil untuk saya, tetapi kualitasnya mengerikan, dan sangat kuning. Selain itu, perampingan video 1080x1920 ke 352x640. Saya kira saya kehilangan satu atau dua saklar. Ada saran?
LOlliffe
1
@LOlliffe add-sameq
Andrew Schleifer
2
@AndrewSchleifer Terima kasih. Saya mencoba itu, tetapi ffmpeg melemparkan kembali padaku 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 juga memberikan kesalahan. Please use -q:a or -q:v, -qscale is ambiguous, tetapi masih berfungsi.
LOlliffe
3

Skrip ini yang akan menampilkan file dengan struktur direktori di bawah "fixFiles". Saat ini diperbaiki ke file MOV dan akan melakukan sejumlah transformasi tergantung pada "rotasi" asli video. Bekerja dengan video yang diambil iOS di Mac yang menjalankan Maverick, tetapi harus mudah diekspor. Bergantung pada telah menginstal exiftool dan 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
David Costa Faidella
sumber
2
Aduh ... Ini mungkin berhasil, tapi itu sangat mengerikan. Pertama-tama, aturan umum pemrograman shell: Anda tidak perlu lebih dari satu grep, cut, awk, atau sed dalam pipa. Setiap grep | cut | sed dapat dilakukan dengan sed atau awk saja. Kemudian, lebih khusus, exiftool dapat diminta untuk mengeluarkan hanya tag yang Anda inginkan - jadi alih-alih memfilter Rotasi, cukup "exiftool -Rotation". Ketiga, Anda tidak perlu begitu banyak "evals" dan "if test ..." Anda harus diganti dengan case $ ROTATION in - untuk keterbacaan dan efisiensi. Semoga berhasil!
Mikhail T.
Tanpa dadu: [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

Jawaban Alexy hampir berhasil untuk saya kecuali bahwa saya mendapatkan kesalahan ini:

timebase 1/90000 tidak didukung oleh standar MPEG 4, nilai maksimum yang diterima untuk penyebut timebase adalah 65535

Saya hanya perlu menambahkan parameter (-r 65535/2733) ke perintah dan itu berhasil. Perintah lengkapnya adalah sebagai berikut:

ffmpeg -i in.mp4 -vf "transpose=1" -r 65535/2733 out.mp4
Smoyth
sumber
Jika Anda mencari framerate "NTSC-film", maka 24000/1001akan lebih akurat.
Reino
2

Solusi tambahan dengan pendekatan berbeda dari solusi yang disebutkan terakhir, adalah untuk memeriksa apakah driver kamera Anda mendukung kontrol kamera v4l2 (yang sangat umum).
Di terminal cukup ketik:

v4l2-ctl -L

Jika driver kamera Anda mendukung kontrol kamera v4l2, Anda harus mendapatkan sesuatu seperti ini (daftar di bawah ini tergantung pada kontrol yang didukung oleh driver kamera Anda):

               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

Dan jika Anda beruntung itu mendukung horizontal_flip dan vertical_flip .
Maka yang perlu Anda lakukan adalah mengatur horizontal_flip dengan:

v4l2-ctl --set-ctrl horizontal_flip=1

atau vertical_flip dengan:

v4l2-ctl --set-ctrl vertical_flip=1

dan kemudian Anda dapat memanggil perangkat video Anda untuk mengambil video baru (lihat contoh di bawah), dan video akan diputar / dibalik.

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

Tentu saja jika Anda perlu memproses video yang sudah ada, maka metode ini bukanlah solusi yang Anda cari.

Keuntungan dari pendekatan ini adalah kita membalik gambar di level sensor, jadi sensor driver sudah memberi kita gambar terbalik, dan itu menyimpan aplikasi (seperti FFmpeg) pemrosesan lebih lanjut dan tidak perlu.

JM
sumber
Informasi hebat tentang v4l2 di sini. Memutar ke arah yang benar pada waktu perekaman jelas lebih disukai :) Pertanyaan yang hampir 10 tahun ini (wow!) Awalnya ditanyakan tentang video yang diunggah dari perangkat iOS jika itu membantu memberikan konteks apa pun :)
jocull
Saya agak baru di komunitas ini dan pertanyaan ini jauh lebih tua daripada senioritas saya di sini ... Saya benar-benar berpikir itu adalah pertanyaan yang baik (dan umum), jadi saya percaya pertanyaan lama ini akan terus membantu banyak pengguna FFmpeg.
JM
1

Sayangnya, ffmpeg versi Ubuntu mendukung videofilters.

Anda perlu menggunakan avidemux atau editor lain untuk mencapai efek yang sama.

Secara terprogram, mencoder telah direkomendasikan.

ldig
sumber
1
Apakah maksud Anda "Versi ffmpeg Ubuntu tidak mendukung videofilters"?
user1438038
2
FYI: "FFmpeg telah kembali di Ubuntu 15.04 Vivid Vervet." atau dapat dikompilasi untuk Ubuntu. -> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
l --marc l
avconv tidak (dalam 14,04), dan tampaknya berfungsi persis sama. (Tapi untuk versi yang lebih baru, pasti gunakan FFmpeg.)
SilverWolf - Reinstate Monica
1

Smartphone: Memulihkan video dalam format vertikal

Ingin mengirimnya ke webside, 90 ° ke kiri (berlawanan arah jarum jam, format lanskap) hmm.

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

melakukannya. Saya mendapatkan format vertikal kembali

debian buster: ffmpeg --versi ffmpeg versi 4.1.4-1 ~ deb10u1 Hak cipta (c) 2000-2019 para pengembang FFmpeg

fb
sumber