1. 程式人生 > >手機影音第七天 視頻的播放下一個視頻功能實現,視頻進度、電量變化的實現

手機影音第七天 視頻的播放下一個視頻功能實現,視頻進度、電量變化的實現

播放器頁面電量變化 視頻進度變化 播放上一個、下一個與序列化實體類 等功能實現

先看下效果圖:

技術分享

在這裏,視頻進度條會根據視頻播放變化,下方的按鈕中,播放下一個,上一個都已實現。

代碼已經托管到碼雲上,想下載看的小夥伴可以從下方地址中獲取

https://git.oschina.net/joy_yuan/MobilePlayer


1、在這張圖上,自定義的顯示電量的那一列已經被系統自帶的狀態欄遮蓋,下面就說一下實現方法:

系統電量變化時,系統會發送一個廣播,所有對這個廣播感興趣的activity都可以註冊廣播來接收這個廣播。在這裏接收系統電量變化,屏幕鎖屏、開屏的廣播,只能使用動態廣播,不能用靜態廣播,這樣是防止在鎖屏後,某些程序偷偷幹事情,開屏後其又隱藏,導致用戶不知道。

定義動態廣播接收到系統的電量變化廣播後,就根據電量值的區間,來動態的切換電量的圖片,具體代碼段如下:

//註冊電量廣播,像鎖屏、開屏、電量變化這樣的廣播,靜態註冊的廣播接收者收不到廣播,因為導致安全問題,所以必須動態註冊
receiver=new MyReceiver();

IntentFilter intentFilter=new IntentFilter();
//當電量變化時發這個廣播
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, intentFilter);

---------------------------------------------------------------------------------------
/**
 * 監聽電量變化的廣播接收者
 */
class MyReceiver extends BroadcastReceiver{


    @Override
    public void onReceive(Context context, Intent intent) {
        int level=intent.getIntExtra("level",0);  //去intent獲取key為level的值,默認是0
        setBattery(level);
    }
}

接收到電量的區間後,來動態設置電量圖片

/**
 * 電量變化的方法
 * @param level
 */
private void setBattery(int level) {
    if (level<=0){
        ivBattery.setImageResource(R.drawable.ic_battery_0);
    }else if (level<=10){
        ivBattery.setImageResource(R.drawable.ic_battery_10);
    }else if (level<=20){
        ivBattery.setImageResource(R.drawable.ic_battery_20);
    }else if (level<=40){
        ivBattery.setImageResource(R.drawable.ic_battery_40);
    }else if (level<60){
        ivBattery.setImageResource(R.drawable.ic_battery_60);
    }else if (level<=80){
        ivBattery.setImageResource(R.drawable.ic_battery_80);
    }else if (level<=100){
        ivBattery.setImageResource(R.drawable.ic_battery_100);
    }
}


2、視頻進度條的變化

seekbar本身有一個setMax();這個是設置seekbar的最大值,我們傳入一個視頻的總時長就可以。在開始播放視頻時,傳一個空的handler,來進行更新seekbar方法。

/**
 * 準備好播放時的監聽
 */
class MyOnPreparedListener implements MediaPlayer.OnPreparedListener {
    

    @Override
    public void onPrepared(MediaPlayer mp) {
        videoview.start(); //開始播放
        duration = videoview.getDuration();  //獲取視頻總時長
        seekbarVideo.setMax(duration);   //設置播放進度的最大值

        //發送消息,來更新視頻進度
        handler.sendEmptyMessage(PROGRESS);

    }
}

然後在handler裏,根據handler的what類型,來做更新進度的操作。videoview.getcurrentPosition()方法獲取當前的視頻進度,然後seekbar有個setpositon()可以設置進度,最後每隔一秒,再發送一個handler來更新這個進度

/**
 * 定義一個handler來處理信息
 */
public Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case PROGRESS:
                //根據準備好播放時候後,發送的更新視頻進度消息,來更新視頻進度
                int currentPosition=videoview.getCurrentPosition();
                seekbarVideo.setProgress(currentPosition);

                //隔一秒刷新一下進度
                removeMessages(PROGRESS);

                handler.sendEmptyMessageDelayed(PROGRESS,1000);
                break;
        }
    }
};


3、系統時間的變化:

在上一面中講到了視頻進度條變換時,用到了handler,在handler裏隔一秒刷新下handler,因此在這裏也是更新系統時間放到了handler裏。

/**
 * 定義一個handler來處理信息
 */
public Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case PROGRESS:
                //根據準備好播放時候後,發送的更新視頻進度消息,來更新視頻進度
                int currentPosition=videoview.getCurrentPosition();
                seekbarVideo.setProgress(currentPosition);

                //設置當前播放的時間,使其顯示在播放器上
                tvCurrentTime.setText(utils.stringForTime(currentPosition));

                //設置系統播放時間,隔一秒刷新一下
                tvSystemTime.setText(getSystemTime());

                //隔一秒刷新一下進度
                removeMessages(PROGRESS);

                handler.sendEmptyMessageDelayed(PROGRESS,1000);
                break;
        }
    }
};


/**
 * 獲取系統時間
 * @return
 */
private String getSystemTime() {
    SimpleDateFormat format=new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
    return format.format(new Date());
}

在這裏要註意的是,獲取系統時間的方法,用的那個SimpleDateFormat()方法,它的包是java.text.SimpleDateFormat;一定要註意了,Android系統可能會自動給我們導成其他包導致報錯


4、要實現播放上一個下一個視頻功能,我們就要獲取視頻數據的列表list,那麽在videoPager中我們通過bundle,將list寫入到bundle中,其中要註意的是 一定要給實體類MediaItem 序列化,即類實現Serializable接口即可,否則會導致報錯。

在videoPager中,按如下代碼傳入list到intent

//給對象序列化後傳到SystemVideoPlayer中
Intent intent=new Intent(context, SystemVideoPlayer.class);
Bundle bundle=new Bundle();
bundle.putSerializable("mediallist",(ArrayList<MediaItem>)mediaList);
intent.putExtras(bundle);
intent.putExtra("position",position);  //將點擊的視頻的位置傳過去,方便定位播放的是哪個視頻
context.startActivity(intent);

在SystemVideoPlayer類中獲取該list

//獲取videopager裏傳過來的list數據,包含media列表的信息
medialist = (ArrayList<MediaItem>) getIntent().getSerializableExtra("mediallist");
position = getIntent().getIntExtra("position",0);


獲取到list和position後,即可非常方便的實現播放上一個,下一個視頻

public void onClick(View v) {
    if ( v == btnVoice ) {
        // Handle clicks for btnVoice
    } else if ( v == switchPlayer ) {
        // Handle clicks for switchPlayer

    } else if ( v == btExit ) {
        // Handle clicks for btExit   退出
        finish();
    } else if ( v == btVideoPre ) {
        // Handle clicks for btVideoPre  播放上一個視頻
        if (medialist!=null&&medialist.size()>0){
            position-=1;
            if (position<=0){
                position=medialist.size()-1;
            }
            MediaItem mediaitem=medialist.get(position);
            tvName.setText(mediaitem.getName());
            videoview.setVideoPath(mediaitem.getData());

        }else if (uri!=null){
            tvName.setText(uri.toString());
            videoview.setVideoURI(uri);
        }



    } else if ( v == btVideoStartPause ) {
        // Handle clicks for btVideoStartPause  播放暫停與啟動
        if (videoview.isPlaying()){
            //視頻在播放,則暫停
            videoview.pause();

            //按鈕圖片設置為暫停
            btVideoStartPause.setBackgroundResource(R.drawable.bt_video_play_selector);
        }else{
            //視頻在暫停,設置為播放
            videoview.start();

            //按鈕圖片設置為播放

            btVideoStartPause.setBackgroundResource(R.drawable.bt_video_pause_selector);            }
    } else if ( v == btNext ) {
        // Handle clicks for btNext   播放下一個
     if (medialist!=null&&medialist.size()>0){
         position+=1;
         if (position>=medialist.size()){
             position=0;
         }

             MediaItem mediaItem = medialist.get(position);
             tvName.setText(mediaItem.getName());
             videoview.setVideoPath(mediaItem.getData());



     }else if (uri!=null){
         //把上一個下一個按鈕設置灰色
         tvName.setText(uri.toString());
         videoview.setVideoURI(uri);
         btNext.setEnabled(false);
         btNext.setBackgroundResource(R.drawable.btn_next_gray);
     }

    } else if ( v == btVideoSwitchScreen ) {
        // Handle clicks for btVideoSwitchScreen
    }
}

這裏做的是循環播放,即播放到最後一個後,按下一個,會播放第一個視頻。

本文出自 “YuanGuShi” 博客,請務必保留此出處http://cm0425.blog.51cto.com/10819451/1948770

手機影音第七天 視頻的播放下一個視頻功能實現,視頻進度、電量變化的實現