1. 程式人生 > >安卓視訊播放器

安卓視訊播放器

 

磨洋工磨了好久,終於決定開始寫視訊播放器了,嗯,相簿播放器那裡,就是典型的舊坑未填,又挖新坑,233.再辭給自己立一個flag,一個月之後就要完成基本上的功能,比如基本的顯示,自動播放了,上一個下一個,暫停開始,拖拉,視訊列表。嗯,其他的慢慢來,總是要有個目標的,都沒人管我,自己再不管自己就要廢了。

嗯,時間真的是飛快哇,我都上班半年啦,清楚的記得,那天過來面試的時候,上午,小雨,打著傘,然後那天還很可憐的,到了公司早飯還沒吃,站在公司外面吃包子,打電話跟人事說到了。穿的風衣T恤牛仔褲,嗯,填簡歷,等待,老大詢問,老老大詢問,工資,就完了,然後就是回去,終於不用跟耗子玩啦,(乾噦),然後週一拖著行李箱,大件小件,也是下雨,打傘就拿不到行李,所以沒打傘,心拔涼拔涼,走到公租房第一句是,這裡沒耗子吧,哈哈,被嚇出陰影。就這樣,過了半年,不能鹹啊,要廢,想一想,當初是怎麼說的。現在就知道該怎麼做了。加油哇皮皮蝦。

嗯,這兩天做了一個,關於天氣的資料的整理,耽誤了一點時間(雖然沒人看233),後面會把他寫出來,繼續寫視訊吧。

18-10-29

昨天去做了頭髮,車禍現場瞭解一下。

視訊現在可以實現基本的,暫停播放,上一首下一首,自動迴圈播放,以及seekbar的實時重新整理。拖拉那裡還有點問題。

嗯,重新寫過......

現在差不多一個月,基本實現了以上說過的功能。

程式碼:

