目录介绍

  • 1.关于此视频封装库介绍
  • 1.1 能够满足那些业务需求
  • 1.2 对比同类型的库有哪些优势
  • 2.关于使用方法说明
  • 2.1 关于gradle引用说明
  • 2.2 添加布局
  • 2.3 最简单的视频播放器参数设定
  • 2.4 注意的问题
  • 2.5 关于开源库中的类说明
  • 3.关于播放类型说明
  • 3.1 普通视频播放
  • 3.2 list页面视频播放
  • 3.3 小窗口视频播放
  • 3.4 类似爱奇艺,优酷会员试看视频播放
  • 3.5 关于封装库中日志打印
  • 4.关于相关方法说明
  • 4.1 关于VideoPlayer类[播放器]中方法说明
  • 4.2 关于VideoPlayerController类[控制器]中方法说明
  • 4.3 关于对象的销毁
  • 5.关于封装的思路
  • 5.1 参考的案例思路
  • 5.2 封装的基本思路
  • 5.3 关于窗口切换分析
  • 5.4 关于VideoPlayerManager视频播放器管理器分析
  • 5.5 关于VideoPlayerController视频控制器分析
  • 5.6 关于InterVideoPlayer接口分析
  • 6.关于如何自定义你想要的视频播放模式
  • 6.1 自定义视频播放器
  • 7.关于效果图的展示
  • 7.1 效果图如下所示
  • 8.关于遇到的问题说明
  • 8.1 视频难点
  • 8.2 遇到的bug
  • 8.3 后期需要实现的功能
  • 9.关于版本更新说明
  • 9.1 V1.0.0 更新于2017年9月4日
  • 9.2 V1.0.1 更新于2017年11月18日
  • 9.3 v1.1.0 更新于2018年1月15日
  • 10.关于参考文档说明
  • 10.1 参考的项目
  • 10.2 参考的博客
  • 11.关其他说明
  • 11.1 目前市场流行的视频框架
  • 11.2 如何选择合适的框架
  • 11.3 关于我的个人博客和站点

0.备注

  • 仿照爱奇艺,优酷播放器写的,十分感谢GitHub上大神前辈们的开源案例和思路。
  • 支持插入广告,设置视频观看权限,观看完后登录或者购买会员。我看到在star较多的项目issues中,有些人正好需要这个案例,库集成后直接通过代码调用即可,灵活且拓展性强。
  • 由于调到做视频的部门,因此此部分代码会持续更新,也欢迎同行提bug或者问题
  • 如果你觉得还可以,给个star吧!我也在持续学习中!!!
  • 项目地址:https://github.com/yangchong211/YCVideoPlayer

1.关于此视频封装库介绍

1.1 能够满足那些业务需求

A基础功能

  • 1.1.1 能够自定义视频加载loading类型,设置视频标题,设置视频底部图片,设置播放时长等基础功能
  • 1.1.2 可以切换播放器的视频播放状态,播放错误,播放未开始,播放开始,播放准备中,正在播放,暂停播放,正在缓冲等等状态
  • 1.1.3 可以自由设置播放器的播放模式,比如,正常播放,全屏播放,和小屏幕播放。其中全屏播放支持旋转屏幕。
  • 1.1.4 可以支持多种视频播放类型,比如,原生封装视频播放器,还有基于ijkplayer封装的播放器。
  • 1.1.5 可以设置是否隐藏播放音量,播放进度,播放亮度等,可以通过拖动seekBar改变视频进度。还支持设置n秒后不操作则隐藏头部和顶部布局功能

-

B高级功能

  • 1.1.6 支持一遍播放一遍缓冲的功能,其中缓冲包括两部分,第一种是播放过程中缓冲,第二种是暂停过程中缓冲
  • 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待添加功能

  • D.1.1 可以支持屏幕截图功能,视频添加水印效果
  • D.1.2 支持弹幕功能
  • D.1.3 后期待定

1.2 对比同类型的库有哪些优势

