A基础功能php
1.1.1 可以自定义视频加载loading类型,设置视频标题,设置视频底部图片,设置播放时长等基础功能html
1.1.2 能够切换播放器的视频播放状态,播放错误,播放未开始,播放开始,播放准备中,正在播放,暂停播放,正在缓冲等等状态android
1.1.3 能够自由设置播放器的播放模式,好比,正常播放,全屏播放,和小屏幕播放。其中全屏播放支持旋转屏幕。git
1.1.4 能够支持多种视频播放类型,好比,原生封装视频播放器,还有基于ijkplayer封装的播放器。github
1.1.5 能够设置是否隐藏播放音量,播放进度,播放亮度等,能够经过拖动seekBar改变视频进度。还支持设置n秒后不操做则隐藏头部和顶部布局功能web
B高级功能面试
1.1.6 支持一遍播放一遍缓冲的功能,其中缓冲包括两部分,第一种是播放过程当中缓冲,第二种是暂停过程当中缓冲segmentfault
1.1.7 基于ijkplayer的封装播放器,支持多种格式视频播放缓存
1.1.8 能够设置是否记录播放位置,设置播放速度,设置屏幕比例微信
1.1.9 支持滑动改变音量【屏幕右边】,改变屏幕亮度【屏幕左边】,支持切换视频清晰度模式
1.1.0 支持list页面中视频播放,滚动后暂停播放,播放能够自由设置是否记录状态。而且还支持删除视频播放位置状态。
C拓展功能
C1产品需求:相似优酷,爱奇艺视频播放器部分逻辑。好比若是用户没有登陆也没有看视频权限,则提示试看视频[自定义布局];若是用户没有登陆可是有看视频权限,则正常观看;若是用户登陆,可是没有充值会员,部分须要权限视频则进入试看模式,试看结束后弹出充值会员界面;若是用户余额不足,好比余额只有99元,可是视频观看要199元,则又有其余提示。
C2自身需求:好比封装好了视频播放库,那么点击视频上登陆按钮则跳到登陆页面;点击充值会员页面也跳到充值页面。这个经过定义接口,可让使用者经过方法调用,灵活处理点击事件。
C.1.1 实现了上面两个需求,灵活可拓展性强。
C.1.2 对于设置视频的宽高,建议设置成4:3或者16:9或者经常使用比例,若是不是经常使用比例,则可能会有黑边。其中黑边的背景能够设置
C.1.3 能够设置播放有权限的视频时的各类文字描述,而没有把它写在封装库中,使用者本身设定
C.1.4 锁定屏幕功能
D待添加功能
1.2.1目前仅仅查了下GitHub上项目
ijkplayer官方库 https://github.com/Bilibili/ijkplayer Vitamio官方库 https://github.com/yixia/VitamioBundle 以jiecao为例的封装库 https://github.com/JasonChow1989/JieCaoVideoPlayer-develop 2年前 https://github.com/open-android/JieCaoVideoPlayer 1年前 https://github.com/lipangit/JiaoZiVideoPlayer 4个月前 https://github.com/CarGuo/GSYVideoPlayer 其余库 https://github.com/danylovolokh/VideoPlayerManager
1.2.2 具备的优点
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!--https://github.com/yangchong211--> <!--若是你以为好,请给个star,让更多人使用,避免重复造轮子--> <!--底图,主要是显示视频缩略图--> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:visibility="visible"/> <!--加载动画view--> <include layout="@layout/custom_video_player_loading"/> <!--改变播放位置--> <include layout="@layout/custom_video_player_change_position"/> <!--改变亮度--> <include layout="@layout/custom_video_player_change_brightness"/> <!--改变声音--> <include layout="@layout/custom_video_player_change_volume"/> <!--播放完成,你也能够自定义--> <include layout="@layout/custom_video_player_completed"/> <!--播放错误--> <include layout="@layout/custom_video_player_error"/> <!--顶部控制区--> <include layout="@layout/custom_video_player_top"/> <!--底部控制区--> <include layout="@layout/custom_video_player_bottom"/> <!--右下角初始显示的总时长--> <TextView android:id="@+id/length" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:layout_marginBottom="12dp" android:layout_marginEnd="8dp" android:padding="4dp" android:visibility="visible" android:text="00:00" android:textColor="@android:color/white" android:textSize="12sp"/> <!--中间开始播放按钮--> <ImageView android:id="@+id/center_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/ic_player_center_start" android:visibility="visible"/> <!--试看按钮--> <ImageView android:id="@+id/iv_try_see" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:src="@drawable/selector_try_see" android:visibility="gone"/> <!--试看布局,非会员显示该布局--> <include layout="@layout/custom_video_player_try_see"/> </RelativeLayout>
compile 'cn.yc:YCVideoPlayerLib:2.2'
<org.yczbj.ycvideoplayerlib.VideoPlayer android:id="@+id/video_player" android:layout_width="match_parent" android:layout_height="240dp"/>
//设置播放类型 // IjkPlayer or MediaPlayer videoPlayer1.setPlayerType(VideoPlayer.TYPE_NATIVE); //网络视频地址 String videoUrl = DataUtil.getVideoListData().get(0).getVideoUrl(); //设置视频地址和请求头部 videoPlayer1.setUp(videoUrl, null); //是否从上一次的位置继续播放 videoPlayer1.continueFromLastPosition(true); //设置播放速度 videoPlayer1.setSpeed(1.0f); //建立视频控制器 VideoPlayerController controller = new VideoPlayerController(this); controller.setTitle("办快来围观拉,自定义视频播放器能够播放视频拉"); //设置视频时长 controller.setLength(98000); //设置5秒不操做后则隐藏头部和底部布局视图 controller.setHideTime(5000); //controller.setImage(R.drawable.image_default); ImageUtil.loadImgByPicasso(this, R.drawable.image_default, R.drawable.image_default, controller.imageView()); //设置视频控制器 videoPlayer1.setController(controller);
//设置视频加载缓冲时加载窗的类型,多种类型 controller.setLoadingType(2); ArrayList<String> content = new ArrayList<>(); content.add("试看结束,yc观看所有内容请开通会员1111。"); content.add("试看结束,yc观看所有内容请开通会员2222。"); content.add("试看结束,yc观看所有内容请开通会员3333。"); content.add("试看结束,yc观看所有内容请开通会员4444。"); controller.setMemberContent(content); controller.setHideTime(5000); //设置设置会员权限类型,第一个参数是否登陆,第二个参数是否有权限看,第三个参数试看完后展现的文字内容,第四个参数是否保存进度位置 controller.setMemberType(false,false,3,true); controller.imageView().setBackgroundResource(R.color.blackText); //ImageUtil.loadImgByPicasso(this, R.color.blackText, R.drawable.image_default, controller.imageView()); //设置试看结束后,登陆或者充值会员按钮的点击事件 controller.setOnMemberClickListener(new OnMemberClickListener() { @Override public void onClick(int type) { switch (type){ case ConstantKeys.Gender.LOGIN: //调到用户登陆也米娜 startActivity(MeLoginActivity.class); break; case ConstantKeys.Gender.MEMBER: //调到用户充值会员页面 startActivity(MeMemberActivity.class); break; default: break; } } });
@Override protected void onStop() { super.onStop(); VideoPlayerManager.instance().releaseVideoPlayer(); } @Override public void onBackPressed() { if (VideoPlayerManager.instance().onBackPressed()) return; super.onBackPressed(); }
//在宿主Activity中设置代码以下 @Override protected void onStop() { super.onStop(); VideoPlayerManager.instance().releaseVideoPlayer(); } @Override public void onBackPressed() { if (VideoPlayerManager.instance().onBackPressed()) return; super.onBackPressed(); } //-------------------------------------------------- //在此Fragment中设置代码以下 @Override public void onStop() { super.onStop(); VideoPlayerManager.instance().releaseVideoPlayer(); }
<activity android:name=".ui.test2.TestMyActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="portrait"/>
controller.setOnMemberClickListener(new OnMemberClickListener() { @Override public void onClick(int type) { switch (type){ case ConstantKeys.Gender.LOGIN: //调到用户登陆也米娜 startActivity(MeLoginActivity.class); break; case ConstantKeys.Gender.MEMBER: //调到用户充值会员页面 startActivity(MeMemberActivity.class); break; default: break; } } }); controller.setOnVideoBackListener(new OnVideoBackListener() { @Override public void onBackClick() { onBackPressed(); } });
recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setHasFixedSize(true); VideoAdapter adapter = new VideoAdapter(this, DataUtil.getVideoListData()); recyclerView.setAdapter(adapter); //注意:下面这个方法不能漏掉 recyclerView.setRecyclerListener(new RecyclerView.RecyclerListener() { @Override public void onViewRecycled(RecyclerView.ViewHolder holder) { VideoPlayer videoPlayer = ((VideoAdapter.VideoViewHolder) holder).mVideoPlayer; if (videoPlayer == VideoPlayerManager.instance().getCurrentVideoPlayer()) { VideoPlayerManager.instance().releaseVideoPlayer(); } } });
public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoViewHolder> { private Context mContext; private List<Video> mVideoList; VideoAdapter(Context context, List<Video> videoList) { mContext = context; mVideoList = videoList; } @Override public VideoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(mContext).inflate(R.layout.item_test_my_video, parent, false); VideoViewHolder holder = new VideoViewHolder(itemView); //建立视频播放控制器,主要只要建立一次就能够呢 VideoPlayerController controller = new VideoPlayerController(mContext); holder.setController(controller); return holder; } @Override public void onBindViewHolder(VideoViewHolder holder, int position) { Video video = mVideoList.get(position); holder.bindData(video); } @Override public int getItemCount() { return mVideoList==null ? 0 : mVideoList.size(); } class VideoViewHolder extends RecyclerView.ViewHolder { VideoPlayerController mController; VideoPlayer mVideoPlayer; VideoViewHolder(View itemView) { super(itemView); mVideoPlayer = (VideoPlayer) itemView.findViewById(R.id.nice_video_player); // 将列表中的每一个视频设置为默认16:9的比例 ViewGroup.LayoutParams params = mVideoPlayer.getLayoutParams(); // 宽度为屏幕宽度 params.width = itemView.getResources().getDisplayMetrics().widthPixels; // 高度为宽度的9/16 params.height = (int) (params.width * 9f / 16f); mVideoPlayer.setLayoutParams(params); } /** * 设置视频控制器参数 * @param controller 控制器对象 */ void setController(VideoPlayerController controller) { mController = controller; mVideoPlayer.setController(mController); } void bindData(Video video) { mController.setTitle(video.getTitle()); mController.setLength(video.getLength()); Glide.with(itemView.getContext()) .load(video.getImageUrl()) .placeholder(R.drawable.image_default) .crossFade() .into(mController.imageView()); mVideoPlayer.setUp(video.getVideoUrl(), null); } } }
if (videoPlayer.isIdle()) { Toast.makeText(this, "要点击播放后才能进入小窗口", Toast.LENGTH_SHORT).show(); } else { videoPlayer.enterTinyWindow(); }
//若是不想打印库中的日志,能够设置 VideoLogUtil.isLog = false;
public class VideoLogUtil { private static final String TAG = "YCVideoPlayer"; public static boolean isLog = true; static void d(String message) { if(isLog){ Log.d(TAG, message); } } static void i(String message) { if(isLog){ Log.i(TAG, message); } } static void e(String message, Throwable throwable) { if(isLog){ Log.e(TAG, message, throwable); } } }
//设置播放类型 // IjkPlayer or MediaPlayer videoPlayer1.setPlayerType(VideoPlayer.TYPE_NATIVE); //设置视频地址和请求头部 videoPlayer1.setUp(videoUrl, null); //建立视频控制器 VideoPlayerController controller = new VideoPlayerController(this); //设置视频控制器 videoPlayer1.setController(controller);
//设置播放类型 // MediaPlayer videoPlayer.setPlayerType(VideoPlayer.TYPE_NATIVE); // IjkPlayer videoPlayer.setPlayerType(VideoPlayer.TYPE_IJK); //网络视频地址 String videoUrl = DataUtil.getVideoListData().get(1).getVideoUrl(); //设置视频地址和请求头部 videoPlayer.setUp(videoUrl, null); //是否从上一次的位置继续播放 videoPlayer.continueFromLastPosition(false); //设置播放速度 videoPlayer.setSpeed(1.0f); //设置播放位置 //videoPlayer.seekTo(3000); //设置音量 videoPlayer.setVolume(50); //设置全屏播放 videoPlayer.enterFullScreen(); //设置小屏幕播放 videoPlayer.enterTinyWindow(); //退出全屏 videoPlayer.exitFullScreen(); //退出小窗口播放 videoPlayer.exitTinyWindow(); //释放,内部的播放器被释放掉,同时若是在全屏、小窗口模式下都会退出 videoPlayer.release(); //释放播放器,注意必定要判断对象是否为空,加强严谨性 videoPlayer.releasePlayer();
//是否从上一次的位置继续播放,没必要须 videoPlayer.continueFromLastPosition(false); //获取最大音量 int maxVolume = videoPlayer.getMaxVolume(); //获取音量值 int volume = videoPlayer.getVolume(); //获取持续时长 long duration = videoPlayer.getDuration(); //获取播放位置 long currentPosition = videoPlayer.getCurrentPosition(); //获取缓冲区百分比 int bufferPercentage = videoPlayer.getBufferPercentage(); //获取播放速度 float speed = videoPlayer.getSpeed(1);
//开始播放 videoPlayer.start(); //开始播放,从某位置播放 videoPlayer.start(3000); //从新播放 videoPlayer.restart(); //暂停播放 videoPlayer.pause();
//判断是否开始播放 boolean idle = videoPlayer.isIdle(); //判断视频是否播放准备中 boolean preparing = videoPlayer.isPreparing(); //判断视频是否准备就绪 boolean prepared = videoPlayer.isPrepared(); //判断视频是否正在缓冲 boolean bufferingPlaying = videoPlayer.isBufferingPlaying(); //判断是不是否缓冲暂停 boolean bufferingPaused = videoPlayer.isBufferingPaused(); //判断视频是否暂停播放 boolean paused = videoPlayer.isPaused(); //判断视频是否正在播放 boolean playing = videoPlayer.isPlaying(); //判断视频是否播放错误 boolean error = videoPlayer.isError(); //判断视频是否播放完成 boolean completed = videoPlayer.isCompleted(); //判断视频是否播放全屏 boolean fullScreen = videoPlayer.isFullScreen(); //判断视频是否播放小窗口 boolean tinyWindow = videoPlayer.isTinyWindow(); //判断视频是否正常播放 boolean normal = videoPlayer.isNormal();
//建立视频控制器 VideoPlayerController controller = new VideoPlayerController(this); //设置视频标题 controller.setTitle("高仿优酷视频播放页面"); //设置视频时长 //controller.setLength(98000); //设置视频加载缓冲时加载窗的类型,多种类型 controller.setLoadingType(2); ArrayList<String> content = new ArrayList<>(); content.add("试看结束,观看所有内容请开通会员1111。"); content.add("试看结束,观看所有内容请开通会员2222。"); content.add("试看结束,观看所有内容请开通会员3333。"); content.add("试看结束,观看所有内容请开通会员4444。"); //设置会员权限话术内容 controller.setMemberContent(content); //设置不操做后,5秒自动隐藏头部和底部布局 controller.setHideTime(5000); //设置设置会员权限类型,第一个参数是否登陆,第二个参数是否有权限看,第三个参数试看完后展现的文字内容,第四个参数是否保存进度位置 controller.setMemberType(false,false,3,true); //设置背景图片 controller.imageView().setBackgroundResource(R.color.blackText); //ImageUtil.loadImgByPicasso(this, R.color.blackText, R.drawable.image_default, controller.imageView()); //设置试看结束后,登陆或者充值会员按钮的点击事件 controller.setOnMemberClickListener(new OnMemberClickListener() { @Override public void onClick(int type) { switch (type){ case ConstantKeys.Gender.LOGIN: //调到用户登陆也米娜 startActivity(MeLoginActivity.class); break; case ConstantKeys.Gender.MEMBER: //调到用户充值会员页面 startActivity(MeMemberActivity.class); break; default: break; } } }); //设置视频清晰度 //videoPlayer.setClarity(list,720); //设置视频控制器 videoPlayer.setController(controller);
@Override public void release() { // 保存播放位置 if (isPlaying() || isBufferingPlaying() || isBufferingPaused() || isPaused()) { VideoPlayerUtils.savePlayPosition(mContext, mUrl, getCurrentPosition()); } else if (isCompleted()) { //若是播放完成,则保存播放位置为0,也就是初始位置 VideoPlayerUtils.savePlayPosition(mContext, mUrl, 0); } // 退出全屏或小窗口 if (isFullScreen()) { exitFullScreen(); } if (isTinyWindow()) { exitTinyWindow(); } mCurrentMode = MODE_NORMAL; // 释放播放器 releasePlayer(); // 恢复控制器 if (mController != null) { mController.reset(); } // gc回收 Runtime.getRuntime().gc(); } //释放播放器,注意必定要判断对象是否为空,加强严谨性 @Override public void releasePlayer() { if (mAudioManager != null) { //放弃音频焦点。使之前的焦点全部者(若是有的话)接收焦点。 mAudioManager.abandonAudioFocus(null); //置空 mAudioManager = null; } if (mMediaPlayer != null) { //释放视频焦点 mMediaPlayer.release(); mMediaPlayer = null; } //从视图中移除TextureView mContainer.removeView(mTextureView); if (mSurface != null) { mSurface.release(); mSurface = null; } //若是SurfaceTexture不为null,则释放 if (mSurfaceTexture != null) { mSurfaceTexture.release(); mSurfaceTexture = null; } //设置状态 mCurrentState = STATE_IDLE; }
Picasso.with(this) .load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png") .into(jzVideo.thumbImageView);
void setOnPreparedListener(IMediaPlayer.OnPreparedListener var1); void setOnCompletionListener(IMediaPlayer.OnCompletionListener var1); void setOnBufferingUpdateListener(IMediaPlayer.OnBufferingUpdateListener var1); void setOnSeekCompleteListener(IMediaPlayer.OnSeekCompleteListener var1); void setOnVideoSizeChangedListener(IMediaPlayer.OnVideoSizeChangedListener var1); void setOnErrorListener(IMediaPlayer.OnErrorListener var1); void setOnInfoListener(IMediaPlayer.OnInfoListener var1); void setOnTimedTextListener(IMediaPlayer.OnTimedTextListener var1);
//设置全屏播放 videoPlayer.enterFullScreen(); //设置小屏幕播放 videoPlayer.enterTinyWindow(); //退出全屏 videoPlayer.exitFullScreen(); //退出小窗口播放 videoPlayer.exitTinyWindow(); //释放,内部的播放器被释放掉,同时若是在全屏、小窗口模式下都会退出 videoPlayer.release(); //释放播放器,注意必定要判断对象是否为空,加强严谨性 videoPlayer.releasePlayer();
public class VideoPlayerManager { private VideoPlayer mVideoPlayer; private static VideoPlayerManager sInstance; private VideoPlayerManager() {} //必定要使用单例模式,保证同一时刻只有一个视频在播放,其余的都是初始状态 public static synchronized VideoPlayerManager instance() { if (sInstance == null) { sInstance = new VideoPlayerManager(); } return sInstance; } public VideoPlayer getCurrentVideoPlayer() { return mVideoPlayer; } void setCurrentVideoPlayer(VideoPlayer videoPlayer) { if (mVideoPlayer != videoPlayer) { releaseVideoPlayer(); mVideoPlayer = videoPlayer; } } //当视频正在播放或者正在缓冲时,调用该方法暂停视频 public void suspendVideoPlayer() { if (mVideoPlayer != null && (mVideoPlayer.isPlaying() || mVideoPlayer.isBufferingPlaying())) { mVideoPlayer.pause(); } } //当视频暂停时或者缓冲暂停时,调用该方法从新开启视频播放 public void resumeVideoPlayer() { if (mVideoPlayer != null && (mVideoPlayer.isPaused() || mVideoPlayer.isBufferingPaused())) { mVideoPlayer.restart(); } } //释放,内部的播放器被释放掉,同时若是在全屏、小窗口模式下都会退出 public void releaseVideoPlayer() { if (mVideoPlayer != null) { mVideoPlayer.release(); mVideoPlayer = null; } } //处理返回键逻辑.若是是全屏,则退出全屏 若是是小窗口,则退出小窗口 public boolean onBackPressed() { if (mVideoPlayer != null) { if (mVideoPlayer.isFullScreen()) { return mVideoPlayer.exitFullScreen(); } else if (mVideoPlayer.isTinyWindow()) { return mVideoPlayer.exitTinyWindow(); } } return false; } }
//建立视频控制器 VideoPlayerController controller = new VideoPlayerController(this); //设置视频标题 controller.setTitle("高仿优酷视频播放页面"); //设置视频时长 //controller.setLength(98000); //设置视频加载缓冲时加载窗的类型,多种类型 controller.setLoadingType(2); ArrayList<String> content = new ArrayList<>(); content.add("试看结束,观看所有内容请开通会员1111。"); content.add("试看结束,观看所有内容请开通会员2222。"); content.add("试看结束,观看所有内容请开通会员3333。"); content.add("试看结束,观看所有内容请开通会员4444。"); //设置会员权限话术内容 controller.setMemberContent(content); //设置不操做后,5秒自动隐藏头部和底部布局 controller.setHideTime(5000); //设置设置会员权限类型,第一个参数是否登陆,第二个参数是否有权限看,第三个参数试看完后展现的文字内容,第四个参数是否保存进度位置 controller.setMemberType(false,false,3,true); //设置背景图片 controller.imageView().setBackgroundResource(R.color.blackText); //ImageUtil.loadImgByPicasso(this, R.color.blackText, R.drawable.image_default, controller.imageView()); //设置试看结束后,登陆或者充值会员按钮的点击事件 controller.setOnMemberClickListener(new OnMemberClickListener() { @Override public void onClick(int type) { switch (type){ case ConstantKeys.Gender.LOGIN: //调到用户登陆也米娜 startActivity(MeLoginActivity.class); break; case ConstantKeys.Gender.MEMBER: //调到用户充值会员页面 startActivity(MeMemberActivity.class); break; default: break; } } }); //设置视频清晰度 //videoPlayer.setClarity(list,720); //设置视频控制器 videoPlayer.setController(controller);
/** * 设置视频Url,以及headers * * @param url 视频地址,能够是本地,也能够是网络视频 * @param headers 请求header. */ void setUp(String url, Map<String, String> headers); /** * 开始播放 */ void start(); /** * 从指定的位置开始播放 * * @param position 播放位置 */ void start(long position); /** * 从新播放,播放器被暂停、播放错误、播放完成后,须要调用此方法从新播放 */ void restart(); /** * 暂停播放 */ void pause(); /** * seek到制定的位置继续播放 * * @param pos 播放位置 */ void seekTo(long pos); /** * 设置音量 * * @param volume 音量值 */ void setVolume(int volume); /** * 设置播放速度,目前只有IjkPlayer有效果,原生MediaPlayer暂不支持 * * @param speed 播放速度 */ void setSpeed(float speed); /** * 开始播放时,是否从上一次的位置继续播放 * * @param continueFromLastPosition true 接着上次的位置继续播放,false从头开始播放 */ void continueFromLastPosition(boolean continueFromLastPosition);
public class YCVideoPlayer extends VideoPlayer { public YCVideoPlayer(Context context) { super(context); } @Override public void setUp(String url, Map<String, String> headers) { super.setUp(url, headers); } @Override public void setController(AbsVideoPlayerController controller) { super.setController(controller); } @Override public void setPlayerType(int playerType) { super.setPlayerType(playerType); } @Override public void continueFromLastPosition(boolean continueFromLastPosition) { super.continueFromLastPosition(continueFromLastPosition); } @Override public void setSpeed(float speed) { super.setSpeed(speed); } @Override public void start() { super.start(); } @Override public void start(long position) { super.start(position); } @Override public void restart() { super.restart(); } @Override public void pause() { super.pause(); } @Override public void seekTo(long pos) { super.seekTo(pos); } @Override public void setVolume(int volume) { super.setVolume(volume); } @Override public boolean isIdle() { return super.isIdle(); } @Override public boolean isPreparing() { return super.isPreparing(); } @Override public boolean isPrepared() { return super.isPrepared(); } @Override public boolean isBufferingPlaying() { return super.isBufferingPlaying(); } @Override public boolean isBufferingPaused() { return super.isBufferingPaused(); } @Override public boolean isPlaying() { return super.isPlaying(); } @Override public boolean isPaused() { return super.isPaused(); } @Override public boolean isError() { return super.isError(); } }
初期最简单功能
9.1.1 支持最简单视频播放,暂停,缓冲,全屏播放等基础功能。
9.1.2 支持滑动改变音量,改变声音大小的功能
9.1.3 还有其余基本功能
9.2 V1.0.1 更新于2017年11月18日
最简单的封装
9.2.1 而且阅读相关视频案例,借鉴了相关思路和复用了部分代码
测试环节
9.3 v1.1.0 更新于2018年1月15日
添加部分功能
9.3.1 添加了设置视频播放权限的功能,用户能够自由设置权限,不过目前只是设置了用户是否登陆,和登陆用户是否有观看权限,由于公司需求是这样的,因此只有这两个。后期遇到其余需求再添加。逻辑已经在库中写好了,用户本身实现就能够呢。
9.3.2 关于权限确定有话术内容,那么用户能够经过调用接口直接设置展现在播放器试看结束后的内容。十分方便,这块参考了优酷和爱奇艺视频
9.3.3 添加了用户多久不操做视频界面后,自动隐藏底部和头部布局视图。若是不设置,默认时间为5秒
9.3.4 添加了多种视频加载时候的加载效果,目前有两种,一种是转圈效果,一种是帧动画效果。固然你能够本身添加动画加载效果
9.4 v1.1.1 更新于2018年1月18日
修改了部分bug
9.4.1 修改了视频横向播放时,点击手机物理返回键,画面展现状态栏问题
9.4.2 修改了在list页面(recyclerView)的视频,当上拉加载更多时,加载十几回会致使崩溃问题
9.4.3 精简了布局文件,方便修改定制和阅读
9.4.4 修改了在网络很差或者飞行模式下,用户播放视频,应该是播放错误而不是一直转圈加载问题
9.4.5 完善了代码的注释,如今几乎全部的方法都有相关注释,方便阅读和理解。去掉了无用的代码
添加了部分功能
https://github.com/CarGuo/GSYVideoPlayer https://github.com/danylovolokh/VideoPlayerManager https://github.com/HotBitmapGG/bilibili-android-client https://github.com/jjdxmashl/jjdxm_ijkplayer https://github.com/JasonChow1989/JieCaoVideoPlayer-develop 2年前 https://github.com/open-android/JieCaoVideoPlayer 1年前 https://github.com/lipangit/JiaoZiVideoPlayer 4个月前 https://github.com/xiaoyanger0825/NiceVieoPlayer https://github.com/curtis2/SuperVideoPlayer https://github.com/tcking/GiraffePlayer
https://segmentfault.com/a/1190000011959615 http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1213/2153.html http://blog.csdn.net/junwang19891012/article/details/8444743 https://www.jianshu.com/p/420f7b14d6f6 http://blog.csdn.net/candicelijx/article/details/39495271