我一執行就會進到這個方法裡面,顯示第一個視訊。

	/**
	 * /storage/usb0/video/雙笙 - 故夢.mp4
	 */
	private VideoView mVideoView;
	private List<VideoFileInfo> videoLists = new ArrayList<VideoFileInfo>();// 新集合,集合記得new,不要犯這種傻錯誤啦
	private int currentVideoIndex = 0;// 當前視訊下標
	private int allTime;// 當前視訊總時間

	// 操作視訊
	public void PlayVideoView() {
		// 獲取pointerObject中的視訊資源
		try {
			List<FileVideoInfo> fileVideoList = pointerObject.getVideoItems();
			for (FileVideoInfo fileVideoInfo : fileVideoList) {
				// 把資料新增到VideoFileInfo裡面,裡面的屬性可用的多一點
				VideoFileInfo vinfo = new VideoFileInfo(fileVideoInfo.getPath());
				videoLists.add(vinfo);
			}
			mVideoView.setVideoPath(videoLists.get(0).getPath());
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}

採用handler做迴圈重新整理介面ui+thread做延遲操作。(以前用的是蠢handler傳送訊息,但是播放下一首的時候會出現同事傳送兩次的錯誤並且改不過來,所以改用handler+thread)。

需要注意的是:這裡我用來做重新整理頁面時間資料的是now_tv,是先自增之後再使用的,視訊需要從00:00開始,所以需要設定now_tv的值的地方都設定成了-1,自增過後就是0了。但是,不知道為什麼,經常會有,textview顯示視訊剩兩三秒才結束,實際播放的視訊就已經結束了。

// thread+handler
	int cProgress;
	int now_tv = -1;
	Thread mThread = new Thread(new Runnable() {
		@SuppressWarnings("static-access")
		@Override
		public void run() {
			sb_progress.setProgress(10);
			try {
				while (isExit) {
					if (isPrepared) {
						/**
						 * 1、在子執行緒死迴圈獲取視訊時長併發送給handler,handler執行ui更新操作,
						 */
						allTime = mVideoView.getDuration();
						Message msg = mHandler.obtainMessage(0, allTime / 1000);// what,obj
						mHandler.sendMessage(msg);
					}
					mThread.sleep(1000);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	});

	@SuppressLint("HandlerLeak")
	Handler mHandler = new Handler() {
		@Override
		public void dispatchMessage(Message msg) {
			super.dispatchMessage(msg);
			switch (msg.what) {
			case 0:
				if (!isPausing) {// 如果是暫停的就不做重新整理操作
					// 更新ui
					now_tv++;
					if (now_tv <= Integer.parseInt(msg.obj + "")) {
						sb_progress.setProgress(now_tv);
						refereshTime(tv_now_time, now_tv);
					}
					// 正常播放的時候就把isCompletion = false;
					isCompletion = false;
				}
				break;

			default:
				Log.e(TAG, "switch default error");
				break;
			}
		}
	};

 seekbar的監聽事件,需要注意的是:這裡的seekto的值是ms(毫秒),所以*1000就正常了,之前我就是不知道這個,所以一直直接seekto(progress),所以導致每一次跳轉的時候都是跳到很前面,直到今天看見一個大佬說了,seekto是毫秒,之前自己在安卓開發api裡面也沒看到這個點。

// seekBar監聽事件
	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		if (fromUser) {
			now_tv = progress;
			// 將seekBar設定到拖動的位置去
			sb_progress.setProgress(progress);
			Log.d(TAG, ".............progress:" + progress);
			// 將mVideoView定位到seekBar拖動的位置,引數是毫秒!
			mVideoView.seekTo(progress * 1000);
		}
	}

	@Override
	public void onStartTrackingTouch(SeekBar arg0) {
	}

	@Override
	public void onStopTrackingTouch(SeekBar arg0) {
	}

 監聽是否播放完畢,是安卓主執行緒中自己一直在做的事情,以前自己還傻傻的自己去迴圈判斷是否播放完畢,,

@Override
	public void onCompletion(MediaPlayer arg0) {
		isCompletion = true;
		sb_progress.setProgress(0);
		mVideoView.setVideoPath(videoLists.get(
				++currentVideoIndex % videoLists.size()).getPath());// 擔心下一個超出計劃範圍??當然還是取模好用哇
		// 播放完成,將now_tv=0
		now_tv = -1;
	}

監聽視訊資源知否準備好,這個也是安卓主執行緒自己一直 在做的事情。每一次準備好之後就可以獲取到新的視訊的時長。

	@Override
	public void onPrepared(MediaPlayer arg0) {
		// 準備好就開始
		mVideoView.start();
		// 獲取視訊總時長
		allTime = mVideoView.getDuration() / 1000;// s
		// 設定seekbar的最大值
		sb_progress.setMax(allTime);
		// 設定文字框
		refereshTime(tv_all_time, allTime);
		isPrepared = true;
	}

 點選上一個下一個以及播放暫停,沒什麼好說的,就是++--和start和pause,這裡我只給暫停播放還了圖片,上一個下一個這裡仔細一點的也可以在按下的時候換一張圖片

    // 上一個
	public void onClickPre(View arg0) {
		Log.d(TAG, "-------------onClickPre---------------");
		now_tv = -1;
        // 點選下一個開始播放
		isPausing = false;
		bt_play.setBackground(getResources().getDrawable(R.drawable.play));
		try {
			if (currentVideoIndex <= 0) {
				currentVideoIndex = videoLists.size() - 1;
				mVideoView.setVideoPath(videoLists.get(
						currentVideoIndex % videoLists.size()).getPath());
			} else {
				mVideoView.setVideoPath(videoLists.get(
						--currentVideoIndex % videoLists.size()).getPath());
			}
		} catch (Exception e) {
			Log.e(TAG, "onClickPre error");
		}
	}

	// 下一個
	public void onClickNext(View arg0) {
		Log.d(TAG, "-------------onClickNext---------------");
		now_tv = -1;
        // 點選下一個開始播放
		isPausing = false;
		bt_play.setBackground(getResources().getDrawable(R.drawable.play));
		sb_progress.setProgress(0);
		mVideoView.setVideoPath(videoLists.get(
				++currentVideoIndex % videoLists.size()).getPath());
	}

	// 播放暫停 
	@SuppressLint("NewApi")
	public void onClickPlay(View arg0) {
		if (!isPausing) {// 點選播放,變成暫停
			mVideoView.pause();
			isPausing = true;
			bt_play.setBackground(getResources().getDrawable(R.drawable.pause));
		} else {// 點選暫停,變成播放
			isPausing = false;
			bt_play.setBackground(getResources().getDrawable(R.drawable.play));
			mVideoView.start();
		}
	}

到這裡及可以實現:上一個,下一個,暫停,播放,seekbar跳轉視訊了。

後面還要慢慢實現:點選視訊視訊縮小,顯示視訊目錄,點選視訊名稱開始播放對應視訊;一段時間不操作,視訊又恢復大小,以及隱藏seekbar和幾個按鈕;還可以實現一個拖動的時候seekbar那裡顯示一個當前拖動到的值的資料;