FFmpeg का उपयोग करके वीडियो के लिए सार्थक थंबनेल


80

FFmpeg उन वीडियो से छवियों को कैप्चर कर सकता है जिनका उपयोग वीडियो को दर्शाने के लिए थंबनेल के रूप में किया जा सकता है। ऐसा करने के अधिकांश सामान्य तरीके FFmpeg Wiki में कैप्चर किए जाते हैं ।

लेकिन, मैं कुछ अंतराल पर यादृच्छिक फ्रेम नहीं चुनना चाहता। मुझे दृश्य परिवर्तनों को पकड़ने के लिए FFmpeg पर फिल्टर का उपयोग करते हुए कुछ विकल्प मिले:

फ़िल्टर thumbnailवीडियो में सबसे अधिक प्रतिनिधि फ्रेम खोजने की कोशिश करता है:

ffmpeg -i input.mp4 -vf  "thumbnail,scale=640:360" -frames:v 1 thumb.png

और निम्न आदेश केवल उन फ़्रेमों का चयन करता है जिनमें पिछले की तुलना में 40% से अधिक परिवर्तन हैं (और शायद दृश्य परिवर्तन हैं) और 5 पीएनजी का अनुक्रम उत्पन्न करता है।

ffmpeg -i input.mp4 -vf  "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png

उपरोक्त आदेशों की जानकारी का श्रेय फैबियो सोननती को दिया जाता है । दूसरे को बेहतर लग रहा था क्योंकि मैं n चित्र प्राप्त कर सकता था और सर्वश्रेष्ठ चुन सकता था। मैंने इसे आजमाया और इसने 5 बार एक ही छवि बनाई।

कुछ और जांच ने मुझे इस ओर अग्रसर किया:

ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr  out%02d.png

-vsync vfrयह सुनिश्चित करता है कि आपको अलग-अलग चित्र मिलें। यह अभी भी हमेशा वीडियो के पहले फ्रेम को चुनता है, ज्यादातर मामलों में पहला फ्रेम क्रेडिट / लोगो है और सार्थक नहीं है, इसलिए मैंने -ssवीडियो के पहले 3 सेकंड को छोड़ने के लिए एक 3 जोड़ा ।

मेरा अंतिम आदेश इस तरह दिखता है:

ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg

यह सबसे अच्छा मैं कर सकता था। मैंने देखा है कि चूंकि मैं केवल 5 वीडियो चुनता हूं, उनमें से ज्यादातर वीडियो की शुरुआत से हैं और बाद में वीडियो में आने वाले महत्वपूर्ण दृश्यों को याद कर सकते हैं

मैं आपके दिमाग को किसी अन्य बेहतर विकल्प के लिए चुनना चाहूंगा।


अच्छी कमांड के उदाहरण। एफडब्ल्यूआईडब्ल्यू, मैं ओएस एक्स (10.8, एफएफएमपीई 1.1 और उससे नीचे) पर एफएफएमईजी-जनरेटेड जेपीईजी चित्रों के साथ किसी भी मुद्दे पर नहीं चला। आपकी दूसरी से अंतिम कमांड मेरे लिए ठीक काम करती है - इसलिए अंतिम- और इनमें से कोई भी परिणाम रिक्त JPG फ़ाइलों में नहीं है। मैंने साथ कंप्लीट किया libopenjpeg.. यकीन नहीं होता कि फर्क पड़ता है।
slhck

धन्यवाद slhck Ffmpeg config / version विवरण के साथ प्रश्न संपादित किया। मैंने इस मशीन पर 1.1 में अपग्रेड नहीं किया है। मैं ऐसा करूंगा और देखूंगा कि क्या यह कोई परिणाम बदलता है।
d33pika

1
तो आप उबंटू पर हैं? क्या आप स्थैतिक निर्माण या खुद को संकलित करने और फिर से चलाने से नवीनतम गिट मास्टर संस्करण की कोशिश कर सकते हैं ? या नवीनतम स्थिर। मैंने अभी-अभी जाँच की है, यह mjpegमेरे लिए एनकोडर का भी उपयोग करता है , और मैंने भी जाँच की jpegoptimऔर exiv2, दोनों ही आपके उदाहरण कमांड्स के सभी JPG परिणामों के साथ मेरे लिए ठीक काम करते हैं।
slhck

