为什么 MediaPlayer.seekTo() 和 onSurfaceTextureUpdated() 在循环内不起作用?
Why MediaPlayer.seekTo() and onSurfaceTextureUpdated() not working inside loop?
我正在尝试从 textureview 上的 MediaPlayer 视频中获取每 100 毫秒帧的屏幕截图(位图),位图的颜色配置应该是 ARGB_8888
我认为每次调用 mediaplayer.seekTo(timeframe) 时都会调用 onSurfaceTextureUpdated,我可以在其中获取位图。
所以我在 activity 中创建了一个按钮,其中 textureview 并在 activity 中应用了点击方法,如下所示:
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。
onSurfaceTextureUpdated() 仅在显示 Toast 消息后调用一次。
我想一定有解决办法,但我不擅长 android 编程,不知道如何解决这个问题。
如何让seekTo和onSurfaceTextureUpdated在循环时正常工作?
我试过的:
使用 MediaMetadataRetriever.getFrameAtTime ,可以在循环内捕获所需的帧,但获取的位图的颜色配置默认为 RGB565,并且不知道如何从 getFrameAtTime 获取 ARGB_8888 配置的图像。
在这种情况下,一个小的递归解决方案会很方便。您可以调用搜索等待回调获取您的位图并进一步搜索。直到您到达流的末尾。
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);
}
}
我正在尝试从 textureview 上的 MediaPlayer 视频中获取每 100 毫秒帧的屏幕截图(位图),位图的颜色配置应该是 ARGB_8888
我认为每次调用 mediaplayer.seekTo(timeframe) 时都会调用 onSurfaceTextureUpdated,我可以在其中获取位图。
所以我在 activity 中创建了一个按钮,其中 textureview 并在 activity 中应用了点击方法,如下所示:
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。
onSurfaceTextureUpdated() 仅在显示 Toast 消息后调用一次。
我想一定有解决办法,但我不擅长 android 编程,不知道如何解决这个问题。
如何让seekTo和onSurfaceTextureUpdated在循环时正常工作?
我试过的:
使用 MediaMetadataRetriever.getFrameAtTime ,可以在循环内捕获所需的帧,但获取的位图的颜色配置默认为 RGB565,并且不知道如何从 getFrameAtTime 获取 ARGB_8888 配置的图像。
在这种情况下,一个小的递归解决方案会很方便。您可以调用搜索等待回调获取您的位图并进一步搜索。直到您到达流的末尾。
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);
}
}