使用MediaPlayer和SurfaceView播放视频

播放视频有两种方式,可以使用videoview和midiaplayer两种方式来播放,因为videoview的封装性高,播放简单,在此不做讨论,本文主要是说mediaplayer方式播放。

mediaplayer播放需要surfaceview来展现播放界面。

本次所要完成的任务主要是在屏幕指定区域播放图片或者视频,即:在一个队列里存有视频和图片等多媒体文件,播放逻辑负责获取队列的每一个文件,当发现文件是图片的时候,使用图片播放方式进行播放,当遇到文件是视频的时候,使用mediaplayer来播放此视频。

因为涉及到重复多次创建,销毁surface,所以需要合理控制。经过测试和查看,发现可见性可以控制surfaceview的销毁。但创建由surfaceholder持有器来控制。

那么这个思路代码如下:

1:创建mediaplayer

if(mediaPlayer==null){
                    mediaPlayer = new MediaPlayer();
                }
                mediaPlayer.setOnCompletionListener(this);
                try {
                    mediaPlayer.setDataSource(path);
                    //移动
                } catch (Exception e) {
                    e.printStackTrace();
                }

2:创建surfaceholder

surfaceHolder = hs_surface.getHolder();
                surfaceHolder.addCallback(this);

3:在surface被创建的时候进行mediaplayer播放

@Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.v("surfaceCreated", "surfaceCreated");
        surfaceHolder = holder;
        mediaPlayer.setDisplay(holder);
//        mediaPlayer.setSurface(surfaceHolder.getSurface());
        try {
            mediaPlayer.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mediaPlayer.start();
    }

4:播放完成后释放mediaplayer,销毁surface,其中销毁surface需要让surfaceview不可见:

    @Override
    public void onCompletion(MediaPlayer mp) {
        if(mediaPlayer!=null){
            mediaPlayer.setDisplay(null);
            mediaPlayer.reset();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        hs_surface.setVisibility(View.GONE);
    }

这样就会调用surfaceDestroyed,见下:

@Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.v("surfaceDestroyed", "surfaceDestroyed");
        surfaceHolder = null;
    }


5:重复进行播放其他视频,此时又需要创建mediaplayer,创建surfaceholder,如此重复进行1、2、3、4步骤即可.


全部代码见下:

