Android uses mediaplayer and TextureView to achieve seamless video switching
Requirement description
For example, when advertising plays, each video lasts 15 seconds. When switching between videos, the machine with poor performance may have a black screen for a period of time, and the experience is not very good. Next, we need to solve this black screen problem.
Solution
Two surfaceview modes are used. After testing, one mediaplayer cannot be used. Add a layer of ImageView on the mediaplayer. After each playback, obtain the image of the last frame of the video to ImageView. After the video switching is completed, ImageView is hidden. This cycle is OK
practice
1. The method of obtaining video stream pictures. Through mediametadataretriever, it is found that the bitmap obtained by some machines may be empty and cannot be solved. Give up
2. Using TextureView, you can obtain the bitmap of the current frame. It is feasible. The code is pasted below
package com.winson.blog.video;
import android.graphics.Bitmap;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import java.io.IOException;
public class VideoFragment extends Fragment {
public static final String TAG = VideoFragment.class.getSimpleName();
String TEST_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/testmp4.mp4";
int mIndex = 0;
String path1 = TEST_PATH;
String[] paths = new String[]{TEST_PATH,TEST_PATH,TEST_PATH};
boolean destory;
Handler mHandler;
Runnable mPlayRun;
FrameLayout content;
TextureView textureView;
ImageView frameImage;
MediaPlayer mediaPlayer;
Bitmap lastFrameBitmap;
public void updateResources(String[] paths) {
this.paths = paths;
if(mHandler != null && mPlayRun!= null){
mHandler.post(mPlayRun);
}
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
mediaPlayer = new MediaPlayer();
mPlayRun = new Runnable() {
@Override
public void run() {
if (mediaPlayer == null || destory) {
return;
}
mediaPlayer.pause();
mediaPlayer.reset();
try {
String path = paths[mIndex % paths.length];
mIndex++;
mediaPlayer.setDataSource(getActivity(),Uri.parse(path));
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer arg0) {
mediaPlayer.start();
frameImage.setVisibility(View.GONE);
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
frameImage.setVisibility(View.VISIBLE);
Bitmap currentFrameBitmap = textureView.getBitmap();
frameImage.setImageBitmap(currentFrameBitmap);
if (lastFrameBitmap != null) {
lastFrameBitmap.recycle();
}
lastFrameBitmap = currentFrameBitmap;
mHandler.post(mPlayRun);
}
});
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
public void release() {
mHandler.removeCallbacks(mPlayRun);
if (mediaPlayer != null) {
mediaPlayer.pause();
mediaPlayer.release();
}
}
public Bitmap getBitmap() {
return textureView == null ? null : textureView.getBitmap();
}
@Override
public void onDestroy() {
super.onDestroy();
release();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) {
content = new FrameLayout(getActivity());
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT);
lp.gravity = Gravity.LEFT | 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(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface,int width,int height) {
Surface s = new Surface(surface);
mediaPlayer.setSurface(s);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface,int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
return content;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
testPlay();
}
public void testPlay() {
// mediaPlayer.pause();
// mediaPlayer.reset();
//
// try {
// mediaPlayer.setDataSource(getActivity(),Uri.parse(TEST_PATH));
// mediaPlayer.prepare();
// mediaPlayer.start();
// } catch (IOException e) {
// e.printStackTrace();
// }
mHandler.post(mPlayRun);
}
}
Related links, GitHub address
The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.
