视频播放自定义控制器

来源:互联网 发布:java 数组最大长度 编辑:程序博客网 时间:2024/05/17 09:33

自定义控制器

import java.lang.reflect.Field;


import android.app.Activity;
import android.content.Context;
import android.graphics.PointF;
import android.media.AudioManager;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import au.mobile.player.R;
import au.mobile.util.DensityUtils;


public class MyMediaController extends android.widget.MediaController {
// 自定义底部控制layout
private LinearLayout mView;
// 播放进度条
private SeekBar mMySeekBar;
// 当前播放时间
private TextView mMyCurrentTime;
// 视频总长度
private TextView mMyTotalTime;
// activity
private Activity mContext;
// 自动隐藏底部控制layout标识
private final int FADE_OUT = 0;
// 自动刷新地不定读条标识
private final int SHOW_PROGRESS = 1;
// 系统播放控制器
private MediaPlayerControl mPlayer;
// 底部控制是否显示(默认不显示)
boolean isShow = false;
// 播放按钮
private ImageButton mPlayButton;
// 拉动进度条后放开的位置
private long mNewposition;
// 是否在拉动进度条
private boolean mDragging = false;
// 底部进度条里顶部距离
private int mTopMargin = 0;
// 底部进度条位置
private int mGravity = Gravity.BOTTOM;
// 系统mediacontroller容器
private ViewGroup mContentView;
// 是否第一次启动
private boolean isFirst = true;
// 自动隐藏底部控制条时间
private long mHideTime = 5000;
// 全屏按钮
private Button mFullScreenButton;
// 全屏按钮点击事件
private OnClickListener mFullScreenClickListener;
// 手势滑动方向(1:横向2:纵向)
private int mDirection;
// 手势滑动起始位置
private PointF mPointF = new PointF();
// 音量
private int mVolumeValue = -1;
// 系统最高音量
private int mMaxVolumeValue;
// 系统声音管理类
private AudioManager mAudioManager;
// 中间显示声音和快进,后退情况layout
private LinearLayout mCenterLayout;
// 中间显示声音还是快进后退的图标
private ImageView mCenterIcon;
// 中间显示音量或快进后退进度
private TextView mCenterInfo;
// 是否显示中间layout
private boolean isCenterShow = false;
// 手势开始时视频播放的时间
private int mCurrentProgress = -1;
// 处理刷新进度条和控制显示隐藏底部控制器线程
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
long pos;
switch (msg.what) {
case FADE_OUT:
hideController();
break;
case SHOW_PROGRESS:
pos = setProgress();
if (!mDragging && isShow && mPlayer.isPlaying()) {
msg = obtainMessage(SHOW_PROGRESS);
sendMessageDelayed(msg, 1000 - (pos % 1000));
}
break;
}
}
};


// 构造
public MyMediaController(Activity context) {
super(context);
mContext = context;
mAudioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
mMaxVolumeValue = mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
mVolumeValue = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
}


// 设置底部控制条隐藏时间
public void setHideTime(int time) {
mHideTime = time;
}


// 重写父类方法,初始化底部控制器和中间layout
@Override
public void setAnchorView(View view) {
super.setAnchorView(view);
initControllerView();
initCenterView();
}


// 设置底部控制器位置(默认放置屏幕底部)
public void setControllerGravity(int gravity) {
mGravity = gravity;
}


// 设置底部进度条
public void setControllerMargin(int margin) {
mTopMargin = margin;
}


// 初始化中间layout
private void initCenterView() {
mCenterLayout = (LinearLayout) LayoutInflater.from(getContext())
.inflate(R.layout.video_play_controller_center_layout, null);
mCenterIcon = (ImageView) mCenterLayout.findViewById(R.id.center_icon);
mCenterInfo = (TextView) mCenterLayout.findViewById(R.id.center_info);
}


// 显示中间layout
public void showCenterView() {
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.CENTER_HORIZONTAL;
params.topMargin = (mTopMargin - DensityUtils.dp2px(mContext, 50)) / 2;
mContentView.removeView(mCenterLayout);
mContentView.addView(mCenterLayout, params);
isCenterShow = true;
}


