Android SurfaceView+MediaPlayer 本地视频播放器(卡拉OK功能)
来源:互联网 发布:js 数组 按50为一批 编辑:程序博客网 时间:2024/05/18 02:39
功能情景:
1.播放视频文件
2.上一首,下一首
3.卡拉ok功能
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>
阅读全文
0 0
- Android SurfaceView+MediaPlayer 本地视频播放器(卡拉OK功能)
- Android SurfaceView + MediaPlayer实现视频播放器
- android MediaPlayer SurfaceView 网络视频播放器
- android surfaceView+mediaPlayer 自定义视频播放器
- Android 视频播放器SurfaceView+Mediaplayer
- Android SurfaceView+MediaPlayer 播放本地raw文件夹下的视频
- android视频播放MediaPlayer+SurfaceView
- 安卓本地视频播放SurfaceView+MediaPlayer
- SurfaceView + MediaPlayer 实现视频播放功能
- Android MediaPlayer本地视频播放器
- Android MediaPlayer本地视频播放器
- android 视频播放器 TextureView , MediaPlayer , SurfaceView 的坑
- Android 播放视频(一)SurfaceView + MediaPlayer
- Android MediaPlayer+SurfaceView实现视频播放
- Android SurfaceView+MediaPlayer实现视频播放
- Android:使用MediaPlayer和SurfaceView播放视频
- Android SurfaceView+ mediaplayer 重复播放视频
- Android SurfaceView+MediaPlayer 无缝播放 视频
- 回顾Hibernate---配置篇
- AFNetworking批量上传图片问题
- STL之算法
- 新导入java项目报错
- iOS 底层解析weak的实现原理(包含weak对象的初始化,引用,释放的分析)
- Android SurfaceView+MediaPlayer 本地视频播放器(卡拉OK功能)
- C++11中的std::function
- 获取本机的ip地址和所属区域
- WebView性能、体验分析与优化
- centos7 YUM安装lnmp
- android source code download from tsinghua
- IC设计基础系列之低功耗篇7:(数字IC)低功耗设计入门(七)——门级电路低功耗设计优化(续)
- n皇后问题(回溯)
- mysql下载地址