Android SurfaceView+MediaPlayer 本地视频播放器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Coder_Hcy/article/details/73379141

功能情景:

       1.播放视频文件

       2.上一首,下一首

       3.卡拉ok功能(只是单纯的用系统mediaplayer切换声道,资源必须要含有三种声道的mkv文件(2,1,1))

           也就是特定资源才有用,虽然是播客对我来说只是月度总结,但我不想误导别人

       4.播放模式(顺序,随机,循环)

效果图


功能的实现:

       1.伴唱功能:(这里是mkv文件切换声道),伴唱转AUDIO,原唱转VIDEO。当然前提是先获得mkv文件的所有声道。

我在视频准备的时候获取所有声道,然后判断是否有这个声道我再转。

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        //视频播放
        mMediaPlayer.start();
        //获取视屏的长度
        tv_video.setText(ProjectUtils.formatTime(mMediaPlayer.getDuration()));
        // mIsStopped = false;
        if (iv_play != null) {
            iv_play.setSelected(false);
        }

        //获取所有的音轨
        trackInfo = mMediaPlayer.getTrackInfo();

    }

       //伴唱与原唱
        RxView.clicks(iv_sing_state).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                int pos = fileName.lastIndexOf('.');
                if (pos != -1) {
                    String indexName = fileName.substring(pos);
                    if (indexName.equalsIgnoreCase(".mkv")) {
                        if (trackInfo != null) {
                            Logger.i("fileName" + fileName);
                            mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO);

                        }
                        if (!iv_sing_state.isSelected()){
                            boolean flag=false;
                            for (int i = 0; i < trackInfo.length; i++) {
                                if (trackInfo[i].getTrackType()== MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO){
                                    flag=true;
                                }
                            }
                            if (flag){
                                //切换音轨(伴唱)
                                if (mMediaPlayer!=null){
                                    mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO);
                                }
                            }
                            iv_sing_state.setSelected(true);
                            
                        }else{
                            boolean flag=false;
                            for (int i = 0; i < trackInfo.length; i++) {
                                if (trackInfo[i].getTrackType()== MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO ){
                                    flag=true;
                                }
                            }

                            if (flag){
                                //原唱
                                if (mMediaPlayer!=null){
                                    mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO);
                                }
                            }
                            iv_sing_state.setSelected(false);

                        }
                        
                    }else{

                        Toast.makeText(VideoPalyActivity.this,"不是卡拉OK文件,不具备伴唱功能",Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });

2.播放模式

          随机模式的算法:当切换到随机模式时,先移除掉当前播放的数据,然后播放下一首的时候,从剩余的随机一条,然后再移除,再随机。知道没有数据,没有数据的时候再从新复制总数据。这里注意的是,可移除的数据集合必然是克隆原先数据集合的,而不是简单的复制(注意java的数据存储)

        //播放模式的切换
        RxView.clicks(iv_state).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {

                if (playMode == 1) {
                    playMode = 2;//随机模式
                    Toast.makeText(VideoPalyActivity.this, "随机模式", Toast.LENGTH_SHORT).show();
                    iv_state.setImageResource(R.drawable.iv_state_suiji_press);
                } else if (playMode == 2) {
                    playMode = 3;//循环模式
                    Toast.makeText(VideoPalyActivity.this, "循环模式", Toast.LENGTH_SHORT).show();

                    iv_state.setImageResource(R.drawable.iv_state_xunhuan_press);
                } else if (playMode == 3) {
                    playMode = 1;//顺序模式
                    Toast.makeText(VideoPalyActivity.this, "顺序模式", Toast.LENGTH_SHORT).show();
                    iv_state.setImageResource(R.drawable.iv_state_shunxu_press);
                }

            }
        });


