首页 > 学院 > 开发设计 > 正文

自定义播放操作(快进,快退,声音,亮度调节)

2019-11-06 09:39:40
字体:
来源:转载
供稿:网友
/** * Created by RonQian on 2017/2/22 15:02 * <p> * 详情描述: 自定义播放操作 */public class CommonVideoView extends FrameLayout implements MediaPlayer.OnPReparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, View.OnTouchListener, View.OnClickListener, Animator.AnimatorListener, SeekBar.OnSeekBarChangeListener { private Activity mContext; private final int UPDATE_VIDEO_SEEKBAR = 1000; private GestureDetector mGestureDetector; private Context context; private FrameLayout viewBox; private CommonHitVideoView videoView; private LinearLayout touchStatusView; private RelativeLayout videoControllerLayout; private ImageView touchStatusImg; private ImageView videoPauseImg; private TextView touchStatusTime; private TextView videoCurTimeText; private TextView videoTotalTimeText; private SeekBar videoSeekBar; private ProgressBar progressBar; private int duration; private String formatTotalTime; private Timer timer = new Timer(); //定义用seekBar当前的位置,触摸快进的时候显示时间 private int position; private int touchStep = 1000;//快进的时间,1秒 private int touchPosition = -1; private boolean videoControllerShow = true;//底部状态栏的显示状态 private boolean animation = false; private VerticalSeekBar volumeSeekBar, brightSeekBar;//音量 亮度 //最大声音 private int mMaxVolume; // 当前声音 private int mVolume = -1; //当前亮度 private float mBrightness = -1f; private AudioManager mAudioManager; private TimerTask timerTask = new TimerTask() { @Override public void run() { videoHandler.sendEmptyMessage(UPDATE_VIDEO_SEEKBAR); } }; private Handler videoHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_VIDEO_SEEKBAR: if (videoView.isPlaying()) { videoSeekBar.setProgress(videoView.getCurrentPosition()); } break; } } }; public CommonVideoView(Context context) { this(context, null); } public CommonVideoView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CommonVideoView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; } public void start(String url, Activity mActivity) { mContext = mActivity; mContext.getWindow().getDecorView().setSystemUiVisibility(View.GONE); mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); mGestureDetector = new GestureDetector(context, new MyGestureListener()); videoSeekBar.setEnabled(false); videoView.setVideoURI(Uri.parse(url)); videoView.start(); } public void setFullScreen() { touchStatusImg.setImageResource(R.mipmap.ic_toland); this.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); videoView.requestLayout(); } public void setNormalScreen() { touchStatusImg.setImageResource(R.mipmap.ic_toland); this.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 400)); videoView.requestLayout(); } @Override protected void onFinishInflate() { super.onFinishInflate(); initView(); } private class MyGestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent e) { return super.onSingleTapUp(e); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { return super.onSingleTapConfirmed(e); } @Override public boolean onDown(MotionEvent e) { return true; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (null == e1 || null == e2) { return false; } float minMove = 10; //最小滑动距离 float minVelocity = 10; //最小滑动速度 float beginX = e1.getX(); float endX = e2.getX(); float beginY = e1.getY(); float endY = e2.getY(); float downX = e1.getRawX(); Display disp = mContext.getWindowManager().getDefaultDisplay(); int windowWidth = disp.getWidth(); int windowHeight = disp.getHeight(); if (Math.abs(endX - beginX) < Math.abs(beginY - endY)) { //上下滑动 if (beginY - endY > minMove && Math.abs(distanceY) > minVelocity) { //上滑 if (beginX > windowWidth * 3.0 / 4.0) {// 右边滑动 屏幕3/4 onBrightnessSlide((beginY - endY) / windowHeight); } else if (beginX < windowWidth * 1.0 / 4.0) {// 左边滑动 屏幕1/4 onVolumeSlide((beginY - endY) / windowHeight); } } else if (endY - beginY > minMove && Math.abs(distanceY) > minVelocity) { //下滑 if (beginX > windowWidth * 3.0 / 4.0) {// 右边滑动 屏幕3/4 onBrightnessSlide((beginY - endY) / windowHeight); } else if (beginX < windowWidth * 1.0 / 4.0) {// 左边滑动 屏幕1/4 onVolumeSlide((beginY - endY) / windowHeight); } } } else { if (Math.abs(distanceX) > Math.abs(distanceY)) {// 横向移动大于纵向移动 if (touchStatusView.getVisibility() != View.VISIBLE) { touchStatusView.setVisibility(View.VISIBLE); } if (endX - beginX > minMove && Math.abs(distanceX) > minVelocity) { position += touchStep; if (position > duration) { position = duration; } touchPosition = position; touchStatusImg.setImageResource(R.mipmap.right); int[] time = getMinuteAndSecond(position); touchStatusTime.setText(String.format("%02d:%02d/%s", time[0], time[1], formatTotalTime)); } else if (beginX - endX > minMove && Math.abs(distanceX) > minVelocity) { position -= touchStep; if (position < 0) { position = 0; } touchPosition = position; touchStatusImg.setImageResource(R.mipmap.left); int[] time = getMinuteAndSecond(position); touchStatusTime.setText(String.format("%02d:%02d/%s", time[0], time[1], formatTotalTime)); } } } return super.onScroll(e1, e2, distanceX, distanceY); } } private void initView() { View view = LayoutInflater.from(context).inflate(R.layout.common_video_view, null); viewBox = (FrameLayout) view.findViewById(R.id.viewBox); videoView = (CommonHitVideoView) view.findViewById(R.id.videoView); videoControllerLayout = (RelativeLayout) view.findViewById(R.id.rl_video_control); touchStatusView = (LinearLayout) view.findViewById(R.id.touch_view); touchStatusImg = (ImageView) view.findViewById(R.id.touchStatusImg); touchStatusTime = (TextView) view.findViewById(R.id.touch_time); videoCurTimeText = (TextView) view.findViewById(R.id.tv_current_time); videoTotalTimeText = (TextView) view.findViewById(R.id.tv_total_time); videoSeekBar = (SeekBar) view.findViewById(R.id.seekBar); videoPauseImg = (ImageView) view.findViewById(R.id.videoPauseImg); progressBar = (ProgressBar) view.findViewById(R.id.load_progress); brightSeekBar = (VerticalSeekBar) view.findViewById(R.id.pb_bright); volumeSeekBar = (VerticalSeekBar) view.findViewById(R.id.pb_volume); videoSeekBar.setOnSeekBarChangeListener(this); videoView.setOnPreparedListener(this); videoView.setOnCompletionListener(this); //注册在设置或播放过程中发生错误时调用的回调函数。如果未指定回调函数,或回调函数返回false,VideoView 会通知用户发生了错误。 videoView.setOnErrorListener(this); viewBox.setOnTouchListener(this); viewBox.setOnClickListener(this); addView(view); } @Override public void onPrepared(MediaPlayer mp) { duration = videoView.getDuration(); int[] time = getMinuteAndSecond(duration); videoTotalTimeText.setText(String.format("%02d:%02d", time[0], time[1])); formatTotalTime = String.format("%02d:%02d", time[0], time[1]); videoSeekBar.setMax(duration); progressBar.setVisibility(View.GONE); mp.start(); videoSeekBar.setEnabled(true); videoPauseImg.setImageResource(R.mipmap.play_video); refershCurrentDurationSeekbar(); } @Override public void onCompletion(MediaPlayer mp) { videoView.seekTo(0); videoSeekBar.setProgress(0); videoPauseImg.setImageResource(R.mipmap.stop_video); } @Override public boolean onError(MediaPlayer mp, int what, int extra) { return false; } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!videoView.isPlaying()) { return false; } float downX = event.getRawX(); break; case MotionEvent.ACTION_UP: if (touchPosition != -1) { videoView.seekTo(touchPosition); touchStatusView.setVisibility(View.GONE); touchPosition = -1; if (videoControllerShow) { return true; } } break; } return mGestureDetector.onTouchEvent(event); } Timer mTimer; TimerTask mTimerTask; /** * 设置播放时间 */ private void refershCurrentDurationSeekbar() { mTimer = new Timer(); mTimerTask = new TimerTask() { @Override public void run() { mContext.runOnUiThread(new Runnable() { @Override public void run() { videoCurTimeText.setText(DateFormatUtils.generateTime(videoView.getCurrentPosition()) + ""); } }); } }; mTimer.schedule(mTimerTask, 0, 500); } private int[] getMinuteAndSecond(int mils) { mils /= 1000; int[] time = new int[2]; time[0] = mils / 60; time[1] = mils % 60; return time; } @Override public void onClick(View v) { switch (v.getId()) { case R.id.videoPauseImg: if (videoView.isPlaying()) { videoView.pause(); videoPauseImg.setImageResource(R.mipmap.stop_video); videoPauseImg.setVisibility(View.VISIBLE); } else { videoView.start(); videoPauseImg.setImageResource(R.mipmap.play_video); videoPauseImg.setVisibility(View.INVISIBLE); } break; case R.id.viewBox: float curY = videoControllerLayout.getY(); if (!animation && videoControllerShow) { animation = true; ObjectAnimator animator = ObjectAnimator.ofFloat(videoControllerLayout, "y", curY, curY + videoControllerLayout.getHeight()); animator.setDuration(200); animator.start(); animator.addListener(this); } else if (!animation) { animation = true; ObjectAnimator animator = ObjectAnimator.ofFloat(videoControllerLayout, "y", curY, curY - videoControllerLayout.getHeight()); animator.setDuration(200); animator.start(); animator.addListener(this); } break; } } @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { this.animation = false; this.videoControllerShow = !this.videoControllerShow; } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { int[] time = getMinuteAndSecond(progress); videoCurTimeText.setText(String.format("%02d:%02d", time[0], time[1])); } @Override public void onStartTrackingTouch(SeekBar seekBar) { videoView.pause(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { videoView.seekTo(videoSeekBar.getProgress()); videoView.start(); videoPauseImg.setVisibility(View.INVISIBLE); videoPauseImg.setImageResource(R.mipmap.play_video); } /** * 滑动改变亮度 * * @param percent */ private void onBrightnessSlide(float percent) { if (mBrightness < 0) { mBrightness = ScreenBrightnessUtil.getSystemBrightness(context) / 255.0F; if (mBrightness <= 0.00f) mBrightness = 0.50f; if (mBrightness < 0.01f) mBrightness = 0.01f; } float finalScreenBrightness = mBrightness + percent; if (finalScreenBrightness > 1.0f) finalScreenBrightness = 1.0f; else if (finalScreenBrightness < 0.01f) finalScreenBrightness = 0.01f; float bright = finalScreenBrightness * 100; int progress = (int) bright; brightSeekBar.setProgress(progress); ScreenBrightnessUtil.setBrightness(mContext, (int) (finalScreenBrightness * 255)); } /** * 滑动改变声音大小 * * @param percent */ private void onVolumeSlide(float percent) { if (mVolume == -1) { mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); if (mVolume < 0) mVolume = 0; } int index = (int) (percent * mMaxVolume) + mVolume; if (index > mMaxVolume) index = mMaxVolume; else if (index < 0) index = 0; double volume = ((double) index / mMaxVolume) * 100; int progress = (int) volume; volumeSeekBar.setProgress(progress); // 变更声音 mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0); } /** * 设置activity的样式 */ private void setActivityTheme() { if (Build.VERSION.SDK_INT >= 21) { View decorView = mContext.getWindow().getDecorView(); int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(option); mContext.getWindow().setNavigationBarColor(Color.TRANSPARENT); mContext.getWindow().setStatusBarColor(Color.TRANSPARENT); } else { View decorView = mContext.getWindow().getDecorView(); int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; decorView.setSystemUiVisibility(option); } } public void stopVideoVide() { if (videoView.isPlaying()) { videoView.pause(); videoPauseImg.setImageResource(R.mipmap.stop_video); } }}

/** * Created by RonQian on 2017/2/22 15:02 *

* 详情描述: 自定义播放操作 */

public class CommonHitVideoView extends VideoView { private static final float ORIENTATION_PORTRAIT_HEIGHT_SCALE = 0.56F;//视频宽高比为16:9 private int videoHeight = 0; private int videoWidth = 0;

public int getVideoHeight() { return videoHeight;}public void setVideoHeight(int videoHeight) { this.videoHeight = videoHeight;}public int getVideoWidth() { return videoWidth;}public void setVideoWidth(int videoWidth) { this.videoWidth = videoWidth;}public void resizeView(int videoWidth, int videoHeight) { this.videoWidth = videoWidth; this.videoHeight = videoHeight; measure(videoWidth, videoHeight);}public CommonHitVideoView(Context context) { this(context, null);}public CommonHitVideoView(Context context, AttributeSet attrs) { this(context, attrs, 0);}public CommonHitVideoView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = getDefaultSize(0, widthMeasureSpec); int height = getDefaultSize(0, heightMeasureSpec); this.getHolder().setFixedSize(width, height); setMeasuredDimension(width, height); setMeasuredDimension(width, height);}

}