1.2.1目前仅仅查了下GitHub上项目

  • 目前GitHub上比较流行的库
  • 至于官方库就不说了,jiecao的库是基于ijkplayer视频框架,目前封装库有许多,下面几个只是star比较多,其中jiecao库比较类似。
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 具有的优势

  • A.代码布局更加简洁,而且无多余代码
  • B.几乎没有多少淡黄色警告,关于注释,通过使用阿里编码插件检测后更加规范,我对代码有洁癖
  • C.视频播放器[负责播放],视频控制器[负责视频播放各种点击或者属性设置操作],控制器抽象类[定义属性抽象类,供子类实现],其他可以看代码。结构分层上比较清晰
  • D.几乎所有的方法或者重要的成员或者局部变量都有相关的注释,注释的内容非常详细
  • E.关于视频属性设置或者按钮点击事件,都可以通过设置相关方法灵活实现。
  • 首先这些库封装的思路和代码都不错,我也是借鉴他们的思路,在他们的思路上改进而封装的。
  • 相比来说代码结构更加清晰,举几个例子
  • 针对视频播放页面布局,由于视频播放状态众多,我封装这库不同状态布局有十几种,许多库的视图布局没注释,显示比较臃肿,如果修改或者定位,不熟悉或者好久不操作,都要花时间找。展示我的布局代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><!--https://github.com/yangchong211--><!--如果你觉得好,请给个star,让更多人使用,避免重复造轮子--><!--底图,主要是显示视频缩略图--><ImageViewandroid: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"/><!--右下角初始显示的总时长--><TextViewandroid: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"/><!--中间开始播放按钮--><ImageViewandroid: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"/><!--试看按钮--><ImageViewandroid: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>

2.关于使用方法说明

2.1 关于gradle引用说明

  • 2.1.1直接引用这段代码就可以
compile 'cn.yc:YCVideoPlayerLib:2.2' 

2.2 添加布局

  • 注意,在实际开发中,由于Android手机碎片化比较严重,分辨率太多了,建议灵活设置布局的宽高比为4:3或者16:9或者你认为合适的,可以用代码设置。
  • 如果宽高比变形,则会有黑边
<org.yczbj.ycvideoplayerlib.VideoPlayerandroid:id="@+id/video_player"android:layout_width="match_parent"android:layout_height="240dp"/>

2.3 最简单的视频播放器参数设定

  • 2.3.1 这个是最简单视频播放器的设置参数代码
    //设置播放类型// IjkPlayer or MediaPlayervideoPlayer1.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);
  • 2.3.2 关于模仿爱奇艺登录会员权限功能代码
    //设置视频加载缓冲时加载窗的类型,多种类型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() {@Overridepublic void onClick(int type) {switch (type){case ConstantKeys.Gender.LOGIN://调到用户登录也米娜startActivity(MeLoginActivity.class);break;case ConstantKeys.Gender.MEMBER://调到用户充值会员页面startActivity(MeMemberActivity.class);break;
                default:break;}}});
  • 2.3.3其他设置,让体验更好
  • 如果是在Activity中的话,建议设置下面这段代码
    @Overrideprotected void onStop() {super.onStop();VideoPlayerManager.instance().releaseVideoPlayer();}@Overridepublic void onBackPressed() {if (VideoPlayerManager.instance().onBackPressed()) return;super.onBackPressed();}
  • 如果是在Fragment中的话,建议设置下面这段代码
    //在宿主Activity中设置代码如下@Overrideprotected void onStop() {super.onStop();VideoPlayerManager.instance().releaseVideoPlayer();}@Overridepublic void onBackPressed() {if (VideoPlayerManager.instance().onBackPressed()) return;super.onBackPressed();}//--------------------------------------------------//在此Fragment中设置代码如下@Overridepublic void onStop() {super.onStop();VideoPlayerManager.instance().releaseVideoPlayer();}

2.4 注意的问题

  • 2.4.1如果是全屏播放,则需要在清单文件中设置当前activity的属性值
  • android:configChanges 保证了在全屏的时候横竖屏切换不会执行Activity的相关生命周期,打断视频的播放
  • android:screenOrientation 固定了屏幕的初始方向
  • 这两个变量控制全屏后和退出全屏的屏幕方向
    <activity android:name=".ui.test2.TestMyActivity"android:configChanges="orientation|keyboardHidden|screenSize"android:screenOrientation="portrait"/>

2.5 关于开源库中的类说明

  • image

3.关于播放类型说明

3.1 普通视频播放

  • 3.1.1 这一步操作可以直接看第二部分内容——关于使用方法说明

3.2 list页面视频播放

  • 3.2.1如何在list页面设置视频
  • 第一步:在activity或者fragment中
    recyclerView.setLayoutManager(new LinearLayoutManager(this));recyclerView.setHasFixedSize(true);VideoAdapter adapter = new VideoAdapter(this, DataUtil.getVideoListData());recyclerView.setAdapter(adapter);//注意:下面这个方法不能漏掉recyclerView.setRecyclerListener(new RecyclerView.RecyclerListener() {@Overridepublic void onViewRecycled(RecyclerView.ViewHolder holder) {VideoPlayer videoPlayer = ((VideoAdapter.VideoViewHolder) holder).mVideoPlayer;if (videoPlayer == VideoPlayerManager.instance().getCurrentVideoPlayer()) {VideoPlayerManager.instance().releaseVideoPlayer();}}});
  • 第二步:在RecyclerView的适配器Adapter中
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;}@Overridepublic 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;}@Overridepublic void onBindViewHolder(VideoViewHolder holder, int position) {Video video = mVideoList.get(position);holder.bindData(video);}@Overridepublic 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/16params.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);}}
}