播放模式要有效果必然要在播放完成下写算法


 @Override
    public void onCompletion(MediaPlayer mp) {
        Toast.makeText(VideoPalyActivity.this, "播放完毕", Toast.LENGTH_SHORT).show();
        seekBar.setProgress(100);
        RxUtils.unsubscribe(seekBarSubscription);
        if (iv_play != null) {
            iv_play.setSelected(true);
        }
        
        if (playMode == 1) {
            Logger.i(TAG, "播放完毕进入顺序模式");
            if (currentPos < data.size()) {
                currentPos++;
                Logger.i("随机::666" + "currentPos=" + currentPos);

                if (currentPos<data.size()){
                    mVideoPath = data.get(currentPos).getAbsolutePath();
                    Logger.i("随机::666" + "mVideoPath=" + mVideoPath);
                    fileName = data.get(currentPos).getName();
                }

            }

        } else if (playMode == 2) {
            Logger.i(TAG, "播放完毕进入随机模式");

            if (copydata.size() != 0) {
                int pos = -1;
                for (int i = 0; i < copydata.size(); i++) {
                    if (copydata.get(i).getAbsolutePath().equals(mVideoPath)) {
                        pos = i;
                    }
                }

                if (pos != -1 && pos < copydata.size()) {
                    copydata.remove(pos);
                }

                int max = copydata.size();
                int min = 0;
                Random random = new Random();
                int rNum = random.nextInt(max) % (max - min + 1) + min;
                mVideoPath = copydata.get(rNum).getAbsolutePath();
                fileName = copydata.get(rNum).getName();

                // mVideoPath = copydata.get(rNum).getFilepath();
                for (int i = 0; i < data.size(); i++) {
                    if (data.get(i).getAbsolutePath().equals(copydata.get(rNum).getAbsolutePath())) {
                        currentPos = i;
                    }
                }
                Logger.i("随机::555" + "currentPos=" + currentPos);
                mVideoPath = data.get(currentPos).getAbsolutePath();
                fileName = data.get(currentPos).getName();
                Logger.i("随机::555" + "mVideoPath=" + mVideoPath);
                copydata.remove(rNum);

            } else {
                copydata = (ArrayList<File>) data.clone();
            }


        } else if (playMode == 3) {
            Logger.i(TAG, "播放完毕进入循环模式");
            Logger.i("随机::777" + "currentPos=" + currentPos);
            Logger.i("随机::777" + "mVideoPath=" + mVideoPath);

        }
        prepare();
    }



附件:完整代码:

package com.wyt.hcy.leyuanindustryproject;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.jakewharton.rxbinding.view.RxView;
import com.orhanobut.logger.Logger;
import com.wyt.db.bean.BrowseLog;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import database.DbUtils;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import utils.ActivityUtils;
import utils.ProjectUtils;
import utils.RxUtils;

/**
 * 屏保不执行任何activity的生命周期
 */


public class VideoPalyActivity extends BaseActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener, MediaPlayer.OnBufferingUpdateListener {

    private ImageView iv_back;
    private ImageView iv_battery;
    private SurfaceView mSurfaceView;
    private MediaPlayer mMediaPlayer;
    private static final String TAG = "VideoPalyActivity";
    private String mVideoPath;
    private TextView tv_video;
    private ImageView iv_play;
    private ImageView iv_previous;
    private ImageView iv_next;
    private static int currentPos = 0;
    private ArrayList<File> data;
    private ArrayList<File> copydata;
    private ImageView iv_pb;
    private int playMode = 1;//默认为顺序模式
    private ImageView iv_state;
    private SeekBar seekBar;
    private Subscription seekBarSubscription, yinGUISubscription, nextMediaSubscription;
    private DbUtils dbUtils;
    private String module_name;
    private String fileName;
    private RelativeLayout rl_title, rl_bottom;
    private MyHandler myHandler;
    private ImageView iv_tf;
    private ImageView iv_sing_state;
    private MediaPlayer.TrackInfo[] trackInfo;
    private ImageView iv_wifi;
    private ActivityUtils activityUtils;
    private SurfaceHolder surfaceHolder;

    private RelativeLayout rl_root;

    private boolean threadFlag = false;
    private BroadcastReceiver receiver;
    private static int currentPosition = 0;


    // private boolean isChangeSingState=false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Logger.i("ViewState:onCreate");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //透明导航栏
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
        setContentView(R.layout.activity_video_paly);


        ProjectUtils.stopBg();

        initUI();
        batteryState(iv_battery);
        tFCardListener(iv_tf);
        wifiListener(iv_wifi, VideoPalyActivity.this);


        IntentFilter intentFilter = new IntentFilter();

        intentFilter.addAction("com.yinghengke.homekey");

        if (receiver == null) {
            receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (intent.getAction().equals("com.yinghengke.homekey")) {
                        release();
                        if (activityUtils != null) {
                            activityUtils.removeAllActivity();
                        }
                    }
                }
            };
        }

        registerReceiver(receiver, intentFilter);


        exchangeZhuti(rl_root);
        activityUtils = ActivityUtils.getIntance();

        activityUtils.putActivity("VideoPalyActivity", VideoPalyActivity.this);

        Bundle bundle = getIntent().getBundleExtra("bundle_data");

        currentPos = bundle.getInt("pos", 0);

        module_name = bundle.getString("module_name", "none");

        myHandler = new MyHandler(this);

        //Logger.i("数据库ok:" + module_name);


        data = (ArrayList<File>) bundle.getSerializable("data");
        copydata = new ArrayList<File>();


        dbUtils = DbUtils.getInstance(VideoPalyActivity.this);

        copydata = (ArrayList<File>) data.clone();

        // Logger.i("随机::" + "data=" + data.toString());

        mVideoPath = data.get(currentPos).getAbsolutePath();
        fileName = data.get(currentPos).getName();
        if (mRunnable != null) {
            threadFlag = true;
            myHandler.postDelayed(mRunnable, 5000);
        }
    }


    private void exchangeZhuti(RelativeLayout ll_root) {

        SharedPreferences sp = getSharedPreferences("setting", Context.MODE_PRIVATE);
        String theme = sp.getString("theme", "bgone");

        if (ll_root != null) {
            switch (theme) {
                case "bgone":
                    ll_root.setBackgroundResource(R.mipmap.bgone);
                    break;
                case "bgtwo":
                    ll_root.setBackgroundResource(R.mipmap.bgtwo);
                    break;
                case "bgthree":
                    ll_root.setBackgroundResource(R.mipmap.bgthree);
                    break;
            }
        }


    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Logger.i("ViewState:onRestart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Logger.i("ViewState:onResume");

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        //Logger.i("按钮效果::" + keyCode);
        //Toast.makeText(VideoPalyActivity.this, "" + keyCode, Toast.LENGTH_SHORT).show();

        switch (keyCode) {
            case KeyEvent.KEYCODE_MEDIA_NEXT:
                //下一首
                Toast.makeText(VideoPalyActivity.this, "下一首", Toast.LENGTH_SHORT).show();
                if (playMode == 2) {
                    if (copydata.size() == 0) {
                        copydata = (ArrayList<File>) data.clone();
                    }
                    int max = copydata.size();
                    int min = 0;
                    Random random = new Random();

                    // do{
                    int rNum = random.nextInt(max) % (max - min + 1) + min;
                    // }while (rNum>=copydata.size());

                    //Logger.i("随机数::" + rNum);
                    // mVideoPath = copydata.get(rNum).getFilepath();
                    for (int i = 0; i < data.size(); i++) {
                        if (data.get(i).getAbsolutePath().equals(copydata.get(rNum).getAbsolutePath())) {
                            currentPos = i;
                        }
                    }

                    // Logger.i("随机::" + "currentPos=" + currentPos);
                    mVideoPath = data.get(currentPos).getAbsolutePath();
                    // Logger.i("随机::" + "mVideoPath=" + mVideoPath);
                    fileName = data.get(currentPos).getName();
                    copydata.remove(rNum);

                    prepare();
                } else {
                    // Logger.i("PPL" + "currentPos=" + currentPos);
                    ++currentPos;
                    if (currentPos < data.size()) {


                        // Logger.i("随机::2" + "currentPos=" + currentPos);
                        mVideoPath = data.get(currentPos).getAbsolutePath();
                        fileName = data.get(currentPos).getName();
                        //  Logger.i("随机::2" + "mVideoPath=" + mVideoPath);
                        prepare();

                    } else {
                        currentPos = data.size() - 1;
                        Toast.makeText(VideoPalyActivity.this, "已经到底了", Toast.LENGTH_SHORT).show();
                    }

                }
                break;
            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
                //上一首
                Toast.makeText(VideoPalyActivity.this, "上一首", Toast.LENGTH_SHORT).show();

                if (playMode == 2) {
                    if (copydata.size() == 0) {
                        copydata = (ArrayList<File>) data.clone();
                    }
                    int max = copydata.size();
                    int min = 0;
                    Random random = new Random();
                    int rNum = random.nextInt(max) % (max - min + 1) + min;
                    // Logger.i("随机数::" + rNum);
                    //mVideoPath = copydata.get(rNum).getFilepath();

                    // int pos=-1;

                    for (int i = 0; i < data.size(); i++) {
                        if (data.get(i).getAbsolutePath().equals(copydata.get(rNum).getAbsolutePath())) {
                            currentPos = i;
                        }
                    }
                    //  Logger.i("随机::4" + "currentPos=" + currentPos);

                    mVideoPath = data.get(currentPos).getAbsolutePath();
                    //  Logger.i("随机::4" + "mVideoPath=" + mVideoPath);
                    fileName = data.get(currentPos).getName();
                    copydata.remove(rNum);
                    prepare();
                } else {
                    currentPos--;
                    if (currentPos >= 0) {
                        //  Logger.i("随机::3" + "currentPos=" + currentPos);
                        mVideoPath = data.get(currentPos).getAbsolutePath();
                        // Logger.i("随机::3" + "mVideoPath=" + mVideoPath);
                        fileName = data.get(currentPos).getName();
                        prepare();
                    } else {
                        currentPos = 0;
                        Toast.makeText(VideoPalyActivity.this, "已经到底了", Toast.LENGTH_SHORT).show();
                    }

                }

                break;
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
                //播放暂停
                if (iv_play != null) {
                    if (iv_play.isSelected()) {
                        if (mMediaPlayer != null) {
                            mMediaPlayer.start();
                            iv_play.setSelected(false);
                        }
                    } else {
                        if (mMediaPlayer != null) {
                            mMediaPlayer.pause();
                            //Toast.makeText(VideoPalyActivity.this,"DDD111",Toast.LENGTH_SHORT).show();
                            iv_play.setSelected(true);
                        }
                    }
                }
                break;
            case KeyEvent.KEYCODE_HOME:


                break;
        }

        return super.onKeyDown(keyCode, event);

    }

    private Runnable mRunnable = new Runnable() {
        @Override
        public void run() {
            if (threadFlag) {
                if (rl_bottom.getVisibility() == View.VISIBLE) {
                    rl_bottom.setVisibility(View.GONE);
                    if (rl_title.getVisibility() == View.VISIBLE) {
                        rl_title.setVisibility(View.GONE);
                    }
                }
            }
        }
    };


    private class MyHandler extends Handler {
        private WeakReference<Activity> weakReference;

        public MyHandler(Activity activity) {
            weakReference = new WeakReference<Activity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (weakReference.get() != null) {
                if (msg.what == 1000) {
                    //showOrHideController();
                }

                if (msg.what == 1001) {
                    rl_title.setVisibility(View.GONE);
                }
                if (msg.what == 1002) {
                    rl_bottom.setVisibility(View.GONE);
                }
            }
        }
    }


    @Override
    protected void onStop() {
        super.onStop();
        Logger.i("ViewState:onStop");
    }

    /**
     * 蓝牙进入OnPause状态
     */
    @Override
    protected void onPause() {
        super.onPause();
        Logger.i("ViewState:onPause");

       /* if (iv_sing_state.isSelected()) {
            iv_sing_state.setSelected(false);
        }
        try {
            if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
               // mMediaPlayer.pause();
                Toast.makeText(VideoPalyActivity.this,"DDD222",Toast.LENGTH_SHORT).show();

                isPlay = false;
            }
        } catch (IllegalStateException e) {
            mMediaPlayer = null;
            // mp = new MediaPlayer();
        }*/

    }

    private void initUI() {
        rl_root = (RelativeLayout) findViewById(R.id.rl_root);


        iv_sing_state = (ImageView) findViewById(R.id.iv_sing_state);

        iv_wifi = (ImageView) findViewById(R.id.iv_wifi);


        //伴唱与原唱
        RxView.clicks(iv_sing_state).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                int pos = fileName.lastIndexOf('.');
                if (pos != -1) {
                    String indexName = fileName.substring(pos);
                    if (indexName.equalsIgnoreCase(".mkv")) {
                        if (trackInfo != null) {
                            //  Logger.i("fileName" + fileName);
                            mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO);

                        }
                        if (!iv_sing_state.isSelected()) {
                            boolean flag = false;
                            for (int i = 0; i < trackInfo.length; i++) {
                                if (trackInfo[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
                                    flag = true;
                                }
                            }
                            if (flag) {
                                //切换音轨(伴唱)
                                //isChangeSingState=true;
                                if (mMediaPlayer != null) {
                                    mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO);
                                }
                            }
                            iv_sing_state.setSelected(true);

                        } else {
                            boolean flag = false;
                            for (int i = 0; i < trackInfo.length; i++) {
                                if (trackInfo[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
                                    flag = true;
                                }
                            }

                            if (flag) {
                                //原唱
                                // isChangeSingState=false;
                                if (mMediaPlayer != null) {
                                    mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO);
                                }
                            }
                            iv_sing_state.setSelected(false);

                        }

                    } else {

                        Toast.makeText(VideoPalyActivity.this, "不是卡拉OK文件,不具备伴唱功能", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });

        rl_bottom = (RelativeLayout) findViewById(R.id.rl_bottom);

        rl_title = (RelativeLayout) findViewById(R.id.rl_title);


        iv_tf = (ImageView) findViewById(R.id.iv_tf);

        iv_back = (ImageView) findViewById(R.id.iv_back);
        iv_state = (ImageView) findViewById(R.id.iv_state);
        seekBar = (SeekBar) findViewById(R.id.seekbar);


        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser && mMediaPlayer != null) {
                    currentPosition = (int) (progress * mMediaPlayer.getDuration() / 100);
                    mMediaPlayer.seekTo(currentPosition);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                threadFlag = false;

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                if (mRunnable != null) {
                    threadFlag = true;
                    myHandler.postDelayed(mRunnable, 5000);
                }
            }
        });


        rl_bottom.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Logger.i("TTYY::");
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (mRunnable != null) {
                        myHandler.removeCallbacks(mRunnable);
                        threadFlag = true;
                        myHandler.postDelayed(mRunnable, 5000);
                    }
                } else {

                    threadFlag = false;
                }
                return true;
            }
        });

        //播放模式的切换
        RxView.clicks(iv_state).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {

                if (playMode == 1) {
                    playMode = 2;//随机模式
                    Toast.makeText(VideoPalyActivity.this, "随机模式", Toast.LENGTH_SHORT).show();
                    iv_state.setImageResource(R.drawable.iv_state_suiji_press);
                } else if (playMode == 2) {
                    playMode = 3;//循环模式
                    Toast.makeText(VideoPalyActivity.this, "循环模式", Toast.LENGTH_SHORT).show();

                    iv_state.setImageResource(R.drawable.iv_state_xunhuan_press);
                } else if (playMode == 3) {
                    playMode = 1;//顺序模式
                    Toast.makeText(VideoPalyActivity.this, "顺序模式", Toast.LENGTH_SHORT).show();
                    iv_state.setImageResource(R.drawable.iv_state_shunxu_press);
                }

            }
        });
        iv_battery = (ImageView) findViewById(R.id.iv_battery);
        tv_video = (TextView) findViewById(R.id.tv_video);

       /* RxView.clicks(iv_back).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {


            }
        });*/


        iv_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
        /*        threadFlag = false;
                if (surfaceHolder != null) {

                    surfaceHolder.getSurface().release();
                }

                release();*/
                finish();

            }
        });


        iv_previous = (ImageView) findViewById(R.id.iv_previous);
        iv_next = (ImageView) findViewById(R.id.iv_next);

        RxView.clicks(iv_next).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                currentPosition = 0;
                if (playMode == 2) {
                    if (copydata.size() == 0) {
                        copydata = (ArrayList<File>) data.clone();
                    }
                    int max = copydata.size();
                    int min = 0;
                    Random random = new Random();

                    // do{
                    int rNum = random.nextInt(max) % (max - min + 1) + min;
                    // }while (rNum>=copydata.size());

                    // Logger.i("随机数::" + rNum);
                    // mVideoPath = copydata.get(rNum).getFilepath();
                    for (int i = 0; i < data.size(); i++) {
                        if (data.get(i).getAbsolutePath().equals(copydata.get(rNum).getAbsolutePath())) {
                            currentPos = i;
                        }
                    }

                    //     Logger.i("随机::" + "currentPos=" + currentPos);
                    mVideoPath = data.get(currentPos).getAbsolutePath();
                    //   Logger.i("随机::" + "mVideoPath=" + mVideoPath);
                    fileName = data.get(currentPos).getName();
                    copydata.remove(rNum);

                    prepare();
                } else {
                    Logger.i("PPL" + "currentPos=" + currentPos);
                    ++currentPos;
                    if (currentPos < data.size()) {


                        Logger.i("随机::2" + "currentPos=" + currentPos);
                        mVideoPath = data.get(currentPos).getAbsolutePath();
                        fileName = data.get(currentPos).getName();
                        Logger.i("随机::2" + "mVideoPath=" + mVideoPath);
                        prepare();

                    } else {
                        currentPos = data.size() - 1;
                        Toast.makeText(VideoPalyActivity.this, "已经到底了", Toast.LENGTH_SHORT).show();
                    }

                }


            }
        });

        RxView.clicks(iv_previous).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {

                currentPosition = 0;
                if (playMode == 2) {
                    if (copydata.size() == 0) {
                        copydata = (ArrayList<File>) data.clone();
                    }
                    int max = copydata.size();
                    int min = 0;
                    Random random = new Random();
                    int rNum = random.nextInt(max) % (max - min + 1) + min;
                    // Logger.i("随机数::" + rNum);
                    //mVideoPath = copydata.get(rNum).getFilepath();

                    // int pos=-1;

                    for (int i = 0; i < data.size(); i++) {
                        if (data.get(i).getAbsolutePath().equals(copydata.get(rNum).getAbsolutePath())) {
                            currentPos = i;
                        }
                    }
                    //  Logger.i("随机::4" + "currentPos=" + currentPos);

                    mVideoPath = data.get(currentPos).getAbsolutePath();
                    // Logger.i("随机::4" + "mVideoPath=" + mVideoPath);
                    fileName = data.get(currentPos).getName();
                    copydata.remove(rNum);
                    prepare();
                } else {
                    currentPos--;
                    if (currentPos >= 0) {

                        //   Logger.i("随机::3" + "currentPos=" + currentPos);
                        mVideoPath = data.get(currentPos).getAbsolutePath();
                        //   Logger.i("随机::3" + "mVideoPath=" + mVideoPath);
                        fileName = data.get(currentPos).getName();
                        prepare();
                    } else {
                        currentPos = 0;
                        Toast.makeText(VideoPalyActivity.this, "已经到底了", Toast.LENGTH_SHORT).show();
                    }

                }

            }
        });

        mSurfaceView = (SurfaceView) findViewById(R.id.sv);

