利用vitamio Mediaplayer 自定義了一個播放器

本人android初學者,學習了Vitamio Mediaplayer 的Demo,參考了農民伯伯大牛的文章,具體鏈接如下:
http://www.cnblogs.com/over140/archive/2012/05/22/2473019.html
實現了簡單的功能:雙擊屏幕切換,點擊顯示進度條,暫停和播放。自己記錄下,許多地方還有待優化的部分,請大家指點哈。
手機拍攝的真機效果不好請大家原諒
顯示效果:
豎屏
橫屏
首先是XML佈局:
xml佈局
這裏增加了進度,播放,暫停等組件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <RelativeLayout
        android:id="@+id/live_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@mipmap/top_bar_bg"
        >
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/detail_back_icon"
            android:layout_centerVertical="true"
            android:padding="5dp"
            />
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_marginLeft="85dp"
            android:layout_marginRight="85dp"
            android:textColor="#1c1c1c"
            android:textSize="25sp"
            android:text="測試視頻"
            />
    </RelativeLayout>
    <RelativeLayout
        android:id="@+id/live_gl_rl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/live_rl_padding"
        >
        <io.vov.vitamio.widget.CenterLayout
            android:id="@+id/live_cl"
            android:layout_width="match_parent"
            android:layout_height="220dp"
            >
            <ImageView
                android:id="@+id/live_iv_videoimage"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:visibility="gone"
                />
            <SurfaceView
                android:id="@+id/myvideo"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                />
            <ImageView
                android:id="@+id/live_iv_play"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@mipmap/play_btn"
                android:visibility="gone"
                />
            <ImageView
                android:id="@+id/live_iv_begin"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@mipmap/play_btn"
                />
        </io.vov.vitamio.widget.CenterLayout>
        <RelativeLayout
            android:id="@+id/live_rl_clear"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/live_cl"
            android:visibility="gone"
            >
            <ImageButton
                android:id="@+id/live_imgbt_play"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_centerVertical="true"
                android:background="@drawable/mediacontroller_button"
                android:src="@drawable/mediacontroller_pause"
                android:contentDescription="@string/mediacontroller_play_pause"
                />
            <TextView
                android:text="00:00:00"
                android:id="@+id/live_tv_current"
                style="@style/MediaController_Text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toRightOf="@id/live_imgbt_play"
                />
            <TextView
                android:id="@+id/live_tv_end"
                style="@style/MediaController_Text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="5dp"
                />
            <SeekBar
                android:id="@+id/live_seekbar"
                style="@style/MediaController_SeekBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@+id/live_tv_end"
                android:layout_toRightOf="@+id/live_tv_current"
                android:focusable="true"
                android:max="1000" />
        </RelativeLayout>
    </RelativeLayout>


</LinearLayout>

JAVA代碼,這裏我仿照着農民伯伯的Demo,利用的GestureDetector(手勢),觸發雙擊和單擊事件,還可以增加亮度和聲音的手勢調節,很可惜目前沒有增加。利用Timer 與Handler每秒觸發任務更新UI組件的進程。

package com.gmw.news.activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;


import com.gmw.news.R;


import java.util.Timer;
import java.util.TimerTask;


import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.widget.CenterLayout;


