2012-12-17 59 views
1

我現在的Android應用程序主要功能是通過內置的攝像頭從記錄的視頻拉幀(10fps的)。無論何時用戶選擇視頻,我都會調用我的類「FrameCollector」,它會循環播放視頻並將幀拉出並將它們存儲到Bitmap的ArrayList中。有了這個工作做好的天數有我想,我是在正確的軌道上,但現在我得到了可怕的「java.lang.OutofMemoryError」安卓:位圖解碼java.lang.OutofMemoryError錯誤

我的代碼如下:

這裏它被設置MediaMetaDataRetriever從將其從主類

public class FrameCollector { 

MediaMetadataRetriever _mmr; 

double _fps; 
double _duration; 
long _counter = 0; 
long _incrementer; 

public FrameCollector(String path, Context context) 
{ 
    try 
    { 
    _mmr = new MediaMetadataRetriever(); 
    _mmr.setDataSource(path); 

    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); 
    String fpsString = pref.getString("prefFPS", "10"); 
    _fps = Double.parseDouble(fpsString); 
    _incrementer = (long) (1000000/_fps); 

    String stringDuration = _mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 
    _duration = Double.parseDouble(stringDuration) * 1000; 
    } 
    catch(Exception ex) 
    { 
     ex.printStackTrace(); 
    } 
} 

然後將下面的方法在該時間加入幀爲位圖並添加位圖以一個ArrayList傳遞的視頻路徑選擇每秒10幀位圖 「bitFrames」

public ArrayList<Bitmap> getBitmaps() 
{ 
    try 
    { 
     ArrayList<Bitmap> bitFrames = new ArrayList<Bitmap>(); 


     Bitmap b = _mmr.getFrameAtTime(_counter); 

     while (_counter < _duration && b != null) 
     { 
      bitFrames.add(b); 
      _counter += _incrementer; 
      b = _mmr.getFrameAtTime(_counter); 
     } 
     return bitFrames; 
    } 
    catch (Exception ex) 
    { 
     ex.printStackTrace(); 
     return null; 
    } 
} 

我想我的問題在於,在這種方法。我相信我需要之前,我把它們存儲到ArrayList中的位圖解碼,但我不能確定如何爲

Bitmap b = BitmapFactory.decode____(_mmr.getFrameAtTime(_counter)); 
-- Whether it be decodeStream, decodeResource, decodeFile all bring errors. 

任何幫助,將不勝感激

非常感謝,

+0

您應該檢查您保存在該陣列中的每個位圖的大小。由於您的應用程序沒有多少可用的Android內存,因此如果您存儲太多大的位圖,則會導致內存不足。 – Aballano

回答

0

決不店位圖一個ArrayList,除非位圖的數量非常小。位圖佔用大量內存。

我沒有在視頻錄製工作過,但我會建議你嘗試獲得一個本地編解碼器庫像ffmpeg來爲你做它。但是,如果您必須自己抓取相框,我建議將它們存儲在相機內存中的固定大小的緩衝區中,並有一個後臺線程,它可以從緩衝區中提取位圖並將其並行存儲到磁盤中。

0

這不是很好的存儲位圖的ArrayList在RAM中。

無論如何,如果你需要超過默認堆大小來存儲位圖在ArrayList中,你可以試試這個破解。 http://habrahabr.ru/post/139717/ 它在俄羅斯,但我猜的代碼是很清楚的瞭解。