video完成后从视图中清除video帧

我创build了一个播放video的媒体播放器。 video完成后,video的最后一帧仍然在表面上。 我想从表面移除video帧,因为延迟了一段video的启动时间。

video的stream程是:

现在表面上的video – >表面上的最后一个video帧 – >表面上的另一个video。

但是所需的stream程是:

要求: 表面上的video – >清除表面(黑色) – >表面上的另一个video。

任何人都可以帮助解决这个问题。

谢谢Ishan jain

Solutions Collecting From Web of "video完成后从视图中清除video帧"

基于Fadden的回答和Andreimarinescu的问题,下面是API 16及以下版本:

private void clearSurface(Surface surface) { EGL10 egl = (EGL10) EGLContext.getEGL(); EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); egl.eglInitialize(display, null); int[] attribList = { EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_BLUE_SIZE, 8, EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE, 0, // placeholder for recordable [@-3] EGL10.EGL_NONE }; EGLConfig[] configs = new EGLConfig[1]; int[] numConfigs = new int[1]; egl.eglChooseConfig(display, attribList, configs, configs.length, numConfigs); EGLConfig config = configs[0]; EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, new int[]{ EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }); EGLSurface eglSurface = egl.eglCreateWindowSurface(display, config, surface, new int[]{ EGL14.EGL_NONE }); egl.eglMakeCurrent(display, eglSurface, eglSurface, context); GLES20.glClearColor(0, 0, 0, 1); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); egl.eglSwapBuffers(display, eglSurface); egl.eglDestroySurface(display, eglSurface); egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroyContext(display, context); egl.eglTerminate(display); } 

漂亮的原油,缺乏错误检查,但它适用于我。

你可以用GLES清除它。 您无法使用Canvas绘图命令清除它,因为这将阻止您再次在该曲面上播放电影。

一个例子可以在Grafika的PlayMovieSurfaceActivity类中find。 clearSurface()方法执行此操作:

  EglCore eglCore = new EglCore(); WindowSurface win = new WindowSurface(eglCore, surface, false); win.makeCurrent(); GLES20.glClearColor(0, 0, 0, 0); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); win.swapBuffers(); win.release(); eglCore.release(); 

EglCoreWindowSurface类是WindowSurface的一部分。 关键是它附着在表面,清除,然后从表面分离。 确保video播放器在执行此操作之前释放了表面,否则GLES将无法连接。

如果你想了解为什么附加/分离的东西是必要的,请参阅系统级graphics体系结构文档。

我有一个类似的问题。 就我而言,我正在展示一张完全覆盖video视图的标题卡,其次是video本身。 随后的第一张标题牌和video效果很好。 但是,当任何后续的标题卡被隐藏时,前一个video的最后一帧会在下一个video开始之前闪烁。 我添加了一个信息监听器到我的VideoView,在隐藏标题卡之前听第一帧渲染。 这覆盖了video,直到第一个正确的帧已经渲染。 我希望这有帮助!

 mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(final MediaPlayer mp, final int what, final int extra) { if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { mTitleCardView.setVisibility(View.GONE); return true; } return false; } }); 

我用非常简单的方法解决了这个问题 – 只要设置Surface不可见,直到准备好video。 如果你想黑屏,可以添加一个黑屏视图(curtainView)。

 public void play(String path) { try { status = STATUS_PREPARING; mSurface.setVisibility(View.INVISIBLE); mCurtainView.setVisibility(View.VISIBLE); // simple black view mPlayer = new MediaPlayer(); if(mSurfaceHolder!=null) mPlayer.setDisplay(mSurfaceHolder); mPlayer.setDataSource(path); mPlayer.prepareAsync(); mPlayer.setOnPreparedListener(this); } catch (Exception e) { return; } } ... @Override public void onPrepared(MediaPlayer mp) { mSurface.setVisibility(View.VISIBLE); if(mSurfaceHolder != null){ mPlayer.start(); mCurtainView.setVisibility(View.GONE); status = STATUS_PLAYING; } else { status = STATUS_DATA_PREPARED; } } private final class SurfaceCallback implements Callback { public void surfaceCreated(SurfaceHolder holder) { mSurfaceHolder = holder; mPlayer.setDisplay(holder); if(status==STATUS_DATA_PREPARED){ mPlayer.start(); mCurtainView.setVisibility(View.GONE); status = STATUS_PLAYING; } } public void surfaceDestroyed(SurfaceHolder holder) { mSurfaceHolder = null; } ... } 

我也有同样的问题。 也许帮助别人。 我在这里find解决schemehttps://stackoverflow.com/a/18906637

我有玩家在服务,在片段我有onCompletecallback和video完成后:

 videoHolder.setFormat(PixelFormat.TRANSPARENT); videoHolder.setFormat(PixelFormat.OPAQUE); videoService.setVideoDisplay(videoHolder); 

video播放完成时清除表面(MediaPlayer onCompletioncallback):

  Canvas canvas = surfaceView.getHolder().lockCanvas(); // Clear surface by drawing on it canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR); // option // canvas.drawColor(Color.BLACK); surfaceView.getHolder().unlockCanvasAndPost(canvas); 

另一个选项 (但我现在不记得清楚 )是当onComplition()callback调用时调用MediaPlayer类函数之一:

 MediaPlayer.stop(); // reset to clear ready to reuse state. MediaPlayer.reset(); // release all releted objects and memory MediaPlayer.release() 

其中一个造成清晰的表面视图。 release()您必须再次创build另一个MediaPlayer实例。