// 隐藏中间layout
public void hideCenterView() {
((ViewGroup) mContext.findViewById(android.R.id.content))
.removeView(mCenterLayout);
isCenterShow = false;
}


// 初始化底部控制器
private void initControllerView() {
try {
// 系统controller容器
mContentView = (ViewGroup) mContext
.findViewById(android.R.id.content);
// 自定义底部控制器
mView = (LinearLayout) LayoutInflater.from(getContext()).inflate(
R.layout.video_play_controller, null);
// 自定义播放按钮
mPlayButton = (ImageButton) mView
.findViewById(R.id.mediacontroller_play_pause);
// 自定义控制条
mMySeekBar = (SeekBar) mView.findViewById(R.id.videoview_seek);
// 自定义播放时间
mMyCurrentTime = (TextView) mView.findViewById(R.id.current_time);
// 自定义总视频时间
mMyTotalTime = (TextView) mView.findViewById(R.id.total_time);
// 自定义全屏按钮
mFullScreenButton = (Button) mView
.findViewById(R.id.mediacontroller_fullscreen);
// mMySeekBar.setMax(1000);
mContentView.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
if (isShow) {
hideController();
} else {
showController();
}


}
});
mFullScreenButton.setOnClickListener(mFullScreenClickListener);
mPlayButton.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
mPlayButton.setBackgroundDrawable(getResources()
.getDrawable(R.drawable.mediacontroller_play));
} else {
mPlayer.start();
mPlayButton.setBackgroundDrawable(getResources()
.getDrawable(R.drawable.mediacontroller_pause));
}
}
});
// 手势事件
mContentView.setOnTouchListener(new OnTouchListener() {


@Override
public boolean onTouch(View v, MotionEvent event) {
int layoutWidth = mContentView.getWidth();
int layoutHeight = mTopMargin;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mDirection = 0;
mPointF.set(event.getX(), event.getY());


break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(event.getX() - mPointF.x) < 10
&& Math.abs(event.getY() - mPointF.y) < 10) {
break;
}
// 判断手势滑动方向,竖向还是横向
if (mDirection == 0) {
if (Math.abs(event.getX() - mPointF.x) >= Math
.abs(event.getY() - mPointF.y)) {
mDirection = 1;
} else {
mDirection = 2;
}
}
if (mDirection == 1) {
if (mCurrentProgress == -1)
mCurrentProgress = mPlayer.getCurrentPosition();


// 横向滑动,处理快进
float percent = (event.getX() - mPointF.x)
/ layoutWidth;
moveSeekTo((long) (percent * 1000));
} else if (mDirection == 2) {
// 竖向滑动,处理音量
float percent = (mPointF.y - event.getY())
/ layoutHeight;
changeVolume(percent * 100);
}
break;
case MotionEvent.ACTION_UP:
mVolumeValue = mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
mDirection = 0;
hideCenterView();
if (!mPlayer.isPlaying())
mPlayer.start();
break;
}
return false;
}
});
// 拖动进度条监听
mMySeekBar
.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStartTrackingTouch(SeekBar bar) {
Log.d("chin", "start");
show(3600000);
mDragging = true;
mHandler.removeMessages(SHOW_PROGRESS);
}


@Override
public void onProgressChanged(SeekBar bar,
int progress, boolean fromuser) {
if (!fromuser) {
return;
}


long duration = mPlayer.getDuration();
mNewposition = (duration * progress) / 1000L;


if (mMyCurrentTime != null)
mMyCurrentTime
.setText(generateTime((int) mNewposition));
}


@Override
public void onStopTrackingTouch(SeekBar bar) {
Log.d("chin", "stop");
mDragging = false;
setProgress();
mPlayer.seekTo((int) mNewposition);
if (!mPlayer.isPlaying()) {
mPlayer.start();
mPlayButton
.setBackgroundDrawable(getResources()
.getDrawable(
R.drawable.mediacontroller_pause));
}
mHandler.sendEmptyMessage(SHOW_PROGRESS);
}
});
// 获取系统MediaPlayerController对象
Field player = android.widget.MediaController.class
.getDeclaredField("mPlayer");
player.setAccessible(true);
mPlayer = (MediaPlayerControl) player.get(this);

} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}


