android自定义视频播放器
来源:互联网 发布:家里蹲 知乎 编辑:程序博客网 时间:2024/05/28 19:23
在网上找了很多相关资料,感觉没有自己想要的,最后决定还是自己来写一个吧。
源代码已经放到资源库中,欢迎下载:http://download.csdn.net/detail/luozhi3527/5353003
程序通过surface+mediaplayer来实现,自定义控制台。能播放本地视频和网络视频。
主要实现代码如下:
package com.xluo.mediaplayertest;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.app.ProgressDialog;import android.media.AudioManager;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.media.MediaPlayer.OnErrorListener;import android.media.MediaPlayer.OnInfoListener;import android.media.MediaPlayer.OnPreparedListener;import android.media.MediaPlayer.OnSeekCompleteListener;import android.media.MediaPlayer.OnVideoSizeChangedListener;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.Display;import android.view.KeyEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.WindowManager;import android.widget.ImageButton;import android.widget.LinearLayout;import android.widget.SeekBar;import android.widget.TextView;import android.widget.Toast;import android.widget.SeekBar.OnSeekBarChangeListener;public class TestVideoPlayer extends Activity implements OnCompletionListener,OnErrorListener,OnInfoListener,OnPreparedListener,OnSeekCompleteListener,OnVideoSizeChangedListener,SurfaceHolder.Callback{ public static final String TAG = "TestVideoPlayer"; private boolean isExit = false; private int currentMusicPosition; //当前音量String url =null;private Uri uri;private String name;private ImageButton playBtn = null;//播放、暂停private TextView playtime = null;//已播放时间private TextView durationTime = null;//总时间private TextView VideoName = null;private SeekBar seekbar = null;//进度private SeekBar soundBar = null;//音量调节private Handler handler = new Handler(){public void handleMessage(Message msg){super.handleMessage(msg);switch (msg.what) {case 1:if(mediaPlayer!=null)currentPosition = mediaPlayer.getCurrentPosition();seekbar.setProgress(currentPosition);playtime.setText(toTime(currentPosition));handler.sendEmptyMessage(1);break;default:break;}}};//用于进度条private int currentPosition;//当前播放位置private ProgressDialog dialog; //加载等待框private AudioManager mAudioManager = null;private View video_contrlbar,titlebar;private boolean isControlBarShow = true; Display currentDisplay; SurfaceView surfaceView; SurfaceHolder surfaceHolder; MediaPlayer mediaPlayer;//使用的是MediaPlayer来播放视频 int ScurrentPosition; //音量 Timer showController = new Timer(); TimerTask timerTask ; private Handler fHandler = new Handler(){public void handleMessage(Message msg){super.handleMessage(msg);switch(msg.what){case 1:video_contrlbar.setVisibility(View.GONE);titlebar.setVisibility(View.GONE);isControlBarShow = false;break;default:break;}}};//用于控制台显隐 boolean readyToPlayer = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //设置屏幕常亮 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置满屏 setContentView(R.layout.activity_main); name = "晴天"; url = "/sdcard/sunny_night.mp4"; //网络视频和本地视频都可以的 Log.d(TAG," url :"+url); dialog = new ProgressDialog(this); //设置等待dialog.setMessage("加载中...");dialog.show();//控制台video_contrlbar = (View)findViewById(R.id.video_contrlbar);titlebar = (View)findViewById(R.id.video_titlebar);showControlBar();/*时间*/playtime = (TextView)findViewById(R.id.video_playtime);//已经播放的时间durationTime = (TextView)findViewById(R.id.video_duration);//总时间VideoName = (TextView)findViewById(R.id.play_movie_name);VideoName.setText(name);/*播放、暂停、停止按钮设置*/playBtn = (ImageButton)findViewById(R.id.video_playBtn);//开始播放playBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (mediaPlayer.isPlaying()){pause();playBtn.setBackgroundResource(R.drawable.video_play_selector);} else{play();playBtn.setBackgroundResource(R.drawable.video_pause_selector);}}});//进度条seekbar = (SeekBar)findViewById(R.id.video_seekbar);seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {if(fromUser)mediaPlayer.seekTo(progress);}});/*音量控制条*/soundBar = (SeekBar)findViewById(R.id.video_sound);soundBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stubif (fromUser){int ScurrentPosition = soundBar.getProgress();mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, ScurrentPosition, 0);}}}); surfaceView = (SurfaceView)findViewById(R.id.SurfaceView); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubshowControlBar(); //点击屏幕时,调出控制台;}}); setup(); currentDisplay = getWindowManager().getDefaultDisplay(); } private void showControlBar(){ //控制台的显隐 video_contrlbar.setVisibility(View.VISIBLE); titlebar.setVisibility(View.VISIBLE); isControlBarShow = true; if(timerTask != null){ timerTask.cancel(); } timerTask = new TimerTask(){ @Override public void run() { // TODO Auto-generated method stub if(isControlBarShow){ Message msg = fHandler.obtainMessage(1); fHandler.sendMessage(msg); } } }; showController.schedule(timerTask, 5000); //5秒后隐藏 } Runnable contrlShow = new Runnable(){@Overridepublic void run() {// TODO Auto-generated method stubvideo_contrlbar.setVisibility(View.GONE);titlebar.setVisibility(View.GONE);isControlBarShow = false;fHandler.postDelayed(contrlShow, 5000);} }; @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } private void loadClip(){ if (mediaPlayer != null) { mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; } mediaPlayer = new MediaPlayer();//创建多媒体对象 mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnErrorListener(this); mediaPlayer.setOnPreparedListener(this); mediaPlayer.setOnSeekCompleteListener(this); mediaPlayer.setOnVideoSizeChangedListener(this); //ListEntity entity = dbDao.find(position); //Log.d(TAG,"list entity object :"+entity); //String url = entity.getUrl(); Log.d(TAG,"url :"+url); uri = Uri.parse(url); Log.d(TAG,"media url :"+url); //uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, //"" + pos); try { mediaPlayer.setDataSource(this, uri); } catch (Exception e) { e.printStackTrace(); } } private void setup(){ loadClip(); try { mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(final MediaPlayer mp) { seekbar.setMax(mp.getDuration());//设置播放进度条最大值 handler.sendEmptyMessage(1);//向handler发送消息,启动播放进度条 playtime.setText(toTime(mp.getCurrentPosition()));//初始化播放时间 durationTime.setText(toTime(mp.getDuration()));//设置时间 mp.seekTo(currentPosition);//初始化MediaPlayer播放位置 /*获得最大音量*/ mAudioManager = (AudioManager) TestVideoPlayer.this.getSystemService(TestVideoPlayer.this.AUDIO_SERVICE); int maxSound = mAudioManager.getStreamMaxVolume( AudioManager.STREAM_MUSIC ); /*获得当前音量*/ int currentSound = mAudioManager.getStreamVolume( AudioManager.STREAM_MUSIC ); soundBar.setMax(maxSound); soundBar.setProgress(currentSound); } }); } catch (Exception e) { e.printStackTrace(); } } private void play(){ Log.d(TAG,"cancel dialog:"+dialog); /* 设置视频尺寸 */ int tmpWidth = currentDisplay.getHeight(); int tmpHeight = currentDisplay.getWidth(); surfaceView.setLayoutParams(new LinearLayout.LayoutParams(tmpHeight,tmpWidth*3/4)); if(dialog != null){ dialog.dismiss(); } mediaPlayer.start(); playBtn.setBackgroundResource(R.drawable.video_pause_selector); } private void pause(){ mediaPlayer.pause(); } public String toTime(int time) { time /= 1000; int minute = time / 60; int hour = minute / 60; int second = time % 60; minute %= 60; return String.format("%02d:%02d:%02d", hour,minute, second); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG,"surafce created"); mediaPlayer.setDisplay(surfaceHolder);//若无次句,将只有声音而无图像 play(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { //surface销毁时结束播放,防止按下home键后仍有声音,但无法播放图像。 if (mediaPlayer != null) { mediaPlayer.reset(); mediaPlayer.release(); mediaPlayer = null; } finish(); } @Override public void onVideoSizeChanged(MediaPlayer arg0, int arg1, int arg2) { } @Override public void onSeekComplete(MediaPlayer mp) { } @Override public void onPrepared(MediaPlayer mp) { } @Override public boolean onInfo(MediaPlayer arg0, int whatInfo, int extra) { return false; } @Override public boolean onError(MediaPlayer arg0, int arg1, int arg2) { return false; } @Override public void onCompletion(MediaPlayer arg0) { //播放完后自动退出 finish(); } public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: exitBy2Click(); break; case KeyEvent.KEYCODE_VOLUME_DOWN: //音量键的控制,调出控制台 Log.d(TAG,"to pressed voice down"); showControlBar(); currentMusicPosition = soundBar.getProgress(); currentMusicPosition--; mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentMusicPosition, 0); soundBar.setProgress(currentMusicPosition); break; case KeyEvent.KEYCODE_VOLUME_UP: Log.d(TAG,"to pressed voice up"); showControlBar(); currentMusicPosition = soundBar.getProgress(); currentMusicPosition++; mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentMusicPosition, 0); soundBar.setProgress(currentMusicPosition); break; default: super.onKeyDown(keyCode, event); } return true; } private void exitBy2Click(){ Timer tExit = null; if (isExit == false) { isExit = true; // 准备退出 Toast.makeText(this, "再按一次退出播放", Toast.LENGTH_SHORT).show(); tExit = new Timer(); tExit.schedule(new TimerTask() { @Override public void run() { isExit = false; // 取消退出 } }, 2000); // 如果2秒钟内没有按下返回键,则启动定时器取消掉刚才执行的任务 } else { if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer.reset(); mediaPlayer = null; } finish(); } }}
主要代码都有注释,没必要再做解释。
- android自定义视频播放器
- Android自定义视频播放器
- android 自定义播放器播放视频
- android surfaceView+mediaPlayer 自定义视频播放器
- Android自定义视频播放器(网络/本地)
- Android视频播放器Exoplayer自定义
- Android中自定义VideoView视频播放器
- 自定义视频播放器
- 自定义视频播放器
- 自定义视频播放器
- 自定义视频播放器
- android 自定义视频播放器之2/1
- android surfaceview自定义视频播放器横竖屏切换总结
- Android使用Vitamio框架自定义视频播放器
- 《android多媒体api》之MediaPlayer自定义视频播放器
- AVPlayer自定义视频播放器
- iOS 自定义视频播放器
- 自定义简单视频播放器
- Autodesk 首届开发者训练营所有讲座课程介绍(包括云,建筑,机械,多媒体以及娱乐几个大方向)
- MySql模糊查询like通配符使用详细介绍
- flexpaper源码的编译,去除logo和打印
- 编程常用电子书(不断更新ing...)
- java实现一个日期的操作
- android自定义视频播放器
- pread pwrite
- C 语言编写windows服务程序的控制程序
- 一个简单的动态规划题
- hdu 4524(水)
- (个人笔记)java 定时执行
- Android提高第十篇之AudioRecord实现"助听器"
- resign app
- Nebula level07