一般项目很多地方都会用到视频播放器,需求简单点的只需要使用系统的Media Player或者VideoView即可。不过如果遇到某些复杂的功能要求或者自定义样式时,系统的播放器可能就不是那么适用了。
这时候就需要我们自己写一个播放器,用以实现日益复杂的播放功能。这里我们提到一款强大的视频播放框架Vitamio。有兴趣的同学可以先了解一下https://www.vitamio.org/。
之所以要用Vitamio,首先他支持的协议和文件类型广泛。MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频;MMS, RTSP, RTMP, HLS(m3u8) 等常见的多种视频流媒体协议,这些都是原生播放器所不具备的。其次Vitamio的兼容性很强,在绝大部分机型上都能正常运行。而且功能强大,比如支持视频的倍速播放,支持字母、音轨等。
话不多说,下面我们看看如何利用Vitamio做出一款功能强大的播放器。
首先说下我们的业务需求,1、需要支持http和rtmp两种协议,在线的直播、点播以及离线版的mp4文件。2、需要支持视频的变速播放功能。3、需要能在窗口、全屏模式间任意切换。其他的小需求如播放进度记忆、专辑列表播放、音量亮度调整这些等等。
代码贴在下面,这里主要讲一下重要功能的实现思路。
播放器的相关控件全部都写在一个layout里面,代码则使用一个工具类统一管理。这样需要用到的界面只需要把这个layout动态的加入布局根目录下即可。
对应系统的MediaPlayer和VideoView,Vitamio也有一个io.vov.vitamio.MediaPlayer和io.vov.vitamio.widget.VideoView,
这里使用io.vov.vitamio.widget.VideoView的setVideoPath()方法就可以轻松支持多种视频格式、协议。
使用io.vov.vitamio.MediaPlayer的setPlaybackSpeed()方法就可以控制播放倍速(取值范围0.5-2.0)
全屏和窗口模式的切换也不难,使用mContext.setRequestedOrientation()方法就可以切换当前Activity的横竖屏模式,竖屏时使用窗口播放(窗口模式下可以拖拽、缩放),横屏时使用全屏播放。无需重置正在播放的视频,这样就可以无缝切换了。
Java代码:
public class HttpVideoWindow { /*构造函数*/ public HttpVideoWindow(Activity activity, float[] screen, VideoCallback videoCallback) { this.callback = videoCallback; this.mContext = activity; LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.screen = screen; minWidth = DensityUtil.dip2px(activity, 192); minHeight = DensityUtil.dip2px(activity, 108); this.parentView = layoutInflater.inflate(R.layout.layout_video_play, null); this.videoView = parentView.findViewById(R.id.rl_video_view); videoView.setVisibility(View.GONE); ll_seek = videoView.findViewById(R.id.ll_seek); ll_seek.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //屏蔽点击事件 } }); this.fl_touchview = videoView.findViewById(R.id.fl_touchview); videoView.setOnTouchListener(videoPositionTouch); iv_playmessage = videoView.findViewById(R.id.iv_playmessage); video_epub = (io.vov.vitamio.widget.VideoView) videoView.findViewById(R.id.video_epub); /* 防止被仿真视图覆盖 */ // video_epub.getHolder().setFormat(PixelFormat.TRANSPARENT); // video_epub.setZOrderMediaOverlay(true); video_epub.getHolder().setType(SurfaceHolder.SURFACE_TYPE_HARDWARE); video_start = (VideoView) videoView.findViewById(R.id.video_start); video_start.setZOrderOnTop(true); /* 防止被仿真视图覆盖 */ video_start.setZOrderMediaOverlay(true); video_start.getHolder().setType(SurfaceHolder.SURFACE_TYPE_HARDWARE); ll_loading = videoView.findViewById(R.id.ll_loading); tv_buffer_info = (TextView) videoView.findViewById(R.id.tv_buffer_info); Animation rotateAnimation = AnimationUtils.loadAnimation(mContext, R.anim.font_loading_progressbar_anim); LinearInterpolator lin = new LinearInterpolator(); rotateAnimation.setInterpolator(lin); ImageView iv_reflsh = (ImageView) videoView.findViewById(R.id.iv_reflsh); iv_reflsh.startAnimation(rotateAnimation); View video_full = videoView.findViewById(R.id.video_full); video_full.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 点击全屏播放 if (playType == 0) { playType = 1; RelativeLayout.LayoutParams param = (RelativeLayout.LayoutParams) videoView.getLayoutParams(); lastPotion = new int[]{param.leftMargin, param.topMargin, param.width, param.height}; rl_window_video.setVisibility(View.GONE); mContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } else { stopFullPlay(); } } }); video_close = (ImageView) videoView.findViewById(R.id.video_close); video_close.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 点击停止播放 closeVideo(); } }); ll_video_complete = (LinearLayout) videoView.findViewById(R.id.ll_video_complete); tv_replay_button = (TextView) videoView.findViewById(R.id.tv_replay_button); tv_replay_button.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { ll_video_complete.setVisibility(View.GONE); String path = (String) videoView.getTag(); currentPosition=0; sb_progress.setProgress((int) currentPosition); sb_progress_full.setProgress((int) currentPosition); if (!TextUtils.isEmpty(path)) playVideoWithId(path, (String)videoView.getTag(videoIdTag), false); //replayVideo(0); } }); tv_share_button = (TextView) videoView.findViewById(R.id.tv_share_button); video_scale = (ImageView) videoView.findViewById(R.id.video_scale); video_scale.setOnTouchListener(videoScaleTouch); sb_progress = (SeekBar) videoView.findViewById(R.id.sb_progress); sb_progress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar arg0) { // 这个里面才更新进度 ll_video_complete.setVisibility(View.GONE); startTouch = false; if (mediaplayer != null && isPrepared) { int progress = sb_progress.getProgress(); isFromTouch = true; sb_progress.removeCallbacks(seekAction); sb_progress.postDelayed(seekAction, 5000); mediaplayer.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar arg0) { startTouch = true; } @Override public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) { if (progress > max) { progress = max; } set(progress, max); sb_progress.setProgress(progress); sb_progress_full.setProgress(progress); } }); tv_time = (TextView) videoView.findViewById(R.id.tv_time); tv_time_temp = (TextView) videoView.findViewById(R.id.tv_time_temp); bt_play = (ImageView) videoView.findViewById(R.id.bt_play); bt_play.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { pauseOrResumeVideo(); } }); bt_pause = (ImageView) videoView.findViewById(R.id.bt_pause); bt_pause.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { pauseOrResumeVideo(); } }); mHiddenBottom = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f); mHiddenBottom.setDuration(300); mShowBottom = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f); mShowBottom.setDuration(300); mHiddenTop = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f); mHiddenTop.setDuration(300); mShowTop = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f); mShowTop.setDuration(300); alpha = new AlphaAnimation(1.0f, 0.0f); alpha.setDuration(1000); // 全屏播放的相关控件 rl_window_video = videoView.findViewById(R.id.rl_window_video); rl_full_video = videoView.findViewById(R.id.rl_full_video); tv_vedioname = (TextView) videoView.findViewById(R.id.tv_vedioname); lv_vediolist = (ListView) videoView.findViewById(R.id.lv_vediolist); ll_seek_full = videoView.findViewById(R.id.ll_seek_full); ll_seek_full.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { } }); ll_back = videoView.findViewById(R.id.ll_back); ll_back.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { } }); bt_stop = videoView.findViewById(R.id.bt_stop); bt_stop.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (playType == 1) { playType = 0; rl_full_video.setVisibility(View.GONE); mContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } }); sb_progress_full = (SeekBar) videoView.findViewById(R.id.sb_progress_full); sb_progress_full.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar arg0) { // 这个里面才更新进度 ll_video_complete.setVisibility(View.GONE); startTouch = false; if (mediaplayer != null && isPrepared) { int progress = sb_progress_full.getProgress(); isFromTouch = true; sb_progress_full.removeCallbacks(seekAction); sb_progress_full.postDelayed(seekAction, 5000); mediaplayer.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar arg0) { startTouch = true; } @Override public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) { if (progress > max) { progress = max; } set(progress, max); sb_progress.setProgress(progress); sb_progress_full.setProgress(progress); } }); tv_time_temp_full = (TextView) videoView.findViewById(R.id.tv_time_temp_full); tv_time_full = (TextView) videoView.findViewById(R.id.tv_time_full); bt_play_full = (ImageView) videoView.findViewById(R.id.bt_play_full); bt_pause_full = (ImageView) videoView.findViewById(R.id.bt_pause_full); bt_play_full.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { pauseOrResumeVideo(); } }); bt_pause_full.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { pauseOrResumeVideo(); } }); iv_last = videoView.findViewById(R.id.iv_last); iv_last.setVisibility(View.GONE); iv_last.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (temp > 0 && vedioList != null && vedioList.size() > 0) { alert2 = DialogUtil.showAlert(mContext, "温馨提示", "是否播放上一节?", "确定", "取消", new OnClickListener() { public void onClick(View v) { temp = temp - 1; VideoBean bean = vedioList.get(temp); stopVideo(); String path = bean.getVideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,bean.getId()); playVideoWithId(path,bean.getId(), path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); tv_vedioname.setText(bean.getName()); showLastAndNext(temp, size); vAdapter.notifyDataSetChanged(); callback.onVideoRecord(bean); alert2.dismiss(); } }, new OnClickListener() { public void onClick(View v) { alert2.dismiss(); } }); } } }); iv_next = videoView.findViewById(R.id.iv_next); iv_next.setVisibility(View.GONE); iv_next.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (vedioList != null && temp < vedioList.size() - 1 && vedioList.size() > 0) { alert2 = DialogUtil.showAlert(mContext, "温馨提示", "是否播放下一节?", "确定", "取消", new OnClickListener() { public void onClick(View v) { temp = temp + 1; VideoBean bean = vedioList.get(temp); stopVideo(); String path = bean.getVideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,bean.getId()); playVideoWithId(path,bean.getId(), path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); tv_vedioname.setText(bean.getName()); showLastAndNext(temp, size); vAdapter.notifyDataSetChanged(); callback.onVideoRecord(bean); alert2.dismiss(); } }, new OnClickListener() { public void onClick(View v) { alert2.dismiss(); } }); } } }); iv_more = videoView.findViewById(R.id.iv_more); iv_more.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (ll_more.getVisibility() == View.VISIBLE) { ll_more.setVisibility(View.GONE); // 恢复自动隐藏 } else { ll_more.setVisibility(View.VISIBLE); ll_vediolist.setVisibility(View.GONE); iv_vediolist.setImageResource(R.drawable.vediolist_down); // 不再自动隐藏 } } }); ll_more = videoView.findViewById(R.id.ll_more); ll_more.setVisibility(View.GONE); ll_more.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { } }); tv_play_speed = (TextView) videoView.findViewById(R.id.tv_play_speed); iv_slow = videoView.findViewById(R.id.iv_slow); iv_slow.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 减慢播放速度 if (mediaplayer != null && isPrepared) { vedio_speed = vedio_speed - 0.1f; if (vedio_speed < 0.5f) { vedio_speed = 0.5f; } mediaplayer.setPlaybackSpeed(vedio_speed); BigDecimal b = new BigDecimal(vedio_speed); float f1 = b.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); tv_play_speed.setText(f1 + "x"); } } }); iv_quick = videoView.findViewById(R.id.iv_quick); iv_quick.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // 加快播放速度 if (mediaplayer != null && isPrepared) { vedio_speed = vedio_speed + 0.1f; if (vedio_speed > 2.0f) { vedio_speed = 2.0f; } mediaplayer.setPlaybackSpeed(vedio_speed); BigDecimal b = new BigDecimal(vedio_speed); float f1 = b.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); tv_play_speed.setText(f1 + "x"); } } }); ll_vediolist = videoView.findViewById(R.id.ll_vediolist); ll_vediolist.setVisibility(View.GONE); iv_vediolist = (ImageView) videoView.findViewById(R.id.iv_vediolist); rl_voice = videoView.findViewById(R.id.rl_voice); rl_voice.setVisibility(View.GONE); rl_light = videoView.findViewById(R.id.rl_light); rl_light.setVisibility(View.GONE); roundPb_light = (RoundProgressBar) videoView.findViewById(R.id.roundPb_light); roundPb_voice = (RoundProgressBar) videoView.findViewById(R.id.roundPb_voice); iv_lock = (ImageView) videoView.findViewById(R.id.iv_lock); iv_lock.setVisibility(View.GONE); iv_lock.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (islock) { islock = false; iv_lock.setImageResource(R.drawable.ic_lock); isShow = true; ll_seek_full.startAnimation(mShowBottom); ll_seek_full.setVisibility(View.VISIBLE); ll_back.startAnimation(mShowTop); ll_back.setVisibility(View.VISIBLE); ll_seek_full.removeCallbacks(hideAction2); ll_seek_full.postDelayed(hideAction2, 10000); } else { islock = true; iv_lock.setImageResource(R.drawable.ic_locked); DialogUtil.showToast(mContext, "已锁屏"); ll_seek_full.startAnimation(mHiddenBottom); ll_seek_full.setVisibility(View.GONE); ll_back.startAnimation(mHiddenTop); ll_back.setVisibility(View.GONE); ll_seek_full.removeCallbacks(hideAction2); ll_seek_full.postDelayed(hideAction2, 10000); if (ll_vediolist.getVisibility() == View.VISIBLE) { ll_vediolist.setVisibility(View.GONE); iv_vediolist.setImageResource(R.drawable.vediolist_down); // 恢复自动隐藏 } if (ll_more.getVisibility() == View.VISIBLE) { ll_more.setVisibility(View.GONE); } } } }); rl_vediolist = videoView.findViewById(R.id.rl_vediolist); rl_vediolist.setVisibility(View.GONE); rl_vediolist.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { if (ll_vediolist.getVisibility() == View.VISIBLE) { ll_vediolist.setVisibility(View.GONE); iv_vediolist.setImageResource(R.drawable.vediolist_down); // 恢复自动隐藏 } else { ll_vediolist.setVisibility(View.VISIBLE); iv_vediolist.setImageResource(R.drawable.vediolist_up); ll_more.setVisibility(View.GONE); // 不再自动隐藏 } } }); tv_connnect = (TextView) videoView.findViewById(R.id.tv_connnect); audiomanager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); maxVolume = audiomanager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); // STREAM_MUSIC该类型为多媒体声音,STREAM_SYSTEM系统音,STREAM_VOICE_CALL通话音,STREAM_RING铃音,STREAM_ALARM闹铃音 } private static final int videoIdTag = R.string.video; private int playType;// 播放类型,0窗口1全屏 private int bgColor_f2f2f2 = Color.parseColor("#f2f2f2"); private Activity mContext;// 调用浮窗的Activity private View parentView;// 浮窗根视图 private float[] screen; private View videoView, fl_touchview, iv_playmessage, ll_loading; private TextView tv_buffer_info;// 缓冲提示 private int bufferSpeed; private io.vov.vitamio.widget.VideoView video_epub;// 视频浮窗的播放器 private VideoView video_start;// 视频头 private io.vov.vitamio.MediaPlayer mediaplayer = null;// 多媒体播放器 private Bitmap bmp;// 当前视频的截图 private boolean isPrepared;// 准备完毕 private long currentPosition;// 当前视频进度 private int max;// 视频总长度 private boolean isStartEnded;// 视频头播放完毕 private View ll_seek; private boolean isShow;// 是否显示进度栏 private ImageView bt_play, bt_play_full;// 播放按钮 private ImageView bt_pause, bt_pause_full;// 暂停按钮 /* 视频进度的显示 */ private SeekBar sb_progress, sb_progress_full; private Timer timer; private TimerTask task; private int count = 0; private boolean startTouch; private TextView tv_time, tv_time_temp, tv_time_full, tv_time_temp_full; private int[] lastPotion;// 记录窗口的位置 private View rl_window_video, rl_full_video;// 全屏窗口切换控件 private View ll_seek_full, ll_back; private View bt_stop;// 退出全屏 private View iv_last;// 播放上一个 private View iv_next;// 播放下一个 private View iv_more, ll_more;// 加速设置 private View ll_vediolist, rl_vediolist;// 视频列表 private int temp, size; private TextView tv_play_speed, tv_connnect, tv_vedioname;// 播放速度 private float vedio_speed = 1.0f; private float video_ratio = 16.0f/9; private View iv_slow, iv_quick; private ImageView iv_vediolist; private LinearLayout ll_video_complete; //播放结束界面 private TextView tv_replay_button; //重播按钮 private TextView tv_share_button; //分享按钮 private ImageView video_scale; //縮放按钮 private ImageView video_close; //关闭按钮 // 音量、亮度相关 private View rl_voice, rl_light; private RoundProgressBar roundPb_light, roundPb_voice; private int currentVolume, currentLight; private AudioManager audiomanager; private int maxVolume; // 锁屏 private ImageView iv_lock; private boolean islock; // 动画相关 private TranslateAnimation mShowBottom, mHiddenBottom, mShowTop, mHiddenTop; private AlphaAnimation alpha; // 视频列表 private ArrayList<VideoBean> vedioList;// 视频列表 private ListView lv_vediolist; private VedioListAdapter vAdapter; // 收费列表 private int paycount = 10 * 60 * 1000; private BookBean bookbean; private boolean isBuy; private boolean buyPause; private Dialog alert; private Dialog alert2; private VideoCallback callback; private long tempPosition; private boolean isComplete = false;//是否播放完成 /*private int maxBufferSize;//默认缓冲池大小*/ public interface VideoCallback { void closeAudio();// 播放视频需要停止其他音频 void showWebVideo(int chapIndex);// 关闭视频弹窗,需要显示web页面视频标签 void onVideoRecord(VideoBean bean);// 修改视频恢复记录 } private Runnable hideAction = new Runnable() { @Override public void run() { isShow = false; ll_seek.removeCallbacks(hideAction); ll_seek.startAnimation(mHiddenBottom); ll_seek.setVisibility(View.GONE); } }; private Runnable hideAction2 = new Runnable() { @Override public void run() { if (ll_vediolist.getVisibility() == View.VISIBLE) { ll_seek_full.postDelayed(hideAction2, 10000); } else { isShow = false; ll_seek_full.removeCallbacks(hideAction2); iv_lock.setVisibility(View.GONE); ll_seek_full.startAnimation(mHiddenBottom); ll_seek_full.setVisibility(View.GONE); ll_back.startAnimation(mHiddenTop); ll_back.setVisibility(View.GONE); // if (ll_vediolist.getVisibility() == View.VISIBLE) { // ll_vediolist.setVisibility(View.GONE); // iv_vediolist.setImageResource(R.drawable.vediolist_down); // // 恢复自动隐藏 // } if (ll_more.getVisibility() == View.VISIBLE) { ll_more.setVisibility(View.GONE); } } } }; private Callback videoCallback = new Callback() { public void surfaceDestroyed(SurfaceHolder arg0) { // Logger.e("surface", "surfaceDestroyed"); if (null != mediaplayer && isPrepared) { try { currentPosition = mediaplayer.getCurrentPosition(); mediaplayer.pause(); } catch (Exception e) { if (videoView.getTag() != null) currentPosition = SharedUtil.getVedioProgress(mContext, (String) videoView.getTag()); } } } public void surfaceCreated(SurfaceHolder holder) { // Logger.e("surface", "surfaceCreated"); if (mediaplayer != null && isPrepared && isStartEnded) { // 此条件判断为用户跳出程序后又返回 // DialogUtil.showToast(mContext, "亲,欢迎回来继续学习" + // currentPosition); if (bmp != null) { Canvas canvas = holder.lockCanvas(); int w = bmp.getWidth(); int h = bmp.getHeight(); Logger.i("图片尺寸", w + "," + h); RectF rectF = new RectF(0, 0, w, h); canvas.drawBitmap(bmp, null, rectF, null); holder.unlockCanvasAndPost(canvas); } try { video_epub.seekTo(currentPosition); } catch (Exception e) { e.printStackTrace(); } } } public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { Logger.e("surface", "surfaceChanged"); } }; private io.vov.vitamio.MediaPlayer.OnPreparedListener videoPreparedListener = new io.vov.vitamio.MediaPlayer.OnPreparedListener() { @Override public void onPrepared(io.vov.vitamio.MediaPlayer mediaPlayer) { // 视频准备完毕,开始播放 // try { // /* 根据视频当前尺寸重设浮窗的尺寸 */ ll_video_complete.setVisibility(View.GONE); float ratio = mediaPlayer.getVideoAspectRatio(); video_ratio = ratio; isShow = true; if (isAnchor) { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_FIT_PARENT, ratio); ll_seek.setVisibility(View.VISIBLE); ll_seek.removeCallbacks(hideAction); ll_seek.postDelayed(hideAction, 10000); }else if (playType == 0) { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_STRETCH, ratio); ll_seek.setVisibility(View.VISIBLE); ll_seek.removeCallbacks(hideAction); ll_seek.postDelayed(hideAction, 10000); } else { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_SCALE, ratio); ll_seek_full.setVisibility(View.VISIBLE); ll_back.setVisibility(View.VISIBLE); iv_lock.setVisibility(View.VISIBLE); ll_seek_full.removeCallbacks(hideAction2); ll_seek_full.postDelayed(hideAction2, 10000); } mediaplayer = mediaPlayer; mediaplayer.setPlaybackSpeed(1.0f); vedio_speed = 1.0f; tv_play_speed.setText("1.0x"); video_epub.setOnCompletionListener(videoCompletionListener); video_epub.setOnErrorListener(videoErrorListener); video_epub.setOnInfoListener(videoInfoListener); video_epub.setOnBufferingUpdateListener(videoBufferListener); isPrepared = true; bt_play.setVisibility(View.INVISIBLE); bt_pause.setVisibility(View.VISIBLE); bt_play_full.setVisibility(View.INVISIBLE); bt_pause_full.setVisibility(View.VISIBLE); try { max = (int) mediaplayer.getDuration(); sb_progress.setMax(max); sb_progress_full.setMax(max); } catch (Exception e) { e.printStackTrace(); } doPlay(false); // 新建一个计时器当播放视频时用来同步更新进度条 if (timer == null) { timer = new Timer(); task = new TimerTask() { public void run() { mContext.runOnUiThread(new Runnable() { @Override public void run() { try { if (mediaplayer != null && isPrepared && !startTouch && mediaplayer.isPlaying()) { int progress = (int) mediaplayer.getCurrentPosition(); if (progress > max) { progress = max; } set(progress, max); sb_progress.setProgress(progress); sb_progress_full.setProgress(progress); // 判断收费 if (progress > paycount + 500) { if (bookbean != null && !isBuy && max != 0) { // 如果播放时间超过10分钟,进行收费提醒 sb_progress.post(new Runnable() { public void run() { sb_progress.setProgress(paycount); if (mediaplayer != null && isPrepared == true) { try { buyPause = true; currentPosition = mediaplayer.getCurrentPosition(); mediaplayer.pause(); iv_playmessage.setVisibility(View.VISIBLE); fl_touchview.setBackgroundResource(R.color.bg_pause); bt_play.setVisibility(View.VISIBLE); bt_pause.setVisibility(View.INVISIBLE); bt_play_full.setVisibility(View.VISIBLE); bt_pause_full.setVisibility(View.INVISIBLE); } catch (Exception e) { e.printStackTrace(); } } if (alert == null || !alert.isShowing()) { // 这里加个判断如果收费框没有弹出再弹窗,保证只有1个弹窗提醒 alert = DialogUtil.showAlert(mContext, mContext.getResources().getString(R.string.str_wenxin_prompt), "未购买只能观看前10分钟\n继续观看,请先购买!", mContext.getResources().getString(R.string.str_buy_now), mContext.getResources().getString(R.string.dismiss), new OnClickListener() { @Override public void onClick(View arg0) { alert.dismiss(); // 立即购买方法 if (bookbean != null && !isBuy) { if (bookbean.getPackageType() == 3) { // 激活购书大礼包直接打开网页 Intent intent = new Intent(mContext, BookWebActivity.class); intent.putExtra("title", "激活"); String urlString = "http://e.100xuexi.com/ComGift.aspx?id=" + bookbean.getId(); intent.putExtra("url", urlString); mContext.startActivityForResult(intent, Request_Result_Code.GET_PACKAGE); } else { Intent intent = new Intent(mContext, PayActivity.class); intent.putExtra("bookid", bookbean.getId()); intent.putExtra("bean", bookbean); intent.putExtra("frominfo", false); mContext.startActivity(intent); } } } }, new OnClickListener() { @Override public void onClick(View arg0) { alert.dismiss(); } }); } } }); } } // 保存一下视频进度 count++; tempPosition = mediaplayer.getCurrentPosition(); if (count % 20 == 0) { Logger.e("saveVedioProgress", "保存进度" + progress); try { bmp = mediaplayer.getCurrentFrame(); } catch (Exception e) { e.printStackTrace(); } SharedUtil.saveVedioProgress(mContext, (String) videoView.getTag(), progress); } } } catch (IllegalStateException e) { } catch (Exception e) { e.printStackTrace(); } } }); } }; timer.schedule(task, 0, 500); } } }; private io.vov.vitamio.MediaPlayer.OnCompletionListener videoCompletionListener = new io.vov.vitamio.MediaPlayer.OnCompletionListener() { @Override public void onCompletion(io.vov.vitamio.MediaPlayer mp) { // 播放完毕再次播放 try { isComplete = true; if (!HttpUtil.isConnectedToInternet(mContext)) { DialogUtil.showToast(mContext, "本视频需要联网才能观看,请先联网!"); return; } Logger.e("","播放结束"+tempPosition+"/"+mp.getCurrentPosition()+"/"+max); if (tempPosition - max < -5000) { DialogUtil.showToast(mContext, "网络异常!重新连接"); String path = (String) videoView.getTag(); if (!TextUtils.isEmpty(path)) playVideoWithId(path,(String)videoView.getTag(videoIdTag),false); //playVideo(path, false); return; } if (videoView.getTag() != null) SharedUtil.saveVedioProgress(mContext, (String) videoView.getTag(), 0); if (vedioList != null && temp < vedioList.size() - 1 && vedioList.size() > 0) { DialogUtil.showToast(mContext, "播放完毕!自动播放下一节"); temp = temp + 1; VideoBean bean = vedioList.get(temp); stopVideo(); String path = bean.getVideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,bean.getId()); playVideoWithId(path,bean.getId(), path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); tv_vedioname.setText(bean.getName()); showLastAndNext(temp, size); vAdapter.notifyDataSetChanged(); callback.onVideoRecord(bean); return; } if (isAnchor){ bt_play.setVisibility(View.VISIBLE); bt_pause.setVisibility(View.INVISIBLE); bt_play_full.setVisibility(View.VISIBLE); bt_pause_full.setVisibility(View.INVISIBLE); ll_video_complete.setVisibility(View.VISIBLE); return; } /* DialogUtil.showToast(mContext, "播放完毕!重新播放"); stopVideo(); String path = (String) videoView.getTag(); playVideo(path, false);*/ DialogUtil.showToast(mContext, "播放完毕!"); closeVideo(); } catch (Exception e) { e.printStackTrace(); } } }; private io.vov.vitamio.MediaPlayer.OnErrorListener videoErrorListener = new io.vov.vitamio.MediaPlayer.OnErrorListener() { public boolean onError(io.vov.vitamio.MediaPlayer mp, int what, int extra) { // 播放错误 try { DialogUtil.showToast(mContext, "亲,视频出错啦!请重新播放"); closeVideo(); } catch (Exception e) { e.printStackTrace(); } return false; } }; private io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener videoBufferListener = new io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener() { @Override public void onBufferingUpdate(io.vov.vitamio.MediaPlayer mp, int percent) { Logger.e("","buffer:" + percent ); if (mp != null && isPrepared == true && isStartEnded && !isFromTouch) { try { if (mp.isPlaying()) { if (percent < 30) { mp.pause(); ll_loading.setVisibility(View.VISIBLE); } else { ll_loading.setVisibility(View.GONE); } } else { if (percent > 95) { if (!buyPause) { mp.start(); ll_loading.setVisibility(View.GONE); } else { buyPause = false; } //缓冲池快满了,这时候将缓冲池增大 /* maxBufferSize = maxBufferSize + 128 * 1024 ; video_epub.setBufferSize(maxBufferSize); Logger.e("","bufferSize:" + maxBufferSize );*/ } else { ll_loading.setVisibility(View.VISIBLE); tv_buffer_info.setText("缓冲中..." + percent + "%\n" + String.valueOf(bufferSpeed) + "KB/S"); } } } catch (Exception e) { } } } }; private io.vov.vitamio.MediaPlayer.OnInfoListener videoInfoListener = new io.vov.vitamio.MediaPlayer.OnInfoListener() { public boolean onInfo(io.vov.vitamio.MediaPlayer arg0, int what, int arg2) { // 缓冲监听 switch (what) { case io.vov.vitamio.MediaPlayer.MEDIA_INFO_BUFFERING_END : // 缓冲结束处理 try { if (mediaplayer != null && isPrepared == true && isStartEnded) { ll_loading.setVisibility(View.GONE); mediaplayer.start(); } } catch (Exception e) { e.printStackTrace(); } break; case io.vov.vitamio.MediaPlayer.MEDIA_INFO_DOWNLOAD_RATE_CHANGED : // 缓冲速度处理 bufferSpeed = arg2; break; } return true; } }; private int minWidth, minHeight; private View.OnTouchListener videoScaleTouch = new View.OnTouchListener() { private int lastX, lastY; private float mPosX, mPosY, mCurrentPosX, mCurrentPosY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN :// 按下时获取xy坐标 lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); mPosX = event.getX(); mPosY = event.getY(); if (minWidth > videoView.getWidth()) { minWidth = videoView.getWidth(); } if (minHeight > videoView.getHeight()) { minHeight = videoView.getHeight(); } break; case MotionEvent.ACTION_MOVE :// 移动 mCurrentPosX = event.getX(); mCurrentPosY = event.getY(); if (Math.abs(mCurrentPosX - mPosX) > 20 || Math.abs(mCurrentPosY - mPosY) > 20) { // 为保证精准度,限制移动像素达到5才执行变更操作 // float videoRatio = 16f/9; // if (mediaplayer != null && isPrepared) // videoRatio = mediaplayer.getVideoAspectRatio(); mPosX = mCurrentPosX; mPosY = mCurrentPosY; // if(mCurrentPosX/mCurrentPosY>videoRatio){ // // }else{ // // } int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; if(dy==0) dy=1; float dRatio = (float)Math.abs(dx)/Math.abs(dy); if(dRatio>1){ /*以X轴移动为准*/ dy = (int) (dx / video_ratio); }else{ dx = (int) (dy * video_ratio); } int scale_left = videoView.getLeft() + dx; int scale_top = videoView.getTop() + dy; int scale_right = videoView.getRight(); int scale_bottom = videoView.getBottom(); if (scale_top < 0) { scale_top = 0; scale_left =scale_right - (int) ((scale_bottom - scale_top)*video_ratio); } if (scale_bottom - scale_top < minHeight) { scale_top = scale_bottom - minHeight; scale_left =scale_right - (int) ((scale_bottom - scale_top)*video_ratio); } if (scale_left < 0) { scale_left = 0; scale_top = (int) (scale_bottom - (scale_right - scale_left)/video_ratio); } if (scale_right - scale_left < minWidth) { scale_left = scale_right - minWidth; scale_top = (int) (scale_bottom - (scale_right - scale_left)/video_ratio); } int width = scale_right - scale_left; int height = scale_bottom - scale_top; RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height); param.leftMargin = scale_left;// 操作之后控件左上角的横坐标 param.topMargin = scale_top;// 操作之后控件左上角的纵坐标 videoView.setLayoutParams(param); // video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_FIT_PARENT, video_ratio); // videoView.layout(scale_left, scale_top, scale_right, // scale_bottom); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); } break; case MotionEvent.ACTION_UP : // 拖动停止 int right = videoView.getRight(); int bottom = videoView.getBottom(); int left = videoView.getLeft(); int top = videoView.getTop(); videoLayout(left, top, right, bottom); break; } return true; } }; private View.OnTouchListener videoPositionTouch = new View.OnTouchListener() { float mPosX, mPosY, mCurrentPosX, mCurrentPosY; int lastX, lastY; private long clickTimeUDown, clickTimeUp; private boolean waitDoubleClick; private int changtype; private int change; private Runnable doubleClickAction = new Runnable() { @Override public void run() { waitDoubleClick = false; } }; @Override public boolean onTouch(View arg0, MotionEvent event) { // 拖拽移动视频位置 switch (event.getAction()) { case MotionEvent.ACTION_DOWN :// 按下时获取xy坐标 changtype = 0;// 每次按下会重新采集变更类型 change = 0; lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); mPosX = event.getX(); mPosY = event.getY(); clickTimeUDown = System.currentTimeMillis(); if (waitDoubleClick) { // 双击暂停或者播放 waitDoubleClick = false; pauseOrResumeVideo(); // if (iv_playmessage.getVisibility() == View.VISIBLE) { // // 恢复播放 // iv_playmessage.setVisibility(View.GONE); // fl_touchview.setBackgroundResource(R.color.transparent); // resumeVideo(); // } else { // // 暂停 // iv_playmessage.setVisibility(View.VISIBLE); // fl_touchview.setBackgroundResource(R.color.bg_pause); // pauseVideo(); // } } else { waitDoubleClick = true; videoView.removeCallbacks(doubleClickAction); videoView.postDelayed(doubleClickAction, 300); } ll_seek.removeCallbacks(hideAction); ll_seek_full.removeCallbacks(hideAction2); break; case MotionEvent.ACTION_MOVE : if (isAnchor) { break; } if (islock && playType == 1) { break; } mCurrentPosX = event.getX(); mCurrentPosY = event.getY(); if (Math.abs(mCurrentPosX - mPosX) > 10 || Math.abs(mCurrentPosY - mPosY) > 10) { // 为保证精准度,限制移动像素达到5才执行变更操作 if (playType == 1) { if ((Math.abs(mCurrentPosX - mPosX) < Math.abs(mCurrentPosY - mPosY)) && changtype != 3) { // 判断上下滑动事件 if (mPosX < screen[1] / 2 && mCurrentPosX < screen[1] / 2 && changtype != 2) { // 左侧滑动,判断为修改音量 rl_voice.setVisibility(View.VISIBLE); changeVoice(mCurrentPosY - mPosY, screen[0]); if (changtype == 0) { // 若是第一次判断,修改变更类型为1,变更音量,此时不再接受其他类型判断 changtype = 1; } } else if (mPosX > screen[1] / 2 && mCurrentPosX > screen[1] / 2 && changtype != 1) { // 右侧滑动,判断为修改亮度 rl_light.setVisibility(View.VISIBLE); changeLight(mCurrentPosY - mPosY, screen[0]); if (changtype == 0) { // 若是第一次判断,修改变更类型为2,变更亮度,此时不再接受其他类型判断 changtype = 2; } } } else if ((Math.abs(mCurrentPosX - mPosX) > Math.abs(mCurrentPosY - mPosY)) && changtype != 1 && changtype != 2) { // 左右滑动,修改视频进度条 if (isShow == false) { isShow = true; ll_seek_full.startAnimation(mShowBottom); ll_seek_full.setVisibility(View.VISIBLE); ll_back.startAnimation(mShowTop); ll_back.setVisibility(View.VISIBLE); iv_lock.setVisibility(View.VISIBLE); } change = change + (int) (0.2f * sb_progress.getMax() * (mCurrentPosX - mPosX) / screen[1]); tv_connnect.setVisibility(View.VISIBLE); if (change < 0) { int a = -change; tv_connnect.setText("-" + TimeUtil.stringForTime(a)); } else { tv_connnect.setText("+" + TimeUtil.stringForTime(change)); } if (changtype == 0) { // 若是第一次判断,修改变更类型为3,变更视频,此时不再接受其他类型判断 changtype = 3; } } } mPosX = mCurrentPosX; mPosY = mCurrentPosY; int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; int left = videoView.getLeft() + dx; int top = videoView.getTop() + dy; int right = videoView.getRight() + dx; int bottom = videoView.getBottom() + dy; if (left < 0) { left = 0; right = left + videoView.getWidth(); } if (right > parentView.getWidth()) { right = parentView.getWidth(); left = right - videoView.getWidth(); } if (top < 0) { top = 0; bottom = top + videoView.getHeight(); } if (bottom > parentView.getHeight()) { bottom = parentView.getHeight(); top = bottom - videoView.getHeight(); } int width = right - left; int height = bottom - top; RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height); param.leftMargin = left;// 操作之后控件左上角的横坐标 param.topMargin = top;// 操作之后控件左上角的纵坐标 videoView.setLayoutParams(param); // Logger.e("video", left+","+top+","+right+","+bottom); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); } break; case MotionEvent.ACTION_UP :// 获取移动结束后的坐标点 int right = videoView.getRight(); int bottom = videoView.getBottom(); int left = videoView.getLeft(); int top = videoView.getTop(); videoLayout(left, top, right, bottom); if (Math.abs(event.getRawX() - lastX) < 10 && Math.abs(event.getRawY() - lastY) < 10 && System.currentTimeMillis() - clickTimeUp > 300 && System.currentTimeMillis() - clickTimeUDown < 150) { clickTimeUp = System.currentTimeMillis(); /* 单击显示或隐藏工具栏 */ if (playType == 0) {// 窗口模式 if (isShow == false) { isShow = true; ll_seek.setVisibility(View.VISIBLE); ll_seek.startAnimation(mShowBottom); } else { isShow = false; ll_seek.startAnimation(mHiddenBottom); ll_seek.setVisibility(View.GONE); } } else {// 全屏模式 if (iv_lock.getVisibility() == View.GONE) { iv_lock.setVisibility(View.VISIBLE); } else { iv_lock.setVisibility(View.GONE); } if (islock) { return true; } if (isShow == false) { isShow = true; ll_seek_full.startAnimation(mShowBottom); ll_seek_full.setVisibility(View.VISIBLE); ll_back.startAnimation(mShowTop); ll_back.setVisibility(View.VISIBLE); } else { isShow = false; ll_seek_full.startAnimation(mHiddenBottom); ll_seek_full.setVisibility(View.GONE); ll_back.startAnimation(mHiddenTop); ll_back.setVisibility(View.GONE); if (ll_vediolist.getVisibility() == View.VISIBLE) { ll_vediolist.setVisibility(View.GONE); iv_vediolist.setImageResource(R.drawable.vediolist_down); // 恢复自动隐藏 } if (ll_more.getVisibility() == View.VISIBLE) { ll_more.setVisibility(View.GONE); } } } } tv_connnect.setText(""); if (rl_light.getVisibility() == View.VISIBLE) { // 执行渐隐动画 rl_light.startAnimation(alpha); rl_light.setVisibility(View.GONE); } if (rl_voice.getVisibility() == View.VISIBLE) { // 执行渐隐动画 rl_voice.startAnimation(alpha); rl_voice.setVisibility(View.GONE); } if (changtype == 3 && Math.abs(change) > 5000) { changeSeekbar(change); } if (playType == 0) { ll_seek.postDelayed(hideAction, 10000); } if (playType == 1) { ll_seek_full.postDelayed(hideAction2, 10000); } break; } return true; } }; private boolean isFromTouch;//是否用户主动操作进度条 Runnable seekAction = new Runnable() { @Override public void run() { isFromTouch = false; } }; /** * 直接全屏播放 * * @param path * @param currentPosition **/ public void directlyFullPlay(String path, long currentPosition) { try { this.currentPosition = currentPosition; videoLayout(0, 0, 0, 0); videoView.setTag(path); playVideoWithId(path,null,false); //playVideo(path, false);// 播放视频 mContext.runOnUiThread(new Runnable() { @Override public void run() { videoView.setVisibility(View.VISIBLE); } }); RelativeLayout.LayoutParams param = (RelativeLayout.LayoutParams) videoView.getLayoutParams(); lastPotion = new int[]{param.leftMargin, param.topMargin, param.width, param.height}; rl_window_video.setVisibility(View.GONE); mContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); } catch (Exception e) { e.printStackTrace(); } } /** 根据滑动距离变更亮度条,正值变大,负值变小 */ private void changeLight(float f, float height) { float change = f / height;// 根据滑动距离计算变动长度,正值向下,复制向上 int changei = (int) (change * 255); int light = currentLight; int afterLight = light - changei; if (afterLight < 1) { afterLight = 1; } if (afterLight > 255) { afterLight = 255; } currentLight = afterLight; setbrightnessValue((float) currentLight); int p = (currentLight * 100) / 255; roundPb_light.setProgress(p); } /** 设置屏幕亮度 */ private void setbrightnessValue(float progress) { if (progress == 0) { // 亮度为0程序会自动锁屏黑掉,所以设置最小为1 progress = 1; } SystemBrightManager.setBrightness(mContext, (int) progress); } /** 根据滑动距离变更音量条,正值变大,负值变小 */ private void changeVoice(float f, float height) { float change = f / height; int changei = (int) (change * 100); int voice = currentVolume; int afterVoice = voice - changei; if (afterVoice < 0) { afterVoice = 0; } if (afterVoice > 100) { afterVoice = 100; } currentVolume = afterVoice; int Volume = (int) ((currentVolume * maxVolume) / 100); audiomanager.setStreamVolume(AudioManager.STREAM_MUSIC, Volume, 0); roundPb_voice.setProgress(currentVolume); } /** 根据滑动距离变更视频进度条,正值向右,负值向左 */ private void changeSeekbar(int change) { // 根据滑动距离变更视频进度条,正值向右,负值向左 if (mediaplayer == null || !isPrepared) { return; } else { int progress = sb_progress_full.getProgress();// 当前位置 int max = sb_progress_full.getMax();// 最大长度 int result = progress + change; if (result < 0) { result = 0; } if (result > max) { result = max; } try { // 同时执行seekto方法 mediaplayer.seekTo(result); } catch (Exception e) { e.printStackTrace(); } } } // /** 显示工具栏 */ // private void ShowView() { // if (isShow == true) { // ll_seek_full.startAnimation(mShowBottom); // ll_seek_full.setVisibility(View.VISIBLE); // ll_back.startAnimation(mShowTop); // ll_back.setVisibility(View.VISIBLE); // if (iv_lock.getVisibility() == View.GONE) { // iv_lock.setVisibility(View.VISIBLE); // } // } // } // // /** 隐藏工具栏 */ // private void HidView() { // if (isShow == false) { // ll_seek_full.startAnimation(mHiddenBottom); // ll_seek_full.setVisibility(View.GONE); // ll_back.startAnimation(mHiddenTop); // ll_back.setVisibility(View.GONE); // if (iv_lock.getVisibility() == View.VISIBLE) { // iv_lock.startAnimation(alpha)1; // iv_lock.setVisibility(View.GONE); // } // if (ll_vediolist.getVisibility() == View.VISIBLE) { // ll_vediolist.setVisibility(View.GONE); // iv_vediolist.setImageResource(R.drawable.vediolist_down); // // 恢复自动隐藏 // } // if (ll_more.getVisibility() == View.VISIBLE) { // ll_more.setVisibility(View.GONE); // } // } // } /** 设置进度的文字显示 */ private void set(int progress, int max) { // 设置视频时间显示 if (progress > max) { progress = max; } tv_time.setText(TimeUtil.stringForTime(max)); tv_time_temp.setText(TimeUtil.stringForTime(progress)); tv_time_full.setText(TimeUtil.stringForTime(max)); tv_time_temp_full.setText(TimeUtil.stringForTime(progress)); } /** 获取浮窗视图 */ public View getLayout() { return this.parentView; } /** 移动视频浮窗的位置 */ public void videoLayout(final int left, final int top, final int right, final int bottom) { if (videoView != null) { mContext.runOnUiThread(new Runnable() { @Override public void run() { int width = right - left; int height = bottom - top; RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height); param.leftMargin = left;// 操作之后控件左上角的横坐标 param.topMargin = top;// 操作之后控件左上角的纵坐标 videoView.setLayoutParams(param); } }); } } /** 退出视频播放 */ public void clearVideo() { try { video_epub.setOnPreparedListener(null); if (mediaplayer != null && isPrepared == true) { video_epub.stopPlayback(); isPrepared = false; currentPosition = 0; } sb_progress.setProgress(0); sb_progress_full.setProgress(0); set(0, max); if (video_start.isPlaying()) video_start.stopPlayback(); videoView.setVisibility(View.GONE); videoView.setTag(null); try { int old = (Integer) parentView.getTag(); callback.showWebVideo(old); parentView.setTag(null); } catch (Exception e) { } } catch (Exception e) { e.printStackTrace(); } } /** 关闭视频播放 */ public void closeVideo() { try { mContext.runOnUiThread(new Runnable() { @Override public void run() { try { stopVideo(); if (video_start.isPlaying()) video_start.stopPlayback(); videoView.setVisibility(View.GONE); videoView.setTag(null); stopFullPlay(); int old = (Integer) parentView.getTag(); callback.showWebVideo(old); parentView.setTag(null); } catch (Exception e) { } } }); } catch (Exception e) { e.printStackTrace(); } } /** 停止视频播放 */ public void stopVideo() { try { if (videoView.getTag() != null) { Logger.e("saveVedioProgress", "清空进度"); //SharedUtil.saveVedioProgress(mContext, (String) videoView.getTag(), 0); SharedUtil.setVideoRecord(mContext, -1, "", "", false, -1, -1, "", "");// 清除异常退出自动播放的缓存 } video_epub.setOnPreparedListener(null); if (mediaplayer != null && isPrepared == true) { video_epub.stopPlayback(); isPrepared = false; currentPosition = 0; } sb_progress.setProgress(0); sb_progress_full.setProgress(0); set(0, max); } catch (Exception e) { e.printStackTrace(); } } /** 恢复视频播放 */ public void replayVideo(int position) { currentPosition = position; try { if (mediaplayer != null) { isPrepared = true; } else { String path = (String) videoView.getTag(); if (!TextUtils.isEmpty(path)) playVideoWithId(path, (String) videoView.getTag(videoIdTag), false); } } catch (Exception e) { e.printStackTrace(); } } /**开始加载视频*/ private void playVideoWithId(final String path, final String id, boolean isStart) { callback.closeAudio(); mContext.runOnUiThread(new Runnable() { @Override public void run() { try { if (TextUtils.isEmpty(path)) { DialogUtil.showToast(mContext, "视频地址不存在!"); return; } //1、缓存完成使用本地播放;2、视频地址是mp4的,直接播放;3视频地址是rtmp的,获取实际地址后再播放 String localPath = VideoDownload.getInstance(mContext).getDownloadVideo(mContext,id); if (!HttpUtil.checkNet(mContext)&&TextUtils.isEmpty(localPath)) { DialogUtil.showToast(mContext, "本视频需要联网才能观看,请先联网!"); return; } video_epub.setBufferSize(512 * 1024); Logger.e("video", "加载视频" + path); isComplete = false; //video_epub.setVideoPath(path); video_epub.setOnPreparedListener(videoPreparedListener); /* 清除画布 */ SurfaceHolder holder = video_epub.getHolder(); Canvas canvas = null; try { canvas = holder.lockCanvas(); if (canvas != null) { canvas.drawColor(bgColor_f2f2f2); canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); } } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) { holder.unlockCanvasAndPost(canvas); } } holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.addCallback(videoCallback); iv_playmessage.setVisibility(View.GONE); fl_touchview.setBackgroundResource(R.color.transparent); ll_loading.setVisibility(View.GONE); if(TextUtils.isEmpty(localPath)){ //未缓存,使用在线地址播放 //播放地址是否添加授权 if(TextUtils.isEmpty(id)){//播放地址未添加授权,直接播放 video_epub.setVideoPath(path); }else{ //根据Id获取实际授权地址 Map<String, String> params = new HashMap<String, String>(); params.put("chapUID", id); String token = MD5Util.md5To32("GetChapVideoSafeUrl_"+id+"_scxuexi"); params.put("token", token); PostResquest.LogURL("接口", URL.GetChapVideoSafeUrl, params, "获取视频的下载地址"); SCApplication.mQueue.add(new PostResquest(params, Request.Method.POST, URL.GetChapVideoSafeUrl, new Response.Listener<String>() { public void onResponse(String arg0) { String json = NetUtil.JSONTokener(arg0); Logger.e("GetChapVideoSafeUrl","获取视频的下载地址:"+json); String realPath = ParserJson.getRealPath(json); if(TextUtils.isEmpty(realPath)){ PostResquest.showError(mContext); }else{ video_epub.setVideoPath(realPath); } //realPath = "https://videofms.oss-cn-beijing.aliyuncs.com/ChapM3U8/acacbc31-72e3-4b6e-aef0-e2235342c455/chap.m3u8?Expires=1521791735&OSSAccessKeyId=TMP.AQGy2-3WXBMHLAxvRti-2iUPNQY6dQW4FJiexUpRfhfH9kd2Odx01h6FLcg3ADAtAhQO6Pd_EEfFIL3YsYGqKlDkq88vBgIVAKMGEIDITml8OXQzd-WGxcaXaWRu&Signature=ikGqsjVA%2B%2FEkBFXTdo33Tf4wyZ0%3D"; //video_epub.setVideoPath(realPath); } }, new Response.ErrorListener() { public void onErrorResponse(VolleyError arg0) { PostResquest.showError(mContext); } })); } //播放视频头 isStartEnded = false; video_start.setVisibility(View.VISIBLE); //video_epub.setVisibility(View.GONE); video_start.setVideoURI(Uri.parse("android.resource://" + mContext.getPackageName() + "/" + R.raw.videostart)); video_start.start(); video_start.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { //片头播放完毕 if(mp!=null){ mp.reset(); } isStartEnded = true; //video_epub.setVisibility(View.VISIBLE); video_start.setVisibility(View.GONE); doPlay(true); } }); }else{ //缓存完毕,播放本地文件 isStartEnded = true; video_epub.setVideoPath(localPath); } } catch (Exception e) { e.printStackTrace(); } } }); } /** 开始加载视频 */ /*private void playVideo(final String path, final boolean isStart) { callback.closeAudio(); mContext.runOnUiThread(new Runnable() { @Override public void run() { try { if (TextUtils.isEmpty(path)) { DialogUtil.showToast(mContext, "视频地址不存在!"); return; } if (!HttpUtil.checkNet(mContext)) { DialogUtil.showToast(mContext, "本视频需要联网才能观看,请先联网!"); return; } *//*maxBufferSize = 512 * 1024 ;*//* video_epub.setBufferSize(512 * 1024); Logger.e("video", "加载视频" + path); isComplete = false; video_epub.setVideoPath(path); video_epub.setOnPreparedListener(videoPreparedListener); *//* 清除画布 *//* SurfaceHolder holder = video_epub.getHolder(); Canvas canvas = null; try { canvas = holder.lockCanvas(); if (canvas != null) { canvas.drawColor(bgColor_f2f2f2); canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); } } catch (Exception e) { e.printStackTrace(); } finally { if (canvas != null) { holder.unlockCanvasAndPost(canvas); } } holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.addCallback(videoCallback); iv_playmessage.setVisibility(View.GONE); fl_touchview.setBackgroundResource(R.color.transparent); ll_loading.setVisibility(View.GONE); // 是否播放片头 if (isStart) { isStartEnded = false; video_start.setVisibility(View.VISIBLE); video_start.setVideoURI(Uri.parse("android.resource://" + mContext.getPackageName() + "/" + R.raw.videostart)); video_start.start(); video_start.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { public void onCompletion(MediaPlayer mp) { if(mp!=null){ mp.reset(); } isStartEnded = true; video_start.setVisibility(View.GONE); doPlay(true); } }); } else { isStartEnded = true; video_start.setVisibility(View.GONE); ll_loading.setVisibility(View.VISIBLE); tv_buffer_info.setText("缓冲中..."); } } catch (Exception e) { e.printStackTrace(); } } }); }*/ /** 暂停播放视频 */ private void pauseVideo() { if (mediaplayer != null && isPrepared == true) { try { currentPosition = mediaplayer.getCurrentPosition(); mediaplayer.pause(); } catch (Exception e) { } } else { DialogUtil.showToast(mContext, "视频加载中,请稍等..."); } } /** 暂停或播放视频 */ private void pauseOrResumeVideo() { if (mediaplayer != null && isPrepared == true && isStartEnded == true) { try { if (mediaplayer.isPlaying()) { currentPosition = mediaplayer.getCurrentPosition(); mediaplayer.pause(); if (ll_video_complete.getVisibility() != View.VISIBLE) { iv_playmessage.setVisibility(View.VISIBLE); } fl_touchview.setBackgroundResource(R.color.bg_pause); bt_play.setVisibility(View.VISIBLE); bt_pause.setVisibility(View.INVISIBLE); bt_play_full.setVisibility(View.VISIBLE); bt_pause_full.setVisibility(View.INVISIBLE); } else { mediaplayer.start(); iv_playmessage.setVisibility(View.GONE); fl_touchview.setBackgroundResource(R.color.transparent); bt_play_full.setVisibility(View.INVISIBLE); bt_pause_full.setVisibility(View.VISIBLE); } } catch (Exception e) { e.printStackTrace(); } } else { DialogUtil.showToast(mContext, "视频加载中,请稍等..."); } } /** 恢复播放视频 */ private void resumeVideo() { if (mediaplayer != null && isPrepared == true && isStartEnded == true) { try { mediaplayer.start(); } catch (Exception e) { e.printStackTrace(); } } else { DialogUtil.showToast(mContext, "视频加载中,请稍等..."); } } /** 缓冲或者视频头播放完毕 */ private void doPlay(boolean showBuffer) { if (mediaplayer != null && isPrepared == true && isStartEnded == true) { try { video_start.setVisibility(View.GONE); if (currentPosition > 0) { sb_progress.setProgress((int) currentPosition); sb_progress_full.setProgress((int) currentPosition); video_epub.seekTo(currentPosition); } else { mediaplayer.start(); } } catch (Exception e) { e.printStackTrace(); } } else if (showBuffer) { // 显示缓冲提示 ll_loading.setVisibility(View.VISIBLE); tv_buffer_info.setText("缓冲中..."); } } private boolean isAnchor = false; /** 点击页面的视频回调,固定位置播放 */ public void startVideoPlay(final String path, int vLeft, int vTop, int vRight, int vBottom, OnClickListener shareClick) { try { isAnchor = true; if (shareClick != null) { tv_share_button.setOnClickListener(shareClick); } videoLayout(vLeft, vTop, vRight, vBottom); video_scale.setVisibility(View.GONE); video_close.setVisibility(View.GONE); video_ratio = (float)(vRight-vLeft)/(vBottom-vTop); // 播放视频 videoView.setTag(path); playVideoWithId(path, null,path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); mContext.runOnUiThread(new Runnable() { @Override public void run() { videoView.setVisibility(View.VISIBLE); } }); iv_more.setVisibility(View.GONE); } catch (Exception e) { e.printStackTrace(); } } /** 点击页面的视频回调,浮窗播放 */ public void videoClick(final String path, int vLeft, int vTop, int vRight, int vBottom) { try { videoLayout(vLeft, vTop, vRight, vBottom); video_ratio = (float)(vRight-vLeft)/(vBottom-vTop); if (videoView.getVisibility() == View.VISIBLE) { if (videoView.getTag() == null || !videoView.getTag().equals(path)) { // 重新播放视频 mContext.runOnUiThread(new Runnable() { @Override public void run() { stopVideo(); videoView.setTag(path); currentPosition = SharedUtil.getVedioProgress(mContext, path);// 恢复上次的进度 playVideoWithId(path,null, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); } }); } } else { // 播放视频 videoView.setTag(path); currentPosition = SharedUtil.getVedioProgress(mContext, path);// 恢复上次的进度 playVideoWithId(path,null, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); mContext.runOnUiThread(new Runnable() { @Override public void run() { videoView.setVisibility(View.VISIBLE); } }); } } catch (Exception e) { e.printStackTrace(); } } /** 点击视频列表,浮窗播放 */ public void startVideoList(int position, ArrayList<VideoBean> list, int vLeft, int vTop, int vRight, int vBottom, BookBean bookBean) { try { this.isBuy = bookBean.isBuy(); this.bookbean = bookBean; videoLayout(vLeft, vTop, vRight, vBottom); VideoBean bean = list.get(position); String path = bean.getVideoUrl(); String videoId = bean.getId(); if (videoView.getVisibility() == View.VISIBLE) { if (videoView.getTag() == null || !videoView.getTag().equals(path)) { // 重新播放视频 stopVideo(); videoView.setTag(path); videoView.setTag(videoIdTag,bean.getId()); playVideoWithId(path,videoId,path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); } } else { // 播放视频 videoView.setTag(path); videoView.setTag(videoIdTag,bean.getId()); playVideoWithId(path,videoId,path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); videoView.setVisibility(View.VISIBLE); } currentPosition = SharedUtil.getVedioProgress(mContext, path);// 恢复上次的进度 tv_vedioname.setText(bean.getName()); this.vedioList = RemoveHead(list); if (vedioList != null && vedioList.size() > 0) { rl_vediolist.setVisibility(View.VISIBLE); size = vedioList.size(); temp = getPosition(bean, vedioList); showLastAndNext(temp, size); vAdapter = new VedioListAdapter(mContext, vedioList); lv_vediolist.setAdapter(vAdapter); lv_vediolist.setSelection(temp); } } catch (Exception e) { e.printStackTrace(); } } /** 显示上一个、下一个按钮状态 */ private void showLastAndNext(int temp, int size) { try { if (temp == 0) { iv_last.setVisibility(View.GONE); } else { iv_last.setVisibility(View.VISIBLE); } if (size == temp + 1) { iv_next.setVisibility(View.GONE); } else if (size > 0) { iv_next.setVisibility(View.VISIBLE); } } catch (Exception e) { e.printStackTrace(); } } private int getPosition(VideoBean vebean, ArrayList<VideoBean> vedioList) { int position = -1; for (int i = 0; i < vedioList.size(); i++) { if (vebean.getVideoUrl().equals(vedioList.get(i).getVideoUrl())) { position = i; return position; } } return position; } private ArrayList<VideoBean> RemoveHead(ArrayList<VideoBean> vedioList2) { ArrayList<VideoBean> list = new ArrayList<VideoBean>(); for (int i = 0; i < vedioList2.size(); i++) { if (!vedioList2.get(i).isHead()) { list.add(vedioList2.get(i)); } } return list; } /** 点击全屏播放 */ public void fullPlay(final String path) { Intent intent = new Intent(); intent.setClass(mContext, VeidoOnlineRtmp.class); intent.putExtra("isbuy", true); intent.putExtra("path", path); intent.putExtra("type", "1"); intent.putExtra("startPoint", currentPosition); intent.putExtra("isEnded", isStartEnded); // Logger.e("", "isStartEnded" + isStartEnded + ";" + "startPoint" + // currentPosition); mContext.startActivityForResult(intent, Request_Result_Code.RESULT_CODE_PLAY_VIDEO); mContext.overridePendingTransition(0, 0); // iv_currentFrame.setImageResource(R.drawable.transparent); // int top = videoView.getTop(); // int left = videoView.getLeft(); // int width = videoView.getWidth(); // int height = videoView.getHeight(); // float scaleX = screen[1] / width; // float scaleY = screen[0] / height; // float translateY = (screen[1] - 2 * top - height) / 2; // float translateX = (screen[0] - 2 * left - width) / 2; // AnimationSet fullScreen = new AnimationSet(true); // RotateAnimation rotate = new RotateAnimation(0f, 90f, // Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // rotate.setDuration(300); // fullScreen.addAnimation(rotate); // ScaleAnimation scale = new ScaleAnimation(1f, scaleY, 1f, scaleX, // Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // scale.setDuration(300); // fullScreen.addAnimation(scale); // TranslateAnimation translate = new TranslateAnimation(0, translateX, // 0, translateY); // translate.setDuration(300); // fullScreen.addAnimation(translate); // fullScreen.setDuration(300); // fullScreen.setFillAfter(false); // fullScreen.setInterpolator(new LinearInterpolator()); // scale.setAnimationListener(new AnimationListener() { // @Override // public void onAnimationStart(Animation arg0) { // video_epub.setVisibility(View.GONE); // } // // @Override // public void onAnimationRepeat(Animation arg0) { // // } // // @Override // public void onAnimationEnd(Animation arg0) { // videoView.postDelayed(new Runnable() { // public void run() { // video_epub.setVisibility(View.VISIBLE); // Intent intent = new Intent(); // intent.setClass(mContext, VeidoOnlineRtmp.class); // intent.putExtra("isbuy", true); // intent.putExtra("path", path); // intent.putExtra("type", "1"); // intent.putExtra("startPoint", currentPosition); // intent.putExtra("isEnded", isStartEnded); // Logger.e("", "isStartEnded" + isStartEnded + ";" + "startPoint" + // currentPosition); // mContext.startActivityForResult(intent, // Request_Result_Code.RESULT_CODE_PLAY_VIDEO); // mContext.overridePendingTransition(0, 0); // iv_currentFrame.setImageResource(R.drawable.transparent); // } // }, 10); // } // }); // videoView.startAnimation(fullScreen); } public void fullPlayVideo(final String path) { mContext.runOnUiThread(new Runnable() { @Override public void run() { Intent intent = new Intent(); intent.setClass(mContext, VeidoOnlineRtmp.class); intent.putExtra("isbuy", true); intent.putExtra("path", path); intent.putExtra("type", "1"); intent.putExtra("startPoint", 0); intent.putExtra("isEnded", path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") < 0); mContext.startActivityForResult(intent, Request_Result_Code.RESULT_CODE_PLAY_VIDEO); } }); } /** 视频播放模式切换 */ public void setVideoType(int type) { playType = type; mContext.runOnUiThread(new Runnable() { @Override public void run() { try { if (playType == 0) { // 窗口 RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(lastPotion[2], lastPotion[3]); param.leftMargin = lastPotion[0];// 操作之后控件左上角的横坐标 param.topMargin = lastPotion[1];// 操作之后控件左上角的纵坐标 videoView.setLayoutParams(param); rl_window_video.setVisibility(View.VISIBLE); try { if (mediaplayer != null && isPrepared) if (isAnchor) { videoView.post(new Runnable() { @Override public void run() { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_FIT_PARENT, mediaplayer.getVideoAspectRatio()); } }); } else { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_STRETCH, mediaplayer.getVideoAspectRatio()); } } catch (Exception e) { } // 显示工具栏 isShow = true; ll_seek.setVisibility(View.VISIBLE); ll_seek.removeCallbacks(hideAction); ll_seek.postDelayed(hideAction, 10000); } else { // 全屏 // RelativeLayout.LayoutParams param = new // RelativeLayout.LayoutParams((int) screen[1], (int) // screen[0]); RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams((int)screen[1], (int)screen[0]); param.leftMargin = 0;// 操作之后控件左上角的横坐标 param.topMargin = 0;// 操作之后控件左上角的纵坐标 videoView.setLayoutParams(param); rl_full_video.setVisibility(View.VISIBLE); try { if (mediaplayer != null && isPrepared) if (isAnchor) { videoView.post(new Runnable() { @Override public void run() { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_FIT_PARENT, mediaplayer.getVideoAspectRatio()); } }); } else { video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_SCALE, mediaplayer.getVideoAspectRatio()); } } catch (Exception e) { } currentLight = SystemBrightManager.getBrightness(mContext);// 获取屏幕当前亮度,最小1,最大255 roundPb_light.setProgress((currentLight * 100) / 255); // 初始化音量 currentVolume = 100 * audiomanager.getStreamVolume(AudioManager.STREAM_MUSIC) / maxVolume;// 获取当前音量,最小0,最大15 roundPb_voice.setProgress(currentVolume); // 显示工具栏 isShow = true; ll_seek_full.setVisibility(View.VISIBLE); ll_back.setVisibility(View.VISIBLE); iv_lock.setVisibility(View.VISIBLE); ll_seek_full.removeCallbacks(hideAction2); ll_seek_full.postDelayed(hideAction2, 10000); } } catch (Exception e) { e.printStackTrace(); } } }); } public boolean stopFullPlay() { boolean flag = false; if (playType == 1) { playType = 0; rl_full_video.setVisibility(View.GONE); mContext.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); flag = true; } return flag; } public void setChapIndex(int chapIndex) { try { final int old = (Integer) parentView.getTag(); mContext.runOnUiThread(new Runnable() { @Override public void run() { callback.showWebVideo(old); } }); } catch (Exception e) { } parentView.setTag(chapIndex); } /** 视频列表的数据适配器 */ public class VedioListAdapter extends BaseAdapter { private LayoutInflater inflater; private ArrayList<VideoBean> mList; private int red = Color.parseColor("#ff605b"); private int white = Color.parseColor("#ffffff"); public VedioListAdapter(Activity context, ArrayList<VideoBean> list) { this.inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.mList = list; } public int getCount() { return mList == null ? 0 : mList.size(); } public Object getItem(int position) { return mList.get(position); } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { VedioListAdapter.ViewHolder holder = null; if (convertView == null) { holder = new VedioListAdapter.ViewHolder(); convertView = inflater.inflate(R.layout.item_vediolistadapter, null); holder.tv_vedioname = (TextView) convertView.findViewById(R.id.tv_vedioname); convertView.setTag(holder); } else { holder = (VedioListAdapter.ViewHolder) convertView.getTag(); } VideoBean bean = mList.get(position); if (null != bean) { holder.tv_vedioname.setText(bean.getName()); if (position == temp) { holder.tv_vedioname.setTextColor(red); } else { holder.tv_vedioname.setTextColor(white); } convertView.setOnClickListener(new OnClickListener() { public void onClick(View v) { // 切换视频 if (temp != position) { // 重新播放视频 temp = position; VideoBean bean = vedioList.get(temp); stopVideo(); String path = bean.getVideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,bean.getId()); playVideoWithId(path,bean.getId(),path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi.com/xxv/mp4:streams") >= 0); tv_vedioname.setText(bean.getName()); showLastAndNext(temp, size); notifyDataSetChanged(); callback.onVideoRecord(bean); // if (ll_vediolist.getVisibility() == View.VISIBLE) // { // ll_vediolist.setVisibility(View.GONE); // iv_vediolist.setImageResource(R.drawable.vediolist_down); // // 恢复自动隐藏 // } } } }); } return convertView; } public class ViewHolder { TextView tv_vedioname; } } /** 修改视频的购买状态 */ public void onPayResult(BookBean bookBean) { this.isBuy = bookBean.isBuy(); if (isBuy && alert != null && alert.isShowing()) alert.dismiss(); } public long getCurrentPosition() { try { currentPosition = mediaplayer.getCurrentPosition(); } catch (Exception e) { e.printStackTrace(); } return currentPosition; } /**判断某个视频是否正在播放*/ public boolean isPlay(VideoBean vebean) { try { if(vedioList.get(temp).getId().equals(vebean.getId())){ return true; } } catch (Exception e) { } return false; } }
layout布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android_custom="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/rl_video_play_layout" android:layout_width="match_parent" android:layout_height="wrap_content"> <RelativeLayout android:id="@+id/rl_video_view" android:layout_width="match_parent" android:layout_height="360dp" android:background="@color/black" > <io.vov.vitamio.widget.VideoView android:id="@+id/video_epub" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:visibility="visible" /> <VideoView android:id="@+id/video_start" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" /> <ImageView android:id="@+id/iv_playmessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:contentDescription="@null" android:src="@drawable/playmessage" android:visibility="gone" /> <TextView android:id="@+id/tv_connnect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#99000000" android:text="" android:textColor="@color/white" android:textSize="27sp" android:visibility="visible" /> <View android:id="@+id/fl_touchview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <RelativeLayout android:id="@+id/rl_window_video" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" > <ImageView android:id="@+id/video_scale" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:padding="12dp" android:src="@drawable/video_scale" /> <ImageView android:id="@+id/video_close" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:padding="12dp" android:src="@drawable/video_close" /> <LinearLayout android:id="@+id/ll_seek" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#99000000" android:orientation="horizontal" > <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" > <ImageView android:id="@+id/bt_play" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:padding="4dp" android:src="@drawable/play_video" /> <ImageView android:id="@+id/bt_pause" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:padding="4dp" android:src="@drawable/pause_video" android:visibility="invisible" /> </FrameLayout> <TextView android:id="@+id/tv_time_temp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center|right" android:text="00:00" android:textColor="@color/white" android:textSize="14sp" /> <SeekBar android:id="@+id/sb_progress" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="7" android:maxHeight="2dp" android:minHeight="2dp" android:padding="12dp" android:progressDrawable="@drawable/thumbar_new" android:thumb="@drawable/thumb_red_round" android:thumbOffset="8dip" > </SeekBar> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center|left" android:text="00:00" android:textColor="@color/white" android:textSize="14sp" /> <ImageView android:id="@+id/video_full" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:padding="12dp" android:src="@drawable/video_full" /> </LinearLayout> </RelativeLayout> <RelativeLayout android:id="@+id/rl_full_video" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" > <RelativeLayout android:id="@+id/rl_voice" android:layout_width="match_parent" android:layout_height="match_parent" > <com.shengcai.view.RoundProgressBar android:id="@+id/roundPb_voice" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" android_custom:centerColor="#AA000000" android_custom:roundColor="#666666" android_custom:roundProgressColor="@color/white" android_custom:roundWidth="10dip" android_custom:textIsDisplayable="false" /> <ImageView android:id="@+id/iv_voice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/voice" /> <TextView android:id="@+id/tv_voice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/iv_voice" android:layout_centerInParent="true" android:paddingTop="5dp" android:text="音量" android:textColor="@color/white" android:textSize="12sp" /> </RelativeLayout> <RelativeLayout android:id="@+id/rl_light" android:layout_width="match_parent" android:layout_height="match_parent" > <com.shengcai.view.RoundProgressBar android:id="@+id/roundPb_light" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerInParent="true" android_custom:centerColor="#AA000000" android_custom:roundColor="#666666" android_custom:roundProgressColor="@color/white" android_custom:roundWidth="10dip" android_custom:textIsDisplayable="false" /> <ImageView android:id="@+id/iv_light" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/light" /> <TextView android:id="@+id/tv_light" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/iv_light" android:layout_centerInParent="true" android:paddingTop="3dp" android:text="亮度" android:textColor="@color/white" android:textSize="12sp" /> </RelativeLayout> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/ll_back" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="2" android:background="#99000000" android:gravity="center" android:orientation="horizontal" > <ImageView android:id="@+id/bt_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@null" android:paddingLeft="15dp" android:paddingRight="15dp" android:scaleType="centerInside" android:src="@drawable/left_btn" /> <TextView android:id="@+id/tv_vedioname" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="left|center_vertical" android:layout_weight="22" android:ellipsize="end" android:paddingLeft="10dp" android:singleLine="true" android:text="" android:textColor="@color/white" android:textSize="20sp" /> <RelativeLayout android:id="@+id/rl_vediolist" android:layout_width="wrap_content" android:layout_height="match_parent" > <TextView android:id="@+id/tv_vediolist" android:layout_width="wrap_content" android:layout_height="match_parent" android:ellipsize="end" android:gravity="left|center" android:paddingLeft="20dp" android:singleLine="true" android:text="列表" android:textColor="@color/white" android:textSize="20sp" /> <ImageView android:id="@+id/iv_vediolist" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_toRightOf="@id/tv_vediolist" android:contentDescription="@null" android:paddingRight="16dp" android:scaleType="centerInside" android:src="@drawable/vediolist_down" /> </RelativeLayout> </LinearLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="10" android:background="#00000000" > <LinearLayout android:id="@+id/ll_vediolist" android:layout_width="250dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#99000000" android:orientation="vertical" > <ListView android:id="@+id/lv_vediolist" android:layout_width="match_parent" android:layout_height="wrap_content" android:cacheColorHint="@color/transparent" android:divider="@null" android:listSelector="@color/transparent" /> </LinearLayout> <LinearLayout android:id="@+id/ll_more" android:layout_width="180dp" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:background="#99000000" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text=" 播放速度" android:textColor="@color/white" android:textSize="16sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ImageView android:id="@+id/iv_slow" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="10dp" android:src="@drawable/ic_playspeed_slow" /> <TextView android:id="@+id/tv_play_speed" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:text="1.0x" android:textColor="@color/white" android:textSize="14sp" /> <ImageView android:id="@+id/iv_quick" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingRight="10dp" android:src="@drawable/ic_playspeed_quick" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/iv_lock" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="16dp" android:src="@drawable/ic_lock" /> </RelativeLayout> <LinearLayout android:id="@+id/ll_seek_full" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="2" android:background="#99000000" android:orientation="horizontal" > <ImageView android:id="@+id/iv_last" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:paddingLeft="15dp" android:paddingRight="15dp" android:src="@drawable/last_vedio" /> <FrameLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" > <ImageView android:id="@+id/bt_play_full" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:paddingLeft="15dp" android:paddingRight="15dp" android:src="@drawable/play" /> <ImageView android:id="@+id/bt_pause_full" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:paddingLeft="15dp" android:paddingRight="15dp" android:src="@drawable/pause" android:visibility="invisible" /> </FrameLayout> <ImageView android:id="@+id/iv_next" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center" android:paddingLeft="15dp" android:paddingRight="15dp" android:src="@drawable/next_vedio" /> <TextView android:id="@+id/tv_time_temp_full" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center|right" android:paddingLeft="10dp" android:text="00:00" android:textColor="@color/white" android:textSize="14sp" /> <SeekBar android:id="@+id/sb_progress_full" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="7" android:maxHeight="2dp" android:minHeight="2dp" android:paddingLeft="15dp" android:paddingRight="15dp" android:progressDrawable="@drawable/thumbar_new" android:thumb="@drawable/thumb_red_round" android:thumbOffset="12dip" /> <TextView android:id="@+id/tv_time_full" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center|left" android:paddingRight="10dp" android:text="00:00" android:textColor="@color/white" android:textSize="14sp" /> <TextView android:id="@+id/iv_more" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:paddingLeft="15dp" android:paddingRight="15dp" android:text="加速" android:textColor="@color/white" android:textSize="14sp" /> </LinearLayout> </LinearLayout> </RelativeLayout> <LinearLayout android:id="@+id/ll_loading" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" android:background="@color/bg_pause" android:gravity="center" android:orientation="vertical" android:visibility="gone" > <ImageView android:id="@+id/iv_reflsh" android:layout_width="36dp" android:layout_height="36dp" android:src="@drawable/loading_bg_1" /> <TextView android:id="@+id/tv_buffer_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:textSize="12sp" android:gravity="center" android:text="缓冲中..." android:textColor="@color/white" /> </LinearLayout> <LinearLayout android:id="@+id/ll_video_complete" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#662e2e2e" android:gravity="center" android:visibility="gone" android:orientation="horizontal" tools:visibility="visible"> <TextView android:id="@+id/tv_replay_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:drawablePadding="6dp" android:drawableTop="@drawable/ic_video_replay" android:layout_marginRight="10dp" android:text="重播" android:textColor="@color/white"/> <TextView android:id="@+id/tv_share_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:drawablePadding="6dp" android:drawableTop="@drawable/ic_video_share" android:layout_marginLeft="10dp" android:text="分享" android:textColor="@color/white"/> </LinearLayout> </RelativeLayout> </RelativeLayout>