Browse Source

加上缓冲时显示网速

yangchong211 6 years ago
parent
commit
4223afe06d

+ 29 - 0
.idea/codeStyles/Project.xml

@@ -0,0 +1,29 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <Objective-C-extensions>
+      <file>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
+      </file>
+      <class>
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
+        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
+      </class>
+      <extensions>
+        <pair source="cpp" header="h" fileNamingConvention="NONE" />
+        <pair source="c" header="h" fileNamingConvention="NONE" />
+      </extensions>
+    </Objective-C-extensions>
+  </code_scheme>
+</component>

+ 0 - 37
.idea/inspectionProfiles/Project_Default.xml

@@ -1,37 +0,0 @@
-<component name="InspectionProjectProfileManager">
-  <profile version="1.0">
-    <option name="myName" value="Project Default" />
-    <inspection_tool class="AlibabaAvoidManuallyCreateThread" enabled="false" level="CRITICAL" enabled_by_default="false" />
-    <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
-      <option name="TOP_LEVEL_CLASS_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="" />
-        </value>
-      </option>
-      <option name="INNER_CLASS_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="" />
-        </value>
-      </option>
-      <option name="METHOD_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
-        </value>
-      </option>
-      <option name="FIELD_OPTIONS">
-        <value>
-          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
-          <option name="REQUIRED_TAGS" value="" />
-        </value>
-      </option>
-      <option name="IGNORE_DEPRECATED" value="false" />
-      <option name="IGNORE_JAVADOC_PERIOD" value="true" />
-      <option name="IGNORE_DUPLICATED_THROWS" value="false" />
-      <option name="IGNORE_POINT_TO_ITSELF" value="false" />
-      <option name="myAdditionalJavadocTags" value="date" />
-    </inspection_tool>
-  </profile>
-</component>

+ 10 - 21
.idea/misc.xml

@@ -5,45 +5,34 @@
     <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
     <option name="myNullables">
       <value>
-        <list size="4">
+        <list size="7">
           <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
           <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
-          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
-          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+          <item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
+          <item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
+          <item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
         </list>
       </value>
     </option>
     <option name="myNotNulls">
       <value>
-        <list size="4">
+        <list size="6">
           <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
           <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
           <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
           <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+          <item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
         </list>
       </value>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">
     <option name="id" value="Android" />
   </component>
-  <component name="masterDetails">
-    <states>
-      <state key="ProjectJDKs.UI">
-        <settings>
-          <last-edited>1.8</last-edited>
-          <splitter-proportions>
-            <option name="proportions">
-              <list>
-                <option value="0.2" />
-              </list>
-            </option>
-          </splitter-proportions>
-        </settings>
-      </state>
-    </states>
-  </component>
 </project>

+ 1 - 1
.idea/vcs.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="VcsDirectoryMappings">
-    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+    <mapping directory="" vcs="Git" />
   </component>
 </project>

+ 34 - 5
README.md

@@ -21,15 +21,17 @@
     - 6.0.8 v2.4.9 更新于2018年8月16日
     - 6.0.9 v2.5.0 更新与2018年8月20日
     - 6.1.0 v2.6.0 更新于2018年9月25日
+    - 6.1.1 v2.7.0 更新与2019年2月14日
 - 7.性能优化和库大小
 - 8.其他说明
