Android MediaPlayer使用

状态图


Android MediaPlayer使用_第1张图片
mediastatu.jpg

需要注意的是和camera的释放类似,调用release()后没法直接进入idle状态,所以mediaplayer的状态是有问题的,要置null

自己的一个栗子:

package yunhen.yunjia.aiservice.camera;

import android.content.res.AssetFileDescriptor;
import android.graphics.Matrix;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;

import java.io.IOException;
import java.lang.ref.WeakReference;

import yunhen.yunjia.aiservice.utils.Logs;
import yunhen.yunjia.aiservice.utils.SPConfig;

public class MediaPlayUtils {
    private static final String TAG = MediaPlayUtils.class.getSimpleName();
    private MediaPlayer mMediaPlayer;
    private static MediaPlayUtils m;
    private WeakReference weak ;

    private String filaHelloName = "1.mp4";
    private String filaSpeakNameMirror = "2Left.mp4";
    private String filaSpeakName = "3Right.mp4";
    private AssetFileDescriptor afdHello;
    private AssetFileDescriptor afd;
    private AssetFileDescriptor afdMirror;
    private boolean isMirror = true;
    MediaPlayer.OnCompletionListener mCompletionListener;

    public static MediaPlayUtils instance() {
        synchronized (MediaPlayUtils.class) {
            if (null == m) {
                synchronized (MediaPlayUtils.class) {
                    m = new MediaPlayUtils();
                }
            }
        }
        return m;
    }
    private MediaPlayUtils() {

    }

