Menggunakan ffmpeg untuk memotong video

333

Saya menggunakan ffmpeg untuk memotong bagian dari file besar seperti ini:

ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv

Bagian -ssberfungsi dengan baik tetapi -tdiabaikan. Itu benar menghapus detik yang ditentukan awal yang ditentukan dengan -sstetapi kemudian terus ke akhir input dengan salinan.

Apakah ada cara untuk menggunakan ffmpeg untuk memotong bagian akhir video tanpa mengode ulangnya?

Neil
sumber
1
sintaks ini benar.
jiggunjer
1
stackoverflow.com/questions/18444194/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

394

Anda dapat menggunakan -ssopsi untuk menentukan cap waktu mulai, dan -topsi untuk menentukan durasi penyandian. Stempel waktu harus dalam HH:MM:SS.xxxformat atau dalam detik ( s.msec).

Berikut ini akan klip 30 detik pertama, dan kemudian klip semua yang 10 detik setelah itu:

ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv

Perhatikan bahwa -tini adalah opsi keluaran dan selalu harus ditentukan setelahnya -i .

Beberapa tips:

  • Untuk versi ffmpeg yang lebih lama, jika Anda gunakan -sssetelahnya -i, Anda mendapatkan pencarian yang lebih akurat dengan mengorbankan eksekusi yang lebih lambat. Lihat juga: Mencari dengan FFmpeg
  • Anda dapat menggunakan -toalih-alih -tmenentukan cap waktu yang ingin Anda potong. Jadi, alih-alih -i <input> -ss 30 -t 10Anda juga bisa melakukan -i <input> -ss 30 -to 40untuk mencapai hal yang sama.

  • Jika ffmpeg Anda tidak mendukung -c, atau -to, sepertinya sudah usang. Kompilasi sendiri versi baru atau unduh bangunan statis dari beranda mereka. Benar-benar tidak rumit.

slhck
sumber
1
@Mondain Sebenarnya, Anda mendapatkan lebih banyak akurasi setelah -ss. Dan slhck menyebutkan ini di sini blog.superuser.com/2012/02/24/... juga dalam dokumentasi ffmpeg untuk -ss itu menyebutkan perbedaan antara meletakkannya sebelum atau sesudah.
barlop
5
+1 Saya datang ke sini untuk mencari tahu bagaimana mengabaikan semuanya setelah 35 detik pertama, terima kasih:ffmpeg -i input.wmv -c copy -t 35 output.wmv
karlphillip
2
Ini tidak berfungsi untuk saya (mp4). Itu hanya menghasilkan layar hitam 5 detik:frame= 150 fps=0.0 q=-1.0 Lsize= 264kB time=00:00:09.97 bitrate= 216.6kbits/s
tukang kunci
2
Ini menghasilkan layar hitam 3-4 detik di awal klip video saya. Modifikasi Chris dengan menghilangkan -c copymenghapus layar hitam awal, lihat jawabannya untuk detail.
joelostblom
4
Anda menulis "Berikut ini akan klip 30 detik pertama, dan kemudian klip semua yang 10 detik setelah itu:" <- Apa artinya itu? Dengan klip maksud Anda termasuk? Karena klip dapat berarti klip keluar. Dengan asumsi yang Anda maksud termasuk. Apakah maksud Anda Mulai dari 30 detik, dan sertakan hanya 10 detik dari sana? Jika demikian maka saya sarankan Anda menulis bahwa itu akan jauh lebih jelas.
barlop
94

Seperti yang disebutkan orang lain, menempatkan -sssebelum (lebih cepat) atau setelah (lebih akurat) -imembuat perbedaan besar. Bagian "Pencarian Cepat Dan Akurat" pada halaman pencarian ffmpeg memberi tahu Anda cara mendapatkan keduanya, dan saya telah menggunakannya, dan itu membuat perbedaan besar. Pada dasarnya Anda meletakkan -sssebelum DAN setelah -i, pastikan untuk meninggalkan cukup waktu sebelum di mana Anda ingin mulai memotong untuk memiliki bingkai kunci lain. Contoh: Jika Anda ingin membuat klip 1 menit, dari 9min0sec hingga 10min 0sec di Video.mp4, Anda bisa melakukannya dengan cepat dan akurat menggunakan:

ffmpeg -ss 00:08:00 -i Video.mp4 -ss 00:01:00 -t 00:01:00 -c copy VideoClip.mp4

Yang pertama -ssberusaha cepat ke (kurang-lebih) 8min0sec, dan yang kedua -ssmencari secara akurat ke 9min0sec, dan yang -t 00:01:00mengeluarkan klip 1min0sec.

