Ffmpeg ব্যবহার করে ফ্রেম তোলার দ্রুততম উপায়?


118

হাই, আমার ffmpeg ব্যবহার করে ভিডিওগুলি থেকে ফ্রেমগুলি বের করতে হবে .. এটির চেয়ে আরও দ্রুততর উপায় আছে কি:

ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg

?


1
^ আপডেট URL: trac.ffmpeg.org/wiki/Seeking
Lambart

5
আপনার যদি সিপিইউ চক্রটি বাড়াতে হয় তবে আপনি সমান্তরালভাবে একাধিক ভিডিও থেকে নিষ্কাশন করতে পারেন:parallel -i {} -r 1/1 {.}-%03d.bmp ::: *mpg
ওলে ট্যাঞ্জ

উত্তর:


155

যদি জেপিইজি এনকোডিং পদক্ষেপটি খুব পারফরম্যান্সের নিবিড় হয়, আপনি সর্বদা বিএমপি চিত্র হিসাবে সঙ্কুচিত ফ্রেমগুলি সংরক্ষণ করতে পারেন:

ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp

এতে জেপিজিতে ট্রান্সকোডিং করে কোয়ান্টাইজেশনের মাধ্যমে আরও গুণমানের ক্ষতি না করার সুবিধাও রয়েছে। (পিএনজিও ক্ষতিহীন তবে জেপিজি এনকোড করতে অনেক বেশি সময় নেয়))


9
এর ফলে আমার মেশিনে প্রচুর ফ্রেম নেমে আসে। আমি কি ffmpeg সব কিছু রেন্ডার করতে বলতে পারি?
Evi1M4chine

45
@ Evi1M4chine কেবলমাত্র -r প্যারামিটারটি সরিয়ে ফেলুন এটি সমস্ত ফ্রেমগুলি বের করবে
স্টুডিওজ

14
আমি যোগ করতে চাই যে সিপিইউতে জেপিইজি আসলেই শক্ত নয়, সংকীর্ণ বিটম্যাপগুলি স্টোরেজটিতে সত্যই শক্ত, তাই আমি সন্দেহ করি যে আপনি জেপিজির সাথে তুলনায় বিএমপির সাথে উচ্চতর থ্রুটপুট পাবেন।
মার্কাস মুলার

4
সমস্ত ফ্রেম নিষ্কাশন করতে:ffmpeg -r 1 file.mp4 -r 1 "$filename%03d.png"
ফায়াতজাফ

10
মানে ffmpeg -r 1 -i file.mp4 -r 1 "$filename%03d.png, তাই না? (আপনি নিখোঁজ ছিলেন -i)
জোসচুয়া

68

এই প্রশ্নটি জুড়ে এসেছিল, সুতরাং এখানে একটি দ্রুত তুলনা করা হয়েছে। 38m07s দীর্ঘ ভিডিও থেকে প্রতি মিনিটে একটি ফ্রেম তোলার জন্য এই দুটি ভিন্ন উপায়ে তুলনা করুন:

time ffmpeg -i input.mp4 -filter:v fps=fps=1/60 ffmpeg_%0d.bmp

1m36.029s

এটি দীর্ঘ সময় নেয় কারণ ffmpeg পছন্দসই ফ্রেমগুলি পেতে পুরো ভিডিও ফাইলটিকে বিশ্লেষণ করে।

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

এটি প্রায় 20 গুণ দ্রুত। আমরা কাঙ্ক্ষিত সময় সূচীতে যেতে এবং একটি ফ্রেম বের করতে দ্রুত চাওয়া ব্যবহার করি, তারপরে প্রতিবারের সূচকের জন্য ffmpeg কয়েকবার কল করুন। নোটটি -accurate_seek এটি ডিফল্ট এবং নিশ্চিত করুন যে আপনি যুক্ত করেছেন-ss ইনপুট ভিডিও -iবিকল্পের আগে ।

নোট করুন যেহেতু পরেরটি ভুল হতে পারে তার-filter:v -fps=fps=... পরিবর্তে এটি ব্যবহার করা ভাল যদিও টিকিটটি স্থির হিসাবে চিহ্নিত হয়েছে , তবুও আমি কিছু সমস্যার অভিজ্ঞতা পেয়েছি, তাই এটি নিরাপদে খেলুন।-r


6
ফেব্রুয়ারী ২০১
::

1
bcএকটি নেটিভ উবুন্টু প্যাকেজ নয়, পরিবর্তে এক ব্যাশ ব্যবহার করতে পারেন: let "i = $i * 60"
বিটিডাব্লু

