2012-04-11 45 views
3

我想要得到的視頻幀數..我米使用下面的代碼:獲取幀,從影片的Android

package com.vidualtest; 

import java.io.File; 
import java.io.FileDescriptor; 

import android.app.Activity; 
import android.graphics.Bitmap; 
import android.media.MediaMetadataRetriever; 
import android.os.Bundle; 
import android.os.Environment; 
import android.widget.ImageView; 

public class VidualTestActivity extends Activity { 
/** Called when the activity is first created. */ 
File file; 
ImageView img; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 


    img = (ImageView) findViewById(R.id.img); 

    File sdcard = Environment.getExternalStorageDirectory(); 
    file = new File(sdcard, "myvid.mp4"); 

    MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 

    try { 
     retriever.setDataSource(file.getAbsolutePath()); 

     img.setImageBitmap(retriever.getFrameAtTime(10000,MediaMetadataRetriever.OPTION_CLOSEST)); 


    } catch (IllegalArgumentException ex) { 
     ex.printStackTrace(); 
    } catch (RuntimeException ex) { 
     ex.printStackTrace(); 
    } finally { 
     try { 
      retriever.release(); 
     } catch (RuntimeException ex) { 
     } 
    } 


} 

}

在這裏getFrameAtTime()IM傳遞不同的靜態時間像10000,20000等,以毫秒爲單位,但我仍然在不同的時間從視頻獲取相同的幀。我的目標是獲得不同時間間隔的不同幀。

請給我你可能的幫助。

感謝

+0

您的代碼對於一個框架來說速度太慢,1秒。你找到了更好的解決方案嗎? – Nativ 2013-10-29 17:07:57

+0

還沒有好友!其實我也在尋找優化的解決方案。 – 2013-10-30 04:39:17

+1

所以看看我的解決方案下面! – Nativ 2013-10-30 08:47:18

回答

0

我認爲getFrameAt()返回最接近您指定的時間間隔的框架,多數民衆贊成。因此,如果與這兩個時間間隔最接近的幀相同,則指定1000或1500作爲時間(以毫秒爲單位)可能會返回相同的幀。要獲得幀數,您可能需要重複幀,然後通過檢查幾個像素來檢查它們是否不同。但是你必須確保你不會錯過任何幀。

1

嘗試微秒,它應該工作!

+6

詳細說明。你的回答太寬泛。 – sschrass 2012-10-07 00:24:49

+2

是更具體更多 – jeremy 2012-10-07 00:27:37

24

時間偏移參數以微秒爲單位,而不是毫秒。所以你的時間偏移乘以1000,它應該正常工作。

非常感謝Google在文檔中沒有指定。

0

隨着jCodec library,我能夠有效地獲得所有幀,此代碼來獲取所有視頻的幀:

private class Decoder extends AsyncTask<File, Integer, Integer> { 
    private static final String TAG = "DECODER"; 

    protected Integer doInBackground(File... params) { 
     FileChannelWrapper ch = null; 
     try { 
      ch = NIOUtils.readableFileChannel(params[0]); 
      FrameGrab frameGrab = new FrameGrab(ch); 
      MediaInfo mi = frameGrab.getMediaInfo(); 
      Bitmap frame = Bitmap.createBitmap(mi.getDim().getWidth(), mi.getDim().getHeight(), Bitmap.Config.ARGB_8888); 

      for (int i = 0; !flag; i++) { 

       frameGrab.getFrame(frame); 
       if (frame == null) 
        break; 
       OutputStream os = null; 
       try { 
        os = new BufferedOutputStream(new FileOutputStream(new File(params[0].getParentFile(), String.format("img%08d.jpg", i)))); 
        frame.compress(CompressFormat.JPEG, 90, os); 
       } finally { 
        if (os != null) 
         os.close(); 
       } 
       publishProgress(i); 

      } 
     } catch (IOException e) { 
      Log.e(TAG, "IO", e); 
     } catch (JCodecException e) { 
      Log.e(TAG, "JCodec", e); 
     } finally { 
      NIOUtils.closeQuietly(ch); 
     } 
     return 0; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     progress.setText(String.valueOf(values[0])); 
    } 
} 
2

如果您的視頻爲10s的。如果你想在1秒後拍攝一幀,你將它增加1000000,這意味着1秒後。

我已存儲的圖像視圖的ID在陣列..

int[] ids_of_images = new int[]{R.id.img,R.id.img2,R.id.img3,R.id.img4,R.id.img5}; 
looper =1000000; 

然後

for(int i=0 ;i <10; i++) 
     { 
      ImageView imageView = (ImageView)findViewById(ids_of_images[i]); 

      imageView.setImageBitmap(retriever.getFrameAtTime(looper,MediaMetadataRetriever.OPTION_CLOSEST)); 

      looper +=1000000; 
     } 

我測試..它正在運行。我已經制作了十個ImageView並且像上面一樣讀取了框架

+1

好邏輯。我會試一試。 – 2014-06-23 07:27:04

+0

負面投票的原因是什麼。請解釋一下 – Nepster 2014-08-04 08:19:33

+0

我沒有那樣做。 – 2014-11-26 10:15:43