Jika Anda memiliki siklus CPU yang tersisa, Anda dapat mengekstrak dari beberapa video secara paralel:parallel -i {} -r 1/1 {.}-%03d.bmp ::: *mpg
Ole Tange
Jawaban:
156
Jika langkah pengkodean JPEG terlalu intensif kinerja, Anda selalu dapat menyimpan bingkai yang tidak dikompresi sebagai gambar BMP:
ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp
Ini juga memiliki keuntungan karena tidak menimbulkan lebih banyak kehilangan kualitas melalui kuantisasi dengan melakukan transcoding ke JPEG. (PNG juga lossless tetapi cenderung membutuhkan waktu lebih lama daripada JPEG untuk dienkode.)
Ini menghasilkan banyak frame yang jatuh di mesin saya. Bisakah saya memberi tahu ffmpeg untuk merender semuanya?
Evi1M4chine
45
@ Evi1M4chine hapus saja parameter -r ini akan mengekstrak semua frame
studioj
14
Saya ingin menambahkan bahwa meskipun JPEG tidak terlalu keras pada CPU, Bitmaps yang tidak dikompresi sangat sulit pada penyimpanan, jadi saya ragu Anda akan mendapatkan hasil yang lebih tinggi dengan BMP dibandingkan dengan JPEG.
Marcus Müller
4
Untuk mengekstrak semua frame:ffmpeg -r 1 file.mp4 -r 1 "$filename%03d.png"
Menemukan pertanyaan ini, jadi inilah perbandingan singkatnya. Bandingkan dua cara berbeda ini untuk mengekstrak satu frame per menit dari video berdurasi 38m07s:
time ffmpeg -i input.mp4 -filter:v fps=fps=1/60 ffmpeg_%0d.bmp
1m36.029s
Ini membutuhkan waktu lama karena ffmpeg mem-parsing seluruh file video untuk mendapatkan frame yang diinginkan.
time for i in {0..39} ; do ffmpeg -accurate_seek -ss `echo $i*60.0 | bc` -i input.mp4 -frames:v 1 period_down_$i.bmp ; done
0m4.689s
Ini sekitar 20 kali lebih cepat. Kami menggunakan pencarian cepat untuk membuka indeks waktu yang diinginkan dan mengekstrak bingkai, lalu memanggil ffmpeg beberapa kali untuk setiap indeks waktu. Perhatikan bahwa -accurate_seekini adalah default
, dan pastikan Anda menambahkan -sssebelum opsi input video -i.
bcbukan paket Ubuntu asli, bukan satu dapat menggunakan bash: let "i = $i * 60". BTW - ide bagus
gilad mayani
3
Tip bagus menambahkan -sssebelumnya -i. Jika tidak, seluruh video akan didekodekan dan bingkai yang tidak diperlukan akan dibuang
MoustafaAAtta
2
Karena ini adalah yang teratas dari google, saya ingin mencatat bahwa pada tahun 2018 ini masih merupakan pendekatan yang menghasilkan dividen. Hasil terbaik tampaknya menjalankan satu ffmpegper inti host Anda - yang (untuk bmp) menghasilkan peningkatan kecepatan yang hampir linier (sampai Anda mencapai beberapa hambatan lain, seperti disk).
Knetic
Ini harus menjadi jawaban yang diterima, karena pertanyaannya adalah tentang 'cara tercepat'. Tentunya Anda perlu mengetahui variabel keluar untuk 'for loop' menggunakan ffprobe yang menurut saya masih lebih cepat dibandingkan dengan metode lain.
iamprem
9
Jika Anda tahu persis frame mana yang akan diekstrak, misalnya 1, 200, 400, 600, 800, 1000, coba gunakan:
Saya menggunakan ini dengan pipa ke montase Imagemagick untuk mendapatkan pratinjau 10 bingkai dari video mana pun. Jelas nomor bingkai yang perlu Anda ketahui menggunakanffprobe
Saya mencoba di ffmpeg -i "input URL" -vf fps=1/5 out%d.png mana URL masukan harus berupa tautan https.
x2212
ffmpeg -i file.mpg -vf fps=1 %d.jpg
Kishan Vaghela
1
Dalam kasus saya, saya membutuhkan bingkai setidaknya setiap detik. Saya menggunakan pendekatan 'mencari' di atas tetapi bertanya-tanya apakah saya bisa memparalelkan tugas tersebut. Saya menggunakan proses N dengan pendekatan FIFO di sini:
/unix/103920/parallelize-a-bash-for-loop/216475#216475
open_sem(){
mkfifo /tmp/pipe-$$
exec 3<>/tmp/pipe-$$
rm /tmp/pipe-$$
local i=$1
for((;i>0;i--)); do
printf %s 000 >&3
done
}
run_with_lock(){
local x
read -u 3 -n 3 x && ((0==x)) || exit $x
(
"$@"
printf '%.3d' $? >&3
)&
}
N=16
open_sem $N
time for i in {0..39} ; do run_with_lock ffmpeg -ss `echo $i` -i /tmp/input/GOPR1456.MP4 -frames:v 1 /tmp/output/period_down_$i.jpg & done
Pada dasarnya saya membagi proses dengan & tetapi membatasi jumlah utas bersamaan ke N.
Ini meningkatkan pendekatan 'seek to' dari 26 detik menjadi 16 detik dalam kasus saya. Satu-satunya masalah adalah utas utama tidak keluar dengan bersih kembali ke terminal karena stdout dibanjiri.
parallel -i {} -r 1/1 {.}-%03d.bmp ::: *mpg
Jawaban:
Jika langkah pengkodean JPEG terlalu intensif kinerja, Anda selalu dapat menyimpan bingkai yang tidak dikompresi sebagai gambar BMP:
Ini juga memiliki keuntungan karena tidak menimbulkan lebih banyak kehilangan kualitas melalui kuantisasi dengan melakukan transcoding ke JPEG. (PNG juga lossless tetapi cenderung membutuhkan waktu lebih lama daripada JPEG untuk dienkode.)
sumber
ffmpeg -r 1 file.mp4 -r 1 "$filename%03d.png"
ffmpeg -r 1 -i file.mp4 -r 1 "$filename%03d.png
, kan? (Anda kehilangan-i
)Menemukan pertanyaan ini, jadi inilah perbandingan singkatnya. Bandingkan dua cara berbeda ini untuk mengekstrak satu frame per menit dari video berdurasi 38m07s:
1m36.029s
Ini membutuhkan waktu lama karena ffmpeg mem-parsing seluruh file video untuk mendapatkan frame yang diinginkan.
0m4.689s
Ini sekitar 20 kali lebih cepat. Kami menggunakan pencarian cepat untuk membuka indeks waktu yang diinginkan dan mengekstrak bingkai, lalu memanggil ffmpeg beberapa kali untuk setiap indeks waktu. Perhatikan bahwa
-accurate_seek
ini adalah default , dan pastikan Anda menambahkan-ss
sebelum opsi input video-i
.Perhatikan bahwa lebih baik menggunakan
-filter:v -fps=fps=...
daripada-r
karena yang terakhir mungkin tidak akurat. Meskipun tiket ditandai sebagai sudah diperbaiki , saya masih mengalami beberapa masalah, jadi lebih baik bermain aman.sumber
bc
bukan paket Ubuntu asli, bukan satu dapat menggunakan bash:let "i = $i * 60"
. BTW - ide bagus-ss
sebelumnya-i
. Jika tidak, seluruh video akan didekodekan dan bingkai yang tidak diperlukan akan dibuangffmpeg
per inti host Anda - yang (untuk bmp) menghasilkan peningkatan kecepatan yang hampir linier (sampai Anda mencapai beberapa hambatan lain, seperti disk).Jika Anda tahu persis frame mana yang akan diekstrak, misalnya 1, 200, 400, 600, 800, 1000, coba gunakan:
Saya menggunakan ini dengan pipa ke montase Imagemagick untuk mendapatkan pratinjau 10 bingkai dari video mana pun. Jelas nomor bingkai yang perlu Anda ketahui menggunakan
ffprobe
.
Sedikit penjelasan:
+
singkatan dari OR dan*
AND\,
hanya keluar dari,
karakter-vsync vfr -q:v 2
itu sepertinya tidak berhasil tetapi saya tidak tahu mengapa - siapa?sumber
Saya mencobanya. 3600 bingkai dalam 32 detik. metode Anda sangat lambat. Anda harus mencobanya.
sumber
ffmpeg -i "input URL" -vf fps=1/5 out%d.png
mana URL masukan harus berupa tautan https.ffmpeg -i file.mpg -vf fps=1 %d.jpg
Dalam kasus saya, saya membutuhkan bingkai setidaknya setiap detik. Saya menggunakan pendekatan 'mencari' di atas tetapi bertanya-tanya apakah saya bisa memparalelkan tugas tersebut. Saya menggunakan proses N dengan pendekatan FIFO di sini: /unix/103920/parallelize-a-bash-for-loop/216475#216475
Pada dasarnya saya membagi proses dengan & tetapi membatasi jumlah utas bersamaan ke N.
Ini meningkatkan pendekatan 'seek to' dari 26 detik menjadi 16 detik dalam kasus saya. Satu-satunya masalah adalah utas utama tidak keluar dengan bersih kembali ke terminal karena stdout dibanjiri.
sumber
Ini berhasil untuk saya
ffmpeg -i file.mp4 -vf fps=1 %d.jpg
sumber