public class LiveActivity extends BaseActivity implements SurfaceHolder.Callback,
        MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener, View.OnTouchListener {
    private String PATH = Environment.getExternalStorageDirectory().getPath()+"/Movies/5.mkv";
    private static final String TAG = "MediaPlayerDemo";
    private int mVideoWidth;
    private int mVideoHeight;
    private MediaPlayer mMediaPlayer;
    private SurfaceView mPreview;
    private SurfaceHolder holder;
    private Bundle extras;
    private static final String MEDIA = "media";
    private static final int LOCAL_AUDIO = 1;
    private static final int STREAM_AUDIO = 2;
    private static final int RESOURCES_AUDIO = 3;
    private static final int LOCAL_VIDEO = 4;
    private static final int STREAM_VIDEO = 5;
    private boolean mIsVideoSizeKnown = false;
    private boolean mIsVideoReadyToBePlayed = false;
    private TextView txVideoTime;
    private SeekBar liveSeekBar;
    private Timer mTimer;
    private TextView txVideoCurrentTime;
    private long videoTime;
    private ImageView playBT;
    public final static int HANDER_UPDATE = 1;
    public final static int HANDER_HIDE = 2;
    private RelativeLayout liveRelative;
    private ImageButton liveImgbtPlay;
    private GestureDetector mGestureDetector;
    //屏幕的寬高
    private int windowWidth;
    private int windowHeight;
    //豎屏寬高
    private int glayoutHeight;
    private int glayoutWidth;
    private ViewGroup.LayoutParams layoutParams;
    private RelativeLayout liveTop;
    private CenterLayout glayout;
    //獲取視頻播放父類的padding,方便全屏的時候修改
    private RelativeLayout liveGlRl;
    private int liveGlRlPaddingBottom;
    private int liveGlRlPaddingLeft;
    private int liveGlRlPaddingRight;
    private int liveGlRlPaddingTop;


    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.v(TAG,"onConfigurationChanged");
    }

    @Override
    public void initData() {
        //初始化庫。若少了會報錯!!
        if(!LibsChecker.checkVitamioLibs(this))
            return;
        //禁止休眠
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        windowWidth = displayMetrics.widthPixels;
        windowHeight = displayMetrics.heightPixels;
        mTimer = new Timer();
        mTimer.schedule(mTimerTask,0,1000);
    }
    private TimerTask mTimerTask = new TimerTask() {
        @Override
        public void run() {
            if(mMediaPlayer == null)
                return;
            if(mMediaPlayer.isPlaying()) {
                Message msg = Message.obtain();
                msg.what = HANDER_UPDATE;
                mHandler.sendMessage(msg);
            }
        }
    };
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(mMediaPlayer == null){
                return;
            }
            switch (msg.what){
                case HANDER_UPDATE:
                    long position = mMediaPlayer.getCurrentPosition();
                    long progress = liveSeekBar.getMax()*position/videoTime;
                    txVideoCurrentTime.setText(formatDuring(position));
                    liveSeekBar.setProgress((int) progress);
                    break;
                case HANDER_HIDE:

                    if(mMediaPlayer.isPlaying()){
                        playBT.setVisibility(View.GONE);
                        liveRelative.setVisibility(View.GONE);
                    }
                    break;
                default:
                    break;
            }


        }
    };
    @Override
    public void initView() {
        //加載佈局文件
        setContentView(R.layout.activity_live);
        txVideoTime = (TextView) findViewById(R.id.live_tv_end);
        txVideoCurrentTime = (TextView) findViewById(R.id.live_tv_current);
        liveSeekBar = (SeekBar) findViewById(R.id.live_seekbar);
        playBT = (ImageView) findViewById(R.id.live_iv_play);
        liveRelative = (RelativeLayout) findViewById(R.id.live_rl_clear);
        liveImgbtPlay = (ImageButton) findViewById(R.id.live_imgbt_play);
        glayout = (CenterLayout) findViewById(R.id.live_cl);
        liveTop = (RelativeLayout) findViewById(R.id.live_top);
        layoutParams = glayout.getLayoutParams();
        glayoutHeight = layoutParams.height;
        glayoutWidth = layoutParams.width;

        liveGlRl = (RelativeLayout) findViewById(R.id.live_gl_rl);
        liveGlRlPaddingBottom = liveGlRl.getPaddingBottom();
        liveGlRlPaddingLeft = liveGlRl.getPaddingLeft();
        liveGlRlPaddingRight = liveGlRl.getPaddingRight();
        liveGlRlPaddingTop = liveGlRl.getPaddingTop();
        //註冊手勢時間
        mGestureDetector = new GestureDetector(this,new MyOnGestureListenner());
        //查找組件
        mPreview = (SurfaceView)findViewById(R.id.myvideo);

        //獲取此surfaceView的holder對象。此holder對象即爲mediaplayer顯示的地方。
        holder = mPreview.getHolder();
        //設置回調。這裏主要是surfaceChanged、surfaceDestroyed、surfaceCreated三個方法。
        holder.addCallback(this);
        holder.setFormat(PixelFormat.RGBA_8888);


        //獲取數據
        //extras = getIntent().getExtras();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    private class MyOnGestureListenner extends GestureDetector.SimpleOnGestureListener{
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            Log.v("onSingleTapUp","onSingleTapUp");
            liveRelative.setVisibility(View.VISIBLE);
            playBT.setVisibility(View.VISIBLE);
            Message msg = Message.obtain();
            msg.what = HANDER_HIDE;
            mHandler.sendMessageDelayed(msg, 3000);
            return super.onSingleTapUp(e);
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.v("onDoubleTap", "onDoubleTap");
            if(mMediaPlayer == null){
                Log.v(TAG,"屏幕高:"+windowHeight+";屏幕寬:"+
                        windowWidth+"豎屏高:"+glayoutHeight+"寬:"+glayoutWidth);
            }
            int mCurrentOrientation = LiveActivity.this.getResources().getConfiguration().orientation;
            WindowManager.LayoutParams attrs = getWindow().getAttributes();
            //如果是橫屏
            if(mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE){

                LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
                getWindow().setAttributes(attrs);
                //取消全屏設置
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                liveTop.setVisibility(View.VISIBLE);
                layoutParams.height = glayoutHeight;
                layoutParams.width = glayoutWidth;
                liveGlRl.setPadding(liveGlRlPaddingLeft,liveGlRlPaddingTop,
                        liveGlRlPaddingRight,liveGlRlPaddingBottom);
                glayout.setLayoutParams(layoutParams);
            }
            //若果是豎屏
            if(mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT){
                LiveActivity.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
                getWindow().setAttributes(attrs);
                //設置全屏
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
                liveTop.setVisibility(View.GONE);
                layoutParams.height = windowWidth;
                layoutParams.width = windowHeight;
                liveGlRl.setPadding(0,0,0,0);
                glayout.setLayoutParams(layoutParams);
            }
            //return super.onDoubleTap(e);
            return true;
        }
    }


    @Override
    public void initAction() {
        //設置觸摸監聽
        mPreview.setOnTouchListener(this);
        mPreview.setFocusable(true);//使能控件獲得焦點
        mPreview.setClickable(true);//表明控件可以點擊
        mPreview.setLongClickable(true);
        playBT.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mMediaPlayer.isPlaying()){
                    mMediaPlayer.stop();
                }else{
                    mMediaPlayer.start();
                }
            }
        });
        liveImgbtPlay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mMediaPlayer.isPlaying()){
                    mMediaPlayer.stop();
                }else{
                    mMediaPlayer.start();
                }
            }
        });
    }
    private void doCleanUp() {
        mVideoWidth = 0;
        mVideoHeight = 0;
        mIsVideoReadyToBePlayed = false;
        mIsVideoSizeKnown = false;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated called");
        final ImageView begin = (ImageView) findViewById(R.id.live_iv_begin);
        begin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                begin.setVisibility(View.GONE);
                playVideo();
            }
        });

    }

    private void playVideo() {
        doCleanUp();
        try {
            //初始化mediaplayer。
            mMediaPlayer =new MediaPlayer(this);
            //設置數據源
            mMediaPlayer.setDataSource(PATH);
            //設置顯示
            mMediaPlayer.setDisplay(holder);
            //準備
            mMediaPlayer.prepareAsync();
            //設置緩衝監聽
            mMediaPlayer.setOnBufferingUpdateListener(this);
            //設置播放完畢監聽
            mMediaPlayer.setOnCompletionListener(this);
            //設置準備完畢監聽
            mMediaPlayer.setOnPreparedListener(this);
            //設置顯示大小監聽
            mMediaPlayer.setOnVideoSizeChangedListener(this);
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
        }catch (Exception e) {
            Log.e(TAG, "error: " + e.getMessage(), e);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.d(TAG, "surfaceChanged called");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(TAG, "surfaceDestroyed called");
    }

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

    @Override
    public void onCompletion(MediaPlayer mp) {
        Log.d(TAG, "onCompletion called");
        mTimer.cancel();
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.d(TAG, "onPrepared called");
        mIsVideoReadyToBePlayed = true;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            videoTime = mMediaPlayer.getDuration();
            txVideoTime.setText(formatDuring(videoTime));
            startVideoPlayback();
        }
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        Log.v(TAG, "onVideoSizeChanged called");
        if (width == 0 || height == 0) {
            Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
            return;
        }
        mIsVideoSizeKnown = true;
        mVideoWidth = width;
        mVideoHeight = height;
        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
            startVideoPlayback();
        }
    }
    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaPlayer();
        doCleanUp();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseMediaPlayer();
        doCleanUp();
    }

    private void releaseMediaPlayer() {
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    private void startVideoPlayback() {
        Log.v(TAG, "startVideoPlayback");

        holder.setFixedSize(mVideoWidth, mVideoHeight);
        mMediaPlayer.start();
    }
    //計算時間
    private  String formatDuring(long mss) {
        long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
        long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
        long seconds = (mss % (1000 * 60)) / 1000;
        String hour = "";
        if(hours < 10) {
            hour = "0" + hours;
        }else{
            hour = hours+"";
        }
        String minute = "";
        if(minutes < 10) {
            minute = "0" + minutes;
        }else{
            minute = hours+"";
        }
        String second = "";
        if(seconds < 10) {
            second = "0" + seconds;
        }else{
            second = seconds+"";
        }
        return hour + ":" + minute + ":"
                + second ;
    }
}

再來一個農民伯伯博客的傳送門,裏面詳細的介紹了Vitamio:
http://www.cnblogs.com/over140/category/409230.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章