1
मैंने अपडेट किया, और यह अब काम करता है! मुझे लगता है कि पिछले संस्करण में कुछ कीड़े थे।
d33pika

क्या आप आगे बढ़ सकते हैं और समाधान- नए संस्करण को पोस्ट कर सकते हैं, अधिमानतः चेंजलॉग के लिंक के साथ जो आपके सामने आया बग दिखा रहा है और बाद में नए संस्करण के साथ तय किया गया है?
लिज़

जवाबों:


29

कैसे के बारे में देख रहे हैं, आदर्श रूप से, पहले> 40% -change फ्रेम में से प्रत्येक के भीतर 5 समय spans, जहां समय अवधि 1, 2, 3, 4, और 5% 20% वीडियो हैं।

आप इसे 6 समय के अंतराल में विभाजित कर सकते हैं और क्रेडिट से बचने के लिए 1 की अवहेलना कर सकते हैं।

व्यवहार में, इसका मतलब यह होगा कि अपने दृश्य परिवर्तन की जाँच करते समय और वीडियो के पहले बिट को बाहर फेंकने के लिए एफपीएस को कम संख्या पर सेट करें।

...कुछ इस तरह:

ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.4)" -frames:v 5 -vsync vfr -vf fps=fps=1/600 out%02d.jpg

1
पूरी तरह से काले या सफेद चित्र मिलते हैं। मैं उनसे कैसे बचता हूं?
d33pika