//        mSurfaceView.setZOrderOnTop(false);
//        mSurfaceView.setZOrderMediaOverlay(false);


        surfaceHolder = mSurfaceView.getHolder();

        surfaceHolder.addCallback(this);


        RxView.clicks(mSurfaceView).throttleFirst(500, TimeUnit.MILLISECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {
                Logger.i("TTYY22::");


                if (rl_title.getVisibility() == View.GONE) {

                    rl_title.setVisibility(View.VISIBLE);

                    rl_bottom.setVisibility(View.VISIBLE);

                    myHandler.removeCallbacks(mRunnable);

                    myHandler.postDelayed(mRunnable, 5000);
                } else {
                    myHandler.removeCallbacks(mRunnable);
                    rl_title.setVisibility(View.GONE);
                    rl_bottom.setVisibility(View.GONE);
                }
            }
        });


        iv_play = (ImageView) findViewById(R.id.iv_play);

        iv_pb = (ImageView) findViewById(R.id.iv_pb);

        RxView.clicks(iv_play).throttleFirst(2, TimeUnit.SECONDS).subscribe(new Action1<Void>() {
            @Override
            public void call(Void aVoid) {

                if (iv_play.isSelected()) {
                    if (mMediaPlayer != null) {
                        mMediaPlayer.start();
                        iv_play.setSelected(false);
                    }
                } else {

                    if (mMediaPlayer != null) {
                        mMediaPlayer.pause();
                        //Toast.makeText(VideoPalyActivity.this,"DDD333",Toast.LENGTH_SHORT).show();

                        iv_play.setSelected(true);
                    }
                }

            }
        });
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        Logger.i("SurfaceViewState:surfaceCreated");


    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Logger.i("SurfaceViewState:surfaceChanged");
     /*   if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) {
            Logger.i("ViewState:onResume重播"+currentPosition);
            //
           // mMediaPlayer.start();
            mMediaPlayer.seekTo(currentPosition);

        } else if (mMediaPlayer == null) {
            prepare();
        }*/
        prepare();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // releaseWithoutStop();
        Logger.i("SurfaceViewState:surfaceDestroyed");

        if (iv_sing_state.isSelected()) {
            iv_sing_state.setSelected(false);
        }
        try {
            if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
                 mMediaPlayer.pause();
                //Toast.makeText(VideoPalyActivity.this,"DDD222",Toast.LENGTH_SHORT).show();

                isPlay = false;
            }
        } catch (IllegalStateException e) {
            mMediaPlayer = null;
            // mp = new MediaPlayer();
        }

        //surfaceHolder.removeCallback(this);
    }


    private void prepare() {
        Logger.i("播放器ViewState::prepare");

        if (mMediaPlayer != null) {
            release();
        }


        //Logger.i(TAG + "播放内容::" + mVideoPath);
        try {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnPreparedListener(this);
            // mMediaPlayer.setOnVideoSizeChangedListener(this);
            mMediaPlayer.setOnCompletionListener(this);
            mMediaPlayer.setOnErrorListener(this);
            mMediaPlayer.setOnInfoListener(this);
            mMediaPlayer.setOnBufferingUpdateListener(this);
            mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
            mMediaPlayer.setDataSource(mVideoPath);
            mMediaPlayer.setDisplay(mSurfaceView.getHolder());
            mMediaPlayer.prepareAsync();
        } catch (UnsatisfiedLinkError e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {

        Logger.i("播放器ViewState:onPrepared");
        //视频播放
        isPlay = true;
        mMediaPlayer.start();
        if (currentPosition != 0) {
            mediaPlayer.seekTo(currentPosition);
        }
        //获取视屏的长度
        tv_video.setText(ProjectUtils.formatTime(mMediaPlayer.getDuration()));
        // mIsStopped = false;
        if (iv_play != null) {
            iv_play.setSelected(false);
        }


        RxUtils.unsubscribe(yinGUISubscription);
        yinGUISubscription = Observable.just(fileName).subscribeOn(Schedulers.io()).subscribe(new Subscriber<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String fileNames) {
                //获取所有的音轨
                try {
                    int pos = fileNames.lastIndexOf('.');
                    if (pos != -1) {
                        String indexName = fileNames.substring(pos);
                        if (indexName.equalsIgnoreCase(".mkv")) {
                            trackInfo = mMediaPlayer.getTrackInfo();
                            /*if (isChangeSingState) {
                                if (mMediaPlayer != null) {
                                    mMediaPlayer.selectTrack(MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO);
                                }
                            }*/
                        }
                    }
                } catch (RuntimeException ex) {
                    Toast.makeText(VideoPalyActivity.this, "音轨获取异常", Toast.LENGTH_SHORT).show();
                }
            }
        });


    }


    private boolean isPlay = true;

    @Override
    public void onCompletion(MediaPlayer mp) {
        Logger.i("播放器ViewState:onCompletion");
        if (isPlay) {
            Toast.makeText(VideoPalyActivity.this, "播放完毕", Toast.LENGTH_SHORT).show();
            seekBar.setProgress(100);
            RxUtils.unsubscribe(seekBarSubscription);
            if (iv_play != null) {
                iv_play.setSelected(true);
            }


            RxUtils.unsubscribe(nextMediaSubscription);
            nextMediaSubscription = Observable.just("").subscribeOn(Schedulers.io()).subscribe(new Subscriber<String>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(String s) {
                    if (playMode == 1) {
                        //Logger.i(TAG, "播放完毕进入顺序模式");
                        if (currentPos < data.size()) {
                            currentPos++;
                            // Logger.i("随机::666" + "currentPos=" + currentPos);
                            if (currentPos < data.size()) {
                                mVideoPath = data.get(currentPos).getAbsolutePath();
                                //   Logger.i("随机::666" + "mVideoPath=" + mVideoPath);
                                fileName = data.get(currentPos).getName();
                            }
                        }

                    } else if (playMode == 2) {
                        //  Logger.i(TAG, "播放完毕进入随机模式");
                        if (copydata.size() != 0) {
                            int pos = -1;
                            for (int i = 0; i < copydata.size(); i++) {
                                if (copydata.get(i).getAbsolutePath().equals(mVideoPath)) {
                                    pos = i;
                                }
                            }
                            if (pos != -1 && pos < copydata.size()) {
                                copydata.remove(pos);
                            }
                            int max = copydata.size();
                            int min = 0;
                            Random random = new Random();
                            int rNum = random.nextInt(max) % (max - min + 1) + min;
                            mVideoPath = copydata.get(rNum).getAbsolutePath();
                            fileName = copydata.get(rNum).getName();
                            // mVideoPath = copydata.get(rNum).getFilepath();
                            for (int i = 0; i < data.size(); i++) {
                                if (data.get(i).getAbsolutePath().equals(copydata.get(rNum).getAbsolutePath())) {
                                    currentPos = i;
                                }
                            }
                            //Logger.i("随机::555" + "currentPos=" + currentPos);
                            if (currentPos < data.size()) {
                                mVideoPath = data.get(currentPos).getAbsolutePath();
                                fileName = data.get(currentPos).getName();
                                // Logger.i("随机::555" + "mVideoPath=" + mVideoPath);
                                copydata.remove(rNum);
                            }
                        } else {
                            copydata = (ArrayList<File>) data.clone();
                        }
                    } else if (playMode == 3) {
                        //   Logger.i(TAG, "播放完毕进入循环模式");
                        // Logger.i("随机::777" + "currentPos=" + currentPos);
                        //  Logger.i("随机::777" + "mVideoPath=" + mVideoPath);

                    }
                    currentPosition = 0;
                    prepare();
                }
            });


        }

    }



  /*  @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {

        release();

        return true;
    }*/


    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Logger.i("播放器ViewState:onError");
        Logger.i(TAG + "播放错误:" + what + "?" + extra + "?" + mVideoPath);
        isPlay = false;

        if (!iv_play.isSelected()) {
            iv_play.setSelected(true);
            prepare();
            // release();
        }
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Logger.i("ViewState:onDestroy");
        release();
        RxUtils.unsubscribe(seekBarSubscription);
        RxUtils.unsubscribe(yinGUISubscription);
        RxUtils.unsubscribe(nextMediaSubscription);
        if (receiver != null) {
            unregisterReceiver(receiver);
        }
    }


    public void releaseWithoutStop() {
        if (mMediaPlayer != null) {
            mMediaPlayer.setDisplay(null);
        }
    }

    public void release() {
        try {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.reset();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        } catch (IllegalStateException e) {
            mMediaPlayer = null;
        }

    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {

        Log.i(TAG, "OnInfo, what = " + what + ", extra = " + extra);
        switch (what) {
            case MediaPlayer.MEDIA_INFO_BUFFERING_START:
                iv_pb.setVisibility(View.VISIBLE);
                break;
            case MediaPlayer.MEDIA_INFO_BUFFERING_END:
            case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                iv_pb.setVisibility(View.GONE);
               /* HashMap<String, String> meta = mMediaPlayer.getMetadata();
                Log.i(TAG, "meta: " + meta.toString());*/


                BrowseLog browseLog = new BrowseLog(module_name, fileName, mVideoPath, System.currentTimeMillis() + "");

                //  Logger.i("数据库插入:" + "module_name:" + module_name);

                dbUtils.insertBrowseLog(browseLog);

                seekBarSubscription = RxUtils.countUpTime().subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        if (mMediaPlayer != null) {
                            long currentPosition = mMediaPlayer.getCurrentPosition();

                            int progress = (int) ((currentPosition / (float) mMediaPlayer
                                    .getDuration()) * 100);
                            //  Logger.i(TAG + "视频播放进度:" + progress);
                            seekBar.setProgress(progress);
                        }
                    }
                });
                break;

            default:
                break;
        }
        return true;
    }


    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        Log.d(TAG, "onBufferingUpdate: " + percent + "%");
    }


}