-- [老版本详细ReadMe,原文档](https://github.com/yangchong211/YCVideoPlayer/blob/master/read/README.md)
+
 
 
 
 
 
 ### 1.视频具有的功能
+- [老版本详细ReadMe,原文档](https://github.com/yangchong211/YCVideoPlayer/blob/master/read/README.md)
 ##### A基础功能
 - A.1.1 能够自定义视频加载loading类型,设置视频标题,设置视频底部图片,设置播放时长等基础功能
 - A.1.2 可以切换播放器的视频播放状态,播放错误,播放未开始,播放开始,播放准备中,正在播放,暂停播放,正在缓冲等等状态
@@ -47,6 +49,7 @@
 - B.1.6 切换横竖屏:切换全屏时,隐藏状态栏,显示自定义top(显示电量);竖屏时恢复原有状态
 - B.1.7 支持切换视频清晰度模式
 - B.1.8 添加锁屏功能,竖屏不提供锁屏按钮,横屏全屏时显示,并且锁屏时,屏蔽手势处理
+- B.1.9 当在播放视频页面,由前台切换到后台时,如果视频正在播放或者正在缓冲时,则暂停视频;当从后台切换到前台时,如果视频暂停时或者缓冲暂停,则重新开启视频播放;当退出页面时则销毁视频资源。
 ##### C拓展功能【这块根据实际情况选择是否需要使用,一般视频付费App会有这个工鞥】
 - **C1产品需求:类似优酷,爱奇艺视频播放器部分逻辑。比如如果用户没有登录也没有看视频权限,则提示试看视频[自定义布局];如果用户没有登录但是有看视频权限,则正常观看;如果用户登录,但是没有充值会员,部分需要权限视频则进入试看模式,试看结束后弹出充值会员界面;如果用户余额不足,比如余额只有99元,但是视频观看要199元,则又有其他提示。**
 - C2自身需求:比如封装好了视频播放库,那么点击视频上登录按钮则跳到登录页面;点击充值会员页面也跳到充值页面。这个通过定义接口,可以让使用者通过方法调用,灵活处理点击事件。
@@ -55,7 +58,8 @@
 - C.1.3 可以设置播放有权限的视频时的各种文字描述,而没有把它写在封装库中,使用者自己设定
 - C.1.4 锁定屏幕功能
 - C.1.5 支持视频小窗口拖拽功能,可以在应用内随意拖拽,单击点击是播放和暂停切换;长按是拖动处理
-
+- C.1.8 支持监听网络状态变化,当从wifi切换到4g,则提示用户视频移动流量提醒通知
+- C.1.9 添加缓存时,显示网络加载速度,待实现功能
 
 
 ### 2.使用方法介绍
@@ -98,14 +102,35 @@ videoPlayer.setController(controller);
     @Override
     protected void onStop() {
         super.onStop();
+        //从前台切到后台,当视频正在播放或者正在缓冲时,调用该方法暂停视频
+        VideoPlayerManager.instance().suspendVideoPlayer();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        //销毁页面,释放,内部的播放器被释放掉,同时如果在全屏、小窗口模式下都会退出
         VideoPlayerManager.instance().releaseVideoPlayer();
     }
-    
+
     @Override
     public void onBackPressed() {
-        if (VideoPlayerManager.instance().onBackPressed()) return;
+        //处理返回键逻辑;如果是全屏,则退出全屏;如果是小窗口,则退出小窗口
+        if (VideoPlayerManager.instance().onBackPressed()){
+            return;
+        }else {
+            //销毁页面
+            VideoPlayerManager.instance().releaseVideoPlayer();
+        }
         super.onBackPressed();
     }
+
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        //从后台切换到前台,当视频暂停时或者缓冲暂停时,调用该方法重新开启视频播放
+        VideoPlayerManager.instance().resumeVideoPlayer();
+    }
     ```
 - **如果是在Fragment中的话,建议设置下面这段代码**
     ```
@@ -229,7 +254,11 @@ videoPlayer.setController(controller);
 ##### 6.1.0 v2.6.0 更新于2018年9月25日
 - 6.1.0.1 优化了视频全屏播放时锁屏的功能
 - 6.1.0.2 添加了视频在应用内小窗口拖动的功能
-
+##### 6.1.1 v2.7.0 更新与2019年2月14日
+- 6.1.1.1 添加了注解限定符,其中包括资源类型注释,类型定义注释,值范围注释,@Nullable和@NonNull等等,增强代码的强壮性
+- 6.1.1.2 当视频播放完成或者意外销毁,都需要解绑注册网络监听广播
+- 6.1.1.3 当在播放视频页面,由前台切换到后台时,如果视频正在播放或者正在缓冲时,则暂停视频;当从后台切换到前台时,如果视频暂停时或者缓冲暂停,则重新开启视频播放
+- 6.1.1.4 添加了缓冲视频和播放准备中加载视频的时候,显示网络速度的逻辑
 
 
 ### 7.性能优化和库大小

+ 1 - 2
YCVideoPlayerLib/build.gradle

@@ -10,7 +10,6 @@ android {
         targetSdkVersion 27
         versionCode 1
         versionName "1.0"
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
 
     buildTypes {
@@ -24,7 +23,7 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:27.1.0'
+    compile 'com.android.support:appcompat-v7:27.1.1'
     //这两个是必须要加的,其它的可供选择
     compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
     compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'

+ 1 - 1
YCVideoPlayerLib/src/main/java/org/yczbj/ycvideoplayerlib/constant/ConstantKeys.java

@@ -62,7 +62,7 @@ public final class ConstantKeys {
      * 3                正在播放
      * 4                暂停播放
      * 5                正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)
-     * 6                正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,此时暂停播放器,继续缓冲,缓冲区数据足够后恢复暂停
+     * 6                暂停缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,此时暂停播放器,继续缓冲,缓冲区数据足够后恢复暂停
      * 7                播放完成
      */
     public @interface CurrentState{

+ 54 - 5
YCVideoPlayerLib/src/main/java/org/yczbj/ycvideoplayerlib/controller/AbsVideoPlayerController.java

@@ -2,15 +2,11 @@ package org.yczbj.ycvideoplayerlib.controller;
 
 import android.content.Context;
 import android.support.annotation.DrawableRes;
-import android.support.annotation.LayoutRes;
-import android.util.DisplayMetrics;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
-
-import org.yczbj.ycvideoplayerlib.utils.VideoLogUtil;
 import org.yczbj.ycvideoplayerlib.utils.VideoPlayerUtils;
 import org.yczbj.ycvideoplayerlib.constant.ConstantKeys;
 import org.yczbj.ycvideoplayerlib.inter.InterVideoPlayer;
@@ -33,6 +29,8 @@ public abstract class AbsVideoPlayerController extends FrameLayout implements Vi
     protected InterVideoPlayer mVideoPlayer;
     private Timer mUpdateProgressTimer;
     private TimerTask mUpdateProgressTimerTask;
+    private Timer mUpdateNetSpeedTimer;
+    private TimerTask mUpdateNetSpeedTask;
     private float mDownX;
     private float mDownY;
     /**
@@ -64,7 +62,6 @@ public abstract class AbsVideoPlayerController extends FrameLayout implements Vi
         mVideoPlayer = videoPlayer;
     }
 
-
     /**
      * 获取是否是锁屏模式
      * @return                      true表示锁屏
@@ -84,6 +81,13 @@ public abstract class AbsVideoPlayerController extends FrameLayout implements Vi
      */
     public abstract void setTopVisibility(boolean isVisibility);
 
+    /**
+     * 设置横屏播放时,tv和audio图标是否显示
+     * @param isVisibility1                 tv图标是否显示
+     * @param isVisibility2                 audio图标是否显示
+     */
+    public abstract void setTvAndAudioVisibility(boolean isVisibility1 , boolean isVisibility2);
+
     /**
      * 设置不操作后,多久自动隐藏头部和底部布局
      * @param time                  时间
@@ -150,6 +154,47 @@ public abstract class AbsVideoPlayerController extends FrameLayout implements Vi
      */
     public abstract void reset();
 
+    /**
+     * 开启缓冲时更新网络加载速度
+     */
+    protected void startUpdateNetSpeedTimer() {
+        cancelUpdateNetSpeedTimer();
+        if (mUpdateNetSpeedTimer == null) {
+            mUpdateNetSpeedTimer = new Timer();
+        }
+        if (mUpdateNetSpeedTask == null) {
+            mUpdateNetSpeedTask = new TimerTask() {
+                @Override
+                public void run() {
+                    //在子线程中更新进度,包括更新网络加载速度
+                    AbsVideoPlayerController.this.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            updateNetSpeedProgress();
+                        }
+                    });
+                }
+            };
+        }
+        mUpdateNetSpeedTimer.schedule(mUpdateNetSpeedTask, 0, 100);
+    }
+
+
+    /**
+     * 取消缓冲时更新网络加载速度
+     */
+    protected void cancelUpdateNetSpeedTimer() {
+        if (mUpdateNetSpeedTimer != null) {
+            mUpdateNetSpeedTimer.cancel();
+            mUpdateNetSpeedTimer = null;
+        }
+        if (mUpdateNetSpeedTask != null) {
+            mUpdateNetSpeedTask.cancel();
+            mUpdateNetSpeedTask = null;
+        }
+    }
+
+
     /**
      * 开启更新进度的计时器。
      */
@@ -190,6 +235,10 @@ public abstract class AbsVideoPlayerController extends FrameLayout implements Vi
         }
     }
 