public class MediaPlayerService extends Service implements
		SurfaceHolder.Callback, OnCompletionListener {

	/**
	 * 目前支持视频和图片混合的话,图片播放每一张持续时间为8秒,
	 * 循环播放,视频播放支持MediaPlayer和videoView两种方式,目前采用的是MediaPlayer播放方式
	 * 
	 */
	private RelativeLayout home_sleep;
	private SurfaceView hs_surface;
	private ImageView hs_image;
	private SurfaceHolder surfaceHolder;
	private String TAG = MediaPlayerService.class.getSimpleName();
	
	private int mShowImageTime = 8000;

	// private String path;
	// 存储最终播放的位置
	private int lastplay = 0;
	// 多媒体播放列表
	private ArrayList<String> medialist;
	private MediaPlayer mediaPlayer;

	private WindowManager windowManager;
	/**
	 * 是否addview标志
	 */
	private boolean addViewFlag = false;
	private WindowManager.LayoutParams mLayoutParams;
	private  RelativeLayout hs_main;
	@Override
	public void onCreate() {
		super.onCreate();
		medialist = new ArrayList<String>();
		windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		home_sleep = (RelativeLayout) inflater.inflate(R.layout.home_sleep,
				null);
		home_sleep.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (addViewFlag) {
					windowManager.removeView(home_sleep);
					addViewFlag = false;
//					if (videoView.isPlaying()) {
//						videoView.stopPlayback();
//					}
					
					if(mediaPlayer.isPlaying()){
						mediaPlayer.stop();
						mediaPlayer.setDisplay(null);
						mediaPlayer.reset();
						mediaPlayer.release();
						mediaPlayer=null;
					}
				}
				return false;
			}
		});
		hs_surface = (SurfaceView) home_sleep.findViewById(R.id.hs_surface);
		hs_image=(ImageView) home_sleep.findViewById(R.id.hs_image);
		hs_surface.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (addViewFlag) {
					windowManager.removeView(home_sleep);
					addViewFlag = false;
//					if (videoView.isPlaying()) {
//						videoView.stopPlayback();
//					}
					
					if(mediaPlayer.isPlaying()){
						mediaPlayer.stop();
						mediaPlayer.setDisplay(null);
						mediaPlayer.reset();
						mediaPlayer.release();
						mediaPlayer=null;
					}
				}
				return false;
			}
		});
		videoView = (VideoView) home_sleep.findViewById(R.id.videoview);  
		hs_main=(RelativeLayout) home_sleep.findViewById(R.id.hs_main);
		mLayoutParams = new WindowManager.LayoutParams();
		mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
		mLayoutParams.alpha= (float)1.0;
		// 设置图片格式,效果为背景透明
		mLayoutParams.format = PixelFormat.RGBA_8888;
		// 设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)
		mLayoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
		// 调整悬浮窗显示的停靠位置为左侧置顶
		mLayoutParams.gravity = Gravity.BOTTOM;
		// 设置悬浮窗口长宽数据
		mLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
		mLayoutParams.height = 731;
		mLayoutParams.x = 0;
		mLayoutParams.y = 80;
	}
	
	 VideoView videoView ;

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent != null) {
			String action = intent.getStringExtra("action");
			Log.v("action", action+":" + medialist+":"+ medialist.size());
			if(!isTopActivy("com.rqst.RqstQueue.HomeActivity", this)){
				return 0;
			}
			if (action.equals("show")) {
				if (addViewFlag) {
					return 0;
				}
				medialist = intent.getStringArrayListExtra("path");
				if (medialist == null || medialist.size() == 0) {
					return 0;
				}else{
					for (int i = 0; i < medialist.size(); i++) {
						Log.d("debug", "item path:" + medialist.get(i));
					}
				}
				if (!addViewFlag) {
					windowManager.addView(home_sleep, mLayoutParams);
					addViewFlag = true;
				}
				home_sleep.setBackgroundColor(Color.WHITE);
				String path = medialist.get(0);
				play(path);
			} else {
				if (addViewFlag) {
					windowManager.removeView(home_sleep);
					addViewFlag = false;
				}
			}
		}
		return Service.START_NOT_STICKY;
	}
	
	
	/**
	 * 播放逻辑,列表文件依次播放,循环播放
	 */
	private void play(String path){
		Log.d("debug", TAG + "->play--------path:" + path);
		if (path != null && path.length() != 0) {
			if ((Utils.isvideo(path)) ) {
//				 RelativeLayout.LayoutParams  params =  new RelativeLayout.LayoutParams(1080,731);
//		         videoView.setLayoutParams(params);
//				 videoView.setVideoPath(path);  
//		         videoView.setMediaController(null); 
//		         videoView.setOnCompletionListener(new OnCompletionListener() {
//					
//					@Override
//					public void onCompletion(MediaPlayer mp) {
//						// TODO Auto-generated method stub
//						String deletedItem = null;
//						int size = medialist.size();
//						if (medialist != null && size != 0
//								&& Utils.isok(medialist.get(0))) {
//							deletedItem = medialist.remove(0);
//						}
//						//TODO 删除完成再添加,只是调换顺序而已
//						if (deletedItem != null) {
//							medialist.add(size-1 , deletedItem);
//						}
//						play(medialist.get(0));
//					}
//				});
//		         videoView.requestFocus();  
//		         videoView.start();
//		         videoView.setVisibility(View.VISIBLE);
				
				
				if(mediaPlayer==null){
					mediaPlayer = new MediaPlayer();
				}
				mediaPlayer.setOnCompletionListener(this);
				try {
					mediaPlayer.setDataSource(path);
					//移动
				} catch (Exception e) {
					e.printStackTrace();
					if (addViewFlag) {
						windowManager.removeView(home_sleep);
						addViewFlag = false;
					}
				}
				hs_surface.setVisibility(View.VISIBLE);
				surfaceHolder = hs_surface.getHolder();
				surfaceHolder.addCallback(this);
			} else if (Utils.ispic(path)) {
				
				hs_image.setVisibility(View.VISIBLE);
				Bitmap b = BitmapFactory.decodeFile(path);
				hs_image.setImageBitmap(b);
				hs_surface.setVisibility(View.GONE);
				picShowHandler.sendEmptyMessageDelayed(0, mShowImageTime);
//				videoView.setVisibility(View.INVISIBLE);
			}
		}else{
			//这种情况应该不会发生
			medialist.remove(0);
			play(medialist.get(0));
		}
	}
	
	
	private Handler picShowHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 0) {
				
				String deletedItem = null;
				int size = medialist.size();
				if (medialist != null && size != 0) {
					deletedItem = medialist.remove(0);
				}
				//TODO 删除完成再添加,只是调换顺序而已
				if (deletedItem != null) {
					medialist.add(size-1, deletedItem);
				}
				play(medialist.get(0));
			}
		};
	};

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		Log.v("surfaceCreated", "surfaceCreated");
		surfaceHolder = holder;
		mediaPlayer.setDisplay(holder);
//		mediaPlayer.setSurface(surfaceHolder.getSurface());
		try {
			mediaPlayer.prepare();
		} catch (IllegalStateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (lastplay < mediaPlayer.getDuration()) {
			mediaPlayer.seekTo(lastplay);
		}
		hs_image.setVisibility(View.GONE);
		mediaPlayer.start();
	}

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

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		Log.v("surfaceDestroyed", "surfaceDestroyed");
		surfaceHolder = null;
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		lastplay = 0;
		String deletedItem = null;
		int size = medialist.size();
		if (medialist != null && size != 0
				&& Utils.isok(medialist.get(0))) {
			deletedItem = medialist.remove(0);
		}
		//TODO 删除完成再添加,只是调换顺序而已
		if (deletedItem != null) {
			medialist.add(size-1 , deletedItem);
		}
		if(mediaPlayer!=null){
			mediaPlayer.setDisplay(null);
			mediaPlayer.reset();
			mediaPlayer.release();
			mediaPlayer = null;
		}
		hs_surface.setVisibility(View.GONE);
		hs_image.setVisibility(View.VISIBLE);
		play(medialist.get(0));
	}

	private  boolean isTopActivy(String cmdName, Context context) {
		ActivityManager manager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		List<RunningTaskInfo> runningTaskInfos = manager
				.getRunningTasks(Integer.MAX_VALUE);
		String cmpNameTemp = null;
		if (null != runningTaskInfos) {
			cmpNameTemp = (runningTaskInfos.get(0).topActivity).getClassName();
		}

		if (null == cmpNameTemp) {
			return false;
		}

		
		return cmpNameTemp.equals(cmdName);

	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值