Android 为什么MediaPlayer.seekTo()和onSurfaceTextureUpdated()在循环中不起作用?
我试图从textureview上的MediaPlayer视频中获取每100ms帧的屏幕截图(位图),位图的颜色配置应为ARGB_8888 我想每次我调用mediaplayer.seekTo(timeframe)时都会调用onSurfaceTextureUpdated,我可以在其中获取位图 因此,我在活动中创建了一个按钮,其中textureview并在活动中应用了单击方法,如下所示:Android 为什么MediaPlayer.seekTo()和onSurfaceTextureUpdated()在循环中不起作用?,android,android-mediaplayer,video-capture,android-bitmap,textureview,Android,Android Mediaplayer,Video Capture,Android Bitmap,Textureview,我试图从textureview上的MediaPlayer视频中获取每100ms帧的屏幕截图(位图),位图的颜色配置应为ARGB_8888 我想每次我调用mediaplayer.seekTo(timeframe)时都会调用onSurfaceTextureUpdated,我可以在其中获取位图 因此,我在活动中创建了一个按钮,其中textureview并在活动中应用了单击方法,如下所示: public void onViewClicked() { float begin = starttim
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();
}
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上的视频未更改,并且在迭代期间未调用OnSurfaceTextureUpdate
onSurfaceTextureUpdated()仅在显示Toast消息后调用一次
我想一定有解决办法,但我不擅长android编程,也不知道如何解决这个问题
如何使seekTo和OnSurfaceTextureUpdate在循环时正常工作
我所尝试的:
使用MediaMetadataRetriever.getFrameAtTime,可以在循环中捕获所需的帧,但默认情况下获取的位图的颜色配置为RGB565,并且不知道如何从getFrameAtTime获取ARGB_8888 config的图像。在这种情况下,一个小小的递归解决方案会很方便。您可以调用seek,等待回调,获取位图并进一步搜索。直到你到达小溪的尽头
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);
}
}
public void onViewClicked(){
viewClicked=true;
seekTo(圆形(起始帧));
}
公共无效seekTo(整数时间){
if(时间<整轮(结束时间段)){
mediaplayer.seekTo(时间);
currenttimeframe=时间;
}
否则{
viewClicked=false;
}
}
已更新SurfaceTexture上的公共空间(SurfaceTexture surface){
如果(单击查看){
位图Bitmap=Bitmap.createBitmap(tvWidth、tvHeight、Bitmap.Config.ARGB_8888);
获取位图(位图);
File File=新文件(Environment.getExternalStorageDirectory().toString(),“capture”+当前时间段+“.jpg”);
OutputStream fout=null;
试一试{
fout=新文件输出流(文件);
压缩(bitmap.CompressFormat.JPEG,100,fout);
fout.flush();
fout.close();
MediaStore.Images.Media.insertImage(this.getContentResolver()、file.getAbsolutePath()、file.getName()、file.getName());
}捕获(IOE异常){
e、 printStackTrace();
}
seekTo(mediaPlayer.getCurrentPosition()+100);
}
}
等待帧缓冲,然后在每次调用seekTo()
后进行渲染。@Abbas,感谢您的快速评论!你能给我一些示例代码吗?谢谢@Abbas!现在我知道如何解决这个问题了!