布局文件:



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.wyt.hcy.leyuanindustryproject.VideoPalyActivity">


    <SurfaceView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <RelativeLayout
        android:id="@+id/rl_title"
        android:layout_width="match_parent"
        android:layout_height="98dp">
        <!--系统电池 wifi 返回-->
        <include layout="@layout/layout_taskbar"></include>

    </RelativeLayout>


    <!--LoadingView-->
    <ImageView
        android:id="@+id/iv_pb"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_centerInParent="true"
        android:src="@drawable/progress_anim" />


    <!--视频播放工具栏-->
    <RelativeLayout
        android:id="@+id/rl_bottom"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        android:background="@mipmap/video_play_bg">

        <ImageView
            android:id="@+id/iv_previous"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="43dp"
            android:clickable="true"
            android:scaleType="fitCenter"
            android:src="@drawable/iv_previous_press" />

        <ImageView
            android:id="@+id/iv_play"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="25dp"
            android:layout_toRightOf="@+id/iv_previous"
            android:clickable="true"
            android:scaleType="fitCenter"
            android:src="@drawable/iv_play_press" />


        <ImageView
            android:id="@+id/iv_next"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="25dp"
            android:layout_toRightOf="@+id/iv_play"
            android:clickable="true"
            android:scaleType="fitCenter"
            android:src="@drawable/iv_next_press" />


        <ImageView
            android:id="@+id/iv_state"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="25dp"
            android:layout_toRightOf="@+id/iv_next"
            android:clickable="true"
            android:scaleType="fitCenter"
            android:src="@drawable/iv_state_shunxu_press" />


        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="312dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="20dp"
            android:layout_toRightOf="@+id/iv_state"
            android:max="100"
            android:maxHeight="15dp"
            android:progressDrawable="@drawable/seekbar_style_01"
            android:thumb="@drawable/seekbar_thumb_style_01" />


        <TextView
            android:id="@+id/tv_video"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10px"
            android:layout_toRightOf="@+id/seekbar"
            android:gravity="center"
            android:text="00:00"
            android:textColor="#ffffff"
            android:textSize="15px" />


        <ImageView
            android:id="@+id/iv_sing_state"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="25dp"
            android:layout_toRightOf="@+id/tv_video"
            android:clickable="true"
            android:scaleType="fitCenter"
            android:src="@drawable/iv_singstate_press" />


        <ImageView
            android:id="@+id/iv_huatong"
            android:layout_width="72dp"
            android:layout_height="72dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="44dp"
            android:clickable="true"
            android:scaleType="fitCenter"
            android:src="@drawable/iv_huatong_press" />

    </RelativeLayout>

    
</RelativeLayout>


          










猜你喜欢

转载自blog.csdn.net/Coder_Hcy/article/details/73379141