我试图从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配置的图像
答案 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);
}
}