3
ভাল টিপ -ssআগে যোগ করা -i। অন্যথায়, পুরো ভিডিওটি ডিকোড করা হবে এবং অপ্রয়োজনীয় ফ্রেমগুলি ফেলে দেওয়া হবে
মৌস্তফাএআত্ত

2
যেহেতু এটি গুগলের শীর্ষে রয়েছে, আমি নোট করতে চাই যে 2018 সালে এটি এখনও একটি পন্থা যা লভ্যাংশ দেয়। সেরা ফলাফলটি ffmpegআপনার হোস্টের প্রতিটি প্রতি চলমান বলে মনে হচ্ছে - যা (বিএমপি জন্য) গতিতে লাইন-লিনিয়ার উন্নতি লাভ করে (যতক্ষণ না আপনি ডিস্কের মতো কিছু অন্যান্য বাধা মারেন)।
কनेटিক

এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, যেহেতু প্রশ্নটি 'দ্রুততম পথে' সম্পর্কে। স্পষ্টতই আপনাকে ffprobe ব্যবহার করে 'ফর লুপের' জন্য প্রস্থান ভেরিয়েবলটি জানতে হবে যা আমি মনে করি যে অন্যান্য পদ্ধতির তুলনায় এখনও দ্রুত।
আইপ্রেম

9

কোন ফ্রেমগুলি বের করতে হবে তা যদি আপনি ঠিক জানেন, যেমন 1, 200, 400, 600, 800, 1000, ব্যবহার করে দেখুন:

select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,1000)' \
       -vsync vfr -q:v 2

আমি এটিকে কোনও ভিডিও থেকে 10 ফ্রেমের পূর্বরূপ পেতে ইমেজম্যাগিকের মনটেজে একটি পাইপ দিয়ে ব্যবহার করছি। স্পষ্টতই ফ্রেম নম্বরগুলি ব্যবহার করে আপনাকে বের করতে হবেffprobe

ffmpeg -i myVideo.mov -vf \
    select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,1000)',scale=320:-1 \
    -vsync vfr -q:v 2 -f image2pipe -vcodec ppm - \
  | montage -tile x1 -geometry "1x1+0+0<" -quality 100 -frame 1 - output.png

সামান্য ব্যাখ্যা:

  1. Ffmpeg এক্সপ্রেশন মধ্যে + OR এবং এবং এর *জন্য দাঁড়িয়েছে
  2. \,কেবল ,চরিত্র থেকে বাঁচাচ্ছে
  3. ছাড়া -vsync vfr -q:v 2এটা কাজ বলে মনে হচ্ছে না কিন্তু আমি জানি কেন না - কেউ কি আছেন?

4

আমি এটা চেষ্টা করেছি. 32 সেকেন্ডে 3600 ফ্রেম। আপনার পদ্ধতি সত্যিই ধীর। আপনার এটি চেষ্টা করা উচিত।

ffmpeg -i file.mpg -s 240x135 -vf fps=1 %d.jpg

আমি চেষ্টা করছি ffmpeg -i "input URL" -vf fps=1/5 out%d.png যেখানে ইনপুট URL টি একটি https লিঙ্ক হতে হবে।
x2212

ffmpeg -i file.mpg -vf fps=1 %d.jpg
কিশান বাঘেলা

1

আমার ক্ষেত্রে আমার কমপক্ষে প্রতি সেকেন্ডে ফ্রেম দরকার। আমি উপরের 'টু টু' পদ্ধতির ব্যবহার করেছি তবে আমি যদি কাজটির সমান্তরাল করতে পারি তবে ভাবছি। আমি এখানে ফিফোর পদ্ধতির সাথে এন প্রক্রিয়াগুলি ব্যবহার করেছি: /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

মূলত আমি এই প্রক্রিয়াটি স্বতঃস্ফূর্তভাবে প্রচ্ছন্ন করেছিলাম তবে এটি সহবর্তী থ্রেডের সংখ্যা এন এর মধ্যে সীমাবদ্ধ করে রেখেছি

এটি আমার ক্ষেত্রে 26 সেকেন্ড থেকে 16 সেকেন্ডে 'সন্ধান করতে' পদ্ধতির উন্নতি করেছে। একমাত্র সমস্যা হ'ল স্টাডাউট প্লাবিত হওয়ার পরে মূল থ্রেডটি পরিষ্কারভাবে টার্মিনালে ফিরে আসে না।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.