3.3 小窗口视频播放

  • 3.3.1建议在设置小窗口先先判断视频播放器是否开始播放
    if (videoPlayer.isIdle()) {Toast.makeText(this, "要点击播放后才能进入小窗口", Toast.LENGTH_SHORT).show();} else {videoPlayer.enterTinyWindow();}

3.4 类似爱奇艺,优酷会员试看视频播放

  • 3.4.1 可以参考——2.3.2 关于模仿爱奇艺登录会员权限功能代码

3.5 关于封装库中日志打印

  • 3.5.1关于封装库中日志打印设置
  • 如果上线产品后不想打印日志,可以在初始化时设置,注意需要在初始化播放器之前设置
    //如果不想打印库中的日志,可以设置VideoLogUtil.isLog = false;
  • 3.5.3关于日志工具类代码
    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);}}}

4.关于相关方法说明

4.1 关于VideoPlayer类中方法说明

  • 4.1.1 关于一定需要这四步
    //设置播放类型// IjkPlayer or MediaPlayervideoPlayer1.setPlayerType(VideoPlayer.TYPE_NATIVE);//设置视频地址和请求头部videoPlayer1.setUp(videoUrl, null);//创建视频控制器VideoPlayerController controller = new VideoPlayerController(this);//设置视频控制器videoPlayer1.setController(controller);
  • 4.1.2 关于VideoPlayer中设置属性方法
    //设置播放类型// MediaPlayervideoPlayer.setPlayerType(VideoPlayer.TYPE_NATIVE);// IjkPlayervideoPlayer.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();
  • 4.1.3 关于VideoPlayer中获取属性方法
        //是否从上一次的位置继续播放,不必须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);
  • 4.1.4 关于VideoPlayer中设置播放状态方法
    //开始播放videoPlayer.start();//开始播放,从某位置播放videoPlayer.start(3000);//重新播放videoPlayer.restart();//暂停播放videoPlayer.pause();
  • 4.1.5 关于VideoPlayer中获取播放状态方法
    //判断是否开始播放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();

4.2 关于VideoPlayerController类[控制器]中方法说明

  • 4.2.1 关于控制器方法
    //创建视频控制器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() {@Overridepublic 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);

4.3 关于对象的销毁

  • 4.3.1在VideoPlayer中如何释放资源的呢?源代码如下所示
    @Overridepublic 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();}//释放播放器,注意一定要判断对象是否为空,增强严谨性@Overridepublic void releasePlayer() {if (mAudioManager != null) {//放弃音频焦点。使以前的焦点所有者(如果有的话)接收焦点。mAudioManager.abandonAudioFocus(null);//置空mAudioManager = null;}if (mMediaPlayer != null) {//释放视频焦点mMediaPlayer.release();mMediaPlayer = null;}//从视图中移除TextureViewmContainer.removeView(mTextureView);if (mSurface != null) {mSurface.release();mSurface = null;}//如果SurfaceTexture不为null,则释放if (mSurfaceTexture != null) {mSurfaceTexture.release();mSurfaceTexture = null;}//设置状态mCurrentState = STATE_IDLE;}

5.关于封装的思路

5.1 参考的案例思路

  • 5.1.1目前参考的案例有
  • 可以直接看下面的参考案例,有记录
  • 5.1.2针对jiaozi代码简单分析
  • JZVideoPlayer为继承自FrameLayout实现的一个组合自定义View来实现了视频播放器的View相关的内容。
  • JZVideoPlayerStandard则是继承自JZVideoPlayer实现了一些自身的功能。
  • JZMediaManager是用来对于MediaPlayer的管理,对于MediaPlayer的一些监听器方法的回调和TextrueView的相关回调处理。
  • JZVideoPlayerManager管理JZVideoPlayer
  • 和自定义相关的工作,最主要是先继承JCVideoPlayerStandard
  • JZMediaSystem主要是实现系统的播放引擎
  • 不得不说,大神封装代码的思路以及代码逻辑的确很强
  • 关于封装库其他感受
  • 第一:不过,感觉大神更新频率大高,而且没有找到每次更新的日志说明,不知道大神又解决了那些bug
  • 第二:黄色警告多,而且注释少,因为视频封装库不像一般库,有时候需求不同,可拓展性要求高。除了自己继承JCVideoPlayerStandard创建视频播放器,其他如果想改代码,还是有点复杂的。
  • 第三:关于使用虽然很简单,但是在JZVideoPlayerStandard这个方法中,布局的对象都是用public修饰,如果你要想自己甚至某个控件背景或者图标等等,则要这样应用。如果你不去看看源代码中布局名称,你根本就不知道这个对象对应的是什么东西。对于不同修饰符,要合适的,如果不合适,那么就会有淡黄色警告。我看了buttonKnife,retrofit,阿里vlayout等等,可以说黄色警告很少……
  Picasso.with(this).load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png").into(jzVideo.thumbImageView);