// 手势快进后退方法
private void moveSeekTo(long per) {
Log.d("chin", String.valueOf(per));
if (!isCenterShow) {
showCenterView();
}
int newPos = (int) ((mPlayer.getDuration() * (per + mMySeekBar
.getProgress())) / 1000L);
if (newPos < 0)
newPos = 0;
else if (newPos > mPlayer.getDuration()) {
newPos = mPlayer.getDuration();
}
mPlayer.seekTo(newPos);
if (per > 0) {
mCenterIcon.setBackgroundDrawable(getResources().getDrawable(
R.drawable.fast_forward_icon));
mCenterInfo.setText(generateTime(newPos));
} else {
mCenterIcon.setBackgroundDrawable(getResources().getDrawable(
R.drawable.fast_backward_icon));
mCenterInfo.setText(generateTime(newPos));
}
}


// 改变声音
private void changeVolume(float percent) {
if (!isCenterShow) {
showCenterView();
}
if (mVolumeValue < 0) {
mVolumeValue = 0;
}


int index = (int) (percent / 100 * mMaxVolumeValue + mVolumeValue);
if (index > mMaxVolumeValue) {
index = mMaxVolumeValue;
} else if (index < 0) {
index = 0;
}


mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, index, 0);
int volume = index * 100 / mMaxVolumeValue;
mCenterInfo.setText(String.valueOf(volume) + "%");
if (volume == 0) {
mCenterIcon.setBackgroundDrawable(getResources().getDrawable(
R.drawable.sound_no));
// mCenterInfo.setText("0%");
} else {
mCenterIcon.setBackgroundDrawable(getResources().getDrawable(
R.drawable.sound_ok));
// mCenterInfo.setText(String.valueOf(mVolumeValue * 100
// / mMaxVolumeValue)
// + "%");
}
}


// 不显示系统丑到爆又不能改ui的控制条
@Override
public void show(int timeout) {
}


public void setFullScreenClickListener(OnClickListener listener) {
mFullScreenClickListener = listener;
}


// 显示自定义底部控制条
public void showController() {
mHandler.removeMessages(FADE_OUT);
if (isFirst) {
super.show(0);
super.hide();
isFirst = false;
}
((ViewGroup) mContext.findViewById(android.R.id.content))
.removeView(mView);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, DensityUtils.dp2px(mContext, 50));
params.gravity = mGravity;
params.topMargin = mTopMargin;


((ViewGroup) mContext.findViewById(android.R.id.content)).addView(
mView, params);
mHandler.sendEmptyMessage(SHOW_PROGRESS);
mHandler.sendMessageDelayed(mHandler.obtainMessage(FADE_OUT), mHideTime);
isShow = true;
}


// 隐藏自定义底部控制条
public void hideController() {
((ViewGroup) mContext.findViewById(android.R.id.content))
.removeView(mView);
isShow = false;
}


// 设置进度条进度
private long setProgress() {
if (mPlayer == null || mDragging) {
return 0;
}


long position = mPlayer.getCurrentPosition();
long duration = mPlayer.getDuration();
if (duration > 0) {
long pos = 1000L * position / duration;
mMySeekBar.setProgress((int) pos);
int percent = mPlayer.getBufferPercentage();
mMySeekBar.setSecondaryProgress(percent * 10);
}
mMyTotalTime.setText(generateTime(duration));
mMyCurrentTime.setText(generateTime(position));
return position;
}


// 把毫秒转化成时分秒
public static 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);
}


}



播放器页面
import java.util.List;


import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.VideoView;
import au.mobile.inject.InjectUtils;
import au.mobile.inject.annotation.ViewInject;
import au.mobile.player.R;
import au.mobile.player.common.Constants;
import au.mobile.player.common.Settings;
import au.mobile.player.db.bean.VideoData;
import au.mobile.util.DensityUtils;
import au.mobile.util.ImageLoader;
import au.mobile.util.ImageLoader.OnLoadListener;