1
काले फ्रेम और उनमें से दृश्यों का पता लगाने के लिए फ़िल्टर हैं ( ffmpeg.org/ffmpeg-filters.html#blackframe या ffmpeg.org/ffmpeg-filters.html#blackdetect )। आप अपने बढ़ते वन-लाइनर में से किसी एक में भी काम करने में सक्षम नहीं हैं, लेकिन आपको निश्चित रूप से काले फ्रेम (अलग चरण) को बाहर निकालने और परिणामस्वरूप वीडियो से थंबनेल निकालने में सक्षम होना चाहिए।
AM

5
जैसे कि सफेद फ्रेम के लिए, अब यह जटिल हो रहा है, लेकिन यह अभी भी ऐसा लगता है कि एक तरीका है: 1. काले फ्रेम बाहर पट्टी। नकारात्मक (सफेद काला हो जाता है) 3. सफेद फ्रेम बाहर पट्टी 4. फिर से नकारात्मक 5. निकालें थंबनेल (यदि आप काले या सफेद फ्रेम को अलग करने का प्रबंधन करते हैं, विशेष रूप से एक पंक्ति में, तो क्या आप इसे यहां वापस पोस्ट कर सकते हैं? मैं इसे भविष्य के पाठकों के लिए उत्तर में जोड़ सकता हूं। ... या वास्तव में आप एक नया प्रश्न और उत्तर बना सकते हैं। यह। मैं निश्चित रूप से इसे बढ़ा दूंगा।)
AM

3
सादे काले और सफेद जैसे उबाऊ छवियों से बचने के लिए: अपनी आवश्यकता से अधिक थंबनेल उत्पन्न करें, उन्हें जेपीईजी के साथ संपीड़ित करें, और अन्य फ़ाइल आकार के साथ छवियां चुनें। यह सभ्य थंबनेल प्राप्त करने के लिए आश्चर्यजनक रूप से अच्छी तरह से काम करता है।
सैम वाटकिंस

2
यह कमांड काम नहीं किया, मुझे एक त्रुटि मिली Unable to find a suitable output format for 'fps=fps=1/600'-vfउस तर्क से पहले समाधान जोड़ना है (देखें stackoverflow.com/questions/28519403/ffmpeg-command-issue )
जॉन विस्मैन

7

सार्थक को परिभाषित करना कठिन है, लेकिन अगर आप एन थंबनेल को कुशलतापूर्वक पूरी वीडियो फ़ाइल बनाना चाहते हैं, तो यह वही है जो मैं उपयोगकर्ता द्वारा अपलोड की गई सामग्री के साथ उत्पादन पर थंबनेल बनाने के लिए उपयोग करता हूं।

छद्म कोड

for X in 1..N
  T = integer( (X - 0.5) * D / N )  
  run `ffmpeg -ss <T> -i <movie>
              -vf select="eq(pict_type\,I)" -vframes 1 image<X>.jpg`

कहाँ पे:

  • डी - वीडियो की अवधि ffmpeg -i <movie>अकेले पढ़ी जाती है या ffprobeजिसमें अच्छा JSON आउटपुट राइटर btw होता है
  • एन - आप चाहते हैं कि थंबनेल की कुल संख्या
  • एक्स - थंबनेल संख्या, 1 से एन तक
  • T-tumbnail के लिए समय बिंदु

बस ऊपर फिल्म के प्रत्येक विभाजन के केंद्र कुंजी-फ्रेम लिखता है। उदाहरण के लिए, यदि फिल्म 300 से लंबी है और आप 3 थंबनेल चाहते हैं, तो यह 50, 150 और 250 के बाद एक मुख्य फ्रेम लेता है। 5 थंबनेल के लिए यह 30s, 90s, 150s, 210s, 270s होगा। आप मूवी की अवधि डी के आधार पर एन को समायोजित कर सकते हैं, जैसे कि 5 मिनट की मूवी में 3 थंबनेल होंगे लेकिन 1 घंटे से अधिक में 20 थंबनेल होंगे।

प्रदर्शन

उपरोक्त ffmpegकमांड का प्रत्येक आह्वान ~ 1GB H.264 के लिए सेकंड (!) का एक अंश लेता है। ऐसा इसलिए है क्योंकि यह तुरंत <time>स्थिति (मन -ssसे पहले -i) को कूदता है और पहला मुख्य फ्रेम लेता है जो व्यावहारिक रूप से जेपीईजी पूरा करता है। सटीक समय की स्थिति से मेल खाने के लिए फिल्म को प्रस्तुत करने के लिए कोई समय बर्बाद नहीं हुआ है।

प्रोसेसिंग के बाद

आप ऊपर scaleया किसी अन्य आकार परिवर्तन विधि के साथ मिश्रण कर सकते हैं । आप ठोस रंग फ़्रेम भी निकाल सकते हैं या इसे अन्य फ़िल्टर जैसे मिश्रण करने का प्रयास कर सकते हैं thumbnail


2
-ss Nइससे पहले -iकि वाह वाह एक अद्भुत टिप है। धन्यवाद!
अपिनस्टीन

2

मैंने एक बार ऐसा ही कुछ किया था, लेकिन मैंने वीडियो के सभी फ़्रेमों (1 एफपीएस में) का निर्यात किया और उनकी तुलना एक पर्ल उपयोगिता के साथ की, जिसमें मैंने पाया कि छवियों के बीच अंतर की गणना करता है। मैंने प्रत्येक फ्रेम की तुलना पिछले थंबनेल से की थी, और यदि यह सभी थंबनेल से अलग था, तो मैंने इसे थंबनेल संग्रह में जोड़ा। यहाँ लाभ यह है कि यदि आपका वीडियो दृश्य A से B तक चला जाता है और वे A पर लौट आते हैं, तो ffmpeg A के 2 फ्रेम निर्यात करेगा।


2 छवियों की तुलना करने के लिए आपने किन कारकों का उपयोग किया?
d33pika

दुर्भाग्य से मुझे याद नहीं है, यह बहुत पहले था। आपको पहले यह तय करने की आवश्यकता है कि किस विधि का उपयोग करने की तुलना करें, और फिर सही कारक खोजने के लिए कुछ परीक्षण करें। यह लंबा नहीं होना चाहिए।
एरन बेन-नटन

मैं यहाँ सिर्फ ज़ोर से सोच रहा हूँ, लेकिन यह बदतर विकल्प नहीं है? जब आप वीडियो से 2 निर्यात की गई छवियों की तुलना करते हैं तो आप पहले से ही कुछ जानकारी खो चुके होते हैं। मेरा मतलब है, यह कोडेक जानकारी से समानता की गणना करना आसान है, क्योंकि यह 2 चित्रों से है, है न? हाल ही में मैं छवियों की तुलना करने के लिए कुछ एल्गोरिदम / पुस्तकालयों में देख रहा हूं और वे काम नहीं करते हैं और एक की आवश्यकता हो सकती है।
शमूएल

खैर, ffmpeg के साथ आप समान_क्वालिटी फ़्लैग का उपयोग करके गुणवत्ता हानि के बिना फ़्रेम निकाल सकते हैं। यदि आप कोडेक की जानकारी का उपयोग करते हैं, तो आपको यह जांचने की आवश्यकता है कि आपको इफ्रेम नहीं मिला है। वैसे भी कि पर्ल उपयोगिता मेरे लिए ठीक काम करती है, और बहुत ही विन्यास योग्य है। यहां देखें: search.cpan.org/~avif/Image-Compare-0.3/Compare.pm
एरन बेन-

2

इसे इस्तेमाल करे

 ffmpeg -i input.mp4 -vf fps= no_of_thumbs_req/total_video_time out%d.png

इस आदेश का उपयोग करके मैं आवश्यक संख्या में थंबनेल उत्पन्न करने में सक्षम हूं जो संपूर्ण वीडियो के प्रतिनिधि हैं।


के लिए सही फार्मूला नहीं होता fpsहो (no_of_frames_req * fps_of_vid) / total_video_frames?
फ्लोलिलो

मैं एक विपरीत समाधान की तलाश कर रहा हूं: उस अवधि से अधिक फ़्रेम चुनें जहां कैमरा अधिक स्थिर है और हिल नहीं रहा है? (जहां क्रमिक फ्रेम के बीच अंतर कम है, अधिक नहीं है)। क्या ऐसा करने के लिए कोई रास्ता है?
टीना जे

1

यहाँ मैं पोस्टर के रूप में उपयोग करने के लिए लाइव m3u8 धाराओं के लिए एक आवधिक थंबनेल उत्पन्न करने के लिए क्या कर रहा हूँ। मैंने पाया कि मेरे सभी सीपीयू को खाने के लिए बस एक निरंतर ffmpeg कार्य चल रहा है, इसलिए इसके बजाय मैं हर 60 सेकंड में एक क्रोनजॉब चलाता हूं जो मेरी धाराओं के लिए सभी थंबनेल उत्पन्न करता है।

#!/usr/bin/env bash

## this is slow but gives better thumbnails (takes about 1+ minutes for 20 files)
#-vf thumbnail,scale=640:360 -frames:v 1 poster.png

## this is faster but thumbnails are random (takes about 8 seconds for 20 files)
#-vf scale=640:360 -frames:v 1 poster.png
cd ~/path/to/streams

find . -type f \
  -name "*.m3u8" \
  -execdir sh -c 'ffmpeg -y -i "$0" -vf scale=640:360 -frames:v 1 "poster.png"' \
  {} \;

यदि आपको 60 सेकंड (क्रोनजॉब की सीमा) से अधिक बार करने की आवश्यकता है, तो आप whileअपनी स्क्रिप्ट में एक लूप कर सकते हैं और इसे हमेशा के लिए निष्पादित करेंगे। बस sleep 30आवृत्ति को 30 सेकंड में बदलने के लिए जोड़ें । मैं बड़ी संख्या में वीडियो के साथ ऐसा करने की अनुशंसा नहीं करता, क्योंकि पिछले रन अगले एक शुरू होने से पहले पूरा नहीं हो सकता है।

आदर्श रूप से क्रोनजोब के साथ मैं इसे हर 5 मिनट में चलाता हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.