Perhatikan juga poin penting ini dari halaman itu: "Jika Anda menggunakan -ssdengan -c:v copy, bitstream yang dihasilkan mungkin berakhir menjadi berombak, tidak dapat diputar, atau tidak selaras dengan aliran audio, karena ffmpeg dipaksa untuk hanya menggunakan / membagi pada i-frames. "

Ini berarti Anda perlu menyandikan ulang video, bahkan jika Anda ingin menyalinnya saja, atau berisiko video itu berombak dan tidak sinkron. Anda bisa mencoba -c copyterlebih dahulu, tetapi jika videonya payah Anda harus melakukannya kembali.

seri-seri
sumber
peringatan yang sama berlaku -c:a copyuntuk cara pencarian ini.
jiggunjer
1
Jawaban terbaik, cara ini bekerja paling baik untuk saya.
Ondra Žižka
3
Tampaknya "-ss" sekarang cepat dan akurat di ffmpeg 2.1+ tanpa menentukannya dua kali. trac.ffmpeg.org/wiki/Seeking
Conrad Meyer
25

Saya menemukan bahwa -ssdikombinasikan dengan -c copymenghasilkan memotong setengah detik di awal.

Untuk menghindari itu, Anda harus menghapus -c copy(yang memang akan melakukan transcode).

Chris
sumber
4
Ada jawaban lain yang berkaitan dengan keakuratan. Pengodean ulang dengan opsi default seringkali BUKAN apa yang ingin Anda lakukan!
Tomasz Gandor
Poin bagus @TomaszGandor
Chris
1
Saya tidak mengerti jawaban @ TomaszGandor sama sekali, tetapi menghapus -c copymemperbaikinya.
Iulian Onofrei
14

MANUAL

Buka file di pemutar media yang akan membingkai demi frame dan memainkan file AVISynth dengan data seperti:

DirectShowSource(("C:\Downloads\Video\Do you want him.flv"), Pixel_Type="yuy2").Crop(0,0,-0,-0)
Subtitle("C:\Downloads\Video\Do you want him.flv", font="Arial", size=24, text_color=$ff0000, align=3)
ShowFrameNumber(scroll=true, x=336, y=27, font="Arial", size=24, text_color=$ff0000)
ShowTime(x=398, y=44, font="Arial", size=24, text_color=$ff0000)

Kemudian potong dengan format waktu EXACT:

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:05.240 -to 00:00:08.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him1.flv"

dan

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:10.240 -to 00:00:14.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him2.flv"

Sekarang buat file txt dengan file video dengan konten seperti:

file 'C:\Downloads\Video\Do you want him1.flv'
file 'C:\Downloads\Video\Do you want him2.flv'

Jalankan ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"
Budman1
sumber
9

Bagi saya -topsi tidak berfungsi, tetapi -vframesberhasil. Saya lebih suka menggunakan #frames, karena saya lebih suka memotong di I-Frames dan saya menemukan GOP untuk menggunakan video ffprobe.

Baris perintah yang bekerja untuk saya adalah:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

By the way, menempatkan -ssdi depan -imembuat perbedaan besar dalam waktu eksekusi.

Ben
sumber
1
Sebenarnya -vframes(atau -frames:v) harus dicari -ikarena ini merupakan opsi keluaran.
slhck
5

Seperti halnya user225366, opsi -t tidak berfungsi untuk video pendek, tetapi itu berlaku untuk video yang lebih panjang. Untuk video pendek sepertinya -frame: v lebih baik. Inilah yang bekerja untuk saya.

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4

Salinan -acodec perlu ditambahkan jika video memiliki audio, seperti yang ditunjukkan oleh jawaban lainnya.

VectorVortec
sumber
0

Saya melihat tidak banyak menyebutkan ini (saya bukan ahli jadi mungkin ada tangkapan), tetapi jika file Anda memiliki aliran lain seperti subtitle dan metadata lain seperti bab dan sebagainya, mungkin untuk memotong / memotong dan menjaga semua aliran dengan mengikuti perintah

ffmpeg -to 60 -i input.mkv -map 0 -c copy output.mkv

Dengan -map 0Anda mengambil semua aliran dalam file, dan dengan -c copyAnda menyalin semua itu sebagaimana adanya.
Menggunakan -tomenghilangkan start via -ssakan memotong video input dari awal hingga 60 detik.

Mengotak-atik mapberguna juga jika Anda ingin hanya stream tertentu yang disimpan dalam cut (mungkin Anda tidak memerlukan semua sumber audio dalam file, atau hanya beberapa subtitle).

Saya menggunakan ini ketika saya perlu membagi file MKV besar yang tidak dapat disimpan dalam penyimpanan FAT32.

Gruber
sumber