我创建了一个在表面视图上播放视频的媒体播放器。完成视频后,视频的最后一帧仍然在表面上。我想从表面移除视频帧,因为经过一段时间后,另一个视频开始播放。
视频流程为:
NOW :表面视频 - >表面上的最后一个视频帧 - >表面上的另一个视频。
但所需的流程是:
必需: 表面视频 - >透明表面(黑色) - >表面上的另一个视频。
任何人都可以帮助解决这个问题。
由于 Ishan jain
答案 0 :(得分:9)
根据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);
}
非常粗糙,缺乏错误检查,但它适用于我。
答案 1 :(得分:5)
您可以使用GLES清除它。您无法使用Canvas
绘图命令清除它,因为这会阻止您再次在该表面上播放电影。
可以在Grafika的PlayMovieSurfaceActivity课程中找到一个示例。 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();
EglCore
和WindowSurface
课程是Grafika的一部分。关键是它附着在表面上,清晰,然后从表面脱离。在执行此操作之前,请确保视频播放器已释放曲面,否则GLES将无法附加。
如果您想了解为什么需要附加/分离内容,请参阅system-level graphics architecture doc。
答案 2 :(得分:3)
我有类似的问题。在我的情况下,我正在显示一个完全覆盖视频视图的标题卡,然后是视频本身。随后的第一张标题卡和视频播放得很好。但是,当隐藏任何后续标题卡时,上一个视频的最后一帧将在下一个视频开始之前闪烁。我在我的VideoView中添加了一个信息监听器,以便在隐藏标题卡之前监听第一帧渲染。这将覆盖视频,直到呈现第一个正确的帧。我希望这有帮助!
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;
}
});
答案 3 :(得分:2)
我有一个示例问题,我在播放器发布后使用这两行来修复它。
surfaceViewHolder.setFormat(PixelFormat.TRANSPARENT); surfaceViewHolder.setFormat(PixelFormat.OPAQUE);
答案 4 :(得分:1)
我有同样的问题。也许帮助别人。我在这里找到了解决方案https://stackoverflow.com/a/18906637
我有玩家在服务中,在片段中我有onComplete回调并且在视频结束后:
videoHolder.setFormat(PixelFormat.TRANSPARENT);
videoHolder.setFormat(PixelFormat.OPAQUE);
videoService.setVideoDisplay(videoHolder);
答案 5 :(得分:0)
我用非常简单的方法解决了这个问题 - 只需将Surface设置为不可见,直到准备好视频为止。 如果你想要黑屏,你可以添加黑屏视图(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;
}
...
}
答案 6 :(得分:-1)
完成视频播放后清除表面(MediaPlayer onCompletion回调):
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()回调调用时,调用MediaPlayer类函数之一:
MediaPlayer.stop();
// reset to clear ready to reuse state.
MediaPlayer.reset();
// release all releted objects and memory
MediaPlayer.release()
其中一个会导致清晰的表面视图。在release()
之后,您必须再次创建另一个MediaPlayer
实例。