5.2 封装的基本思路

  • 5.2.1关于简单的思路分析
  • a1.可以把视频播放和设置视频属性控制器分离,对于VideoPlayer中,各种UI状态和操作反馈都封装到VideoPlayerController控制器里面。如果需要根据不同的项目需求来修改播放器的功能,就只重写VideoPlayerController就可以了。
  • a2.对于VideoPlayer这个类,可以先创建一个帧布局容器,然后在初始化的时候将视频播放器控制器放到里面,然后通过设置控制器来进行视频播放
  • a3.当调用了开始播放的方法后,就初始化播放器,包括原生的,还有IjkMediaPlayer
  • a4.而基于IjkMediaPlayer的视频播放,需要添加各种监听事件,通过阅读IMediaPlayer源码可以知道:可以在这些监听事件中添加各种对视频的操作逻辑,具体可以看代码。
    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);
  • a5.定义好了监听事件后,就创建了播放,重置播放,暂停等各种方法

5.3 关于窗口切换分析

  • 5.3.1 关于窗口切换调用的代码
    //设置全屏播放videoPlayer.enterFullScreen();//设置小屏幕播放videoPlayer.enterTinyWindow();//退出全屏videoPlayer.exitFullScreen();//退出小窗口播放videoPlayer.exitTinyWindow();//释放,内部的播放器被释放掉,同时如果在全屏、小窗口模式下都会退出videoPlayer.release();//释放播放器,注意一定要判断对象是否为空,增强严谨性videoPlayer.releasePlayer();

5.4 关于VideoPlayerManager视频播放器管理器分析

  • 5.4.1可以直接看源代码,我对每个方法都有详细的注释
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;}
}

5.5 关于VideoPlayerController视频控制器分析

  • 5.5.1VideoPlayerController的作用
  • 播放控制界面上,播放、暂停、播放进度、缓冲动画、全屏/小屏等触发都是直接调用播放器对应的操作的。
  • 5.5.2VideoPlayerController的方法如下所示
    //创建视频控制器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() {@Overridepublic 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);