public class PlayActivity extends BaseActivity {
// VideoView系统
@ViewInject(id = R.id.video_view)
private VideoView mVideoView;
// 视频列表
@ViewInject(id = R.id.video_list)
private GridView mVideoList;
// 自定义控制器
private MyMediaController myMediaController;
// 视频数据结构
private List<VideoData> mVideoDataList;
// 图片加载类
private ImageLoader mImageLoader;
// 视频列表适配器
private VideoListAdapter mAdapter;
// 视频信息layout
@ViewInject(id = R.id.video_info_layout)
private LinearLayout mVideoInfoLayout;
// 播放器所在layout
@ViewInject(id = R.id.video_layout)
private FrameLayout mVideoLayout;
// 手机方向
private int ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.play_layout);
InjectUtils.inject(this);
mImageLoader = new ImageLoader(this, Settings.IMAGE_PATH,
Settings.TEMP_PATH);
initView();
}


// 返回按钮事件
@Override
public void onBackPressed() {
mVideoView.stopPlayback();
super.onBackPressed();
}


// 初始化
private void initView() {
Intent getIntent = getIntent();
mVideoDataList = getIntent
.getParcelableArrayListExtra(Constants.VIDEOSEASON_INFO);
mAdapter = new VideoListAdapter();
mVideoList.setAdapter(mAdapter);
if (mVideoDataList != null && mVideoDataList.size() > 0) {
// 设置视频地址
mVideoView.setVideoURI(Uri.parse(mVideoDataList.get(0)
.getVideoUrl()));
// 视频准备完成监听
mVideoView.setOnPreparedListener(new OnPreparedListener() {


@Override
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
myMediaController.showController();
}
});
// 自定义控制器
myMediaController = new MyMediaController(PlayActivity.this);
// 设置自定义控制器位置
myMediaController.setControllerGravity(Gravity.TOP);
// 设置自定义控制器margin
myMediaController.setControllerMargin(DensityUtils.dp2px(
PlayActivity.this, 250));
// 添加自定义控制器
mVideoView.setMediaController(myMediaController);
// 全屏按钮点击事件
myMediaController.setFullScreenClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
if (ORIENTATION == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
} else if (ORIENTATION == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
setRequestedOrientation(ORIENTATION);
}
});
}
// 视频列表点击事件
mVideoList.setOnItemClickListener(new OnItemClickListener() {


@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
myMediaController.hideController();
mVideoView.setVideoURI(Uri.parse(mVideoDataList.get(position)
.getVideoUrl()));
mVideoView.setOnPreparedListener(new OnPreparedListener() {


@Override
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
myMediaController.showController();
}
});
}
});
}


// 手机横屏竖屏切换监听
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// 横屏
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int mWidth = dm.widthPixels;
int mHeight = dm.heightPixels;
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
lp.width = mWidth;
lp.height = mHeight;
myMediaController.setControllerGravity(Gravity.BOTTOM);
myMediaController.setControllerMargin(0);
myMediaController.hideController();
myMediaController.showController();
mVideoLayout.setLayoutParams(lp);
mVideoView.getHolder().setFixedSize(lp.width, lp.height);
// 竖屏
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int mWidth = dm.widthPixels;
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
lp.width = mWidth;
lp.height = DensityUtils.dp2px(this, 300);
myMediaController.setControllerGravity(Gravity.TOP);
myMediaController.setControllerMargin(DensityUtils.dp2px(
PlayActivity.this, 250));
myMediaController.hideController();
myMediaController.showController();
mVideoLayout.setLayoutParams(lp);
mVideoView.getHolder().setFixedSize(lp.width, lp.height);
}
}


// 视频列表适配器
private class VideoListAdapter extends BaseAdapter {


@Override
public int getCount() {
return mVideoDataList.size();
}


@Override
public VideoData getItem(int position) {
return mVideoDataList.get(position);
}


@Override
public long getItemId(int position) {
return 0;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(PlayActivity.this).inflate(
R.layout.video_list_item, null);
holder.image = (ImageView) convertView.findViewById(R.id.image);
holder.name = (TextView) convertView.findViewById(R.id.name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
mImageLoader.loadImage(mVideoDataList.get(position).getImageUrl(),
holder.image, new OnLoadListener() {


@Override
public void onLoad(Bitmap bitmap, View targetView) {
((ImageView) targetView).setImageBitmap(bitmap);
}
});
holder.name.setText(mVideoDataList.get(position).getName());
return convertView;
}


public class ViewHolder {
ImageView image;
TextView name;
}
}


}

0 0
原创粉丝点击