2016-07-25 1 views
0

J'essaie d'extraire plusieurs images d'une vidéo, mais elle génère parfois une exception fatale. Ce que je suis en train de faire ici, c'est que je vais chercher le cadre pendant un certain temps et que je tourne si l'orientation est portrait. La raison de l'échec peut être un problème de mémoire. S'il vous plaît suggérer où je me trompe.Erreur lors de la récupération de plusieurs images d'une vidéo via FFmpegMediaMetadataRetriever

private ArrayList<Bitmap> getFrames() { 

    ArrayList<Bitmap> bmFrames = new ArrayList<>(); 
    Bitmap bmp = null; 
    Bitmap orientedBitmap = null; 

    try { 
     int baseTime = Integer.parseInt(model.getDuration()); 
     baseTime = baseTime/11 * 1000; 

     baseTimeArray = new int[11]; 
     for (int i = 0; i < 11; i++) { 
      baseTimeArray[i] = baseTime * (i); 

      Log.d("TAG", "fetching frame from " + baseTimeArray[i]); 

      try { 
       FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever(); 
       mmr.setDataSource(new File(sourceFilePath).getAbsolutePath()); 
       bmp = getBitmapViaFFMPEG(baseTimeArray[i], mmr); 

       if (rotationMetaData != null) { 
        Matrix matrix = new Matrix(); 

        matrix.postRotate(90); 

        //Bitmap scaledBitmap = Bitmap.createScaledBitmap(bmp,50,50,true); 
        if (bmp != null) 
         orientedBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); 
        else 
         Log.d(TAG,"returned bitmap was null"); 
       } 
       //Log.d("TAG", "rotation: " + rotation); 
       mmr.release(); 
      } catch (IllegalArgumentException ex) { 
       ex.printStackTrace(); 
      } catch (RuntimeException ex) { 
       ex.printStackTrace(); 
      } catch (Exception ex) { 
       ex.printStackTrace(); 
      } 

      if (rotationMetaData != null) 
       bmFrames.add(orientedBitmap); 
      else 
       bmFrames.add(bmp); 


     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return bmFrames; 
} 

Erreur journal

enter image description here

+0

Salut. Avez-vous résolu votre problème? Si vous pouvez vous s'il vous plaît partager des solutions? –

+0

Je vais partager la solution lundi. –

+0

ok Merci! @Lalit –

Répondre

0

Je sais qu'il est trop tard pour poster une réponse mais il peut aider quelqu'un. Ci-dessous classe peut être utilisé pour afficher les trames vidéo

public class TimeLineView extends View { 

private Uri mVideoUri; 
private int mHeightView; 
private LongSparseArray<Bitmap> mBitmapList = null; 

public TimeLineView(@NonNull Context context, AttributeSet attrs) { 
    this(context, attrs, 0); 
} 

public TimeLineView(@NonNull Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    init(); 
} 

private void init() { 
    mHeightView = getContext().getResources().getDimensionPixelOffset(R.dimen.frames_video_height); 
} 

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    final int minW = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth(); 
    int w = resolveSizeAndState(minW, widthMeasureSpec, 1); 

    final int minH = getPaddingBottom() + getPaddingTop() + mHeightView; 
    int h = resolveSizeAndState(minH, heightMeasureSpec, 1); 

    setMeasuredDimension(w, h); 
} 

@Override 
protected void onSizeChanged(final int w, int h, final int oldW, int oldH) { 
    super.onSizeChanged(w, h, oldW, oldH); 

    if (w != oldW) { 
     getBitmap(w); 
    } 
} 

private void getBitmap(final int viewWidth) { 
    BackgroundExecutor.execute(new BackgroundExecutor.Task("", 0L, "") { 
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
            @Override 
            public void execute() { 
             try { 
              LongSparseArray<Bitmap> thumbnailList = new LongSparseArray<>(); 

              MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); 
              mediaMetadataRetriever.setDataSource(getContext(), mVideoUri); 

              // Retrieve media data 
              long videoLengthInMs = Integer.parseInt(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) * 1000; 

              // Set thumbnail properties (Thumbs are squares) 
              final int thumbWidth = mHeightView; 
              final int thumbHeight = mHeightView; 

              int numThumbs = (int) Math.ceil(((float) viewWidth)/thumbWidth); 

              final long interval = videoLengthInMs/numThumbs; 

              for (int i = 0; i < numThumbs; ++i) { 
               Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(i * interval, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); 
               // TODO: bitmap might be null here, hence throwing NullPointerException. You were right 
               try { 
                bitmap = Bitmap.createScaledBitmap(bitmap, thumbWidth, thumbHeight, false); 
               } catch (Exception e) { 
                e.printStackTrace(); 
               } 
               thumbnailList.put(i, bitmap); 
              } 

              mediaMetadataRetriever.release(); 
              returnBitmaps(thumbnailList); 
             } catch (final Throwable e) { 
              Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e); 
             } 
            } 
           } 
    ); 
} 

private void returnBitmaps(final LongSparseArray<Bitmap> thumbnailList) { 
    UiThreadExecutor.runTask("", new Runnable() { 
       @Override 
       public void run() { 
        mBitmapList = thumbnailList; 
        invalidate(); 
       } 
      } 
      , 0L); 
} 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
@Override 
protected void onDraw(@NonNull Canvas canvas) { 
    super.onDraw(canvas); 

    if (mBitmapList != null) { 
     canvas.save(); 
     int x = 0; 

     for (int i = 0; i < mBitmapList.size(); i++) { 
      Bitmap bitmap = mBitmapList.get(i); 

      if (bitmap != null) { 
       canvas.drawBitmap(bitmap, x, 0, null); 
       x = x + bitmap.getWidth(); 
      } 
     } 
    } 
} 

public void setVideo(@NonNull Uri data) { 
    mVideoUri = data; 
} 
} 

Et utiliser comme ça

mTimeLineView = (TimeLineView) view.findViewById(R.id.timelineview); 
mTimeLineView.setVideo(Uri.parse("video_path"));