+    /**
+     * 更新进度,包括更新网络加载速度
+     */
+    protected abstract void updateNetSpeedProgress();
 
     /**
      * 更新进度,包括进度条进度,展示的当前播放位置时长,总时长等。

+ 86 - 23
YCVideoPlayerLib/src/main/java/org/yczbj/ycvideoplayerlib/controller/VideoPlayerController.java

@@ -1,5 +1,6 @@
 package org.yczbj.ycvideoplayerlib.controller;
 
+import android.annotation.SuppressLint;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -9,6 +10,8 @@ import android.net.NetworkInfo;
 import android.os.BatteryManager;
 import android.os.CountDownTimer;
 import android.support.annotation.DrawableRes;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -131,7 +134,16 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
      * 默认为false,不显示
      */
     private boolean mIsCenterPlayerVisibility = false;
-
+    /**
+     * 设置横屏播放时,tv图标是否显示
+     * 默认为false,不显示
+     */
+    private boolean mIsTvIconVisibility = false;
+    /**
+     * 设置横屏播放时,audio图标是否显示
+     * 默认为false,不显示
+     */
+    private boolean mIsAudioIconVisibility = false;
     /**
      * 网络变化监听广播,在网络变更时进行对应处理
      */
@@ -224,6 +236,10 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         }
     }
 