5.6 关于InterVideoPlayer接口分析

  • 5.6.1关于此接口方法有
  • 跟jiaozi代码类似
    /*** 设置视频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);

6.关于如何自定义你想要的视频播放模式

6.1 自定义视频播放器

  • 6.1.1如何自定义自己的播放器
  • 第一步:首先继承VideoPlayer这个类
  • 第二步:然后重写部分你需要更改功能的方法,只需要选择你需要重写的方法即可。
  • 6.1.2代码展示如下所示
    public class YCVideoPlayer extends VideoPlayer {public YCVideoPlayer(Context context) {super(context);}@Overridepublic void setUp(String url, Map<String, String> headers) {super.setUp(url, headers);}@Overridepublic void setController(AbsVideoPlayerController controller) {super.setController(controller);}@Overridepublic void setPlayerType(int playerType) {super.setPlayerType(playerType);}@Overridepublic void continueFromLastPosition(boolean continueFromLastPosition) {super.continueFromLastPosition(continueFromLastPosition);}@Overridepublic void setSpeed(float speed) {super.setSpeed(speed);}@Overridepublic void start() {super.start();}@Overridepublic void start(long position) {super.start(position);}@Overridepublic void restart() {super.restart();}@Overridepublic void pause() {super.pause();}@Overridepublic void seekTo(long pos) {super.seekTo(pos);}@Overridepublic void setVolume(int volume) {super.setVolume(volume);}@Overridepublic boolean isIdle() {return super.isIdle();}@Overridepublic boolean isPreparing() {return super.isPreparing();}@Overridepublic boolean isPrepared() {return super.isPrepared();}@Overridepublic boolean isBufferingPlaying() {return super.isBufferingPlaying();}@Overridepublic boolean isBufferingPaused() {return super.isBufferingPaused();}@Overridepublic boolean isPlaying() {return super.isPlaying();}@Overridepublic boolean isPaused() {return super.isPaused();}@Overridepublic boolean isError() {return super.isError();}}

7.关于效果图的展示

7.1 效果图如下所示

image
image
image
image
image
image
image
image
image
image
image

8.关于遇到的问题说明

8.1 视频难点

  • 8.1.1 当视频切换全屏或者从全屏切换到正常小屏幕时,如何管理activity的生命周期
  • 8.1.2 在列表list页面,滑动显示小窗口,那么什么时候显示小窗口呢?关于RecyclerView的滑动位移超出屏幕有没有更好的解决办法?
  • 8.1.2 当屏幕从全屏退出时,播放位置要滑到记录的位置,代码逻辑复杂,如何避免耦合度太高

8.2 遇到的bug

  • 8.2.1 当视频切花时,如何避免视频不卡顿
  • 8.2.2 在fragment中,当左右滑动出另一个fragment中,视频还在播放,怎么样处理这部分逻辑
  • 8.2.3 在显示缓冲比时,网络不好或者暂停缓冲时有问题,所以暂停还没有添加该功能
  • 8.2.4 播放进度条seekbar跳动问题,有人反映不是那么顺畅
  • 8.2.5 部分华为手机播放视频有问题,在找原因
  • 8.2.6 在拖动时显示当前帧的画面图片,类似优酷那个功能,最终还是没有实现

8.3 后期需要实现的功能

  • 8.3.1 如果有多集视频,则添加上一集和下一集的功能
  • 8.3.2 拖动滑动条,显示帧画面
  • 8.3.3 实现弹幕功能
  • 8.4.4 有些手机播放有问题,测试找问题
  • 8.5.5 切换视频清晰度有问题,是重新开始播放,因为切换清晰度时,调用的视频链接是不同的。比如高清视频和标准视频链接是不同的,所以难以实现切换后记录位置播放。但是看了下优酷,爱奇艺视频,切换后是接着之前观看的位置播放,这个需要思考下怎么实现。欢迎同行给出好的建议。
  • 8.5.6 待定

9.关于版本更新说明

  • 9.1 V1.0.0 更新于2017年10月4日
  • 9.2 V1.0.1 更新于2017年11月18日
  • 9.3 v1.1.0 更新于2018年1月15日

10.关于参考文档说明

10.1 参考的项目

  • 10.1.1参考的开源项目有
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

10.2 参考的博客

  • 10.2.1参考的博客有'
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

11.关其他说明

11.1 目前市场流行的视频框架

  • 1.Android原生VideoView
  • 2.Google 开源视频播放框架 ExoPlayer
  • 3.Vitamio 视频播放框架
  • 4.Bilibili 开源视频播放框架ijkplayer

11.2 如何选择

  • 11.2.1.Android原生VideoView
  • 1.1 VideoView 的使用非常简单,播放视频的步骤:

    • 在界面布局文件中定义 VideoView 组件,或在程序中创建 VideoView 组件
    • 调用 VideoView 的如下两个方法来加载指定的视频:

      • setVidePath(String path):加载 path 文件代表的视频
      • setVideoURI(Uri uri):加载 uri 所对应的视频
    • 调用 VideoView 的 start()、stop()、psuse() 方法来控制视频的播放
  • 11.2.2.Google 开源视频播放框架 ExoPlayer
  • 2.1 框架地址:https://github.com/google/ExoPlayer
  • 2.2 用法

    • ExoPlayer 开源项目包含了 library 和 示例:

      • ExoPlayer library – 这部分是核心的库
      • Demo app – 这部分是演示怎么使用 ExoPlayer 的 Demo
    • ExoPlayer 库的核心类是 ExoPlayer 类。该类维护了播放器的全局状态 。比如如何获取媒体数据,如何缓冲以及是怎样的编码格式。
    • ExoPlayer 基于 MediaCodec 和 AudioTrack 提供了默认的音视频的 TrackRenderer 实现。所有的 renderers 都需要 SampleSource 对象,ExoPlayer 从 SampleSource 获得 media samples 用于播放。下图展示了 ExoPlayer 是如何配置组合这些组件用于播放音视频的。
    • standard-model
    • ExoPlayer 库提供了一些不同类型的 SampleSource 实例:
    • ExtractorSampleSource – 用于 MP3,M4A,WebM,MPEG-TS 和 AAC;

      • ChunkSampleSource – 用于 DASH 和平滑流的播放;
      • HlsSampleSource – 用于 HLS 播放;
    • 在 ExoPlayer 的 Dome 中使用 DemoPlayer 对 ExoPlayer 进行了封装,并提供了使用上述几种 SampleSource 构建 TrackRenderer 的 Builder。

      • SmoothStreamingRendererBuilder
      • DashRendererBuilder
      • ExtractorRendererBuilder
    • 在使用的时候我们根据不同的需求创建对应的 RendererBuilder,然后将 RendererBuilder 传递给 DemoPlayer 然后调用 DemoPlayer 的 setPlayWhenReady 方法。
  • 2.3 优缺点
  • ExoPlayer 相较于 MediaPlayer 有很多很多的优点:

    • 支持动态的自适应流 HTTP (DASH) 和 平滑流,任何目前 MediaPlayer 支持的视频格式(同时它还支持 HTTP 直播(HLS),MP4,MP3,WebM,M4A,MPEG-TS 和 AAC)。
    • 支持高级的 HLS 特性,例如正确处理 EXT-X-DISCONTINUITY 标签;
    • 支持自定义和扩治你的使用场景。ExoPlayer 专门为此设计;
    • 便于随着 App 的升级而升级。因为 ExoPlayer 是一个包含在你的应用中的库,对于你使用哪个版本有完全的控制权,并且你可以简单的跟随应用的升级而升级;
    • 更少的适配性问题。
  • ExoPlayer 的缺点:

    • ExoPlayer 的音频和视频组件依赖 Android 的 MediaCodec 接口,该接口发布于 Android4.1(API 等级 16)。因此它不能工作于之前的Android 版本。
  • 11.2.3.Vitamio 视频播放框架
  • 3.1 用法
  • 官网:https://www.vitamio.org
  • Vitamio 的使用步骤:

    • 1.下载 Vitamio 库,并作为工程依赖。
    • 2.在 Activity 的 onCreate 方法中添加如下代码,初始化 Vitamio 的解码器
  • 3.2 优点

    • 强大,支持超多格式视频和网络视频播放。
    • 使用简单。调用非常简单,方便使用。
    • 其官方还给出了其他很多优点,但是个人觉得不足以成为优点。
  • 11.2.4.Bilibili 开源视频播放框架ijkplayer
  • 4.1 特点

    • HTTPS支持
    • 支持弹幕
    • 支持基本的拖动,声音、亮度调节
    • 支持边播边缓存
    • 支持视频本身自带rotation的旋转(90,270之类),重力旋转与手动旋转的同步支持
    • 支持列表播放,直接添加控件为封面,列表全屏动画,视频加载速度,列表小窗口支持拖动
    • 5.0的过场效果,调整比例,多分辨率切换
    • 支持切换播放器,进度条小窗口预览
    • 其他一些小动画效果,rtsp、concat、mpeg
  • 4.2 优缺点

    • ijkplayer 最大的优点就是可以根据需要编译需要的解码器。在编译的时候通过 ln -s module-default.sh module.sh 选择要编译的解码器。ijkplayer 在 config 目录下提供了三种 module.sh 。也可自己修改 module.sh 。
    • ijkplayer 的缺点是库太大。加入项目后会大大增加你的 APP 的大小。

11.3 关于我的个人博客和站点

  • github: https://github.com/yangchong211
  • 知乎: https://www.zhihu.com/people/yang-chong-69-24/pins/posts
  • 简书: http://www.jianshu.com/u/b7b2c6ed9284
  • csdn: http://my.csdn.net/m0_37700275
  • 喜马拉雅听书: http://www.ximalaya.com/zhubo/71989305/
  • 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
  • 邮箱:yangchong211@163.com
  • 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100239.headeruserinfo.3.dT4bcV

阅读原文http://click.aliyun.com/m/40402/

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. layui 文件上传进度条

    使用HisiPhPK框架做一个是视频上传的后台 ,再需要视频上传的页面,我感觉肯定要做视频上传的进度条啊,于是就开始研究这个后台,这个后台是使用的框架是layui,现成的组件肯定是用着最爽的,百度求真知、互相借鉴学习下面是几个学习的方法链接,学习的方法,不太详细的社区原创…...

    2024/4/14 16:25:18
  2. java初学者(零基础如何入门),我适不适合学习JAVA?

    推荐一个Java《学习》+交流群: 523401738每天晚上在腾讯课堂都有一个Java技术学习课,会有老师分享干货,帮助大家分析解答问题对于初入Java的学生们来说,都会有一个疑惑?我适合学习编程吗? 编程入门遇到难题的时候想到过放弃,当你写完一个程序的时候感到内心的欣慰,这都取…...

    2024/5/5 23:42:15
  3. Monte Carlo method

    最近在用simset仿真r ray的particle detection,涉及到monte carlo方法,在以前做NMF接触过一些.其实就是跑大量数据然后看其统计特性 比方说画一个方形,然后里面紧贴画个圆 不断往这个图案上随机丢针 丢个几十万 然后可以数插在圆内和圆外的针数 这样就可以计算出pi来了,呵呵 这…...

    2024/5/6 0:46:19
  4. Velocity基本语法

    一、基本语法1、"#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等;如:#if($info.imgs)<img src="$info.imgs" border=0>#else<img src="noPhoto.jpg">#end2、"$&qu…...

    2024/4/12 8:53:16
  5. 图形界面的进度条

    import java.awt.*;//引入相应库类 import javax.swing.*;public class L10_1 extends JWindow {//进度条组件,因为在线程类L10_01要引用它,所以需要定义为类成员变量JProgressBar bar = new JProgressBar(1, 100);//构造函数public L10_1() {//背景图片,注意图片的位置JLab…...

    2024/5/5 19:19:08
  6. 天猫提示您使用的浏览器版本过低的完美解决办法

    有的朋友在使用电脑访问淘宝天猫时会看到提示说“您使用的浏览器版本过低”,那么,这是什么意思呢?当我们看到这个提示时应该怎么办呢?有的朋友看到的提示是这样的:有的朋友看到的提示是这样的:有的朋友看到的提示是这样的:出现这些提示是因为你使用了旧版IE,旧版IE已经…...

    2024/4/18 21:32:08
  7. java学习交流群

    java学习交流群 本人创建一个java学习交流的群,目的是给各位学习java的同胞们一个聚集地,不管是新手老手都可以来一起学习.群号:972573544 本群是一个纯交流学习,工作的群 发招聘信息的,培训机构,在群里发直播课,卖书的卖视频的,请绕路,发现立即飞机...

    2024/4/12 8:52:58
  8. Hamiltonian Monte Carlo算法理解

    因为RBN,学习了一会儿MCMC,理解不太深,但在接触Bayesian GAN时碰到HMC又很晕,好在看了两篇博客,重新梳理了MCMC,对HMC有了点初步理解,整理如下。 两篇博客一篇是CSDN,一篇是WordPress上的。CSDN应该是翻译WordPress上的。theclevermachine博客 https://theclevermachin…...

    2024/4/12 14:31:56
  9. Velocity语法-收集整理

    Velocity语法-收集整理VTL-Velocity Template Language: VTL意味着提供最简单、最容易并且最整洁的方式合并页面动态内容。 VTL使用references来在web site内嵌套动态内容,一个变量就是一种类型的reference。变量是某种类型的refreence,它可以指向java代码中的定义,或者从当…...

    2024/4/12 8:53:10
  10. egret连接java websocket

    这是一号返回的 其中ziji是当前窗口1 to是发送对象2这是二号返回的下面是egret代码 将信息用json发送给服务器private textfield: egret.TextField;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////…...

    2024/4/16 21:10:33
  11. 模拟新浪微博登陆(直接调用cookie方法)

    之前写过一篇模拟登录新浪微博,是采用POST用户名/密码等参数(经过加密)并保存Cookie来模拟登录的方法。一般情况下,为了保证安全性,网站会定期更新登录的detail,例如修改参数名、更新加密(散列)算法等。所以模拟登录的代码定期肯定会失效,但是如果网站没有进行大的更新…...

    2024/4/9 18:26:04
  12. 我的Java学习之路

      将近两个月的时间没有更新过博客了,这个东西还是不能断,以后要坚持按时更新。这段时间主要在学习Java编程方面的知识,之前自己主要是通过C++来做图像,技多不压身,学习了一个月,再次写一篇博客来总结这段时间的学习过程,作为一个Java的入门级菜鸟选手,这算是一篇…...

    2024/4/28 1:48:10
  13. 倒计时进度条动态效果

    效果图HTML <div class="progress-bar-box"><div class="wrap"><div class="box"><div class="text">0%</div></div></div><div class="hint">倒计时:00:00:00</div&g…...

    2024/4/12 8:52:52
  14. 马尔科夫链蒙特卡洛(Markov chain Monte Carlo)

    (学习这部分内容大约需要1.3小时) 摘要 马尔科夫链蒙特卡洛(Markov chain Monte Carlo, MCMC) 是一类近似采样算法. 它通过一条拥有稳态分布 \(p\) 的马尔科夫链对目标分布 \(p\) 进行采样. 预备知识 学习MCMC需要以下预备知识 条件分布: MCMC常常被用于从条件分布中采样. 蒙特…...

    2024/4/13 15:49:26
  15. 安卓投屏软件 免root按键脚本,安卓免费群控系统

    铁鹰安卓群控系统是陈汤网络科技有限公司历史半年研发的安卓群控软件,模竖屏自动切换,集成了js语法,用js就可以控制手机按键,完全免root, js脚本无脑开发,并且如果有界面的话还可以用html做界面,js 与 html是最简单的了,支持脚本录制,并且有强大的找图找s功能,全程无脑,批量管理…...

    2024/4/26 0:33:32
  16. 使用Apache Velocity生成HTML报表

    pom.xml中加入jar依赖<dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version></dependency>velocity语法规则见:https://github.com/putaoshu/jdf/blob/m…...

    2024/4/9 18:25:59
  17. C# 推箱子游戏&对战游戏

    推箱子游戏提纲,只有向右向上的操作,向左向下同理,后期需完善。1 namespace 推箱子2 {3 class Program4 {5 static void Main(string[] args)6 {7 //小人初始位置的索引8 int x = 1;9 int y = 8;10 11 …...

    2024/4/20 6:40:44
  18. 如何用java实现简单的区块链

    本文目的是通过java实战开发教程理解区块链是什么。将通过实战入门学习,用Java自学开发一个很基本的区块链,并在此基础上能扩展如web框架应用等。这个基本的java区块链也实现简单的工作量证明系统。本文用一个java例子,演示了开发一个区块链应用的过程,涉及到所有区块链的概念…...

    2024/4/19 1:38:17
  19. 利用AJAX技术实现网页无刷新进度条显示

    在网页中实现页面无刷新的进度条显示不是一件很麻烦的事情,但如果这个进度条要能准确反映当前事务或者复杂逻辑的执行进度,那么却并不是一件容易的事情,目前Ajax技术流行,所以本文作者试想通过AJAX来实现网页准确进度条,以銄读者。 首先应该想一个问题,复杂事务或者事务逻…...

    2024/5/5 13:24:07
  20. 百度贴吧一键自动顶贴软件!学习自己开发吧

    大家好!我们今天给大家带来一款教程,通过易语言制作一个贴吧顶帖工具!所需要的工具: 1、 精易WEB浏览器 2、 易语言 然后为了节省大家的时间,软件的基本界面我们已经弄好了。我们需要做的就是设置账号COOKIE,然后实现自动登录账号,然后通过浏览器的调表模块进行自…...

    2024/4/12 8:54:04

最新文章

  1. 【银角大王——Django课程——靓号搜索实现/单独一篇】

    搜索框功能实现 靓号搜索在Django框架中搜索功能实现——底层就是模糊查询添加一个搜索框&#xff0c;使用bootstrap框架将GO&#xff01;修改成一个放大镜靓号列表函数代码解释效果演示 靓号搜索 在Django框架中搜索功能实现——底层就是模糊查询 数字条件用法字符串条件用法…...

    2024/5/6 1:26:06
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 使用pytorch构建有监督的条件GAN(conditional GAN)网络模型

    本文为此系列的第四篇conditional GAN&#xff0c;上一篇为WGAN-GP。文中在无监督的基础上重点讲解作为有监督对比无监督的差异&#xff0c;若有不懂的无监督知识点可以看本系列第一篇。 原理 有条件与无条件 如图投进硬币随机得到一个乒乓球的例子可以看成是一个无监督的GAN&…...

    2024/4/30 2:16:10
  4. 深入理解springboot

    第五章 访问数据库 1.配置数据源 在applicaiton.properties中 spring.datasource.urljdbc:mysql://localhost:3306/chapter5 第九章 springmvc 1.总体流程 http请求发送给控制器&#xff0c;控制器与业务层交互&#xff0c;业务层使用noSQL缓存&#xff0c;业务层与数据访问层…...

    2024/5/5 15:07:17
  5. rust 自定义安装 error: linker `link.exe` not found

    解决方案 On VS 2022, I tested both solutions. 4.39 GB “MSVC v143 - VS 2022 C x64/x86 build tools” and “Windows 10 SDK” 2.86 GB “Desktop development with C” Its better to just select “Desktop Development with C”. Heres the download for VS 202…...

    2024/5/4 9:00:24
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/4 23:55:17
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/4 18:20:48
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57