为什么MediaPlayer.seekTo()和onSurfaceTextureUpdated()在循环内部无效?

时间:2017-04-13 07:16:39

标签: android android-mediaplayer video-capture android-bitmap textureview

我试图从textureview上的MediaPlayer视频获取每个100ms帧的屏幕截图(位图),并且位图的颜色配置应为ARGB_8888

我认为每次调用mediaplayer.seekTo(timeframe)时都会调用onSurfaceTextureUpdated,我可以在那里获取位图。

所以我在活动中创建了一个按钮,其中textureview和应用于活动中的click方法,如下所示:

public void onViewClicked() {

    float begin = starttimeframe;  // starting point of analysis in timeframe
    float end = endtimeframe;      // ending point of analysis in timeframe

    int f = round(begin);
    status = 2;
    while (f < round(end)) {
        mediaplayer.seekTo(f);
        currenttimeframe = f;
        f += 100;  // forward to next frame (100ms interval)
    }

    Toast.makeText(Extractor2Activity.this, "Done!", Toast.LENGTH_SHORT).show();
}

当surfacetexture像这样更新时,添加了捕获textureview的代码:

    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
            Bitmap bitmap = Bitmap.createBitmap(tvWidth, tvHeight, Bitmap.Config.ARGB_8888);
            textureView.getBitmap(bitmap);

            File file = new File(Environment.getExternalStorageDirectory().toString(), "capture" + current timeframe + ".jpg");

            OutputStream fout = null;
            try {
                fout = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
                fout.flush();
                fout.close();
                MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
            } catch (IOException e) {
                e.printStackTrace();
            }
    }

问题是,textureview上的视频没有改变,onSurfaceTextureUpdated在迭代过程中没有被调用。

只有在显示Toast消息后,

onSurfaceTextureUpdated()才会被调用。

我想必须有一个解决方案,但我不擅长Android编程,也不知道如何解决这个问题。

如何使循环中的seekTo和onSurfaceTextureUpdated正常工作?

我尝试了什么

使用MediaMetadataRetriever.getFrameAtTime,可以在循环内捕获所需的帧,但默认情况下获取的位图的颜色配置为RGB565,并且不知道如何从getFrameAtTime获取ARGB_8888配置的图像

1 个答案:

答案 0 :(得分:0)

在这种情况下,一个小的递归解决方案将很方便。您可以致电寻求等待回拨获取您的位图并进一步寻求。直到你到达流的末尾。

public void onViewClicked() {

    viewClicked = true;

    seekTo(round(starttimeframe));
}

public void seekTo(int time) {
    if (time < round(endtimeframe)) {
        mediaplayer.seekTo(time);
        currenttimeframe = time;
    }
    else {
        viewClicked = false;
    }
}

public void onSurfaceTextureUpdated(SurfaceTexture surface) {
   if (viewClicked) {
        Bitmap bitmap = Bitmap.createBitmap(tvWidth, tvHeight, Bitmap.Config.ARGB_8888);
        textureView.getBitmap(bitmap);

        File file = new File(Environment.getExternalStorageDirectory().toString(), "capture" + current timeframe + ".jpg");

        OutputStream fout = null;
        try {
            fout = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
            fout.flush();
            fout.close();
            MediaStore.Images.Media.insertImage(this.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
        } catch (IOException e) {
            e.printStackTrace();
        }
        seekTo(mediaPlayer.getCurrentPosition() + 100);
   }
}