/** * Created by RonQian on 2017/2/21 10:46 * <p> * 详情描述:垂直seekbar */public class VerticalSeekBar extends SeekBar { private boolean mIsDragging; private float mTouchDownY; private int mScaledTouchSlop; private boolean isInScrollingContainer = false; public boolean isInScrollingContainer() { return isInScrollingContainer; } public void setInScrollingContainer(boolean isInScrollingContainer) { this.isInScrollingContainer = isInScrollingContainer; } /** * On touch, this offset plus the scaled value from the position of the * touch will form the progress value. Usually 0. */ float mTouchProgressOffset; public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); } public VerticalSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalSeekBar(Context context) { super(context); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(h, w, oldh, oldw); } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(heightMeasureSpec, widthMeasureSpec); setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth()); } @Override protected synchronized void onDraw(Canvas canvas) { canvas.rotate(-90); canvas.translate(-getHeight(), 0); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled()) { return false; } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (isInScrollingContainer()) { mTouchDownY = event.getY(); } else { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); onSizeChanged(getWidth(), getHeight(), 0, 0); } break; case MotionEvent.ACTION_MOVE: if (mIsDragging) { trackTouchEvent(event); } else { final float y = event.getY(); if (Math.abs(y - mTouchDownY) > mScaledTouchSlop) { setPressed(true); invalidate(); onStartTrackingTouch(); trackTouchEvent(event); attemptClaimDrag(); } } onSizeChanged(getWidth(), getHeight(), 0, 0); break; case MotionEvent.ACTION_UP: if (mIsDragging) { trackTouchEvent(event); onStopTrackingTouch(); setPressed(false); } else { // Touch up when we never crossed the touch slop threshold // should // be interpreted as a tap-seek to that location. onStartTrackingTouch(); trackTouchEvent(event); onStopTrackingTouch(); } onSizeChanged(getWidth(), getHeight(), 0, 0); // ProgressBar doesn't know to repaint the thumb drawable // in its inactive state when the touch stops (because the // value has not apparently changed) invalidate(); break; } return true; } private void trackTouchEvent(MotionEvent event) { final int height = getHeight(); final int top = getPaddingTop(); final int bottom = getPaddingBottom(); final int available = height - top - bottom; int y = (int) event.getY(); float scale; float progress = 0; // 下面是最小值 if (y > height - bottom) { scale = 0.0f; } else if (y < top) { scale = 1.0f; } else { scale = (float) (available - y + top) / (float) available; progress = mTouchProgressOffset; } final int max = getMax(); progress += scale * max; setProgress((int) progress); } /** * This is called when the user has started touching this widget. */ void onStartTrackingTouch() { mIsDragging = false; } /** * This is called when the user either releases his touch or the touch is * canceled. */ void onStopTrackingTouch() { mIsDragging = false; } private void attemptClaimDrag() { ViewParent p = getParent(); if (p != null) { p.requestDisallowInterceptTouchEvent(true); } } @Override public synchronized void setProgress(int progress) { super.setProgress(progress); onSizeChanged(getWidth(), getHeight(), 0, 0); }}

未完,待续…


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表