一般项目很多地方都会用到视频播放器,需求简单点的只需要使用系统的Media Player或者VideoView即可。不过如果遇到某些复杂的功能要求或者自定义样式时,系统的播放器可能就不是那么适用了。
这时候就需要我们自己写一个播放器,用以实现日益复杂的播放功能。这里我们提到一款强大的视频播放框架Vitamio。有兴趣的同学可以先了解一下/。
之所以要用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) SystemService(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); /* 防止被仿真视图覆盖 */ // Holder().setFormat(PixelFormat.TRANSPARENT); // video_epub.setZOrderMediaOverlay(true); Holder().setType(SurfaceHolder.SURFACE_TYPE_HARDWARE); video_start = (VideoView) videoView.findViewById(R.id.video_start); video_start.setZOrderOnTop(true); /* 防止被仿真视图覆盖 */ video_start.setZOrderMediaOverlay(true); Holder().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) LayoutParams(); lastPotion = new int[]{param.leftMargin, pMargin, 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) Tag(); currentPosition=0; sb_progress.setProgress((int) currentPosition); sb_progress_full.setProgress((int) currentPosition); if (!TextUtils.isEmpty(path))playVideoWithId(path, (Tag(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 = Progress(); isFromTouch = true; veCallbacks(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(); isFromTouch = true; sb_veCallbacks(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 = (temp); stopVideo(); String path = VideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,Id()); playVideoWithId(Id(), path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); tv_vedioname.Name()); showLastAndNext(temp, size); ifyDataSetChanged(); VideoRecord(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 = (temp); stopVideo(); String path = VideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,Id()); playVideoWithId(Id(), path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); tv_vedioname.Name()); showLastAndNext(temp, size); ifyDataSetChanged(); VideoRecord(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 (Visibility() == 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_veCallbacks(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_veCallbacks(hideAction2); ll_seek_full.postDelayed(hideAction2, 10000); if (Visibility() == View.VISIBLE) {ll_vediolist.setVisibility(View.GONE); iv_vediolist.setImageResource(R.drawable.vediolist_down); // 恢复自动隐藏 }if (Visibility() == 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 (Visibility() == 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) SystemService(Context.AUDIO_SERVICE); maxVolume = StreamMaxVolume(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; veCallbacks(hideAction); ll_seek.startAnimation(mHiddenBottom); ll_seek.setVisibility(View.GONE); }}; private Runnable hideAction2 = new Runnable() {@Override public void run() {if (Visibility() == View.VISIBLE) {ll_seek_full.postDelayed(hideAction2, 10000); } else {isShow = false; ll_veCallbacks(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 (Visibility() == View.VISIBLE) { // ll_vediolist.setVisibility(View.GONE); // iv_vediolist.setImageResource(R.drawable.vediolist_down); // // 恢复自动隐藏 // } if (Visibility() == 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 = CurrentPosition(); mediaplayer.pause(); } catch (Exception e) {if (Tag() != null)currentPosition = VedioProgress(mContext, (String) Tag()); }}}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 = Width(); int h = Height(); 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 = VideoAspectRatio(); 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); veCallbacks(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); veCallbacks(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_veCallbacks(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) Duration(); 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) CurrentPosition(); 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 = CurrentPosition(); mediaplayer.pause(); iv_playmessage.setVisibility(View.VISIBLE); fl_touchview.lor.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, Resources().getString(R.string.str_wenxin_prompt), "未购买只能观看前10分钟n继续观看,请先购买!", Resources().getString(R.string.str_buy_now), Resources().getString(R.string.dismiss), new OnClickListener() {@Override public void onClick(View arg0) {alert.dismiss(); // 立即购买方法 if (bookbean != null && !isBuy) {if (PackageType() == 3) {// 激活购书大礼包直接打开网页 Intent intent = new Intent(mContext, BookWebActivity.class); intent.putExtra("title", "激活"); String urlString = ".aspx?id=" + Id(); intent.putExtra("url", urlString); mContext.startActivityForResult(intent, Request_Result_Code.GET_PACKAGE); } else {Intent intent = new Intent(mContext, PayActivity.class); intent.putExtra("bookid", Id()); intent.putExtra("bean", bookbean); intent.putExtra("frominfo", false); mContext.startActivity(intent); }}}}, new OnClickListener() {@Override public void onClick(View arg0) {alert.dismiss(); }}); }}}); }}// 保存一下视频进度 count++; tempPosition = CurrentPosition(); if (count % 20 == 0) {Logger.e("saveVedioProgress", "保存进度" + progress); try {bmp = CurrentFrame(); } catch (Exception e) {e.printStackTrace(); }SharedUtil.saveVedioProgress(mContext, (String) Tag(), 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+"/"CurrentPosition()+"/"+max); if (tempPosition - max < -5000) {DialogUtil.showToast(mContext, "网络异常!重新连接"); String path = (String) Tag(); if (!TextUtils.isEmpty(path))playVideoWithId(path,(Tag(videoIdTag),false); //playVideo(path, false); return; }if (Tag() != null)SharedUtil.saveVedioProgress(mContext, (String) Tag(), 0); if (vedioList != null && temp < vedioList.size() - 1 && vedioList.size() > 0) {DialogUtil.showToast(mContext, "播放完毕!自动播放下一节"); temp = temp + 1; VideoBean bean = (temp); stopVideo(); String path = VideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,Id()); playVideoWithId(Id(), path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); tv_vedioname.Name()); showLastAndNext(temp, size); ifyDataSetChanged(); VideoRecord(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) Tag(); 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 (Action()) {case MotionEvent.ACTION_DOWN :// 按下时获取xy坐标 lastX = (int) RawX(); lastY = (int) RawY(); mPosX = X(); mPosY = Y(); if (minWidth > Width()) {minWidth = Width(); }if (minHeight > Height()) {minHeight = Height(); }break; case MotionEvent.ACTION_MOVE :// 移动 mCurrentPosX = X(); mCurrentPosY = Y(); if (Math.abs(mCurrentPosX - mPosX) > 20 || Math.abs(mCurrentPosY - mPosY) > 20) {// 为保证精准度,限制移动像素达到5才执行变更操作 // float videoRatio = 16f/9; // if (mediaplayer != null && isPrepared) // videoRatio = VideoAspectRatio(); mPosX = mCurrentPosX; mPosY = mCurrentPosY; // if(mCurrentPosX/mCurrentPosY>videoRatio){ // // }else{ // // } int dx = (int) RawX() - lastX; int dy = (int) RawY() - 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 = Left() + dx; int scale_top = Top() + dy; int scale_right = Right(); int scale_bottom = Bottom(); 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;// 操作之后控件左上角的横坐标 pMargin = 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) RawX(); lastY = (int) RawY(); }break; case MotionEvent.ACTION_UP : // 拖动停止 int right = Right(); int bottom = Bottom(); int left = Left(); int top = Top(); 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 (Action()) {case MotionEvent.ACTION_DOWN :// 按下时获取xy坐标 changtype = 0;// 每次按下会重新采集变更类型 change = 0; lastX = (int) RawX(); lastY = (int) RawY(); mPosX = X(); mPosY = Y(); clickTimeUDown = System.currentTimeMillis(); if (waitDoubleClick) {// 双击暂停或者播放 waitDoubleClick = false; pauseOrResumeVideo(); // if (Visibility() == View.VISIBLE) { // // 恢复播放 // iv_playmessage.setVisibility(View.GONE); // fl_touchview.ansparent); // resumeVideo(); // } else { // // 暂停 // iv_playmessage.setVisibility(View.VISIBLE); // fl_touchview.lor.bg_pause); // pauseVideo(); // } } else {waitDoubleClick = true; veCallbacks(doubleClickAction); videoView.postDelayed(doubleClickAction, 300); }veCallbacks(hideAction); ll_veCallbacks(hideAction2); break; case MotionEvent.ACTION_MOVE :if (isAnchor) {break; }if (islock && playType == 1) {break; }mCurrentPosX = X(); mCurrentPosY = Y(); 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 * Max() * (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) RawX() - lastX; int dy = (int) RawY() - lastY; int left = Left() + dx; int top = Top() + dy; int right = Right() + dx; int bottom = Bottom() + dy; if (left < 0) {left = 0; right = left + Width(); }if (right > Width()) {right = Width(); left = right - Width(); }if (top < 0) {top = 0; bottom = top + Height(); }if (bottom > Height()) {bottom = Height(); top = bottom - Height(); }int width = right - left; int height = bottom - top; RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height); param.leftMargin = left;// 操作之后控件左上角的横坐标 pMargin = top;// 操作之后控件左上角的纵坐标 videoView.setLayoutParams(param); // Logger.e("video", left+","+top+","+right+","+bottom); lastX = (int) RawX(); lastY = (int) RawY(); }break; case MotionEvent.ACTION_UP :// 获取移动结束后的坐标点 int right = Right(); int bottom = Bottom(); int left = Left(); int top = Top(); videoLayout(left, top, right, bottom); if (Math.RawX() - lastX) < 10 && Math.RawY() - 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 (Visibility() == 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 (Visibility() == View.VISIBLE) {ll_vediolist.setVisibility(View.GONE); iv_vediolist.setImageResource(R.drawable.vediolist_down); // 恢复自动隐藏 }if (Visibility() == View.VISIBLE) {ll_more.setVisibility(View.GONE); }}}}tv_connnect.setText(""); if (Visibility() == View.VISIBLE) {// 执行渐隐动画 rl_light.startAnimation(alpha); rl_light.setVisibility(View.GONE); }if (Visibility() == 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) LayoutParams(); lastPotion = new int[]{param.leftMargin, pMargin, 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();// 当前位置 int max = sb_Max();// 最大长度 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 (Visibility() == 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 (Visibility() == View.VISIBLE) { // iv_lock.startAnimation(alpha)1; // iv_lock.setVisibility(View.GONE); // } // if (Visibility() == View.VISIBLE) { // ll_vediolist.setVisibility(View.GONE); // iv_vediolist.setImageResource(R.drawable.vediolist_down); // // 恢复自动隐藏 // } // if (Visibility() == 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;// 操作之后控件左上角的横坐标 pMargin = 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) Tag(); 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) Tag(); callback.showWebVideo(old); parentView.setTag(null); } catch (Exception e) {}}}); } catch (Exception e) {e.printStackTrace(); }}/** 停止视频播放 */ public void stopVideo() {try {if (Tag() != null) {Logger.e("saveVedioProgress", "清空进度"); //SharedUtil.saveVedioProgress(mContext, (String) Tag(), 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) Tag(); if (!TextUtils.isEmpty(path))playVideoWithId(path, (String) Tag(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 = Instance(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 = Holder(); 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.lor.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 = RealPath(json); if(TextUtils.isEmpty(realPath)){PostResquest.showError(mContext); }else{video_epub.setVideoPath(realPath); }//realPath = ".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(source://" + PackageName() + "/" + 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 = Holder(); 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.ansparent); ll_loading.setVisibility(View.GONE); // 是否播放片头 if (isStart) { isStartEnded = false; video_start.setVisibility(View.VISIBLE); video_start.setVideoURI(Uri.parse(source://" + PackageName() + "/" + 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 = CurrentPosition(); mediaplayer.pause(); } catch (Exception e) {}} else {DialogUtil.showToast(mContext, "视频加载中,请稍等..."); }}/** 暂停或播放视频 */ private void pauseOrResumeVideo() {if (mediaplayer != null && isPrepared == true && isStartEnded == true) {try {if (mediaplayer.isPlaying()) {currentPosition = CurrentPosition(); mediaplayer.pause(); if (ll_Visibility() != View.VISIBLE) {iv_playmessage.setVisibility(View.VISIBLE); }fl_touchview.lor.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.lor.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/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/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 (Visibility() == View.VISIBLE) {if (Tag() == null || !Tag().equals(path)) {// 重新播放视频 mContext.runOnUiThread(new Runnable() {@Override public void run() {stopVideo(); videoView.setTag(path); currentPosition = VedioProgress(mContext, path);// 恢复上次的进度 playVideoWithId(path,null, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); }}); }} else {// 播放视频 videoView.setTag(path); currentPosition = VedioProgress(mContext, path);// 恢复上次的进度 playVideoWithId(path,null, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/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 = (position); String path = VideoUrl(); String videoId = Id(); if (Visibility() == View.VISIBLE) {if (Tag() == null || !Tag().equals(path)) {// 重新播放视频 stopVideo(); videoView.setTag(path); videoView.setTag(videoIdTag,Id()); playVideoWithId(path,videoId,path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); }} else {// 播放视频 videoView.setTag(path); videoView.setTag(videoIdTag,Id()); playVideoWithId(path,videoId,path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); videoView.setVisibility(View.VISIBLE); }currentPosition = VedioProgress(mContext, path);// 恢复上次的进度 tv_vedioname.Name()); 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 (VideoUrl().(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 (!(i).isHead()) {list.(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(ansparent); // int top = Top(); // int left = Left(); // int width = Width(); // int height = Height(); // 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(ansparent); // } // }, 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/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];// 操作之后控件左上角的横坐标 pMargin = 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, VideoAspectRatio()); }}); } else {video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_STRETCH, VideoAspectRatio()); }} catch (Exception e) {}// 显示工具栏 isShow = true; ll_seek.setVisibility(View.VISIBLE); veCallbacks(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;// 操作之后控件左上角的横坐标 pMargin = 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, VideoAspectRatio()); }}); } else {video_epub.setVideoLayout(io.vov.vitamio.widget.VideoView.VIDEO_LAYOUT_SCALE, VideoAspectRatio()); }} catch (Exception e) {}currentLight = Brightness(mContext);// 获取屏幕当前亮度,最小1,最大255 roundPb_light.setProgress((currentLight * 100) / 255); // 初始化音量 currentVolume = 100 * StreamVolume(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_veCallbacks(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) Tag(); 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) SystemService(Context.LAYOUT_INFLATER_SERVICE); this.mList = list; }public int getCount() {return mList == null ? 0 : mList.size(); }public Object getItem(int position) {(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) Tag(); }VideoBean bean = (position); if (null != bean) {holder.tv_vedioname.Name()); 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 = (temp); stopVideo(); String path = VideoUrl(); videoView.setTag(path); videoView.setTag(videoIdTag,Id()); playVideoWithId(Id(),path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); //playVideo(path, path.indexOf("rtmp://videofms.100xuexi/xxv/mp4:streams") >= 0); tv_vedioname.Name()); showLastAndNext(temp, size); notifyDataSetChanged(); VideoRecord(bean); // if (Visibility() == 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 = CurrentPosition(); } catch (Exception e) {e.printStackTrace(); }return currentPosition; }/**判断某个视频是否正在播放*/ public boolean isPlay(VideoBean vebean) {try {(temp).getId().Id())){return true; }} catch (Exception e) {}return false; }}
layout布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="" xmlns:android_custom="" xmlns: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>
本文发布于:2024-01-31 19:39:28,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170670117030890.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |