Android使用媒体播放器和TextureView实现视频无缝切换

  

<强>需求描述

  

比如广告播放,每个视频15秒,视频之间切换的时候,性能不太好的机器可能会黑屏一段时间,体验不太好,接下来我们就是要解决这个黑屏问题。

  

<>强解决方案

  

使用两个surfaceView方式,经过测试不行
  使用一个媒体播放器,在媒体播放器上面加一层ImageView,每次播放完成后,获取视频的最后一帧的图像给ImageView,视频切换完成,ImageView隐藏,如此往复循环,可行

  

<>强实践

  

1。获取视频流图片方式,通过MediaMetadataRetriever,测试发现,部分机器获取的位图可能为空,无法解决,放弃

  

2。使用TextureView方式,可以获取当前帧的位图,可行,下面贴代码

        包com.winson.blog.video;      进口android.graphics.Bitmap;   进口android.graphics.SurfaceTexture;   进口android.media.MediaPlayer;   进口android.net.Uri;   进口android.os.Bundle;   进口android.os.Environment;   进口handler;   进口android.support.annotation.Nullable;   进口android.support.v4.app.Fragment;   进口android.util.Log;   进口android.view.Gravity;   进口android.view.LayoutInflater;   进口android.view.Surface;   进口android.view.TextureView;   进口android.view.View;   进口android.view.ViewGroup;   进口android.widget.FrameLayout;   进口android.widget.ImageView;      进口java.io.IOException;      公开课VideoFragment延伸片段{      公共静态最终字符串标签=VideoFragment.class.getSimpleName ();      字符串TEST_PATH=Environment.getExternalStorageDirectory () .getAbsolutePath () +“/testmp4.mp4”;   int mIndex=0;   字符串path2=TEST_PATH;   String[]路径=new String [] {TEST_PATH、TEST_PATH TEST_PATH, TEST_PATH, TEST_PATH, TEST_PATH};      布尔欺;   处理程序mHandler;   可运行mPlayRun;   FrameLayout内容;   TextureView TextureView;   ImageView frameImage;   媒体播放器媒体播放器;   位图lastFrameBitmap;      公共空间updateResources (String[]路径){   这一点。路径=路径;   如果(mHandler !=零,,mPlayRun !=null) {   mHandler.post (mPlayRun);   }   }      @Override   公共空间onCreate (@Nullable包savedInstanceState) {   super.onCreate (savedInstanceState);      mHandler=new处理程序();   媒体播放器=新媒体播放器();   mPlayRun=new Runnable () {      @Override   公共空间run () {      如果(媒体播放器==null | |欺){   返回;      }   mediaPlayer.pause ();   mediaPlayer.reset ();      尝试{   字符串路径=路径(mIndex % paths.length);   mIndex + +;      mediaPlayer.setDataSource (getActivity (), Uri.parse(路径));   媒体播放器。setOnPreparedListener(新MediaPlayer.OnPreparedListener () {      @Override   公共空间onPrepared(媒体播放器arg0) {   mediaPlayer.start ();   frameImage.setVisibility (View.GONE);   }   });   媒体播放器。setOnCompletionListener(新MediaPlayer.OnCompletionListener () {   @Override   公共空间onCompletion(媒体播放器mp) {   frameImage.setVisibility (View.VISIBLE);   位图currentFrameBitmap=textureView.getBitmap ();   frameImage.setImageBitmap (currentFrameBitmap);   如果(lastFrameBitmap !=null) {   lastFrameBitmap.recycle ();   }   lastFrameBitmap=currentFrameBitmap;      mHandler.post (mPlayRun);   }   });   mediaPlayer.prepareAsync ();      }捕捉(异常e) {   e.printStackTrace ();   }   }      };   }         公共空间释放(){   mHandler.removeCallbacks (mPlayRun);   如果(媒体播放器!=null) {   mediaPlayer.pause ();   mediaPlayer.release ();   }   }      公共位图getBitmap () {   返回textureView==null & # 63;空:textureView.getBitmap ();   }      @Override   公共空间onDestroy () {   super.onDestroy ();   release ();   }      @Nullable   @Override   公众视线onCreateView (LayoutInflater增压泵,@Nullable ViewGroup容器,@Nullable包savedInstanceState) {   内容=new FrameLayout (getActivity ());      FrameLayout。LayoutParams lp=new FrameLayout.LayoutParams (FrameLayout.LayoutParams。MATCH_PARENT FrameLayout.LayoutParams.MATCH_PARENT);   lp。重力=重力。左| Gravity.TOP;      textureView=new textureView (getActivity ());   textureView.setLayoutParams (lp);   content.addView (textureView);      frameImage=new ImageView (getActivity ());   frameImage.setScaleType (ImageView.ScaleType.FIT_XY);   frameImage.setLayoutParams (lp);   content.addView (frameImage);      textureView。setSurfaceTextureListener(新TextureView.SurfaceTextureListener () {   @Override   公共空间onSurfaceTextureAvailable (int SurfaceTexture表面,int宽度、高度){   表面s=新表面(表面);   mediaPlayer.setSurface(年代);      }      @Override   公共空间onSurfaceTextureSizeChanged (int SurfaceTexture表面,int宽度、高度){   }      @Override   公共布尔onSurfaceTextureDestroyed (SurfaceTexture表面){   返回错误;   }      @Override   公共空间onSurfaceTextureUpdated (SurfaceTexture表面){   }   });      返回内容;   }      @Override   公共空间onActivityCreated (@Nullable包savedInstanceState) {   super.onActivityCreated (savedInstanceState);      testPlay ();   }      公共空间testPlay () {//mediaPlayer.pause ();//mediaPlayer.reset ();////{试//mediaPlayer.setDataSource (getActivity (), Uri.parse (TEST_PATH));//mediaPlayer.prepare ();//mediaPlayer.start ();//}捕捉(IOException e) {//e.printStackTrace ();//}      mHandler.post (mPlayRun);   }         }

Android使用媒体播放器和TextureView实现视频无缝切换