播放器二次封裝與實現

視頻播放、音頻播放在Android平臺的應用非常廣泛,最近正好學習研究了一下播放器層面的Android實現,

對底層播放器做了二次的封裝,主要進行的工作如下:

§ 主要實現

1、播放控制
(1)簡化播放接口處理
(2)增加一些友好型播控接口:快退、快進、重新播放等。
(3)單視頻、多視頻列表播放
2、播放狀態
(1)播放狀態控制
(2)播放狀態調用時及時反饋
(3)較全的播放信息,通過回調接口隔時通知
(4)視頻緩衝動畫自動處理
(5)播放顯示畫面尺寸、位置自由設定
(6)播放HTTP源時,支持Headers設置
(7)增加快退、快進開關
3、其他
(1)音量控制
(2)視頻源廣告支持
4、待補充完善
(1)資源單獨進行預加載

 

§ MediaPlayer狀態機參考

 

§ 主要結構設計

 1、主要接口

IPlayController:負責播放控制
IPlayerUI:負責播放控制的UI處理
IPlaySetter:負責播放控制的參數設置
IPlayerEventListener:播放回調事件通知接口
MediaPlayerEvent:播放事件載體

2、適配、分發、通知線程

MediaPlayerAdapter:原生態播放器適配
NotifyEventThread:回調通知監聽線程
PlayDispatcher:播放器外觀分發處理

3、構造、處理、狀態

 

PlayerBuilder:構造播放器基礎信息,用戶接口
PlayerHandler:主線程操作處理
StatusCommander:播放控制命令狀態處理
VolumeController:音量控制處理

4、外觀、狀態、UI

WMediaPlayer:播放器外觀層
PlayContext:播放器上下文
StatusResolver:播放器實時狀態信息
UIHandler:負責UI效果處理

§ 源碼下載

爲方便需要的朋友進一步的進行定製,先將實現的代碼提供給大家,附帶了DEMO示例。點擊下載

部分示例代碼:

public class MainActivity extends Activity implements OnClickListener {

	public static final String playUrl = "/mnt/sdcard/test.mp4";
	private WMediaPlayer player = new WMediaPlayer();
	private SurfaceView sv = null;
	private TextView txtStatus;
	private SeekBar seekbar = null;
	private ProgressBar progressBar = null;
	private Button btnPlay, btnPause, btnUnPause, btnStop, btnReplay,
			btnVolume, btnStatus, btnClose, btnSeekUp, btnSeekDown, btnLoad;
	private int volume = 1;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		init();

		// Intent it = new Intent(getBaseContext(), PlayerActivity.class);
		// startActivity(it);

		sv = (SurfaceView) findViewById(R.id.surfaceView1);
		SurfaceHolder sh = sv.getHolder();
		sh.addCallback(sc);
	}

	private SurfaceHolder.Callback sc = new SurfaceHolder.Callback() {
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			// test
			PlayerBuilder builder = PlayerBuilder.getInstance();
			builder.setContext(getBaseContext());
			builder.setSurfaceView(sv);
			// builder.setVolumeBar(seekbar);
			builder.setVolumeBar(progressBar);
			builder.setLoadingAnim(LoadAnimType.Animation, R.anim.loads_redload);
			builder.setEventListener(eventListener);

			player.setBuilder(builder);
			player.setPlayUrl(playUrl);
			// player.setPlayList();
			player.play();
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
		}
	};

	IPlayerEventListener eventListener = new IPlayerEventListener() {
		@Override
		public void onMediaPlayerEvent(MediaPlayerEvent event) {

		}
	};

	@Override
	protected void onDestroy() {
		player.destroy();
		super.onDestroy();
	}

	@Override
	public void onClick(View v) {
		int id = v.getId();
		switch (id) {
		case R.id.btnPlay:
			player.play();
			break;
		case R.id.btnPause:
			player.pause();
			break;
		case R.id.btnUnPause:
			player.unpause();
			break;
		case R.id.btnStop:
			player.stop();
			break;
		case R.id.btnClose:
			player.close();
			break;
		case R.id.btnReplay:
			player.replay();
			break;
		case R.id.btnSeekUp:
			player.seek(player.getStatusResolver().getCurTime() + 30);
			break;
		case R.id.btnSeekDown:
			player.seek(player.getStatusResolver().getCurTime() - 30);
			break;
		case R.id.btnVolume:
			volume++;
			player.getVolumeController().setVolume(volume);
			// player.getPlayer().setVolume(0.5f, 0.5f);
			break;
		case R.id.btnStatus:
			String status = Utils.gson.toJson(player.getStatusResolver());
			txtStatus.setText(status);
			break;
		case R.id.btnLoad:
			UIHandler.getInstance()
					.showLoading(
							PlayerBuilder.getInstance().getPlayContext()
									.getAnimResId());
			break;
		default:
			break;
		}
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章