    /**
     * 当前播放的视频
     * 

{@link MediaPlayUtils#currStatu}

* @return */ public Statu currStatu() { return currStatu; } public void init(TextureView surfaceView) { if (null == mMediaPlayer) { mMediaPlayer = new MediaPlayer(); } else { } weak = new WeakReference<>(surfaceView); // pathDef = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath() // + File.separator+ filaHelloName; // pathSpeak = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath() // + File.separator + filaSpeakName; try { afdHello = weak.get().getContext().getAssets().openFd(filaHelloName); afd = weak.get().getContext().getAssets().openFd(filaSpeakName); afdMirror = weak.get().getContext().getAssets().openFd(filaSpeakNameMirror); } catch (IOException e) { e.printStackTrace(); } } public void setCompletionListener(MediaPlayer.OnCompletionListener completionListener) { mCompletionListener = completionListener; } public void play(Statu statu) { currStatu = statu; if (null == mMediaPlayer) { mMediaPlayer = new MediaPlayer(); } else if (isPlaying()){ pause(); // stop(); // release(); } resetDate(statu); Logs.instance().e(TAG,"weak.get() is null "+ (weak.get() == null)); Logs.instance().e(TAG,"weak.getSurfaceTexture is null "+ (weak.get().getSurfaceTexture() == null)); Surface s = new Surface(weak.get().getSurfaceTexture()); mMediaPlayer.setSurface(s);//设置video影片以surfaceviewholder播放 mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.setVolume(0f, 0f); mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mediaPlayer) { updateSizeCenterCrop(); mediaPlayer.start(); } }); mMediaPlayer.setOnCompletionListener(mCompletionListener); mMediaPlayer.prepareAsync(); } public enum Statu{ /** * 问好嘴动循环 */ hello_speaking_loop, /** * 问好嘴不动循环 */ hellow_not_speak_loop, /** * 向上抬手 */ tai_shou_one, /** * 抬手不动循环 */ tai_shou_loop, /** * 向下放手 */ fang_shou_one; } public void reset() { if (null != mMediaPlayer) { try { mMediaPlayer.reset(); } catch (IllegalStateException e) { e.printStackTrace(); } } } public void pause() { if (null != mMediaPlayer) { try { mMediaPlayer.pause(); } catch (IllegalStateException e) { e.printStackTrace(); } } } public boolean isPlaying() { if (null != mMediaPlayer) { try { return mMediaPlayer.isPlaying(); } catch (IllegalStateException e) { e.printStackTrace(); } } return false; } Statu currStatu; public void resetDate(Statu statu) { reset(); try { if (Statu.hello_speaking_loop == statu) { String path = SPConfig.instance(weak.get().getContext()) .getVideoPathHellow(); if (null == path || "".equals(path)) { mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength()); } else { mMediaPlayer.setDataSource(path); } } else if (Statu.hellow_not_speak_loop == statu) { String path = SPConfig.instance(weak.get().getContext()) .getVideoPathHellowLoop(); if (null == path || "".equals(path)) { mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength()); } else { mMediaPlayer.setDataSource(path); } } else if (Statu.tai_shou_one == statu) { String path = ""; if (isMirror) { path = SPConfig.instance(weak.get().getContext()) .getVideoPathLeftTaiShou(); if (null == path || "".equals(path)) { mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength()); } else { mMediaPlayer.setDataSource(path); } }else { path = SPConfig.instance(weak.get().getContext()) .getVideoPathRightTaiShou(); if (null == path || "".equals(path)) { mMediaPlayer.setDataSource(afdHello.getFileDescriptor(),afdHello.getStartOffset(),afdHello.getLength()); } else { mMediaPlayer.setDataSource(path); } } } else if (Statu.tai_shou_loop == statu) { // mMediaPlayer.setDataSource(pathSpeak); if (isMirror) {//镜像模式下向左 String pathLeft = SPConfig.instance(weak.get().getContext()).getVideoPathLeftTaiShouLoop(); if (null == pathLeft || "".equals(pathLeft)) { mMediaPlayer.setDataSource(afdMirror.getFileDescriptor(),afdMirror.getStartOffset(),afdMirror.getLength()); } else { mMediaPlayer.setDataSource(pathLeft); } } else { String pathRight = SPConfig.instance(weak.get().getContext()).getVideoPathRightTaiShouLoop(); if (null == pathRight || "".equals(pathRight)) { mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); } else { mMediaPlayer.setDataSource(pathRight); } } } else if (Statu.fang_shou_one == statu) { if (isMirror) {//镜像模式下向左 String pathLeft = SPConfig.instance(weak.get().getContext()).getVideoPathLeftFangShou(); if (null == pathLeft || "".equals(pathLeft)) { mMediaPlayer.setDataSource(afdMirror.getFileDescriptor(),afdMirror.getStartOffset(),afdMirror.getLength()); } else { mMediaPlayer.setDataSource(pathLeft); } } else { String pathRight = SPConfig.instance(weak.get().getContext()).getVideoPathRightFangShou(); if (null == pathRight || "".equals(pathRight)) { mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength()); } else { mMediaPlayer.setDataSource(pathRight); } } } } catch (IOException e) { e.printStackTrace(); Log.e(TAG,"IOException "+e.getMessage()); } } public void stop() { if (null != mMediaPlayer) { try { mMediaPlayer.stop(); } catch (IllegalStateException e) { e.printStackTrace(); } } } public void release() { if (null != mMediaPlayer) { try { mMediaPlayer.release(); } catch (IllegalStateException e) { e.printStackTrace(); } mMediaPlayer = null; } } public void destroy() { stop(); release(); } public void setMirror(boolean mirror) { this.isMirror = mirror; } //重新计算video的显示位置,让其全部显示并据中 public void updateSizeCenter(){ int mVideoWidth = mMediaPlayer.getVideoWidth(); int mVideoHeight = mMediaPlayer.getVideoHeight(); float sx = (float) weak.get().getWidth() / (float) mVideoWidth; float sy = (float) weak.get().getHeight() / (float) mVideoHeight; Matrix matrix = new Matrix(); //第1步:把视频区移动到View区,使两者中心点重合. matrix.preTranslate((weak.get().getWidth() - mVideoWidth) / 2, (weak.get().getHeight() - mVideoHeight) / 2); //第2步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来. matrix.preScale(mVideoWidth / (float) weak.get().getWidth(), mVideoHeight / (float) weak.get().getHeight()); //第3步,等比例放大或缩小,直到视频区的一边和View一边相等.如果另一边和view的一边不相等,则留下空隙 if (sx >= sy){ matrix.postScale(sy, sy, weak.get().getWidth() / 2, weak.get().getHeight() / 2); }else{ matrix.postScale(sx, sx, weak.get().getWidth() / 2, weak.get().getHeight() / 2); } weak.get().setTransform(matrix); weak.get().postInvalidate(); } //重新计算video的显示位置,裁剪后全屏显示 public void updateSizeCenterCrop(){ int mVideoWidth = mMediaPlayer.getVideoWidth(); int mVideoHeight = mMediaPlayer.getVideoHeight(); float sx = (float) weak.get().getWidth() / (float) mVideoWidth; float sy = (float) weak.get().getHeight() / (float) mVideoHeight; Matrix matrix = new Matrix(); float maxScale = Math.max(sx, sy); //第1步:把视频区移动到View区,使两者中心点重合. matrix.preTranslate((weak.get().getWidth() - mVideoWidth) / 2, (weak.get().getHeight() - mVideoHeight) / 2); //第2步:因为默认视频是fitXY的形式显示的,所以首先要缩放还原回来. matrix.preScale(mVideoWidth / (float)weak.get(). getWidth(), mVideoHeight / (float) weak.get().getHeight()); //第3步,等比例放大或缩小,直到视频区的一边超过View一边, 另一边与View的另一边相等. 因为超过的部分超出了View的范围,所以是不会显示的,相当于裁剪了. matrix.postScale(maxScale, maxScale, weak.get().getWidth() / 2, weak.get().getHeight() / 2);//后两个参数坐标是以整个View的坐标系以参考的 weak.get().setTransform(matrix); weak.get().postInvalidate(); } }

你可能感兴趣的:(Android MediaPlayer使用)