6

我想知道是否可以从 Android 中正在运行的视频中提取帧?我需要定期提取帧并将它们发送以进行进一步处理。

有人能为我找到答案吗?

谢谢,

阿比

4

3 回答 3

14

您可以使用MediaMetadataRetriever

我目前正在使用它,通过调用:

mediaMetadataRetriever.getFrameAtTime(timeUs,MediaMetadataRetriever.OPTION_CLOSEST);

我得到了框架的bitmap.

请注意,它仅受支持,因为:API Level 10.

于 2011-12-05T15:06:12.310 回答
5

您可以使用以下代码:

String SrcPath="/sdcard/Pictures/Video Task/";

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();

mediaMetadataRetriever.setDataSource(SrcPath);
String METADATA_KEY_DURATION = mediaMetadataRetriever
        .extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);

Bitmap bmpOriginal = mediaMetadataRetriever.getFrameAtTime(0);
int bmpVideoHeight = bmpOriginal.getHeight();
int bmpVideoWidth = bmpOriginal.getWidth();

Log.d("LOGTAG", "bmpVideoWidth:'" + bmpVideoWidth + "'  bmpVideoHeight:'" + bmpVideoHeight + "'");

byte [] lastSavedByteArray = new byte[0];

float factor = 0.20f;
int scaleWidth = (int) ( (float) bmpVideoWidth * factor );
int scaleHeight = (int) ( (float) bmpVideoHeight * factor );
int max = (int) Long.parseLong(METADATA_KEY_DURATION);
for ( int index = 0 ; index < max ; index++ )
{
    bmpOriginal = mediaMetadataRetriever.getFrameAtTime(index * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
    bmpVideoHeight = bmpOriginal == null ? -1 : bmpOriginal.getHeight();
    bmpVideoWidth = bmpOriginal == null ? -1 : bmpOriginal.getWidth();
    int byteCount = bmpOriginal.getWidth() * bmpOriginal.getHeight() * 4;
    ByteBuffer tmpByteBuffer = ByteBuffer.allocate(byteCount);
    bmpOriginal.copyPixelsToBuffer(tmpByteBuffer);
    byte [] tmpByteArray = tmpByteBuffer.array();

    if ( !Arrays.equals(tmpByteArray, lastSavedByteArray))
    {
        int quality = 100;
        String mediaStorageDir="/sdcard/Pictures/Video Task/";
        File outputFile = new File(mediaStorageDir , "IMG_" + ( index + 1 )
                + "_" + max + "_quality_" + quality + "_w" + scaleWidth + "_h" + scaleHeight + ".png");
        Log.e("Output Files::>>",""+outputFile);
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(outputFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Bitmap bmpScaledSize = Bitmap.createScaledBitmap(bmpOriginal, scaleWidth, scaleHeight, false);

        bmpScaledSize.compress(Bitmap.CompressFormat.PNG, quality, outputStream);

        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        lastSavedByteArray = tmpByteArray;
    }
}
capturedImageView.setImageBitmap(bmpOriginal);
mediaMetadataRetriever.release();
于 2016-08-25T12:33:34.317 回答
0

假设您使用的是 MediaPlayer,我相信无法提取视频(或音频)帧。媒体播放器运行它自己的进程 [mediaplayerservice]。而且,只有这个进程才能访问这些帧。如果其他进程可以访问原始帧,则认为这是一种安全违规。例如,假设您正在播放一些受版权保护的内容,那么不应允许提供对这些帧的访问。

于 2010-03-06T23:46:28.527 回答