package cn.demo.videolist;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.Rect;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import cn.demo.videolist.media.IMediaController;
import cn.demo.videolist.media.IjkVideoView;
import tv.danmaku.ijk.media.player.IMediaPlayer;
/**
* @Description ${控制器}
*/
public class CustomMediaContoller implements IMediaController {
private static final int SET_VIEW_HIDE = 1;
private static final int TIME_OUT = 5000;
private static final int MESSAGE_SHOW_PROGRESS = 2;
private static final int PAUSE_IMAGE_HIDE = 3;
private static final int MESSAGE_SEEK_NEW_POSITION = 4;
private static final int MESSAGE_HIDE_CONTOLL = 5;
private View itemView;
private View view;
private boolean isShow;
private IjkVideoView videoView;
private boolean isScroll;
private SeekBar seekBar;
AudioManager audioManager;
private ProgressBar progressBar;
private boolean isSound;
private boolean isDragging;
private boolean isPause;
private boolean isShowContoller;
private ImageView sound, full, play;
private TextView time, allTime,seekTxt;
private PointF lastPoint;
private Context context;
private ImageView pauseImage;
private Bitmap bitmap;
private GestureDetector detector;
private RelativeLayout show;
private VSeekBar brightness_seek, sound_seek;
private LinearLayout brightness_layout, sound_layout;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SET_VIEW_HIDE:
isShow = false;
itemView.setVisibility(View.GONE);
break;
case MESSAGE_SHOW_PROGRESS:
setProgress();
if (!isDragging && isShow) {
msg = obtainMessage(MESSAGE_SHOW_PROGRESS);
sendMessageDelayed(msg, 1000);
}
break;
case PAUSE_IMAGE_HIDE:
pauseImage.setVisibility(View.GONE);
break;
case MESSAGE_SEEK_NEW_POSITION:
if (newPosition >= 0) {
videoView.seekTo((int) newPosition);
newPosition = -1;
}
break;
case MESSAGE_HIDE_CONTOLL:
seekTxt.setVisibility(View.GONE);
brightness_layout.setVisibility(View.GONE);
sound_layout.setVisibility(View.GONE);
break;
}
}
};
public CustomMediaContoller(Context context, View view) {
this.view = view;
itemView = view.findViewById(R.id.media_contoller);
this.videoView = (IjkVideoView) view.findViewById(R.id.main_video);
itemView.setVisibility(View.GONE);
isShow = false;
isDragging = false;
isShowContoller = true;
this.context = context;
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
initView();
initAction();
}
public void initView() {
progressBar = (ProgressBar) view.findViewById(R.id.loading);
seekBar = (SeekBar) itemView.findViewById(R.id.seekbar);
allTime = (TextView) itemView.findViewById(R.id.all_time);
time = (TextView) itemView.findViewById(R.id.time);
full = (ImageView) itemView.findViewById(R.id.full);
sound = (ImageView) itemView.findViewById(R.id.sound);
play = (ImageView) itemView.findViewById(R.id.player_btn);
pauseImage = (ImageView) view.findViewById(R.id.pause_image);
brightness_layout = (LinearLayout) view.findViewById(R.id.brightness_layout);
brightness_seek = (VSeekBar) view.findViewById(R.id.brightness_seek);
sound_layout = (LinearLayout) view.findViewById(R.id.sound_layout);
sound_seek = (VSeekBar) view.findViewById(R.id.sound_seek);
show = (RelativeLayout) view.findViewById(R.id.show);
seekTxt= (TextView) view.findViewById(R.id.seekTxt);
}
private void initAction() {
sound_seek.setEnabled(false);
brightness_seek.setEnabled(false);
isSound = false;
detector = new GestureDetector(context, new PlayGestureListener());
mMaxVolume = ((AudioManager) context.getSystemService(Context.AUDIO_SERVICE))
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
String string = generateTime((long) (duration * progress * 1.0f / 100));
time.setText(string);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
setProgress();
isDragging = true;
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
handler.removeMessages(MESSAGE_SHOW_PROGRESS);
show();
handler.removeMessages(SET_VIEW_HIDE);
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
isDragging = false;
videoView.seekTo((int) (duration * seekBar.getProgress() * 1.0f / 100));
handler.removeMessages(MESSAGE_SHOW_PROGRESS);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
isDragging = false;
handler.sendEmptyMessageDelayed(MESSAGE_SHOW_PROGRESS, 1000);
show();
}
});
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (detector.onTouchEvent(event))
return true;
// 处理手势结束
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_UP:
endGesture();
break;
}
return false;
}
});
itemView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("custommedia", "event");
Rect seekRect = new Rect();
seekBar.getHitRect(seekRect);
if ((event.getY() >= (seekRect.top - 50)) && (event.getY() <= (seekRect.bottom + 50))) {
float y = seekRect.top + seekRect.height() / 2;
//seekBar only accept relative x
float x = event.getX() - seekRect.left;
if (x < 0) {
x = 0;
} else if (x > seekRect.width()) {
x = seekRect.width();
}
MotionEvent me = MotionEvent.obtain(event.getDownTime(), event.getEventTime(),
event.getAction(), x, y, event.getMetaState());
return seekBar.onTouchEvent(me);
}
return false;
}
});
videoView.setOnInfoListener(new IMediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(IMediaPlayer mp, int what, int extra) {
Log.e("setOnInfoListener", what + "");
switch (what) {
case IMediaPlayer.MEDIA_INFO_BUFFERING_START:
//开始缓冲
if (progressBar.getVisibility() == View.GONE)
progressBar.setVisibility(View.VISIBLE);
break;
case IMediaPlayer.MEDIA_INFO_BUFFERING_END:
//开始播放
progressBar.setVisibility(View.GONE);
break;
case IMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
// statusChange(STATUS_PLAYING);
progressBar.setVisibility(View.GONE);
break;
case IMediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START:
progressBar.setVisibility(View.GONE);
break;
}
return false;
}
});
sound.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isSound) {
//静音
sound.setImageResource(R.mipmap.sound_mult_icon);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, true);
} else {
//取消静音
sound.setImageResource(R.mipmap.sound_open_icon);
audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false);
}
isSound = !isSound;
}
});
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (videoView.isPlaying()) {
pause();
} else {
reStart();
}
}
});
full.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("full", "full");
if (getScreenOrientation((Activity) context) == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
((Activity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
((Activity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
});
}
public void start() {
pauseImage.setVisibility(View.GONE);
itemView.setVisibility(View.GONE);
play.setImageResource(R.mipmap.video_stop_btn);
progressBar.setVisibility(View.VISIBLE);
}
public void pause() {
play.setImageResource(R.mipmap.video_play_btn);
videoView.pause();
bitmap = videoView.getBitmap();
if (bitmap != null) {
pauseImage.setImageBitmap(bitmap);
pauseImage.setVisibility(View.VISIBLE);
}
}
public void reStart() {
play.setImageResource(R.mipmap.video_stop_btn);
videoView.start();
if (bitmap != null) {
handler.sendEmptyMessageDelayed(PAUSE_IMAGE_HIDE, 100);
bitmap.recycle();
bitmap = null;
// pauseImage.setVisibility(View.GONE);
}
}
private long duration;
public void setShowContoller(boolean isShowContoller) {
this.isShowContoller = isShowContoller;
handler.removeMessages(SET_VIEW_HIDE);
itemView.setVisibility(View.GONE);
}
public int getScreenOrientation(Activity activity) {
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
int orientation;
// if the device's natural orientation is portrait:
if ((rotation == Surface.ROTATION_0
|| rotation == Surface.ROTATION_180) && height > width ||
(rotation == Surface.ROTATION_90
|| rotation == Surface.ROTATION_270) && width > height) {
switch (rotation) {
case Surface.ROTATION_0:
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
break;
case Surface.ROTATION_90:
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
break;
case Surface.ROTATION_180:
orientation =
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
break;
case Surface.ROTATION_270:
orientation =
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
break;
default:
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
break;
}
}
// if the device's natural orientation is landscape or if the device
// is square:
else {
switch (rotation) {
case Surface.ROTATION_0:
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
break;
case Surface.ROTATION_90:
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
break;
case Surface.ROTATION_180:
orientation =
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
break;
case Surface.ROTATION_270:
orientation =
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
break;
default:
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
break;
}
}
return orientation;
}
@Override
public void hide() {
if (isShow) {
handler.removeMessages(MESSAGE_SHOW_PROGRESS);
isShow = false;
handler.removeMessages(SET_VIEW_HIDE);
itemView.setVisibility(View.GONE);
}
}
@Override
public boolean isShowing() {
return isShow;
}
@Override
public void setAnchorView(View view) {
}
@Override
public void setEnabled(boolean enabled) {
}
@Override
public void setMediaPlayer(MediaController.MediaPlayerControl player) {
}
@Override
public void show(int timeout) {
handler.sendEmptyMessageDelayed(SET_VIEW_HIDE, timeout);
}
@Override
public void show() {
if (!isShowContoller)
return;
isShow = true;
progressBar.setVisibility(View.GONE);
itemView.setVisibility(View.VISIBLE);
handler.sendEmptyMessage(MESSAGE_SHOW_PROGRESS);
show(TIME_OUT);
}
@Override
public void showOnce(View view) {
}
private String generateTime(long time) {
int totalSeconds = (int) (time / 1000);
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;
return hours > 0 ? String.format("%02d:%02d:%02d", hours, minutes, seconds) : String.format("%02d:%02d", minutes, seconds);
}
public void setVisiable() {
show();
}
private long setProgress() {
if (isDragging) {
return 0;
}
long position = videoView.getCurrentPosition();
long duration = videoView.getDuration();
this.duration = duration;
if (!generateTime(duration).equals(allTime.getText().toString()))
allTime.setText(generateTime(duration));
if (seekBar != null) {
if (duration > 0) {
long pos = 100L * position / duration;
seekBar.setProgress((int) pos);
}
int percent = videoView.getBufferPercentage();
seekBar.setSecondaryProgress(percent);
}
String string = generateTime((long) (duration * seekBar.getProgress() * 1.0f / 100));
time.setText(string);
return position;
}
private VedioIsPause vedioIsPause;
public interface VedioIsPause {
void pause(boolean pause);
}
public void setPauseImageHide() {
pauseImage.setVisibility(View.GONE);
}
public class PlayGestureListener extends GestureDetector.SimpleOnGestureListener {
private boolean firstTouch;
private boolean volumeControl;
private boolean seek;
@Override
public boolean onDown(MotionEvent e) {
firstTouch = true;
handler.removeMessages(SET_VIEW_HIDE);
//横屏下拦截事件
if (getScreenOrientation((Activity) context) == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
return true;
}else {
return super.onDown(e);
}
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
float x = e1.getX() - e2.getX();
float y = e1.getY() - e2.getY();
if (firstTouch) {
seek = Math.abs(distanceX) >= Math.abs(distanceY);
volumeControl = e1.getX() < view.getMeasuredWidth() * 0.5;
firstTouch = false;
}
if (seek) {
onProgressSlide(-x / view.getWidth(),e1.getX()/view.getWidth());
} else {
float percent = y / view.getHeight();
if (volumeControl) {
onVolumeSlide(percent);
} else {
onBrightnessSlide(percent);
}
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
private int volume = -1;
private float brightness = -1;
private long newPosition = 1;
private int mMaxVolume;
/**
* 手势结束
*/
private void endGesture() {
volume = -1;
brightness = -1f;
if (newPosition >= 0) {
handler.removeMessages(MESSAGE_SEEK_NEW_POSITION);
handler.sendEmptyMessage(MESSAGE_SEEK_NEW_POSITION);
}
handler.removeMessages(MESSAGE_HIDE_CONTOLL);
handler.sendEmptyMessageDelayed(MESSAGE_HIDE_CONTOLL, 500);
}
/**
* 滑动改变声音大小
*
* @param percent
*/
private void onVolumeSlide(float percent) {
if (volume == -1) {
volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if (volume < 0)
volume = 0;
}
// hide();
int index = (int) (percent * mMaxVolume) + volume;
if (index > mMaxVolume)
index = mMaxVolume;
else if (index < 0)
index = 0;
// 变更声音
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
if (sound_layout.getVisibility()==View.GONE)
sound_layout.setVisibility(View.VISIBLE);
// 变更进度条
int i = (int) (index * 1.0f / mMaxVolume * 100);
if (i == 0) {
sound.setImageResource(R.mipmap.sound_mult_icon);
} else {
sound.setImageResource(R.mipmap.sound_open_icon);
}
sound_seek.setProgress(i);
}
/**
* 滑动跳转
*
* @param percent 移动比例
* @param downPer 按下比例
*/
private void onProgressSlide(float percent,float downPer) {
long position = videoView.getCurrentPosition();
long duration = videoView.getDuration();
long deltaMax = Math.min(100 * 1000, duration - position);
long delta = (long) (deltaMax * percent);
newPosition = delta + position;
if (newPosition > duration) {
newPosition = duration;
} else if (newPosition <= 0) {
newPosition = 0;
delta = -position;
}
int showDelta = (int) delta / 1000;
Log.e("showdelta", ((downPer +percent)*100) + "");
if (showDelta != 0) {
if (seekTxt.getVisibility()==View.GONE)
seekTxt.setVisibility(View.VISIBLE);
String current=generateTime(newPosition);
seekTxt.setText(current+"/"+allTime.getText());
}
}
/**
* 滑动改变亮度
*
* @param percent
*/
private void onBrightnessSlide(float percent) {
if (brightness < 0) {
brightness = ((Activity) context).getWindow().getAttributes().screenBrightness;
if (brightness <= 0.00f) {
brightness = 0.50f;
} else if (brightness < 0.01f) {
brightness = 0.01f;
}
}
Log.d(this.getClass().getSimpleName(), "brightness:" + brightness + ",percent:" + percent);
WindowManager.LayoutParams lpa = ((Activity) context).getWindow().getAttributes();
lpa.screenBrightness = brightness + percent;
if (lpa.screenBrightness > 1.0f) {
lpa.screenBrightness = 1.0f;
} else if (lpa.screenBrightness < 0.01f) {
lpa.screenBrightness = 0.01f;
}
if (brightness_layout.getVisibility()==View.GONE)
brightness_layout.setVisibility(View.VISIBLE);
brightness_seek.setProgress((int) (lpa.screenBrightness * 100));
((Activity) context).getWindow().setAttributes(lpa);
}
}