• Android 播放器SurfaceView播放后(前)清屏 Clear video frame from surfaceview on video complete, 播放开始出现上一次播放的残留画面


    Android MediaPlayer某些播放场景下,由于SurfaceView的使用方式的问题,可能遇到 播放开始出现上一次播放的残留画面,为此需要在每次播放开始或结束时,对SurfaceView做清屏clear

    方式一:  注意可能导致的问题 You can't clear it with Canvas draw commands because that will prevent you from playing movies on that surface again.

    1 Paint paint = new Paint();
    2 paint.setColor(0xff000000);
    3 Canvas canvas = surface.lockCanvas(null);
    4 canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
    5 canvas.drawRect(0, 0, 0 + canvas.getWidth(), 0 + canvas.getHeight(), paint);
    6 surface.unlockCanvasAndPost(canvas);

    使用如下这种方式,lockCanvas后清空再unlockCanvasAndPost,会导致后续播放出问题,也就是如果当前要清空的SurfaceView后续要去作为player的输出surface就不能采用这种方式了

    原因:参考 https://stackoverflow.com/questions/24902114/mediaplayer-cannot-render-to-textureview-after-image-render/24914966#24914966

    //You can't do this, due to a limitation of the Android app framework (as of //Android 4.4 at least).
    
    //The SurfaceTexture that underlies the TextureView is a buffer consumer. //The MediaPlayer is one example of a buffer producer, Canvas is another. //Once you attach a producer, you have to detach it before you can attach //a second producer.
    
    //The trouble is that there is no way to detach a software-based (Canvas) //buffer producer. There could be, but isn't. So once you draw with Canvas, //you're stuck. (There's a note to that effect here.)
    
    //You can detach a GLES producer. For example, in one of Grafika's video //player classes you can find a clearSurface() method that clears the //surface to black using GLES. Note the EGL context and window are //created and explicitly released within the scope of the method. You could //expand the method to show an image instead.

    方式二:使用GLES 来清除

    https://stackoverflow.com/questions/25660994/clear-video-frame-from-surfaceview-on-video-complete

    https://github.com/autumnqin/grafika/blob/master/src/com/android/grafika/PlayMovieSurfaceActivity.java

    直接上代码:自己体会哈哈哈

     1 import android.opengl.EGL14;
     2 import android.opengl.EGLConfig;
     3 import android.opengl.EGLContext;
     4 import android.opengl.EGLDisplay;
     5 import android.opengl.EGLExt;
     6 import android.opengl.EGLSurface;
     7 import android.opengl.GLES20;
     8 
     9 //=====
    10 
    11 /**
    12  * Clears the playback surface to black.
    13  */
    14 private void clearSurface(Surface surface) {
    15     EGLDisplay display = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
    16     int[] version = new int[2];
    17     EGL14.eglInitialize(display, version, 0, version, 1);
    18 
    19     int[] attribList = {
    20             EGL14.EGL_RED_SIZE, 8,
    21             EGL14.EGL_GREEN_SIZE, 8,
    22             EGL14.EGL_BLUE_SIZE, 8,
    23             EGL14.EGL_ALPHA_SIZE, 8,
    24             EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
    25             EGL14.EGL_NONE, 0,
    26             EGL14.EGL_NONE
    27     };
    28     EGLConfig[] configs = new EGLConfig[1];
    29     int[] numConfigs = new int[1];
    30     EGL14.eglChooseConfig(display, attribList, 0, configs, 0, configs.length, numConfigs, 0);
    31 
    32     EGLConfig config = configs[0];
    33     EGLContext context = EGL14.eglCreateContext(display, config, EGL14.EGL_NO_CONTEXT, new int[]{
    34             EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
    35             EGL14.EGL_NONE
    36     }, 0);
    37 
    38     EGLSurface eglSurface = EGL14.eglCreateWindowSurface(display, config, surface,
    39             new int[]{
    40                 EGL14.EGL_NONE
    41             }, 0);
    42 
    43     EGL14.eglMakeCurrent(display, eglSurface, eglSurface, context);
    44     GLES20.glClearColor(0, 0, 0, 1);
    45     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    46     EGL14.eglSwapBuffers(display, eglSurface);
    47     EGL14.eglDestroySurface(display, eglSurface);
    48     EGL14.eglMakeCurrent(display, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
    49     EGL14.eglDestroyContext(display, context);
    50     EGL14.eglTerminate(display);
    51 }

    每次播放结束时都销毁SurfaceView 是不会出现上次播放的残留画面的,也就不用考虑清屏了

    心有猛虎,细嗅蔷薇,生活就该无惧无悔..... PS:文章系作者工作学习总结,受作者知识水平的限制,文章难免有错误之处,仅供参考,转载请注明出处:http://www.cnblogs.com/roger-yu/
  • 相关阅读:
    SEO(搜索引擎优化)已死
    C#与Java的详细比较(全)
    回眸·预言:Google媒体,称霸在2014 (转载)& 2015 update
    转载:Google calendar预览
    一个开源的ESB(企业服务总线) Celtix
    未来网虫生活图景
    今年圣诞节google标的意思
    我的生活质量
    Google Reader的午夜维护信息
    SNS网站应该更加自然
  • 原文地址:https://www.cnblogs.com/roger-yu/p/14963069.html
Copyright © 2020-2023  润新知