android capture video frame

前端 未结 8 1701
名媛妹妹
名媛妹妹 2020-11-29 03:40

I need to get a frame of a video file (it may be on sdcard, cache dir or app dir). I have package android.media in my application and inside I have class MediaMetadataRetrie

相关标签:
8条回答
  • 2020-11-29 04:08

    The exception is thrown also when the File doesn't exist. So before calling setDataSource() you'd better check if new File(url).exists().

    0 讨论(0)
  • 2020-11-29 04:14

    I was getting the same error using the ThumbnailUtils class http://developer.android.com/reference/android/media/ThumbnailUtils.html
    It uses MediaMetadataRetriever under the hood and most of the time you can send it a filepath using this method with no problem:

    public static Bitmap createVideoThumbnail (String filePath, int kind)  
    

    However, on Android 4.0.4, I kept getting the same error @gabi was seeing. Using a file descriptor instead solved the problem and still works for non-4.0.4 devices. I actually ended up subclassing ThumbnailUtils. Here is my subclass method:

     public static Bitmap createVideoThumbnail(FileDescriptor fDescriptor, int kind) 
     {
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(fDescriptor);
            bitmap = retriever.getFrameAtTime(-1);
        } 
        catch (IllegalArgumentException ex) {
            // Assume this is a corrupt video file
            Log.e(LOG_TAG, "Failed to create video thumbnail for file description: " + fDescriptor.toString());
        }
        catch (RuntimeException ex) {
            // Assume this is a corrupt video file.
            Log.e(LOG_TAG, "Failed to create video thumbnail for file description: " + fDescriptor.toString());
        } finally {
            try {
                retriever.release();
            } catch (RuntimeException ex) {
                // Ignore failures while cleaning up.
            }
        }
    
        if (bitmap == null) return null;
    
        if (kind == Images.Thumbnails.MINI_KIND) {
            // Scale down the bitmap if it's too large.
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int max = Math.max(width, height);
            if (max > 512) {
                float scale = 512f / max;
                int w = Math.round(scale * width);
                int h = Math.round(scale * height);
                bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
            }
        } else if (kind == Images.Thumbnails.MICRO_KIND) {
            bitmap = extractThumbnail(bitmap,
                    TARGET_SIZE_MICRO_THUMBNAIL,
                    TARGET_SIZE_MICRO_THUMBNAIL,
                    OPTIONS_RECYCLE_INPUT);
        }
        return bitmap;
    }
    
    0 讨论(0)
  • 2020-11-29 04:17

    I used this code and that is working for me. you can try this one.

    if (Build.VERSION.SDK_INT >= 14) {
                    ffmpegMetaDataRetriever.setDataSource(
                            videoFile.getAbsolutePath(),
                            new HashMap<String, String>());
                } else {
                    ffmpegMetaDataRetriever.setDataSource(videoFile
                            .getAbsolutePath());
                }
    
    0 讨论(0)
  • 2020-11-29 04:17

    Uri's are not very specific. Sometimes they refer to something in a bundle. They often need to be translated to an absolute path form. The other instance in which you used the Uri, it probably was smart enough to check what kind of Uri it was. This case that you have shown appears to be not looking very hard.

    0 讨论(0)
  • 2020-11-29 04:19

    The following works for me:

    public static Bitmap getVideoFrame(FileDescriptor FD) {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            try {
                retriever.setDataSource(FD);
                return retriever.getFrameAtTime();
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            } catch (RuntimeException ex) {
                ex.printStackTrace();
            } finally {
                try {
                    retriever.release();
                } catch (RuntimeException ex) {
                }
            }
            return null;
        }
    

    Also works if you use a path instead of a filedescriptor.

    0 讨论(0)
  • 2020-11-29 04:19

    I have the same mistake on my application. I saw on this site that

    this is an unofficial way of doing it and it will only work in cupcake (and maybe later version). The Android team does not guarantee that libmedia_jni.so, which the java file uses, will be included or have the same interface in future versions.

    http://osdir.com/ml/AndroidDevelopers/2009-06/msg02442.html

    I have updated my phone to GingerBread and it doesn't work anymore.

    0 讨论(0)
提交回复
热议问题