+
+    /**
+     * 当播放完成或者意外销毁,都需要解绑注册网络监听广播
+     */
     private void unRegisterNetChangedReceiver() {
         if (hasRegisterNetReceiver) {
             if (netChangedReceiver != null) {
@@ -340,23 +356,6 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         this.setOnClickListener(this);
     }
 
-    /**
-     * 设置视频播放器中间的播放键是否显示,设置自定义图片
-     * @param isVisibility          是否可见
-     * @param image                 image
-     */
-    @Override
-    public void setCenterPlayer(boolean isVisibility, @DrawableRes int image) {
-        this.mIsCenterPlayerVisibility = isVisibility;
-        if(isVisibility){
-            if(image==0){
-                mCenterStart.setImageResource(R.drawable.ic_player_center_start);
-            }else {
-                mCenterStart.setImageResource(image);
-            }
-        }
-    }
-
 
     /**
      * 18年3月15日添加
@@ -373,6 +372,19 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         }
     }
 
+    /**
+     * 设置横屏播放时,tv和audio图标是否显示
+     * @param isVisibility1                 tv图标是否显示
+     * @param isVisibility2                 audio图标是否显示
+     */
+    @Override
+    public void setTvAndAudioVisibility(boolean isVisibility1, boolean isVisibility2) {
+        this.mIsTvIconVisibility = isVisibility1;
+        this.mIsAudioIconVisibility = isVisibility2;
+        mIvHorTv.setVisibility(mIsTvIconVisibility?VISIBLE:GONE);
+        mIvHorAudio.setVisibility(mIsAudioIconVisibility?VISIBLE:GONE);
+    }
+
 
     /**
      * 18年1月12号添加
@@ -405,10 +417,11 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
 
     /**
      * 设置不操作后,多久自动隐藏头部和底部布局
+     * 添加值范围注释,限定时间为1秒到10秒之间
      * @param time                  时间
      */
     @Override
-    public void setHideTime(long time) {
+    public void setHideTime(@IntRange(from = 1000 , to = 10000) long time) {
         this.time = time;
     }
 
@@ -418,7 +431,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
      * @param title             视频标题
      */
     @Override
-    public void setTitle(String title) {
+    public void setTitle(@NonNull String title) {
         mTitle.setText(title);
     }
 
@@ -476,7 +489,22 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         }
     }
 
-
+    /**
+     * 设置中间播放按钮是否显示,并且支持设置自定义图标
+     * @param isVisibility          是否可见,默认不可见
+     * @param image                 image
+     */
+    @Override
+    public void setCenterPlayer(boolean isVisibility, @DrawableRes int image) {
+        this.mIsCenterPlayerVisibility = isVisibility;
+        if(isVisibility){
+            if(image==0){
+                mCenterStart.setImageResource(R.drawable.ic_player_center_start);
+            }else {
+                mCenterStart.setImageResource(image);
+            }
+        }
+    }
 
     /**
      * 获取是否是锁屏模式
@@ -548,6 +576,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
      * 当播放状态发生改变时
      * @param playState 播放状态:
      */
+    @SuppressLint("SetTextI18n")
     @Override
     public void onPlayStateChanged(int playState) {
         switch (playState) {
@@ -564,10 +593,12 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
                 mBottom.setVisibility(View.GONE);
                 mCenterStart.setVisibility(View.GONE);
                 mLength.setVisibility(View.GONE);
+                startUpdateNetSpeedTimer();
                 break;
             //播放准备就绪
             case ConstantKeys.CurrentState.STATE_PREPARED:
                 startUpdateProgressTimer();
+                cancelUpdateNetSpeedTimer();
                 break;
             //正在播放
             case ConstantKeys.CurrentState.STATE_PLAYING:
@@ -575,6 +606,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
                 mCenterStart.setVisibility(View.GONE);
                 mRestartPause.setImageResource(R.drawable.ic_player_pause);
                 startDismissTopBottomTimer();
+                cancelUpdateNetSpeedTimer();
                 break;
             //暂停播放
             case ConstantKeys.CurrentState.STATE_PAUSED:
@@ -582,21 +614,24 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
                 mCenterStart.setVisibility(mIsCenterPlayerVisibility?View.VISIBLE:View.GONE);
                 mRestartPause.setImageResource(R.drawable.ic_player_start);
                 cancelDismissTopBottomTimer();
+                cancelUpdateNetSpeedTimer();
                 break;
             //正在缓冲(播放器正在播放时,缓冲区数据不足,进行缓冲,缓冲区数据足够后恢复播放)
             case ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING:
                 mLoading.setVisibility(View.VISIBLE);
                 mCenterStart.setVisibility(View.GONE);
                 mRestartPause.setImageResource(R.drawable.ic_player_pause);
-                mLoadText.setText("正在缓冲...");
+                mLoadText.setText("正在准备...");
                 startDismissTopBottomTimer();
+                cancelUpdateNetSpeedTimer();
                 break;
             //正在缓冲
             case ConstantKeys.CurrentState.STATE_BUFFERING_PAUSED:
                 mLoading.setVisibility(View.VISIBLE);
                 mRestartPause.setImageResource(R.drawable.ic_player_start);
-                mLoadText.setText("正在缓冲...");
+                mLoadText.setText("正在准备...");
                 cancelDismissTopBottomTimer();
+                startUpdateNetSpeedTimer();
                 break;
             //播放错误
             case ConstantKeys.CurrentState.STATE_ERROR:
@@ -604,6 +639,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
                 setTopBottomVisible(false);
                 mTop.setVisibility(View.VISIBLE);
                 mError.setVisibility(View.VISIBLE);
+                cancelUpdateNetSpeedTimer();
                 break;
             //播放完成
             case ConstantKeys.CurrentState.STATE_COMPLETED:
@@ -617,6 +653,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
                 }
                 //当播放完成就解除广播
                 unRegisterNetChangedReceiver();
+                cancelUpdateNetSpeedTimer();
                 break;
             default:
                 break;
@@ -624,6 +661,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
     }
 
 
+
     /**
      * 当播放器的播放模式发生变化时
      * @param playMode 播放器的模式:
@@ -658,6 +696,8 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
                 mLlTopOther.setVisibility(GONE);
                 if (mIsTopAndBottomVisibility){
                     mLlHorizontal.setVisibility(View.VISIBLE);
+                    mIvHorTv.setVisibility(mIsTvIconVisibility?VISIBLE:GONE);
+                    mIvHorAudio.setVisibility(mIsAudioIconVisibility?VISIBLE:GONE);
                 }else {
                     mLlHorizontal.setVisibility(View.GONE);
                 }
@@ -701,6 +741,8 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         mLoading.setVisibility(View.GONE);
         mError.setVisibility(View.GONE);
         mCompleted.setVisibility(View.GONE);
+        //解绑注册网络监听广播
+        unRegisterNetChangedReceiver();
     }
 
 
@@ -916,6 +958,23 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         setTopBottomVisible(!mIsLock);
     }
 
+    /**
+     * 更新进度,包括更新网络加载速度
+     */
+    @SuppressLint("SetTextI18n")
+    @Override
+    protected void updateNetSpeedProgress() {
+        //获取网络加载速度
+        long tcpSpeed = mVideoPlayer.getTcpSpeed();
+        VideoLogUtil.i("获取网络加载速度++++++++"+tcpSpeed);
+        if (tcpSpeed>0){
+            int speed = (int) (tcpSpeed/1024);
+            //显示网速
+            mLoading.setVisibility(View.VISIBLE);
+            mLoadText.setText("网速"+speed+"kb");
+        }
+    }
+
 
     /**
      * 更新播放进度
@@ -935,6 +994,9 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
         mDuration.setText(VideoPlayerUtils.formatTime(duration));
         // 更新时间
         mTime.setText(new SimpleDateFormat("HH:mm", Locale.CHINA).format(new Date()));
+
+        long tcpSpeed = mVideoPlayer.getTcpSpeed();
+        VideoLogUtil.i("获取网络加载速度---------"+tcpSpeed);
     }
 
     /**
@@ -958,6 +1020,7 @@ public class VideoPlayerController extends AbsVideoPlayerController implements V
      */
     @Override
     protected void hideChangePosition() {
+        //隐藏
         mChangePosition.setVisibility(View.GONE);
     }
 

+ 1 - 1
YCVideoPlayerLib/src/main/java/org/yczbj/ycvideoplayerlib/inter/InterVideoPlayer.java

@@ -145,7 +145,7 @@ public interface InterVideoPlayer {
      * 获取播放速度
      *
      * @param speed 播放速度
-     * @return 播放速度
+     * @return      播放速度
      */
     float getSpeed(float speed);
 

+ 61 - 28
YCVideoPlayerLib/src/main/java/org/yczbj/ycvideoplayerlib/player/VideoPlayer.java

@@ -12,19 +12,14 @@ import android.os.Build;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RequiresApi;
-import android.support.v7.app.AppCompatActivity;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.TextureView;
-import android.view.View;
 import android.view.ViewGroup;
-import android.view.Window;
 import android.widget.FrameLayout;
 import android.widget.Toast;
-
 import org.yczbj.ycvideoplayerlib.constant.ConstantKeys;
 import org.yczbj.ycvideoplayerlib.controller.AbsVideoPlayerController;
 import org.yczbj.ycvideoplayerlib.inter.InterVideoPlayer;
@@ -87,7 +82,6 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
     private boolean continueFromLastPosition = true;
     private long skipToPosition;
 
-
     public VideoPlayer(Context context) {
         this(context, null);
     }
@@ -100,7 +94,6 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
         super(context, attrs, defStyleAttr);
         mContext = context;
         init();
-
     }
 
     /**
@@ -152,7 +145,7 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
      * 设置视频控制器,必须设置
      * @param controller        AbsVideoPlayerController子类对象,可用VideoPlayerController,也可自定义
      */
-    public void setController(AbsVideoPlayerController controller) {
+    public void setController(@NonNull AbsVideoPlayerController controller) {
         //这里必须先移除
         mContainer.removeView(mController);
         mController = controller;
@@ -194,6 +187,9 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
      */
     @Override
     public void setSpeed(float speed) {
+        if (speed<0){
+            VideoLogUtil.d("设置的视频播放速度不能小于0");
+        }
         if (mMediaPlayer instanceof IjkMediaPlayer) {
             ((IjkMediaPlayer) mMediaPlayer).setSpeed(speed);
         } else if(mMediaPlayer instanceof MediaPlayer){
@@ -228,6 +224,9 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
      */
     @Override
     public void start(long position) {
+        if (position<0){
+            VideoLogUtil.d("设置开始播放的播放位置不能小于0");
+        }
         skipToPosition = position;
         start();
     }
@@ -266,12 +265,13 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
     @Override
     public void pause() {
         if (mCurrentState == ConstantKeys.CurrentState.STATE_PLAYING) {
+            //如果是播放状态,那么则暂停播放
             mMediaPlayer.pause();
             mCurrentState = ConstantKeys.CurrentState.STATE_PAUSED;
             mController.onPlayStateChanged(mCurrentState);
             VideoLogUtil.d("STATE_PAUSED");
-        }
-        if (mCurrentState == ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING) {
+        } else if (mCurrentState == ConstantKeys.CurrentState.STATE_BUFFERING_PLAYING) {
+            //如果是正在缓冲状态,那么则暂停暂停缓冲
             mMediaPlayer.pause();
             mCurrentState = ConstantKeys.CurrentState.STATE_BUFFERING_PAUSED;
             mController.onPlayStateChanged(mCurrentState);
@@ -286,6 +286,9 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
      */
     @Override
     public void seekTo(long pos) {
+        if (pos<0){
+            VideoLogUtil.d("设置开始跳转播放位置不能小于0");
+        }
         if (mMediaPlayer != null) {
             mMediaPlayer.seekTo(pos);
         }
@@ -552,21 +555,7 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
                 //IjkMediaPlayer    基于Ijk
                 case ConstantKeys.IjkPlayerType.TYPE_IJK:
                 default:
-                    //创建IjkMediaPlayer对象
-                    mMediaPlayer = new IjkMediaPlayer();
-                    //设置ijkPlayer播放器的硬件解码相关参数
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(1, "analyzemaxduration", 100L);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(1, "probesize", 10240L);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(1, "flush_packets", 1L);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "packet-buffering", 0L);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "framedrop", 1L);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "mediacodec", 0);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "opensles", 0);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "framedrop", 1);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(4, "start-on-prepared", 0);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(1, "http-detect-range-support", 0);
-                    ((IjkMediaPlayer)mMediaPlayer).setOption(2, "skip_loop_filter", 48);
+                    createIjkMediaPlayer();
                     break;
             }
             //设置音频流类型
@@ -574,6 +563,52 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
         }
     }
 
+    private void createIjkMediaPlayer() {
+        //创建IjkMediaPlayer对象
+        mMediaPlayer = new IjkMediaPlayer();
+        int PLAYER = IjkMediaPlayer.OPT_CATEGORY_PLAYER;
+        int CODEC = IjkMediaPlayer.OPT_CATEGORY_CODEC;
+        int FORMAT = IjkMediaPlayer.OPT_CATEGORY_FORMAT;
+
+        //设置ijkPlayer播放器的硬件解码相关参数
+        //设置播放前的最大探测时间
+        ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "analyzemaxduration", 100L);
+        //设置播放前的探测时间 1,达到首屏秒开效果
+        ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "analyzeduration", 1L);
+        //播放前的探测Size,默认是1M, 改小一点会出画面更快
+        ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "probesize", 10240L);
+        //设置是否开启变调isModifyTone?0:1
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER,"soundtouch",0);
+        //每处理一个packet之后刷新io上下文
+        ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "flush_packets", 1L);
+        //是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "packet-buffering", 0L);
+        //播放重连次数
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "reconnect", 5);
+        //最大缓冲大小,单位kb
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "max-buffer-size", 10240L);
+        //跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "framedrop", 1L);
+        //最大fps
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "max-fps", 30L);
+        //SeekTo设置优化
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "enable-accurate-seek", 1L);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "opensles", 0);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "framedrop", 1);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "start-on-prepared", 0);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "http-detect-range-support", 0);
+        //设置是否开启环路过滤: 0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小
+        ((IjkMediaPlayer)mMediaPlayer).setOption(CODEC, "skip_loop_filter", 48);
+
+        //jkPlayer支持硬解码和软解码。
+        //软解码时不会旋转视频角度这时需要你通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED去获取角度,自己旋转画面。
+        //或者开启硬解硬解码,不过硬解码容易造成黑屏无声(硬件兼容问题),下面是设置硬解码相关的代码
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "mediacodec", 0);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "mediacodec-auto-rotate", 1);
+        ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "mediacodec-handle-resolution-change", 1);
+    }
+
 
     /**
      * 初始化TextureView
@@ -1021,9 +1056,7 @@ public class VideoPlayer extends FrameLayout implements InterVideoPlayer {
     public void releasePlayer() {
         if (mAudioManager != null) {
             //放弃音频焦点。使以前的焦点所有者(如果有的话)接收焦点。
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
-                mAudioManager.abandonAudioFocus(null);
-            }
+            mAudioManager.abandonAudioFocus(null);
             //置空
             mAudioManager = null;
         }

BIN
YCVideoPlayerLib/src/main/res/drawable-xhdpi/ic_back_white.png


+ 18 - 9
YCVideoPlayerLib/src/main/res/layout/custom_video_player_top.xml

@@ -27,7 +27,8 @@
         android:maxLength="10"
         android:text="视频标题"
         android:textColor="@android:color/white"
-        android:textSize="16sp"/>
+        android:textSize="16sp"
+        android:layout_marginLeft="5dp" />
 
     <!--竖屏的时候需要展现的布局,定制的-->
     <LinearLayout
@@ -36,7 +37,8 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:layout_marginEnd="8dp"
-        android:visibility="visible">
+        android:visibility="visible"
+        android:layout_marginRight="8dp">
         <ImageView
             android:id="@+id/iv_audio"
             android:layout_width="20dp"
@@ -47,19 +49,22 @@
             android:layout_width="20dp"
             android:layout_height="20dp"
             android:layout_marginStart="15dp"
-            android:src="@drawable/ic_player_dl"/>
+            android:src="@drawable/ic_player_dl"
+            android:layout_marginLeft="15dp" />
         <ImageView
             android:id="@+id/iv_share"
             android:layout_width="20dp"
             android:layout_height="20dp"
             android:layout_marginStart="15dp"
-            android:src="@drawable/ic_player_share"/>
+            android:src="@drawable/ic_player_share"
+            android:layout_marginLeft="15dp" />
         <ImageView
             android:id="@+id/iv_menu"
             android:layout_width="20dp"
             android:layout_height="20dp"
             android:layout_marginStart="15dp"
-            android:src="@drawable/ic_player_menu"/>
+            android:src="@drawable/ic_player_menu"
+            android:layout_marginLeft="15dp" />
     </LinearLayout>
 
 
@@ -70,28 +75,32 @@
         android:layout_height="wrap_content"
         android:layout_marginEnd="8dp"
         android:visibility="gone"
-        android:orientation="horizontal">
+        android:orientation="horizontal"
+        android:layout_marginRight="8dp">
 
         <ImageView
             android:id="@+id/iv_hor_audio"
             android:layout_width="20dp"
             android:layout_height="20dp"
             android:layout_marginStart="15dp"
-            android:src="@drawable/ic_player_audio"/>
+            android:src="@drawable/ic_player_audio"
+            android:layout_marginLeft="15dp" />
 
         <ImageView
             android:id="@+id/iv_hor_tv"
             android:layout_width="20dp"
             android:layout_height="20dp"
             android:layout_marginStart="15dp"
-            android:src="@drawable/ic_player_tv"/>
+            android:src="@drawable/ic_player_tv"
+            android:layout_marginLeft="15dp" />
 
         <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="15dp"
             android:orientation="vertical"
-            android:visibility="visible">
+            android:visibility="visible"
+            android:layout_marginLeft="15dp">
             <ImageView
                 android:id="@+id/battery"
                 android:layout_width="wrap_content"

+ 9 - 18
app/build.gradle

@@ -3,12 +3,12 @@ apply plugin: 'com.neenbedankt.android-apt'
 apply plugin: 'realm-android'
 
 android {
-    compileSdkVersion 26
+    compileSdkVersion 27
     buildToolsVersion '27.0.3'
     defaultConfig {
         applicationId "org.yczbj.ycvideoplayer"
         minSdkVersion 17
-        targetSdkVersion 26
+        targetSdkVersion 27
         versionCode 11
         versionName "1.1.1"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
@@ -16,7 +16,7 @@ android {
         multiDexEnabled true
         ndk {
             //设置支持的SO库架构
-            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
+            abiFilters 'armeabi', 'armeabi-v7a'
         }
 
     }
@@ -27,15 +27,6 @@ android {
         }
     }
 
-    android {
-        lintOptions {
-            checkReleaseBuilds false
-            // Or, if you prefer, you can continue to check for errors in release builds,
-            // but continue the build even when errors are found:
-            abortOnError false
-        }
-    }
-
     //为了解决第三方库重复打包了META_INF问题,替换为有冲突的依赖
     packagingOptions {
         exclude 'META-INF/rxjava.properties'
@@ -46,10 +37,10 @@ android {
 dependencies {
     compile fileTree(include: ['*.jar'], dir: 'libs')
     //官方库
-    compile 'com.android.support:appcompat-v7:26.1.0'
-    compile 'com.android.support:recyclerview-v7:26.1.0'
-    compile 'com.android.support:design:26.1.0'
-    compile 'com.android.support:cardview-v7:26.1.0'
+    compile 'com.android.support:appcompat-v7:27.1.0'
+    compile 'com.android.support:recyclerview-v7:27.1.0'
+    compile 'com.android.support:design:27.1.0'
+    compile 'com.android.support:cardview-v7:27.1.0'
     compile 'com.android.support:support-annotations:25.3.1'
     compile 'com.android.support:multidex:1.0.1'
 
@@ -94,7 +85,7 @@ dependencies {
     compile 'cn.yc:YCBaseAdapterLib:1.3'                            //adapter封装
     compile 'cn.yc:YCDialogLib:3.5'                                 //弹窗
     compile 'cn.yc:YCProgressLib:1.2'                               //进度条
-    compile 'cn.yc:YCVideoPlayerLib:2.6.0'                            //播放器
-//    compile project(':YCVideoPlayerLib')
+//    compile 'cn.yc:YCVideoPlayerLib:2.6.0'                            //播放器
+    compile project(':YCVideoPlayerLib')
     compile 'cn.yc:YCStatusBarLib:1.3.1'                              //状态栏
 }

+ 2 - 0
app/src/main/java/org/yczbj/ycvideoplayer/ui/test/test2/view/VideoAdapter.java

@@ -9,6 +9,7 @@ import android.view.ViewGroup;
 import org.yczbj.ycvideoplayer.R;
 import org.yczbj.ycvideoplayer.ui.test.test2.model.Video;
 import org.yczbj.ycvideoplayer.util.ImageUtil;
+import org.yczbj.ycvideoplayerlib.constant.ConstantKeys;
 import org.yczbj.ycvideoplayerlib.player.VideoPlayer;
 import org.yczbj.ycvideoplayerlib.controller.VideoPlayerController;
 
@@ -68,6 +69,7 @@ public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoViewHol
          */
         void setController(VideoPlayerController controller) {
             mController = controller;
+            mVideoPlayer.setPlayerType(ConstantKeys.IjkPlayerType.TYPE_IJK);
             mVideoPlayer.setController(mController);
         }
 

