2013-02-27 137 views
8

में वीडियो से बिटमैप निकालें मैं एक वीडियो से सभी फ्रेम निकालने की कोशिश कर रहा हूं।
कोड का पालन करके मैं एक वीडियो के पहले 30 फ्रेम लाने के लिए चाहता हूं, लेकिन मुझे केवल 30 फ्रेम पहले फ्रेम मिल गया।एंड्रॉइड

private ArrayList<Bitmap> getFrames(String path) { 
    try { 
     ArrayList<Bitmap> bArray = new ArrayList<Bitmap>(); 
     bArray.clear(); 
     MediaMetadataRetriever mRetriever = new MediaMetadataRetriever(); 
     mRetriever.setDataSource("/sdcard/myvideo.mp4");      

     for (int i = 0; i < 30; i++) { 
      bArray.add(mRetriever.getFrameAtTime(1000*i, 
         MediaMetadataRetriever.OPTION_CLOSEST_SYNC)); 
     } 
     return bArray; 
    } catch (Exception e) { return null; } 
} 

अब, मैं वीडियो से सभी फ्रेम कैसे प्राप्त कर सकता हूं?

+0

'getFrameAtTime' को दिया गया समय microseconds में दिया गया है, इसलिए 30 एफपीएस वीडियो के लिए प्रत्येक फ्रेम के बीच लगभग 33333 माइक्रोसॉन्ड होंगे। आपके कोड को पढ़ने का प्रयास करने वाला अंतिम फ्रेम 30000 माइक्रोसॉन्ड पर है - यानी आप दूसरे फ्रेम तक आगे बढ़े नहीं होंगे (पाठ्यक्रम की आपकी फ्रेम दर के आधार पर)। दूसरी बात यह है कि 'OPTION_CLOSEST_SYNC' आपके द्वारा निर्दिष्ट समय के निकट _keyframe_ को पुनर्प्राप्त करता है। संपीड़ित वीडियो में कुल फ्रेम की तुलना में आम तौर पर कम कीफ्रेम होते हैं। – Michael

+0

हैलो @ माइकल, 30 एफपीएस के साथ मेरा वीडियो। और अब मैं निकालने बिटमैप्स के लिए कोड निम्न का उपयोग कर रहा .... के लिए (int i = 0; i <10; i ++) { \t \t \t \t bArray.add (mRetriever.getFrameAtTime (33333 * मैं, \t \t \t \t \t \t MediaMetadataRetriever.OPTION_CLOSEST_SYNC)); \t \t \t} लेकिन कुछ भी नहीं बदला जा सकता है .. यहां मुझे बिटमैप में केवल पहला फ्रेम मिला है .. –

+1

जैसा कि मैंने अपनी पहली टिप्पणी में लिखा था, आप 'OPTION_CLOSEST_SYNC' का उपयोग करते समय दिए गए समय के निकटतम कीफ्रेम पुनर्प्राप्त कर रहे हैं। यह असंभव नहीं है कि वीडियो में प्रत्येक कीफ्रेम के लिए 10 या अधिक फ्रेम शामिल हैं। यदि आप केवल कीफ्रेम के बजाय किसी भी प्रकार का फ्रेम प्राप्त करना चाहते हैं तो 'OPTION_CLOSEST' का उपयोग करें। – Michael

उत्तर

2

एंड्रॉइड एसडीके में वीडियो समर्थन सीमित है और H264 एन्कोडेड वीडियो के लिए फ्रेम निष्कर्षण केवल मुख्य फ्रेम के लिए संभव है। एक मनमानी फ्रेम निकालने के लिए, आपको FFmpegMediaMetadataRetriever जैसी लाइब्रेरी का उपयोग करना होगा जो वीडियो से डेटा निकालने के लिए मूल कोड का उपयोग करता है। यह बहुत तेज है, प्रीकंपिल्ड बाइनरी (एआरएम और एक्स 86 के लिए) के साथ आता है, इसलिए आपको सी ++ और मेकफ़ाइल में जाने की आवश्यकता नहीं है, अपाचे 2.0 के तहत लाइसेंस प्राप्त है और यह डेमो एंड्रॉइड ऐप के साथ आता है।

एक शुद्ध जावा लाइब्रेरी भी है, JCodec लेकिन यह धीमा है और जब मैंने पिछले साल इसका इस्तेमाल किया तो निकाले गए फ्रेम के रंग विकृत हो गए।

+0

मैंने जेसीओडीसी की कोशिश की, लेकिन मुझे 240fps धीमी गति mp4 से keyframes के अलावा कुछ भी नहीं मिला। मैं ओपनसीवी की जावा बाइंडिंग, वीडियो कैप्चर क्लास का उपयोग कर समाप्त हुआ। मेरा मानना ​​है कि यह कवर के तहत ffmpeg का उपयोग कर रहा है। मैं सभी फ्रेम, और प्रत्येक प्रसिद्धि के टाइमस्टैम्प और वीडियो की कुल संख्या फ्रेम भी प्राप्त करने में सक्षम था। चेतावनी - यह जावा एसडीके था, मैंने अभी तक एंड्रॉइड के लिए नवीनतम ओपनसीवी की कोशिश नहीं की है। – medloh

0

getFrame मिलीसेकंड में डेटा प्राप्त करें लेकिन आप लूप के लिए .001 मिलीसेकंड में वृद्धि कर रहे हैं।

for(int i=1000000;i<millis*1000;i+=1000000) // for incrementing 1s use 1000 
    { 
     bArray.add(mRetriever.getFrameAtTime(i, 
         MediaMetadataRetriever.OPTION_CLOSEST_SYNC)); 
    } 

इसे ऊपर की तरह बदलें। आप जो चाहते हैं उसे बनाने के लिए ऊपर नमूना है। मैंने इसका उत्तर भी दिया here