+ 0 - 4
app/src/main/java/org/yczbj/ycvideoplayer/ui/video/contract/IVideoArticle.java

@@ -26,9 +26,5 @@ public interface IVideoArticle {
          */
         void doLoadMoreData();
 
-        /**
-         * 设置适配器
-         */
-        void doSetAdapter(List<MultiNewsArticleDataBean> dataBeen);
     }
 }

+ 5 - 7
app/src/main/java/org/yczbj/ycvideoplayer/ui/video/presenter/VideoArticlePresenter.java

@@ -1,5 +1,6 @@
 package org.yczbj.ycvideoplayer.ui.video.presenter;
 
+import android.annotation.SuppressLint;
 import android.text.TextUtils;
 
 import com.blankj.utilcode.util.TimeUtils;
@@ -37,6 +38,7 @@ public class VideoArticlePresenter implements IVideoArticle.Presenter {
         this.time = TimeUtils.getNowString();
     }
 
+    @SuppressLint("CheckResult")
     @Override
     public void doLoadData(String... category) {
         try {
@@ -97,7 +99,9 @@ public class VideoArticlePresenter implements IVideoArticle.Presenter {
                 .subscribe(new Consumer<List<MultiNewsArticleDataBean>>() {
                     @Override
                     public void accept(@NonNull List<MultiNewsArticleDataBean> list) throws Exception {
-                        doSetAdapter(list);
+                        dataList.addAll(list);
+                        view.onSetAdapter(dataList);
+                        view.onHideLoading();
                     }
                 }, new Consumer<Throwable>() {
                     @Override
@@ -113,12 +117,6 @@ public class VideoArticlePresenter implements IVideoArticle.Presenter {
         doLoadData();
     }
 
-    @Override
-    public void doSetAdapter(List<MultiNewsArticleDataBean> dataBeen) {
-        dataList.addAll(dataBeen);
-        view.onSetAdapter(dataList);
-        view.onHideLoading();
-    }
 
     @Override
     public void doRefresh() {

+ 46 - 2
app/src/main/java/org/yczbj/ycvideoplayer/ui/video/view/activity/VideoContentActivity.java

@@ -1,5 +1,6 @@
 package org.yczbj.ycvideoplayer.ui.video.view.activity;
 
+import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.graphics.Color;
 import android.os.Bundle;
@@ -77,18 +78,56 @@ public class VideoContentActivity extends BaseMVPActivity {
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
     }
 
+    @Override
+    protected void onStart() {
+        super.onStart();
+        LogUtils.e("VideoContentActivity----"+"onStart");
+    }
+
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        LogUtils.e("VideoContentActivity----"+"onResume");
+    }
+
     @Override
     protected void onStop() {
         super.onStop();
+        VideoPlayerManager.instance().suspendVideoPlayer();
+        LogUtils.e("VideoContentActivity----"+"onStop");
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
         VideoPlayerManager.instance().releaseVideoPlayer();
     }
 
     @Override
     public void onBackPressed() {
-        if (VideoPlayerManager.instance().onBackPressed()) return;
+        if (VideoPlayerManager.instance().onBackPressed()){
+            return;
+        }else {
+            VideoPlayerManager.instance().releaseVideoPlayer();
+            LogUtils.e("VideoContentActivity----"+"退出activity");
+        }
         super.onBackPressed();
+        LogUtils.e("VideoContentActivity----"+"onBackPressed");
     }
 
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        VideoPlayerManager.instance().resumeVideoPlayer();
+        LogUtils.e("VideoContentActivity----"+"onRestart");
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        LogUtils.e("VideoContentActivity----"+"onPause");
+    }
 
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -99,6 +138,7 @@ public class VideoContentActivity extends BaseMVPActivity {
         initView();
         initData();
         onLoadData();
+        LogUtils.e("VideoContentActivity----"+"onCreate");
     }
 
     @Override
@@ -230,7 +270,7 @@ public class VideoContentActivity extends BaseMVPActivity {
         //创建视频控制器
         controller = new VideoPlayerController(this);
         controller.setTitle(videoTitle);
-        controller.setLoadingType(ConstantKeys.Loading.LOADING_QQ);
+        controller.setLoadingType(ConstantKeys.Loading.LOADING_RING);
         controller.imageView().setBackgroundResource(R.color.blackText);
         controller.setOnVideoBackListener(new OnVideoBackListener() {
             @Override
@@ -244,6 +284,9 @@ public class VideoContentActivity extends BaseMVPActivity {
         videoPlayer.continueFromLastPosition(true);
         //设置播放速度
         videoPlayer.setSpeed(1.0f);
+
+        int maxVolume = videoPlayer.getMaxVolume();
+        LogUtils.e("视频播放器"+maxVolume);
     }
 
     private static String getVideoContentApi(String videoid) {
@@ -269,6 +312,7 @@ public class VideoContentActivity extends BaseMVPActivity {
     }
 
 
+    @SuppressLint("CheckResult")
     private void getVideoData(VideoModel model, String url) {
         model.getVideoContent(url)
                 .subscribeOn(Schedulers.io())

+ 92 - 0
read/wiki2.md

@@ -0,0 +1,92 @@
+# 视频优化处理
+#### 目录介绍
+- 01.播放加载优化
+- 02.前后台切换优化
+- 03.视频播放异常优化
+- 04.视频播放颤动优化
+- 05.视频解码优化
+- 06.SeekTo设置优化
+- 07.关于so库优化
+- 08.关于网络状态监听优化
+- 09.关于代码规范优化
+
+
+
+
+### 05.视频解码优化
+- ijkplayer和ffplay在打开rtmp串流视频时,大多数都会遇到5~10秒的延迟,在ffplay播放时,如果加上-fflags nobuffer可以缩短播放的rtmp视频延迟在1s内,而在IjkMediaPlayer中加入
+    ```
+    mMediaPlayer = new IjkMediaPlayer();
+    int PLAYER = IjkMediaPlayer.OPT_CATEGORY_PLAYER;
+    int CODEC = IjkMediaPlayer.OPT_CATEGORY_CODEC;
+    int FORMAT = IjkMediaPlayer.OPT_CATEGORY_FORMAT;
+    //设置播放前的最大探测时间
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "analyzemaxduration", 100L);
+    //播放前的探测Size,默认是1M, 改小一点会出画面更快
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "probesize", 10240L);
+    //每处理一个packet之后刷新io上下文
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "flush_packets", 1L);
+    //是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "packet-buffering", 0L);
+    //跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "framedrop", 1L);
+    ```
+- jkPlayer支持硬解码和软解码。 软解码时不会旋转视频角度这时需要你通过onInfo的what == IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED去获取角度,自己旋转画面。或者开启硬解硬解码,不过硬解码容易造成黑屏无声(硬件兼容问题),下面是设置硬解码相关的代码
+    ```
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "mediacodec", 0);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "mediacodec-auto-rotate", 1);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "mediacodec-handle-resolution-change", 1);
+    ```
+- 其他更多关于解码相关的内容
+    ```
+    int PLAYER = IjkMediaPlayer.OPT_CATEGORY_PLAYER;
+    int CODEC = IjkMediaPlayer.OPT_CATEGORY_CODEC;
+    int FORMAT = IjkMediaPlayer.OPT_CATEGORY_FORMAT;
+
+    //设置ijkPlayer播放器的硬件解码相关参数
+    //设置播放前的最大探测时间
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "analyzemaxduration", 100L);
+    //设置播放前的探测时间 1,达到首屏秒开效果
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "analyzeduration", 1L);
+    //播放前的探测Size,默认是1M, 改小一点会出画面更快
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "probesize", 10240L);
+    //设置是否开启变调isModifyTone?0:1
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER,"soundtouch",0);
+    //每处理一个packet之后刷新io上下文
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "flush_packets", 1L);
+    //是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "packet-buffering", 0L);
+    //播放重连次数
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "reconnect", 5);
+    //最大缓冲大小,单位kb
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "max-buffer-size", 10240L);
+    //跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "framedrop", 1L);
+    //最大fps
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "max-fps", 30L);
+    //SeekTo设置优化
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "enable-accurate-seek", 1L);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "opensles", 0);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "framedrop", 1);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(PLAYER, "start-on-prepared", 0);
+    ((IjkMediaPlayer)mMediaPlayer).setOption(FORMAT, "http-detect-range-support", 0);
+    //设置是否开启环路过滤: 0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小
+    ((IjkMediaPlayer)mMediaPlayer).setOption(CODEC, "skip_loop_filter", 48);
+    ```
+
+
+### 06.SeekTo设置优化
+- 某些视频在SeekTo的时候,会跳回到拖动前的位置,这是因为视频的关键帧的问题,通俗一点就是FFMPEG不兼容,视频压缩过于厉害,seek只支持关键帧,出现这个情况就是原始的视频文件中i 帧比较少
+    ```
+    mediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
+    ```
+
+
+
+
+
+
+
+
+

+ 0 - 0
read/wiki5.md