Explorar o código

1,添加了核心,未来,原生播放器模块
2,将三种播放器整合在了一起

lyn %!s(int64=5) %!d(string=hai) anos
pai
achega
0ed63ecfe9
Modificáronse 96 ficheiros con 2570 adicións e 802 borrados
  1. 4 0
      .idea/gradle.xml
  2. 40 58
      app/build.gradle
  3. 0 68
      app/src/androidTest/java/com/haochuan/hciptvbasic/MainActivityTest.java
  4. 25 3
      app/src/main/AndroidManifest.xml
  5. 4 33
      app/src/main/java/com/haochuan/hciptvbasic/BaseApp.java
  6. 125 25
      app/src/main/java/com/haochuan/hciptvbasic/BaseWebActivity.java
  7. 16 21
      app/src/main/java/com/haochuan/hciptvbasic/MainActivity.java
  8. 0 86
      app/src/main/java/com/haochuan/hciptvbasic/Util/DownloadUtils.java
  9. 0 109
      app/src/main/java/com/haochuan/hciptvbasic/Util/MyLocation.java
  10. 23 19
      app/src/main/java/com/haochuan/hciptvbasic/test/TestActivity.java
  11. 7 12
      app/src/main/java/com/haochuan/hciptvbasic/test/TestPlayerActivity.java
  12. 0 228
      app/src/main/java/com/haochuan/hciptvbasic/video/HCPlayer.java
  13. 0 2
      app/src/main/java/com/haochuan/hciptvbasic/webview/HCWebChromeClient.java
  14. 2 2
      app/src/main/java/com/haochuan/hciptvbasic/webview/PayToJS.java
  15. 69 64
      app/src/main/java/com/haochuan/hciptvbasic/webview/PlayerToJS.java
  16. 19 17
      app/src/main/java/com/haochuan/hciptvbasic/webview/UtilToJS.java
  17. 9 0
      app/src/main/res/drawable/bg_ad_time.xml
  18. 7 0
      app/src/main/res/layout/activity_test.xml
  19. 0 9
      app/src/main/res/layout/player_hc.xml
  20. 34 0
      build.gradle
  21. 1 0
      core/.gitignore
  22. 42 0
      core/build.gradle
  23. 21 0
      core/proguard-rules.pro
  24. 27 0
      core/src/androidTest/java/com/haochuan/core/ExampleInstrumentedTest.java
  25. 11 0
      core/src/main/AndroidManifest.xml
  26. 15 7
      app/src/main/java/com/haochuan/hciptvbasic/video/BaseMediaPlayer.java
  27. 3 1
      app/src/main/java/com/haochuan/hciptvbasic/video/IVideoPlayer.java
  28. 30 9
      app/src/main/java/com/haochuan/hciptvbasic/Util/Logger.java
  29. 122 0
      core/src/main/java/com/haochuan/core/util/DownloadServer.java
  30. 117 0
      core/src/main/java/com/haochuan/core/util/FileUtil.java
  31. 47 0
      core/src/main/java/com/haochuan/core/util/HandlerUtil.java
  32. 24 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/JSONUtil.java
  33. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/JsUtil.java
  34. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/Juge.java
  35. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/MacUtil.java
  36. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/MathUtil.java
  37. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/Md5Util.java
  38. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/MessageCode.java
  39. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/web/MyRequest.java
  40. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/RegexUtil.java
  41. 1 1
      app/src/main/java/com/haochuan/hciptvbasic/Util/ScreenSnap.java
  42. 2 2
      app/src/main/java/com/haochuan/hciptvbasic/Util/ToolsUtil.java
  43. 6 0
      core/src/main/res/values/colors.xml
  44. 3 0
      core/src/main/res/values/strings.xml
  45. 17 0
      core/src/test/java/com/haochuan/core/ExampleUnitTest.java
  46. 1 0
      gsyvideo/.gitignore
  47. 42 0
      gsyvideo/build.gradle
  48. 21 0
      gsyvideo/proguard-rules.pro
  49. 27 0
      gsyvideo/src/androidTest/java/com/haochuan/gsyvideo/ExampleInstrumentedTest.java
  50. 11 0
      gsyvideo/src/main/AndroidManifest.xml
  51. 2 3
      app/src/main/java/com/haochuan/hciptvbasic/video/EmptyControlVideoView.java
  52. 15 12
      app/src/main/java/com/haochuan/hciptvbasic/video/HCGsyVideoPlayer.java
  53. 1 1
      app/src/main/res/layout/player_gsy_hc.xml
  54. 15 0
      gsyvideo/src/main/res/layout/view_video_control_empty.xml
  55. 6 0
      gsyvideo/src/main/res/values/colors.xml
  56. 3 0
      gsyvideo/src/main/res/values/strings.xml
  57. 17 0
      gsyvideo/src/test/java/com/haochuan/gsyvideo/ExampleUnitTest.java
  58. 1 1
      settings.gradle
  59. 1 0
      systemvideo/.gitignore
  60. 40 0
      systemvideo/build.gradle
  61. 21 0
      systemvideo/proguard-rules.pro
  62. 27 0
      systemvideo/src/androidTest/java/com/haochuan/systemvideo/ExampleInstrumentedTest.java
  63. 11 0
      systemvideo/src/main/AndroidManifest.xml
  64. 49 0
      systemvideo/src/main/java/com/haochuan/systemvideo/ErrorMessage.java
  65. 170 0
      systemvideo/src/main/java/com/haochuan/systemvideo/SystemVideoPlayer.java
  66. 11 0
      systemvideo/src/main/res/layout/layout_system_video.xml
  67. 6 0
      systemvideo/src/main/res/values/colors.xml
  68. 3 0
      systemvideo/src/main/res/values/strings.xml
  69. 11 0
      systemvideo/src/main/res/values/styles.xml
  70. 17 0
      systemvideo/src/test/java/com/haochuan/systemvideo/ExampleUnitTest.java
  71. 1 0
      weilai_video/.gitignore
  72. 69 0
      weilai_video/build.gradle
  73. BIN=BIN
      weilai_video/libs/adsdk.jar
  74. BIN=BIN
      weilai_video/libs/armeabi-v7a/libadsdk.so
  75. BIN=BIN
      weilai_video/libs/armeabi-v7a/liblogsdk.so
  76. BIN=BIN
      weilai_video/libs/armeabi-v7a/libottlogin.so
  77. BIN=BIN
      weilai_video/libs/armeabi-v7a/libupgradesdk.so
  78. BIN=BIN
      weilai_video/libs/icntvplayersdk.jar
  79. BIN=BIN
      weilai_video/libs/logsdk.jar
  80. BIN=BIN
      weilai_video/libs/ottlogin.jar
  81. BIN=BIN
      weilai_video/libs/universal-image-loader-1.9.5.jar
  82. BIN=BIN
      weilai_video/libs/upgradeSDK.jar
  83. 29 0
      weilai_video/proguard-rules.pro
  84. 27 0
      weilai_video/src/androidTest/java/com/haochuan/weilai_video/ExampleInstrumentedTest.java
  85. 11 0
      weilai_video/src/main/AndroidManifest.xml
  86. 408 0
      weilai_video/src/main/java/com/haochuan/weilai_video/CNTVLogin.java
  87. 281 0
      weilai_video/src/main/java/com/haochuan/weilai_video/WeiLaiVideoPlayer.java
  88. 81 0
      weilai_video/src/main/java/com/haochuan/weilai_video/store/LocalStore.java
  89. 128 0
      weilai_video/src/main/java/com/haochuan/weilai_video/util/AdDataUtil.java
  90. 69 0
      weilai_video/src/main/java/com/haochuan/weilai_video/util/ReportCNTVLog.java
  91. 9 0
      weilai_video/src/main/res/drawable-v24/bg_ad_time.xml
  92. 10 0
      weilai_video/src/main/res/layout/player_wl.xml
  93. 6 0
      weilai_video/src/main/res/values/colors.xml
  94. 3 0
      weilai_video/src/main/res/values/strings.xml
  95. 11 0
      weilai_video/src/main/res/values/styles.xml
  96. 17 0
      weilai_video/src/test/java/com/haochuan/weilai_video/ExampleUnitTest.java

+ 4 - 0
.idea/gradle.xml

@@ -9,6 +9,10 @@
           <set>
             <option value="$PROJECT_DIR$" />
             <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/core" />
+            <option value="$PROJECT_DIR$/gsyvideo" />
+            <option value="$PROJECT_DIR$/systemvideo" />
+            <option value="$PROJECT_DIR$/weilai_video" />
           </set>
         </option>
         <option name="resolveModulePerSourceSet" value="false" />

+ 40 - 58
app/build.gradle

@@ -1,34 +1,26 @@
 apply plugin: 'com.android.application'
 
 android {
-    compileSdkVersion 28
+    compileSdkVersion versions.compileSdk
     defaultConfig {
         applicationId "com.haochuan.hciptvbasic"
-        minSdkVersion 19
-        targetSdkVersion 28
-        versionCode 1
-        versionName "1.0.1"
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+        minSdkVersion versions.minSdk
+        targetSdkVersion versions.targetSdk
+        versionCode versions.versionCode
+        versionName versions.versionName
+        testInstrumentationRunner lib.test.test_runner
         ndk {
             //APP的build.gradle设置支持的SO库架构
             abiFilters 'armeabi', 'armeabi-v7a', 'x86'
         }
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            buildConfigField "Boolean", "isDebug", "false"     //app全局是否调试,发布版本不要开启
-            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
-        }
 
-        debug {
-            buildConfigField "Boolean", "isDebug", "true"     //app全局是否调试,调试版本开启
-        }
+        buildConfigField "int", "player_type", "1"; //播放器类型;1,原生;2,未来;3,GsyPlayer
     }
 
+
     compileOptions {
-        sourceCompatibility 'VERSION_1_8'
-        targetCompatibility 'VERSION_1_8'
+        sourceCompatibility versions.Java
+        targetCompatibility versions.Java
     }
 
     sourceSets {
@@ -37,49 +29,39 @@ android {
         }
     }
 
-    // Gradle automatically adds 'android.test.runner' as a dependency.
-    useLibrary 'android.test.runner'
+    buildTypes {
+        release {
+            zipAlignEnabled true
+            shrinkResources true
+            debuggable false
+            minifyEnabled true
+            buildConfigField "Boolean", "isDebug", "false"     //app全局是否调试,发布版本不要开启
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+
+        debug {
+            zipAlignEnabled false
+            shrinkResources false
+            debuggable true
+            minifyEnabled false
+            buildConfigField "Boolean", "isDebug", "true"     //app全局是否调试,调试版本开启
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
 
-    useLibrary 'android.test.base'
-    useLibrary 'android.test.mock'
 }
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
-    implementation 'com.android.support:appcompat-v7:28.0.0'
-    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
-    implementation 'androidx.appcompat:appcompat:1.0.2'
-    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
-    testImplementation 'junit:junit:4.12'
-    androidTestImplementation 'com.android.support.test:runner:1.0.2'
-    // Core library
-    androidTestImplementation 'androidx.test:core:1.0.0'
-
-    // AndroidJUnitRunner and JUnit Rules
-    androidTestImplementation 'androidx.test:runner:1.1.0'
-    androidTestImplementation 'androidx.test:rules:1.1.0'
-
-    // Assertions
-    androidTestImplementation 'androidx.test.ext:junit:1.0.0'
-    androidTestImplementation 'androidx.test.ext:truth:1.0.0'
-    androidTestImplementation 'com.google.truth:truth:0.42'
-
-    // Espresso dependencies
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
-    androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
-    androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0'
-
-    // The following Espresso dependency can be either "implementation"
-    // or "androidTestImplementation", depending on whether you want the
-    // dependency to appear on your APK's compile classpath or the test APK
-    // classpath.
-    androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'
-    implementation 'com.shuyu:GSYVideoPlayer:7.0.2'
-    implementation 'com.yanzhenjie.nohttp:nohttp:1.1.11'
-    implementation 'com.liulishuo.filedownloader:library:1.7.6'
-
-
+    implementation lib.support.v7
+    implementation lib.support.constraint_layout
+    implementation lib.support.appcompat
+    implementation lib.support.constraintlayout
+    testImplementation lib.test.junit
+    androidTestImplementation lib.test.runner
+    androidTestImplementation lib.test.espresso
+    implementation project(':gsyvideo')
+    implementation project(path: ':core')
+    implementation project(path: ':weilai_video')
+    implementation project(path: ':systemvideo')
 }

+ 0 - 68
app/src/androidTest/java/com/haochuan/hciptvbasic/MainActivityTest.java

@@ -1,68 +0,0 @@
-package com.haochuan.hciptvbasic;
-
-import android.content.Context;
-
-
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import androidx.test.rule.ActivityTestRule;
-
-import com.haochuan.hciptvbasic.Util.ScreenSnap;
-import com.haochuan.hciptvbasic.webview.PayToJS;
-import com.haochuan.hciptvbasic.webview.UtilToJS;
-
-import org.junit.Rule;
-import org.junit.Test;
-
-
-public class MainActivityTest{
-
-    @Rule
-    public ActivityTestRule<MainActivity> mActivityRule
-            = new ActivityTestRule<>(MainActivity.class);
-
-
-
-   private Context getContext(){
-       return InstrumentationRegistry.getInstrumentation().getContext();
-   }
-
-
-
-    @Test
-    public void playTest(){
-       try{
-           MainActivity activity = mActivityRule.getActivity();
-           String url = "https://gzhc-sxrj.oss-cn-shenzhen.aliyuncs.com/gzhc-djbl/djbl01.mp4";
-           int x = 0;
-           int y = 0;
-           int width = ScreenSnap.getScreenWidth(getContext());
-           int height = ScreenSnap.getScreenHeight(getContext());
-
-       }catch (Throwable throwable) {
-           throwable.printStackTrace();
-       }
-
-    }
-
-    @Test
-    public void testPayToJs(){
-        MainActivity activity = mActivityRule.getActivity();
-        PayToJS payToJS = new PayToJS(getContext(),activity.getWebView());
-        payToJS.getUserId();
-    }
-
-    @Test
-    public void testToolToJs(){
-        MainActivity activity = mActivityRule.getActivity();
-        UtilToJS utilToJS = new UtilToJS(activity,activity.getWebView());
-        String filePath = "/storage/emulated/0/Android/data/com.haochuan.hciptvbasic/cache/temp/com.haochuan.hciptvbasic1.apk";
-        String url = "http://117.169.11.222:8018/tv/index.php?m=Home&c=Activity&a=getActStatus";
-        String paramJson = "{\"m\":\"Home\",\"c\":\"Activity\",\"a\":\"getActStatus\"}";
-        String headJson = "{\"cookie\":\"head=123123123131fdfsfsdfs\"}";
-        utilToJS.clientWebRequest("");
-        //Logger.d("md5:" + md5);
-        //toolToJS.download("http://202.99.114.74:56251/dudu_youxi/h5/gameList/apk/jiSuKuangBiao.apk");
-
-    }
-}

+ 25 - 3
app/src/main/AndroidManifest.xml

@@ -4,6 +4,28 @@
 
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 
+    <!-- 未来电视所需权限 -->
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.GET_TASKS" />
+    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.REORDER_TASKS" />
+    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+
+    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+
     <application
         android:name=".BaseApp"
         android:allowBackup="true"
@@ -15,15 +37,15 @@
         <activity android:name=".test.TestPlayerActivity">
         </activity>
         <activity android:name=".test.TestActivity">
-
-        </activity>
-        <activity android:name=".MainActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".MainActivity">
+
+        </activity>
 
         <uses-library
             android:name="android.test.runner"

+ 4 - 33
app/src/main/java/com/haochuan/hciptvbasic/BaseApp.java

@@ -2,44 +2,15 @@ package com.haochuan.hciptvbasic;
 
 import android.app.Application;
 
-import com.liulishuo.filedownloader.FileDownloader;
-import com.tt.memorymonitorlib.MemoryMonitor;
-import com.yanzhenjie.nohttp.InitializationConfig;
-import com.yanzhenjie.nohttp.NoHttp;
-import com.yanzhenjie.nohttp.URLConnectionNetworkExecutor;
-import com.yanzhenjie.nohttp.cache.DBCacheStore;
-import com.yanzhenjie.nohttp.cookie.DBCookieStore;
+import com.haochuan.core.util.DownloadServer;
+
 
 public class BaseApp extends Application {
     @Override
     public void onCreate() {
         super.onCreate();
-        initHttp();
-        FileDownloader.setupOnApplicationOnCreate(this);   //初始化文件下载插件
-        MemoryMonitor.getInstance().init(this);//初始化memory monitor
+        DownloadServer.getInstance().initHttp(this);
     }
 
-    private void initHttp() {
-        InitializationConfig config = InitializationConfig.newBuilder(this)
-                // 全局连接服务器超时时间,单位毫秒,默认10s。
-                .connectionTimeout(10 * 1000)
-                // 全局等待服务器响应超时时间,单位毫秒,默认10s。
-                .readTimeout(10 * 1000)
-                // 配置缓存,默认保存数据库DBCacheStore,保存到SD卡使用DiskCacheStore。
-                .cacheStore(
-                        // 如果不使用缓存,setEnable(false)禁用。
-                        new DBCacheStore(this).setEnable(false)
-                )
-                // 配置Cookie,默认保存数据库DBCookieStore,开发者可以自己实现CookieStore接口。
-                .cookieStore(
-                        // 如果不维护cookie,setEnable(false)禁用。
-                        new DBCookieStore(this).setEnable(false)
-                )
-                // 配置网络层,默认URLConnectionNetworkExecutor,如果想用OkHttp:OkHttpNetworkExecutor。
-                .networkExecutor(new URLConnectionNetworkExecutor())
-                // 全局重试次数,配置后每个请求失败都会重试x次。
-                .retry(2)
-                .build();
-        NoHttp.initialize(config);
-    }
+
 }

+ 125 - 25
app/src/main/java/com/haochuan/hciptvbasic/BaseWebActivity.java

@@ -8,10 +8,12 @@ package com.haochuan.hciptvbasic;
 
 import android.annotation.SuppressLint;
 import android.app.ActivityManager;
+import android.app.AlertDialog;
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
+import android.util.Log;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.webkit.WebSettings;
@@ -22,14 +24,19 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.content.ContextCompat;
 
-import com.haochuan.hciptvbasic.Util.Logger;
-import com.haochuan.hciptvbasic.video.BaseMediaPlayer;
-import com.haochuan.hciptvbasic.video.HCPlayer;
-import com.haochuan.hciptvbasic.video.IVideoPlayer;
+import com.haochuan.core.BaseMediaPlayer;
+import com.haochuan.core.IVideoPlayer;
+import com.haochuan.core.Logger;
+import com.haochuan.core.util.HandlerUtil;
+import com.haochuan.gsyvideo.HCGsyVideoPlayer;
 import com.haochuan.hciptvbasic.webview.PayToJS;
 import com.haochuan.hciptvbasic.webview.PlayerToJS;
 import com.haochuan.hciptvbasic.webview.HCWebChromeClient;
 import com.haochuan.hciptvbasic.webview.UtilToJS;
+import com.haochuan.systemvideo.SystemVideoPlayer;
+import com.haochuan.weilai_video.CNTVLogin;
+import com.haochuan.weilai_video.WeiLaiVideoPlayer;
+import com.haochuan.weilai_video.util.ReportCNTVLog;
 
 import java.util.List;
 
@@ -42,7 +49,7 @@ public abstract class BaseWebActivity extends AppCompatActivity {
     String payToJSName = PayToJS.class.getSimpleName();         //payToJS类名
     String toolToJSName = UtilToJS.class.getSimpleName();       //toolToJS类名
     //播放器
-    private HCPlayer mHCPlayer = null;
+    private BaseMediaPlayer mHCPlayer = null;
 
     /**-----------------------虚函数-----------------------*/
 
@@ -55,8 +62,14 @@ public abstract class BaseWebActivity extends AppCompatActivity {
         super.onCreate(savedInstanceState);
 
         //初始化日志
-        Logger.init(this);
+        Logger.init(this,getWebView());
 
+        //如果是未来版本,需要先初始化其sdk
+        if(BuildConfig.player_type == 2){
+            CNTVInit();
+        }
+
+        //初始化播放器
         initPlayer();
 
         webView = new WebView(this);
@@ -64,6 +77,14 @@ public abstract class BaseWebActivity extends AppCompatActivity {
         setContentView(webView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
 
         initWebSetting(webView);
+
+        //未来版本需要先初始化SDK成功再加载页面
+        if(BuildConfig.player_type != 2){
+            runH5();
+        }
+    }
+
+    private void runH5(){
         webView.loadUrl(getIndexURL());
     }
 
@@ -81,9 +102,10 @@ public abstract class BaseWebActivity extends AppCompatActivity {
             webView.onResume();
         }
         if(mHCPlayer !=null){
-            mHCPlayer.onResume();
+            mHCPlayer.resume();
         }
 
+
     }
 
     @Override
@@ -93,7 +115,7 @@ public abstract class BaseWebActivity extends AppCompatActivity {
             webView.onPause();
         }
         if(mHCPlayer !=null){
-            mHCPlayer.onPause();
+            mHCPlayer.pause();
         }
     }
 
@@ -103,9 +125,7 @@ public abstract class BaseWebActivity extends AppCompatActivity {
         boolean isForeground = isRunningForeground(this);
         if (!isForeground) {
             Handler handler = new Handler(getMainLooper());
-            handler.postDelayed(() -> {
-                exit();
-            }, 500);
+            handler.postDelayed(() -> AppExit(), 500);
         }
     }
 
@@ -126,7 +146,7 @@ public abstract class BaseWebActivity extends AppCompatActivity {
             webView = null;
         }
         if(mHCPlayer !=null){
-            mHCPlayer.onDestroy();
+            mHCPlayer.release();
         }
         super.onDestroy();
     }
@@ -136,7 +156,14 @@ public abstract class BaseWebActivity extends AppCompatActivity {
      */
     @Override
     public void onBackPressed() {
-        utilToJS.onBackPressed();
+        if(CNTVLogin.getInstance().isOpenAdshow()){
+            Log.d("djbl","onBackPressed close ad");
+            ViewGroup viewGroup = (ViewGroup) getWindow().getDecorView();
+            CNTVLogin.getInstance().removeADImage(this,viewGroup);
+        }else{
+            utilToJS.onBackPressed();
+        }
+
     }
 
     /*--------------------------初始化函数---------------------------*/
@@ -144,8 +171,20 @@ public abstract class BaseWebActivity extends AppCompatActivity {
     * 初始化播放器
     * */
     private void initPlayer(){
-        mHCPlayer = new HCPlayer(this);
-        mHCPlayer.setIVideoPlayerListener(new IVideoPlayer() {
+        switch (BuildConfig.player_type){
+            case 1:
+                mHCPlayer = new SystemVideoPlayer(this);
+                break;
+            case 2:
+                mHCPlayer = new WeiLaiVideoPlayer(this);
+                break;
+            case 3:
+                mHCPlayer = new HCGsyVideoPlayer(this);
+                break;
+            default:
+                break;
+        }
+        mHCPlayer.setVideoPlayerListener(new IVideoPlayer() {
             @Override
             public void onPreparing() {
                 playerToJS.onPlayerPreparing();
@@ -183,10 +222,77 @@ public abstract class BaseWebActivity extends AppCompatActivity {
             @Override
             public void onError(int what, int extra) {
                 playerToJS.onPlayerError(what,extra);
+                if(BuildConfig.player_type == 2){
+                    CNTVPlayerErrorAlert();
+                }
+            }
+
+        });
+    }
+
+
+
+    /*---------------------------------------未来电视方法-------------------------------------*/
+    //这部分代码只在接入未来电视播放时有,如果不是,请注释掉
+
+    /*
+    *初始化未来SDK
+    * 加载未来电视广告图片
+    * */
+    private void CNTVInit(){
+        CNTVLogin.getInstance().init(this, new CNTVLogin.OnCNTVListener() {
+            @Override
+            public void onOttLoginSuccess() {
+                runH5();
             }
+
+            @Override
+            public void onOttLoginFail(String code, String msg) {
+                OttLoginFailAlert(code,msg);
+            }
+
+            @Override
+            public void onOttLoginError(Throwable throwable) {
+                OttLoginFailAlert("-1",throwable == null ? "发生未知异常" : throwable.getMessage());
+            }
+        });
+        ViewGroup viewGroup = (ViewGroup) getWindow().getDecorView();
+        CNTVLogin.getInstance().showAdImage(this,viewGroup);
+    }
+
+    /*
+    *ott登陆失败提示
+    * */
+    private void OttLoginFailAlert(String code,String message){
+        HandlerUtil.runOnUiThread(()->{
+            String msg = String.format("认证失败 code:%s,失败信息:%s",code,message);
+            new AlertDialog.Builder(this)
+                    .setTitle("ott认证失败")
+                    .setMessage(msg)
+                    .setPositiveButton("确定", (dialog, which) -> {
+                        dialog.dismiss();
+                        AppExit();
+                    })
+                    .show();
         });
     }
 
+    /*
+     * 未来电视功能:视频播放错误,提示并且退出播放
+     * */
+    private void CNTVPlayerErrorAlert(){
+        HandlerUtil.runOnUiThread(()->{
+            new AlertDialog.Builder(BaseWebActivity.this)
+                    .setTitle("提示")
+                    .setMessage("该节目已下线!")
+                    .setCancelable(false)
+                    .setPositiveButton("确定", (dialog, which) -> {
+                        playerToJS.stop();
+                    }).show();
+        });
+    }
+
+    /*---------------------------------------未来电视方法 end-------------------------------------*/
 
     @SuppressLint({"SetJavaScriptEnabled", "JavascriptInterface", "AddJavascriptInterface"})
     private void initWebSetting(WebView webView) {
@@ -223,15 +329,6 @@ public abstract class BaseWebActivity extends AppCompatActivity {
 
     /*-----------------------------------功能函数 start----------------------------------*/
 
-    /*
-     *  将日志发给前端
-     *  @param log    日志内容
-     * */
-
-    public void loggerToJs(String log){
-        getUtilToJS().logToJs(log);
-    }
-
     /**
      * 判断应用是否处于前台
      *
@@ -257,7 +354,10 @@ public abstract class BaseWebActivity extends AppCompatActivity {
     /*
      * 退出应用
      * */
-    public void exit() {
+    public void AppExit() {
+        if(BuildConfig.player_type == 2){
+            new ReportCNTVLog().reportExitLog();
+        }
         android.os.Process.killProcess(android.os.Process.myPid());   //获取PID
         System.exit(0);
     }

+ 16 - 21
app/src/main/java/com/haochuan/hciptvbasic/MainActivity.java

@@ -3,8 +3,6 @@ package com.haochuan.hciptvbasic;
 import android.os.Bundle;
 import android.util.Log;
 
-import com.haochuan.hciptvbasic.Util.Logger;
-
 import java.util.Timer;
 import java.util.TimerTask;
 
@@ -20,26 +18,32 @@ public class MainActivity extends BaseWebActivity {
         super.onCreate(savedInstanceState);
 
         //test
-        /*String playParamJson = "{\n" +
+        String playParamJson = "{\n" +
+                "    \"examine_id\": 200000253,\n" +
                 "    \"url\": \"https://gzhc-sxrj.oss-cn-shenzhen.aliyuncs.com/gzhc-djbl/djbl01.mp4\"\n" +
                 "}";
         int state = getPlayerToJS().getPlayerStatus();
-        Logger.d("播放器状态:" + state);
-        getPlayerToJS().play(playParamJson);
 
         new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
+                getPlayerToJS().play(playParamJson);
+            }
+        },10000);
+        /*new Timer().schedule(new TimerTask() {
+            @Override
+            public void run() {
                 int state = 0;
                 switch (testCount){
                     case 0:
-                        String changeParamJson = "{\n" +
+                        *//*String changeParamJson = "{\n" +
                                 "    \"x\": 60,\n" +
                                 "    \"y\": 60,\n" +
                                 "    \"width\": 480,\n" +
                                 "    \"height\": 270\n" +
                                 "}";
-                        getPlayerToJS().change(changeParamJson);
+                        getPlayerToJS().change(changeParamJson);*//*
+
                         break;
                     case 1:
                         getPlayerToJS().pause();
@@ -52,7 +56,10 @@ public class MainActivity extends BaseWebActivity {
                         Log.d(TAG,"播放器状态:" + state);
                         break;
                     case 3:
-                        getPlayerToJS().seek(5);
+                        String param = "{\n" +
+                                "  \"time\": 5\n" +
+                                "}";
+                        getPlayerToJS().seek(param);
                         state = getPlayerToJS().getPlayerStatus();
                         Log.d(TAG,"播放器状态:" + state);
                         break;
@@ -68,19 +75,7 @@ public class MainActivity extends BaseWebActivity {
                 }
                 testCount++;
             }
-        },0,2000);*/
-        /*int requestResult = getUtilToJS().clientWebRequest("{\n" +
-                "    \"url\": \"http://117.169.11.222:8018/tv/index.php?m=Home&c=Activity&a=getActStatus\",\n" +
-                "    \"method\": 1,\n" +
-                "    \"content_type\": \"application/json\",\n" +
-                "    \"param_json\": {\n" +
-                "        \"act_id\": 123123,\n" +
-                "        \"uid\": 123123123\n" +
-                "    },\n" +
-                "    \"ignore_result\": 0,\n" +
-                "    \"tag\": \"11_huodong\"\n" +
-                "}");
-        Log.d(TAG,"requestResult:" + requestResult);*/
+        },10000,5000);*/
         //getUtilToJS().appExit();
     }
 

+ 0 - 86
app/src/main/java/com/haochuan/hciptvbasic/Util/DownloadUtils.java

@@ -1,86 +0,0 @@
-package com.haochuan.hciptvbasic.Util;
-
-
-import com.liulishuo.filedownloader.BaseDownloadTask;
-import com.liulishuo.filedownloader.FileDownloadLargeFileListener;
-import com.liulishuo.filedownloader.FileDownloader;
-import com.liulishuo.filedownloader.util.FileDownloadUtils;
-
-import java.io.File;
-
-/**
- * 下载文件工具类
- */
-public class DownloadUtils {
-
-    /**
-     * 下载文件
-     *
-     * @param url           下载地址
-     * @param fileName      文件名
-     * @param fileExtension 文件扩展名,例如exe,apk,xml等等
-     * @param listener      下载进度监听
-     */
-    public static void download(String url, final String fileName, String fileExtension, final DownloadProgressListener listener) {
-        Logger.d("准备下载文件:%s");
-        final String filePath = FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "temp" + File.separator + fileName + "." + fileExtension;
-        if (listener != null) {
-            listener.onDownloadStart();
-        }
-        FileDownloader.getImpl().create(url)
-                .setPath(filePath, false)
-                .setCallbackProgressTimes(500)
-                .setMinIntervalUpdateSpeed(400)
-                .setListener(new FileDownloadLargeFileListener() {
-                    @Override
-                    protected void pending(BaseDownloadTask task, long soFarBytes, long totalBytes) {
-
-                    }
-
-                    @Override
-                    protected void progress(BaseDownloadTask task, long soFarBytes, long totalBytes) {
-                        int progress = (int) ((soFarBytes * 100) / totalBytes);
-                        Logger.d(String.format("文件下载中,进度【%s, %s, %s】", soFarBytes, progress, totalBytes));
-                        if (listener != null) {
-                            listener.onDownloadProgress(progress);
-                        }
-                    }
-
-                    @Override
-                    protected void paused(BaseDownloadTask task, long soFarBytes, long totalBytes) {
-
-                    }
-
-                    @Override
-                    protected void completed(BaseDownloadTask task) {
-                        Logger.d(String.format("文件下载成功,路径:%s", filePath));
-                        if (listener != null) {
-                            listener.onDownloadSuccessful(filePath);
-                        }
-                    }
-
-                    @Override
-                    protected void error(BaseDownloadTask task, Throwable e) {
-                        Logger.e(String.format("文件下载异常:%s", e));
-                        if (listener != null) {
-                            listener.onDownloadFail(e.getMessage());
-                        }
-                    }
-
-                    @Override
-                    protected void warn(BaseDownloadTask task) {
-
-                    }
-                }).start();
-    }
-
-    public interface DownloadProgressListener {
-        void onDownloadStart();
-
-        void onDownloadProgress(int progress);
-
-        void onDownloadSuccessful(String filePath);
-
-        void onDownloadFail(String message);
-    }
-}

+ 0 - 109
app/src/main/java/com/haochuan/hciptvbasic/Util/MyLocation.java

@@ -1,109 +0,0 @@
-package com.haochuan.hciptvbasic.Util;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.os.Bundle;
-import android.util.Log;
-
-import androidx.core.app.ActivityCompat;
-
-import java.util.List;
-
-public class MyLocation {
-    LocationManager locationManager;
-    String TAG = "MyLocation";
-
-    LocationListener mListener = new LocationListener() {
-        @Override
-        public void onStatusChanged(String provider, int status, Bundle extras) {
-        }
-
-        @Override
-        public void onProviderEnabled(String provider) {
-        }
-
-        @Override
-        public void onProviderDisabled(String provider) {
-        }
-
-        // 如果位置发生变化,重新显示
-        @Override
-        public void onLocationChanged(Location location) {
-            showLocation(location);
-        }
-    };
-
-    public MyLocation(Context context){
-        locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
-    }
-
-    public void showProviders(){
-        if(locationManager == null){
-            Log.e(TAG,"LocationManager is null");
-            return;
-        }
-        List<String> list = locationManager.getAllProviders();
-        if(list != null){
-            for(String name : list){
-                Log.d(TAG,"provider name:" + name);
-            }
-        }
-    }
-
-    public void getLocation(Context context){
-        if(locationManager == null){
-            Log.e(TAG,"LocationManager is null");
-            return;
-        }
-        List<String> providers = locationManager.getProviders(true);
-        String locationProvider;
-        if (providers.contains(LocationManager.NETWORK_PROVIDER)) {
-            //如果是网络定位
-            locationProvider = LocationManager.NETWORK_PROVIDER;
-        } else if (providers.contains(LocationManager.GPS_PROVIDER)) {
-            //如果是GPS定位
-            locationProvider = LocationManager.GPS_PROVIDER;
-        } else if (providers.contains(LocationManager.PASSIVE_PROVIDER)) {
-            //如果是PASSIVE定位
-            locationProvider = LocationManager.PASSIVE_PROVIDER;
-        }
-        else {
-            Log.e(TAG, "没有可用的位置提供器");
-            return;
-        }
-
-        //3.获取上次的位置,一般第一次运行,此值为null
-        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
-                && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
-            // TODO: Consider calling
-            //    ActivityCompat#requestPermissions
-            // here to request the missing permissions, and then overriding
-            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
-            //                                          int[] grantResults)
-            // to handle the case where the user grants the permission. See the documentation
-            // for ActivityCompat#requestPermissions for more details.
-            return;
-        }
-        Location location = locationManager.getLastKnownLocation(locationProvider);
-        if (location != null) {
-            showLocation(location);
-        } else {
-            // 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
-            locationManager.requestLocationUpdates(locationProvider, 1000, 200, mListener);
-        }
-    }
-
-    /**
-     * 获取经纬度
-     * @param location
-     */
-    private void showLocation(Location location) {
-        String longtitude=String.valueOf(location.getLongitude());
-        String latitude=String.valueOf(location.getLatitude());
-        Log.e("经纬度信息:",longtitude+"  "+latitude);
-    }
-}

+ 23 - 19
app/src/main/java/com/haochuan/hciptvbasic/test/TestActivity.java

@@ -5,7 +5,6 @@ import android.widget.Button;
 
 import com.haochuan.hciptvbasic.BaseWebActivity;
 import com.haochuan.hciptvbasic.R;
-import com.haochuan.hciptvbasic.Util.MyLocation;
 
 public class TestActivity extends BaseWebActivity {
 
@@ -22,17 +21,23 @@ public class TestActivity extends BaseWebActivity {
 
         Button playBtn = findViewById(R.id.play_btn);
         playBtn.setOnClickListener(v -> {
-            String url = "https://gzhc-sxrj.oss-cn-shenzhen.aliyuncs.com/gzhc-djbl/djbl01.mp4";
-            String x = "20";
-            String y = "30";
-            String width = "640";
-            String height = "360";
-            getPlayerToJS().play("");
+            String playParamJson = "{\n" +
+                    "    \"examine_id\": 200000253,\n" +
+                    "    \"url\": \"https://gzhc-sxrj.oss-cn-shenzhen.aliyuncs.com/gzhc-djbl/djbl01.mp4\"\n" +
+                    "}";
+            getPlayerToJS().play(playParamJson);
+            playBtn.requestFocus();
         });
 
         Button changeBtn = findViewById(R.id.change_btn);
+        String changeParam = "{\n" +
+                "    \"x\": 100,\n" +
+                "    \"y\": 100,\n" +
+                "    \"width\": 640,\n" +
+                "    \"height\": 360\n" +
+                "}";
         changeBtn.setOnClickListener(v ->
-                getPlayerToJS().change(""));
+                getPlayerToJS().change(changeParam));
 
         Button pauseBtn = findViewById(R.id.pause_btn);
         pauseBtn.setOnClickListener(v -> getPlayerToJS().pause());
@@ -47,7 +52,10 @@ public class TestActivity extends BaseWebActivity {
             if(seekPos > getMediaPlayer().getDuration()){
                 seekPos = getMediaPlayer().getDuration() - 1000;
             }
-            getPlayerToJS().seek(seekPos);
+            String param = "{\n" +
+                    "  \"time\": 0\n" +
+                    "}";
+            getPlayerToJS().seek(param);
         });
 
         Button backBtn = findViewById(R.id.back_btn);
@@ -57,14 +65,17 @@ public class TestActivity extends BaseWebActivity {
             if(seekPos < 0){
                 seekPos = 1000;
             }
-            getPlayerToJS().seek(seekPos);
+            String param = "{\n" +
+                    "  \"time\": 10\n" +
+                    "}";
+            getPlayerToJS().seek(param);
         });
 
         Button exitBtn = findViewById(R.id.exit_btn);
         exitBtn.setOnClickListener(v -> getPlayerToJS().stop());
 
-        //显示位置
-        getLocations();
+        Button exitAppBtn = findViewById(R.id.exit_app);
+        exitAppBtn.setOnClickListener(v -> getUtilToJS().appExit());
 
         /*String intentJson = new UtilToJS(this,getWebView()).getIntentJson();
         Logger.d("intentJson:" + intentJson);*/
@@ -89,13 +100,6 @@ public class TestActivity extends BaseWebActivity {
         //MemoryMonitor.getInstance().stop();
     }
 
-    /*
-    * 获取位置信息
-    * */
-    private void getLocations(){
-        MyLocation myLocation = new MyLocation(this);
-        myLocation.getLocation(this);
-    }
 
 
 }

+ 7 - 12
app/src/main/java/com/haochuan/hciptvbasic/test/TestPlayerActivity.java

@@ -3,11 +3,8 @@ package com.haochuan.hciptvbasic.test;
 import androidx.appcompat.app.AlertDialog;
 import androidx.appcompat.app.AppCompatActivity;
 
-import android.app.Activity;
-import android.app.Application;
 import android.content.DialogInterface;
 import android.os.Bundle;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.widget.LinearLayout;
@@ -15,21 +12,19 @@ import android.widget.ProgressBar;
 import android.widget.SeekBar;
 import android.widget.TextView;
 
+import com.haochuan.core.IVideoPlayer;
+import com.haochuan.core.Logger;
+import com.haochuan.gsyvideo.HCGsyVideoPlayer;
 import com.haochuan.hciptvbasic.R;
-import com.haochuan.hciptvbasic.Util.Logger;
-import com.haochuan.hciptvbasic.video.HCPlayer;
-import com.haochuan.hciptvbasic.video.IVideoPlayer;
 
 import java.math.BigDecimal;
 import java.util.Formatter;
 import java.util.Locale;
-import java.util.Timer;
-import java.util.TimerTask;
 
 public class TestPlayerActivity extends AppCompatActivity implements IVideoPlayer {
 
     //页面组件对象
-    private HCPlayer hcPlayer;
+    private HCGsyVideoPlayer hcPlayer;
     private ProgressBar loadingBar;
     private LinearLayout bottomContainer;
     private SeekBar videoProgressBar;
@@ -66,8 +61,8 @@ public class TestPlayerActivity extends AppCompatActivity implements IVideoPlaye
         loadingBar.setMax(100);
         loadingBar.setProgress(0);
 
-        hcPlayer.setIVideoPlayerListener(this);
-        hcPlayer.play(testUrl);
+        hcPlayer.setVideoPlayerListener(this);
+        hcPlayer.play(testUrl,"","");
 
 
     }
@@ -209,7 +204,7 @@ public class TestPlayerActivity extends AppCompatActivity implements IVideoPlaye
                 .setNegativeButton("重播", new DialogInterface.OnClickListener() {
             @Override
             public void onClick(DialogInterface dialog, int which) {
-                hcPlayer.play(testUrl);
+                hcPlayer.play(testUrl,"","");
             }
         }).setPositiveButton("退出", new DialogInterface.OnClickListener() {
             @Override

+ 0 - 228
app/src/main/java/com/haochuan/hciptvbasic/video/HCPlayer.java

@@ -1,228 +0,0 @@
-package com.haochuan.hciptvbasic.video;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.haochuan.hciptvbasic.R;
-import com.haochuan.hciptvbasic.Util.Logger;
-
-import static com.haochuan.hciptvbasic.Util.MessageCode.PLAYER_OBJ_NULL;
-import static com.haochuan.hciptvbasic.Util.MessageCode.SUCCESS;
-
-public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
-
-    private HCGsyVideoPlayer mHcGsyVideoPlayer;
-
-    private IVideoPlayer iVideoPlayerListener;
-
-    public HCPlayer(@NonNull Context context) {
-        super(context);
-        init(context);
-    }
-
-    public HCPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
-        super(context, attrs);
-        init(context);
-    }
-
-    public HCPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        init(context);
-    }
-
-
-    /**--------------------------功能性函数------------------------*/
-
-    /*
-    * 视频VIEW初始化
-    * */
-    private void init(Context context){
-        View.inflate(context, R.layout.player_hc,this);
-        mHcGsyVideoPlayer = findViewById(R.id.hc_gsy_player);
-        mHcGsyVideoPlayer.setVideoPlayerListener(this);
-    }
-
-    public void setIVideoPlayerListener(IVideoPlayer listener){
-        this.iVideoPlayerListener = listener;
-    }
-
-    /*--------------------------播放器通用事件接口-----------------------------*/
-    @Override
-    public void onPreparing() {
-        if(iVideoPlayerListener != null){
-            iVideoPlayerListener.onPreparing();
-        }else{
-            Logger.e("HCPlayer 未设置监听接口");
-        }
-    }
-
-    @Override
-    public void onPlaying() {
-        if(iVideoPlayerListener != null){
-            iVideoPlayerListener.onPlaying();
-        }else{
-            Logger.e("HCPlayer 未设置监听接口");
-        }
-    }
-
-    @Override
-    public void onResume() {
-        resume();
-    }
-
-    @Override
-    public void onPause() {
-        if(iVideoPlayerListener != null){
-            iVideoPlayerListener.onPause();
-        }else{
-            Logger.e("HCPlayer 未设置监听接口");
-        }
-    }
-
-
-    @Override
-    public void onDestroy() {
-        release();
-    }
-
-    @Override
-    public void onPlayingBuffering() {
-        if(iVideoPlayerListener != null){
-            iVideoPlayerListener.onPlayingBuffering();
-        }else{
-            Logger.e("HCPlayer 未设置监听接口");
-        }
-    }
-
-    @Override
-    public void onCompletion() {
-        if(iVideoPlayerListener != null){
-            iVideoPlayerListener.onCompletion();
-        }else{
-            Logger.e("HCPlayer 未设置监听接口");
-        }
-    }
-
-
-    @Override
-    public void onError(int what, int extra) {
-        if(iVideoPlayerListener != null){
-            iVideoPlayerListener.onError(what,extra);
-        }else{
-            Logger.e("HCPlayer 未设置监听接口");
-        }
-    }
-
-    /*------------------------通用操作接口-------------------------*/
-    @Override
-    public void play(String url) {
-        mHcGsyVideoPlayer.play(url);
-    }
-
-    @Override
-    public void setStartTime(int time){mHcGsyVideoPlayer.setStartTime(time);}
-
-    @Override
-    public void resume() {
-        if(mHcGsyVideoPlayer != null){
-            mHcGsyVideoPlayer.resume();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t resume");
-        }
-    }
-
-    @Override
-    public void pause() {
-        if(mHcGsyVideoPlayer != null){
-            mHcGsyVideoPlayer.pause();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t pause");
-        }
-    }
-
-    @Override
-    public void seek(int position) {
-        if(mHcGsyVideoPlayer != null){
-            mHcGsyVideoPlayer.seek(position);
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t seek");
-        }
-    }
-
-    @Override
-    public void release() {
-        if(mHcGsyVideoPlayer != null){
-            mHcGsyVideoPlayer.release();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t release");
-        }
-    }
-
-    @Override
-    public boolean isPlaying() {
-        if(mHcGsyVideoPlayer != null){
-            return mHcGsyVideoPlayer.isPlaying();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t get isPlaying state");
-            return false;
-        }
-    }
-
-    @Override
-    public boolean isPrePared() {
-        if(mHcGsyVideoPlayer != null){
-            return mHcGsyVideoPlayer.isPrePared();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t get prepared state");
-            return false;
-        }
-    }
-
-    @Override
-    public int getDuration() {
-        if(mHcGsyVideoPlayer != null){
-            return mHcGsyVideoPlayer.getDuration();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t get duration");
-            return 0;
-        }
-    }
-
-    @Override
-    public int getCurrentPlayPosition() {
-        if(mHcGsyVideoPlayer != null){
-            return mHcGsyVideoPlayer.getCurrentPlayPosition();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t get current play position");
-            return 0;
-        }
-    }
-
-    @Override
-    public int getCurrentStatus() {
-        if(mHcGsyVideoPlayer != null){
-            return mHcGsyVideoPlayer.getCurrentStatus();
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t get current status");
-            return 0;
-        }
-    }
-
-    public int setSpeed(@NonNull float speed){
-        mHcGsyVideoPlayer.setSpeed(speed);
-        if(mHcGsyVideoPlayer != null){
-            mHcGsyVideoPlayer.setSpeed(speed);
-            return SUCCESS;
-        }else{
-            Logger.w("mHcGsyVideoPlayer is null,can`t get current status");
-            return PLAYER_OBJ_NULL;
-        }
-    }
-
-
-
-}

+ 0 - 2
app/src/main/java/com/haochuan/hciptvbasic/webview/HCWebChromeClient.java

@@ -4,8 +4,6 @@ import android.util.Log;
 import android.webkit.ConsoleMessage;
 import android.webkit.WebChromeClient;
 
-import com.haochuan.hciptvbasic.Util.Logger;
-
 
 public class HCWebChromeClient extends WebChromeClient {
 

+ 2 - 2
app/src/main/java/com/haochuan/hciptvbasic/webview/PayToJS.java

@@ -4,8 +4,8 @@ import android.content.Context;
 import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 
-import com.haochuan.hciptvbasic.Util.JsUtil;
-import com.haochuan.hciptvbasic.Util.Logger;
+import com.haochuan.core.Logger;
+import com.haochuan.core.util.JsUtil;
 
 public class PayToJS {
     private Context context;                        //MainActivity 句柄

+ 69 - 64
app/src/main/java/com/haochuan/hciptvbasic/webview/PlayerToJS.java

@@ -4,7 +4,6 @@ import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
 import android.app.Activity;
 import android.content.Context;
-import android.content.Intent;
 import android.text.TextUtils;
 import android.view.ViewGroup;
 import android.view.animation.LinearInterpolator;
@@ -12,22 +11,21 @@ import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 import android.widget.FrameLayout;
 
-import com.haochuan.hciptvbasic.Util.JSONUtil;
-import com.haochuan.hciptvbasic.Util.JsUtil;
-import com.haochuan.hciptvbasic.Util.Logger;
-import com.haochuan.hciptvbasic.Util.MathUtil;
-import com.haochuan.hciptvbasic.Util.MessageCode;
-import com.haochuan.hciptvbasic.Util.RegexUtil;
-import com.haochuan.hciptvbasic.Util.ScreenSnap;
-import com.haochuan.hciptvbasic.video.BaseMediaPlayer;
+import com.haochuan.core.BaseMediaPlayer;
+import com.haochuan.core.Logger;
+import com.haochuan.core.util.JSONUtil;
+import com.haochuan.core.util.JsUtil;
+import com.haochuan.core.util.MathUtil;
+import com.haochuan.core.util.RegexUtil;
+import com.haochuan.core.util.ScreenSnap;
 
 import org.json.JSONObject;
 
-import static com.haochuan.hciptvbasic.Util.MessageCode.EXCEPTION_ERROR;
-import static com.haochuan.hciptvbasic.Util.MessageCode.PARAM_ERROR;
-import static com.haochuan.hciptvbasic.Util.MessageCode.PLAYER_NO_INIT;
-import static com.haochuan.hciptvbasic.Util.MessageCode.PLAYER_OBJ_NULL;
-import static com.haochuan.hciptvbasic.Util.MessageCode.SUCCESS;
+import static com.haochuan.core.util.MessageCode.EXCEPTION_ERROR;
+import static com.haochuan.core.util.MessageCode.PARAM_ERROR;
+import static com.haochuan.core.util.MessageCode.PLAYER_NO_INIT;
+import static com.haochuan.core.util.MessageCode.PLAYER_OBJ_NULL;
+import static com.haochuan.core.util.MessageCode.SUCCESS;
 
 
 public class PlayerToJS {
@@ -37,13 +35,8 @@ public class PlayerToJS {
 
 
     /*--------------------传给前端的播放器事件--------------------------*/
-    private String JS_EVENT_PREPARING = "javascript:onPlayerPreparing()";
-    private String JS_EVENT_PLAYING = "javascript:onPlayerPlaying()";
-    private String JS_EVENT_RESUME = "javascript:onPlayerResume()";
-    private String JS_EVENT_PAUSE = "javascript:onPlayerPause()";
-    private String JS_EVENT_PLAYINGBUFFER = "javascript:onPlayingBuffer()";
-    private String JS_EVENT_COMPLETE = "javascript:onPlayerComplete()";
     private String JS_EVENT_PLAYERROR="javascript:onPlayerError(%s,%s)";
+    private String JS_PLAYER_STATUS = "javascript:onPlayerStatus(%s)";
 
 
     public PlayerToJS(Context context, WebView webView, BaseMediaPlayer mediaPlayer) {
@@ -59,14 +52,14 @@ public class PlayerToJS {
      * 播放器准备事件
      * */
     public void onPlayerPreparing(){
-        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PREPARING);
+        executePlayStatusEvent(1);
     }
 
     /*
      * 播放器开始播放事件
      * */
     public void onPlayerPlaying(){
-        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PLAYING);
+        executePlayStatusEvent(2);
     }
 
     /*
@@ -74,7 +67,7 @@ public class PlayerToJS {
      * */
     public void onPlayerResume(){
         Logger.d("onPlayerResume");
-        JsUtil.evaluateJavascript(context,webView,JS_EVENT_RESUME);
+        executePlayStatusEvent(4);
     }
 
     /*
@@ -82,17 +75,15 @@ public class PlayerToJS {
      * */
     public void onPlayerPause(){
         Logger.d("onPlayerPause");
-        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PAUSE);
+        executePlayStatusEvent(3);
     }
 
-
-
     /*
      * 播放器缓冲事件
      * */
     public void onPlayingBuffer(){
         Logger.d("onPlayerBuffer");
-        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PLAYINGBUFFER);
+        executePlayStatusEvent(5);
     }
 
     /*
@@ -100,7 +91,7 @@ public class PlayerToJS {
      * */
     public void onPlayerComplete(){
         Logger.d("onPlayerComplete");
-        JsUtil.evaluateJavascript(context,webView,JS_EVENT_COMPLETE);
+        executePlayStatusEvent(6);
     }
 
     /*
@@ -159,7 +150,9 @@ public class PlayerToJS {
             String y = JSONUtil.getString(playParam,"y","0");
             String width = JSONUtil.getString(playParam,"width","1280");
             String height = JSONUtil.getString(playParam,"height","720");
-            return videoPlay(url,seekTime,x,y,width,height);
+            String examineId = JSONUtil.getString(playParam,"examine_id","");
+            String examineType = JSONUtil.getString(playParam,"examine_type","program");
+            return videoPlay(url,seekTime,x,y,width,height,examineId,examineType);
         }catch (Exception e){
             e.printStackTrace();
             Logger.e(EXCEPTION_ERROR,"异常抛出:" + e.getMessage());
@@ -306,6 +299,7 @@ public class PlayerToJS {
         return baseMediaPlayer.getCurrentPlayPosition();
     }
 
+
     /**-------------------------------------------功能函数-----------------------------------------------*/
 
     /*
@@ -316,46 +310,53 @@ public class PlayerToJS {
     * @param height             播放器高度
     * @param seekTime           播放初始位置,单位 s
     * */
-    private int videoPlay(String url,String seekTime, String x,String y,String width, String height){
-        if(baseMediaPlayer == null){
-            Logger.e(PLAYER_OBJ_NULL,"播放器对象为空,不能播放");
-            return PLAYER_OBJ_NULL;
-        }
-        if(!RegexUtil.isUrl(url)){
-            Logger.e(PARAM_ERROR,"调用play函数,url格式不正确,不能执行播放,请检查;url:" + url);
-            return PARAM_ERROR;
-        }
-        if(MathUtil.isDigitsOnly(x) && MathUtil.isDigitsOnly(y) && MathUtil.isDigitsOnly(width) && MathUtil.isDigitsOnly(height) && MathUtil.isDigitsOnly(seekTime)){
-            int screenWidth = ScreenSnap.getScreenWidth(context);
-            int screenHeight = ScreenSnap.getScreenHeight(context);
-            int transformX = (int) (Float.parseFloat(x) * screenWidth / 1280);
-            int transformY = (int) (Float.parseFloat(y) * screenHeight / 720);
-            int transformWidth = (int) (Float.parseFloat(width) * screenWidth / 1280);
-            int transformHeight = (int) (Float.parseFloat(height) * screenHeight / 720);
-
-            int transformSeekTime = Integer.parseInt(seekTime);
-            if(transformSeekTime < 0){
-                transformSeekTime = 0;
-            }else{
-                transformSeekTime *= 1000;
+    private int videoPlay(String url,String seekTime, String x,String y,String width, String height,
+                          String examineId,String examineType){
+        try{
+            if(baseMediaPlayer == null){
+                Logger.e(PLAYER_OBJ_NULL,"播放器对象为空,不能播放");
+                return PLAYER_OBJ_NULL;
             }
-            final int realSeekTime = transformSeekTime;
+            if(!RegexUtil.isUrl(url)){
+                Logger.e(PARAM_ERROR,"调用play函数,url格式不正确,不能执行播放,请检查;url:" + url);
+                return PARAM_ERROR;
+            }
+            if(MathUtil.isDigitsOnly(x) && MathUtil.isDigitsOnly(y) && MathUtil.isDigitsOnly(width) && MathUtil.isDigitsOnly(height) && MathUtil.isDigitsOnly(seekTime)){
+                int screenWidth = ScreenSnap.getScreenWidth(context);
+                int screenHeight = ScreenSnap.getScreenHeight(context);
+                int transformX = (int) (Float.parseFloat(x) * screenWidth / 1280);
+                int transformY = (int) (Float.parseFloat(y) * screenHeight / 720);
+                int transformWidth = (int) (Float.parseFloat(width) * screenWidth / 1280);
+                int transformHeight = (int) (Float.parseFloat(height) * screenHeight / 720);
+
+                int transformSeekTime = Integer.parseInt(seekTime);
+                if(transformSeekTime < 0){
+                    transformSeekTime = 0;
+                }else{
+                    transformSeekTime *= 1000;
+                }
+                final int realSeekTime = transformSeekTime;
 
-            Logger.d(String.format("调用播放函数。转换坐标(%s, %s),宽高(%s, %s)", transformX, transformY, transformWidth, transformHeight));
+                Logger.d(String.format("调用播放函数。转换坐标(%s, %s),宽高(%s, %s)", transformX, transformY, transformWidth, transformHeight));
 
-            Activity activity = (Activity)context;
-            activity.runOnUiThread(()->{
-                initVideoParamsIfNoInit(baseMediaPlayer,transformX, transformY, transformWidth, transformHeight);
-                baseMediaPlayer.play(url);
-                baseMediaPlayer.setStartTime(realSeekTime);
-                webView.requestFocus();
-            });
-            return SUCCESS;
-        }else{
-            Logger.e(PARAM_ERROR,String.format("请正确传递play函数参数:x:%s;y:%s;width:%s;height:%s;seekTime:%s",
-                    x,y,width,height,seekTime));
+                Activity activity = (Activity)context;
+                activity.runOnUiThread(()->{
+                    initVideoParamsIfNoInit(baseMediaPlayer,transformX, transformY, transformWidth, transformHeight);
+                    baseMediaPlayer.play(url,examineId,examineType);
+                    baseMediaPlayer.setStartTime(realSeekTime);
+                    webView.requestFocus();
+                });
+                return SUCCESS;
+            }else{
+                Logger.e(PARAM_ERROR,String.format("请正确传递play函数参数:x:%s;y:%s;width:%s;height:%s;seekTime:%s",
+                        x,y,width,height,seekTime));
+                return PARAM_ERROR;
+            }
+        }catch (Exception e){
+            e.printStackTrace();
             return EXCEPTION_ERROR;
         }
+
     }
 
 
@@ -477,4 +478,8 @@ public class PlayerToJS {
             e.printStackTrace();
         }
     }
+
+    private void executePlayStatusEvent(int status){
+        JsUtil.evaluateJavascript(context,webView,String.format(JS_PLAYER_STATUS,status));
+    }
 }

+ 19 - 17
app/src/main/java/com/haochuan/hciptvbasic/webview/UtilToJS.java

@@ -6,24 +6,20 @@ import android.text.TextUtils;
 import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 
+import com.haochuan.core.Logger;
+import com.haochuan.core.util.HandlerUtil;
+import com.haochuan.hciptvbasic.BaseWebActivity;
 import com.haochuan.hciptvbasic.BuildConfig;
-import com.haochuan.hciptvbasic.Util.DownloadUtils;
-import com.haochuan.hciptvbasic.Util.JSONUtil;
-import com.haochuan.hciptvbasic.Util.JsUtil;
-import com.haochuan.hciptvbasic.Util.Logger;
-import com.haochuan.hciptvbasic.Util.MacUtil;
-import com.haochuan.hciptvbasic.Util.MathUtil;
-import com.haochuan.hciptvbasic.Util.Md5Util;
-import com.haochuan.hciptvbasic.Util.ToolsUtil;
+import com.haochuan.core.util.JSONUtil;
+import com.haochuan.core.util.JsUtil;
+import com.haochuan.core.util.MacUtil;
+import com.haochuan.core.util.MathUtil;
+import com.haochuan.core.util.ToolsUtil;
 
 import org.json.JSONObject;
-import org.w3c.dom.Text;
 
-import java.io.File;
-
-import static com.haochuan.hciptvbasic.Util.MessageCode.EXCEPTION_ERROR;
-import static com.haochuan.hciptvbasic.Util.MessageCode.PARAM_ERROR;
-import static com.haochuan.hciptvbasic.Util.MessageCode.SUCCESS;
+import static com.haochuan.core.util.MessageCode.EXCEPTION_ERROR;
+import static com.haochuan.core.util.MessageCode.SUCCESS;
 
 
 public class UtilToJS {
@@ -97,9 +93,15 @@ public class UtilToJS {
     @JavascriptInterface
     public int appExit(){
         try{
-            ((Activity) context).runOnUiThread(() -> {
-                android.os.Process.killProcess(android.os.Process.myPid());   //获取PID
-                System.exit(0);
+            HandlerUtil.runOnUiThread(() -> {
+               Activity activity =(Activity)context;
+               if(activity instanceof BaseWebActivity){
+                   BaseWebActivity baseWebActivity = (BaseWebActivity)activity;
+                   baseWebActivity.AppExit();
+               }else{
+                   android.os.Process.killProcess(android.os.Process.myPid());   //获取PID
+                   System.exit(0);
+               }
             });
             return SUCCESS;
         }catch (Exception e){

+ 9 - 0
app/src/main/res/drawable/bg_ad_time.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <corners android:radius="8dp" />
+    <solid android:color="#ffffff" />
+    <stroke
+        android:width="1dp"
+        android:color="#625987" />
+</shape>

+ 7 - 0
app/src/main/res/layout/activity_test.xml

@@ -61,6 +61,13 @@
             android:layout_marginTop="8dp"
             android:text="退出"
             android:id="@+id/exit_btn"/>
+        <Button
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_marginTop="8dp"
+            android:text="退出app"
+            android:id="@+id/exit_app"/>
     </LinearLayout>
 
 </FrameLayout>

+ 0 - 9
app/src/main/res/layout/player_hc.xml

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical" android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <com.haochuan.hciptvbasic.video.HCGsyVideoPlayer
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:id="@+id/hc_gsy_player"/>
-</FrameLayout>

+ 34 - 0
build.gradle

@@ -12,6 +12,40 @@ buildscript {
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
     }
+
+    ext.versions = [
+            'minSdk'                : 19,
+            'targetSdk'             : 28,
+            'compileSdk'            : 28,
+            'Java'                  : JavaVersion.VERSION_1_8,
+            'supportLibrary'        : '28.0.0',
+            'versionCode'           : 1,
+            'versionName'           : "1.0.1"
+    ]
+
+    // 引用的lib
+    ext.lib = [
+            /**  常备底层库*/
+            support                      : [
+                    v7          : "com.android.support:appcompat-v7:${versions.supportLibrary}",
+                    constraint_layout  : 'com.android.support.constraint:constraint-layout:1.1.3',
+                    appcompat   : 'androidx.appcompat:appcompat:1.0.2',
+                    constraintlayout : 'androidx.constraintlayout:constraintlayout:1.1.3',
+            ],
+            test                         : [
+                    junit   : 'junit:junit:4.12',
+                    runner  : 'com.android.support.test:runner:1.0.2',
+                    espresso: 'com.android.support.test.espresso:espresso-core:3.0.2',
+                    test_runner  : 'androidx.test.runner.AndroidJUnitRunner',
+            ],
+
+            //其他依赖组件
+            dependency_library            :[
+                    nohttp  : 'com.yanzhenjie.nohttp:nohttp:1.1.11',
+                    GSYVideoPlayer  : 'com.shuyu:GSYVideoPlayer:7.0.2',
+            ],
+    ]
+
 }
 
 allprojects {

+ 1 - 0
core/.gitignore

@@ -0,0 +1 @@
+/build

+ 42 - 0
core/build.gradle

@@ -0,0 +1,42 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion versions.compileSdk
+    defaultConfig {
+        minSdkVersion versions.minSdk
+        targetSdkVersion versions.targetSdk
+        versionCode versions.versionCode
+        versionName versions.versionName
+        testInstrumentationRunner lib.test.test_runner
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            buildConfigField "Boolean", "isDebug", "false"     //app全局是否调试,发布版本不要开启
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+
+        debug {
+            minifyEnabled false
+            buildConfigField "Boolean", "isDebug", "true"     //app全局是否调试,调试版本开启
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    compileOptions {
+        sourceCompatibility versions.Java
+        targetCompatibility versions.Java
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+    implementation lib.support.appcompat
+    testImplementation lib.test.junit
+    androidTestImplementation lib.test.runner
+    androidTestImplementation lib.test.espresso
+    implementation lib.dependency_library.nohttp
+}

+ 21 - 0
core/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 27 - 0
core/src/androidTest/java/com/haochuan/core/ExampleInstrumentedTest.java

@@ -0,0 +1,27 @@
+package com.haochuan.core;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.haochuan.core", appContext.getPackageName());
+    }
+}

+ 11 - 0
core/src/main/AndroidManifest.xml

@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.haochuan.core">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme" />
+</manifest>

+ 15 - 7
app/src/main/java/com/haochuan/hciptvbasic/video/BaseMediaPlayer.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.video;
+package com.haochuan.core;
 
 import android.content.Context;
 import android.util.AttributeSet;
@@ -23,11 +23,13 @@ public abstract class BaseMediaPlayer extends FrameLayout {
     }
 
     /*---------------------------操作函数------------------------*/
+
+
     /*
-    * 播放视频
-    *@param url
-    * */
-    public abstract void play(String url);
+     * 播放视频
+     *@param jsonParam
+     * */
+    public abstract void play(String url,String examineId,String examineType);
 
 
     /*
@@ -57,8 +59,8 @@ public abstract class BaseMediaPlayer extends FrameLayout {
 
 
     /*
-    * 资源释放
-    * */
+     * 资源释放
+     * */
     public abstract void release();
 
     /*---------------------------获取播放器状态和参数函数------------------------*/
@@ -93,4 +95,10 @@ public abstract class BaseMediaPlayer extends FrameLayout {
      * */
     public abstract int getCurrentStatus();
 
+    /*
+    * 设置事件监听
+    * */
+    public  abstract void setVideoPlayerListener(@NonNull IVideoPlayer iVideoPlayer);
+
 }
+

+ 3 - 1
app/src/main/java/com/haochuan/hciptvbasic/video/IVideoPlayer.java

@@ -1,6 +1,7 @@
-package com.haochuan.hciptvbasic.video;
+package com.haochuan.core;
 
 public interface IVideoPlayer {
+    /*---------------事件接口----------------*/
     void onPreparing();
 
     void onPlaying();
@@ -16,4 +17,5 @@ public interface IVideoPlayer {
     void onCompletion();
 
     void onError(int what, int extra);
+
 }

+ 30 - 9
app/src/main/java/com/haochuan/hciptvbasic/Util/Logger.java

@@ -1,20 +1,21 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core;
 
+import android.app.Activity;
 import android.content.Context;
+import android.os.Build;
 import android.util.Log;
+import android.webkit.WebView;
 
 import androidx.annotation.NonNull;
 
-import com.haochuan.hciptvbasic.BaseWebActivity;
-import com.haochuan.hciptvbasic.BuildConfig;
-import com.haochuan.hciptvbasic.MainActivity;
-
 public class Logger {
     private static String TAG = "HcIPTV";
     private static Context context;
+    private static WebView webView;
 
-    public static void init(Context appContext){
+    public static void init(Context appContext,WebView mWebView){
         context = appContext;
+        webView = mWebView;
     }
 
     public static void d(@NonNull String message){
@@ -52,9 +53,29 @@ public class Logger {
 
     private static void messageToJs(@NonNull String message){
         //将日志传给MainActivity,然后传给js
-        if(context instanceof MainActivity){
-            BaseWebActivity baseWebActivity = (BaseWebActivity) context;
-            baseWebActivity.loggerToJs(message);
+
+    }
+
+
+    public static void evaluateJavascript(String script) {
+        if(context == null){
+            Log.e(TAG,"context is null,can`t execute evaluateJavascript");
+            return;
+        }
+        if(webView == null){
+            Log.e(TAG,"webView is null,can`t execute evaluateJavascript");
+            return;
+        }
+        Activity activity = (Activity)context;
+        if (webView == null) {
+            return;
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            activity.runOnUiThread(()-> webView.evaluateJavascript(script, value -> {
+                //此处为 js 返回的结果
+            }));
+        } else {
+            activity.runOnUiThread(()-> webView.loadUrl(script));
         }
     }
 

+ 122 - 0
core/src/main/java/com/haochuan/core/util/DownloadServer.java

@@ -0,0 +1,122 @@
+package com.haochuan.core.util;
+
+import android.content.Context;
+
+import com.yanzhenjie.nohttp.Headers;
+import com.yanzhenjie.nohttp.InitializationConfig;
+import com.yanzhenjie.nohttp.NoHttp;
+import com.yanzhenjie.nohttp.RequestMethod;
+import com.yanzhenjie.nohttp.URLConnectionNetworkExecutor;
+import com.yanzhenjie.nohttp.cache.DBCacheStore;
+import com.yanzhenjie.nohttp.cookie.DBCookieStore;
+import com.yanzhenjie.nohttp.download.DownloadListener;
+import com.yanzhenjie.nohttp.download.DownloadQueue;
+import com.yanzhenjie.nohttp.download.DownloadRequest;
+
+/**
+ * @author jewel
+ * @email jewelbao88@gmail.com
+ * @gitsite https://github.com/jewelbao
+ * @since 2019/1/10
+ */
+public class DownloadServer {
+
+    private static DownloadServer instance;
+    private static DownloadRequest downloadRequest;
+
+    public static DownloadServer getInstance() {
+        if (instance == null) {
+            synchronized (DownloadServer.class) {
+                if (instance == null) {
+                    instance = new DownloadServer();
+                }
+            }
+        }
+        return instance;
+    }
+
+    public void initHttp(Context context){
+        InitializationConfig config = InitializationConfig.newBuilder(context)
+                // 全局连接服务器超时时间,单位毫秒,默认10s。
+                .connectionTimeout(60 * 1000)
+                // 全局等待服务器响应超时时间,单位毫秒,默认10s。
+                .readTimeout(60 * 1000)
+                // 配置缓存,默认保存数据库DBCacheStore,保存到SD卡使用DiskCacheStore。
+                .cacheStore(
+                        // 如果不使用缓存,setEnable(false)禁用。
+                        new DBCacheStore(context).setEnable(true)
+                )
+                // 配置Cookie,默认保存数据库DBCookieStore,开发者可以自己实现CookieStore接口。
+                .cookieStore(
+                        // 如果不维护cookie,setEnable(false)禁用。
+                        new DBCookieStore(context).setEnable(true)
+                )
+                // 配置网络层,默认URLConnectionNetworkExecutor,如果想用OkHttp:OkHttpNetworkExecutor。
+                .networkExecutor(new URLConnectionNetworkExecutor())
+                // 全局重试次数,配置后每个请求失败都会重试x次。
+                .retry(2)
+                .build();
+        NoHttp.initialize(config);
+    }
+
+    private DownloadQueue mDownloadQueue;
+
+    private DownloadServer() {
+        mDownloadQueue = NoHttp.newDownloadQueue();
+    }
+
+    public void download(int what, DownloadRequest mRequest, DownloadListener mListener) {
+        mDownloadQueue.add(what, mRequest, mListener);
+    }
+
+    public void download(Context context, String downloadUrl, String fileFolder, String fileName, DownloadServerListener listener){
+        downloadRequest = new DownloadRequest(downloadUrl, RequestMethod.GET, fileFolder,
+                fileName, true, true);
+        downloadRequest.setCancelSign(context);
+        download(100, downloadRequest, new DownloadListener() {
+            @Override
+            public void onDownloadError(int what, Exception exception) {
+                listener.onError(what,exception);
+                downloadRequest = null;
+            }
+
+            @Override
+            public void onStart(int what, boolean isResume, long rangeSize, Headers responseHeaders, long allCount) {
+
+            }
+
+            @Override
+            public void onProgress(int what, int progress, long fileCount, long speed) {
+
+            }
+
+            @Override
+            public void onFinish(int what, String filePath) {
+                listener.onFinish(filePath);
+                downloadRequest = null;
+            }
+
+            @Override
+            public void onCancel(int what) {
+
+            }
+        });
+    }
+
+
+
+
+
+    public void cancelBySign(Object sign) {
+        mDownloadQueue.cancelBySign(sign);
+    }
+
+    public void cancelAll() {
+        mDownloadQueue.cancelAll();
+    }
+
+    public interface DownloadServerListener{
+        public void onFinish(String filePath);
+        public void onError(int what, Exception exception);
+    }
+}

+ 117 - 0
core/src/main/java/com/haochuan/core/util/FileUtil.java

@@ -0,0 +1,117 @@
+package com.haochuan.core.util;
+
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+public final class FileUtil {
+    /**
+     * Create a file, if the directory of the file does not exist, create a superior directory
+     *
+     * @param filePath file path
+     * @return Returning true indicates that the file was created successfully or already exists.
+     */
+    private static String TAG = "FileUtil";
+    public static boolean createFile(String filePath) {
+        File file = new File(filePath);
+        if (!file.exists()) {
+            if (!file.getParentFile().exists()) {
+                boolean mkDirsResult = makeDirs(file.getParent());
+                if (!mkDirsResult) {
+                    Log.d(TAG, "create File[" + filePath + "] fail because it's parent dir created failed");
+                    return false;
+                }
+            }
+            try {
+                boolean createFileResult = file.createNewFile();
+                Log.d(TAG, "create File[" + filePath + "] result " + createFileResult);
+                return createFileResult;
+            } catch (IOException e) {
+                Log.e(TAG, "create File[" + filePath + "]cause exception : " + e.getLocalizedMessage());
+                e.printStackTrace();
+                return false;
+            }
+        } else {
+            Log.d(TAG, "File[" + filePath + "] had exists!");
+            return true;
+        }
+    }
+
+    /**
+     * Create a directory, if the directory has a parent directory, create the same
+     *
+     * @param dirPath Directory path
+     * @return Return true to create a successful one.
+     */
+    public static boolean makeDirs(String dirPath) {
+        File folder = new File(dirPath);
+        if (!folder.exists()) {
+            boolean mkDirsResult = folder.mkdirs();
+            Log.d(TAG, "makeDirs[" + dirPath + "] result " + mkDirsResult);
+            return mkDirsResult;
+        }
+        Log.d(TAG, "Dirs[" + dirPath + "] had exists!");
+        return true;
+    }
+
+    /**
+     * Delete the file, if the file is a directory and there is a subordinate directory or file, the deletion will fail
+     *
+     * @param filePath file path
+     * @return Returning true indicates that the file was deleted successfully or the file does not exist.
+     */
+    public static boolean delete(String filePath) {
+        File file = new File(filePath);
+        if (file.exists()) {
+            boolean deleteFileResult = file.delete();
+            Log.d(TAG, "deleted File[" + filePath + "] result " + deleteFileResult);
+            return deleteFileResult;
+        }
+        Log.d(TAG, "File[" + filePath + "] is not exists");
+        return true;
+    }
+
+
+    /**
+     * Be cautious! Force the file to be deleted. If the file is a directory and there is a subordinate directory or file, it will be deleted together.
+     *
+     * @param filePath file path
+     * @return Return true to indicate that the file or all files in the file directory are deleted successfully.
+     */
+    public static boolean deleteForce(String filePath) {
+        File file = new File(filePath);
+        if (file.exists()) {
+            File[] childFiles = file.listFiles();
+            if (childFiles == null || childFiles.length == 0) {
+                boolean deleteDirsResult = file.delete();
+                Log.d(TAG, "deleted file[" + filePath + "] result " + deleteDirsResult);
+                return deleteDirsResult;
+            }
+            for (File childFile : childFiles) {
+                deleteForce(childFile.getPath());
+            }
+            boolean deleteDirsResult = file.delete();
+            Log.d(TAG, "deleted file[" + filePath + "] result " + deleteDirsResult);
+            return deleteDirsResult;
+        }
+        Log.d(TAG, "file[" + filePath + "] is not exists");
+        return true;
+    }
+
+    /**
+     * Rename file
+     *
+     * @param filePath file path
+     * @param newName  New file name
+     * @return Returning true indicates that the file was named successfully.
+     */
+    public static boolean rename(String filePath, String newName) {
+        File file = new File(filePath);
+        File newFile = new File(file.getParent(), newName);
+        boolean renameFileResult = file.renameTo(newFile);
+        Log.d(TAG, "rename File[" + filePath + "] result " + renameFileResult);
+        Log.d(TAG, "newFile Name[" + file.getName() + "] ");
+        return renameFileResult;
+    }
+}

+ 47 - 0
core/src/main/java/com/haochuan/core/util/HandlerUtil.java

@@ -0,0 +1,47 @@
+package com.haochuan.core.util;
+
+import android.os.Handler;
+import android.os.Looper;
+
+public class HandlerUtil {
+    private static final Handler HANDLER = new Handler(Looper.getMainLooper());
+
+    /**
+     * Causes the Runnable to be added to the message queue. The runnable will be run on the thread to which this handler is attached
+     *
+     * @return Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting
+     */
+    public static boolean runOnUiThread(Runnable runnable) {
+        return HANDLER.post(runnable);
+    }
+
+    /**
+     * Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. The runnable will be run on the thread to which this handler is attached.
+     *
+     * @return Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting. Note that a result of true does not mean the Runnable will be processed -- if the looper is quit before the delivery time of the message occurs then the message will be dropped.
+     */
+    public static boolean runOnUiThreadDelay(Runnable runnable, long delayMillis) {
+        return HANDLER.postDelayed(runnable, delayMillis);
+    }
+
+    /**
+     * Remove any pending posts of Runnable r that are in the message queue.
+     */
+    public static void removeRunable(Runnable runnable) {
+        HANDLER.removeCallbacks(runnable);
+    }
+
+    /**
+     * Remove any pending posts of messages with code 'what' that are in the message queue.
+     */
+    public static void removeMessages(int what) {
+        HANDLER.removeMessages(what);
+    }
+
+    /**
+     * Remove all callbacks and messages
+     */
+    public static void removeAll() {
+        HANDLER.removeCallbacksAndMessages(null);
+    }
+}

+ 24 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/JSONUtil.java

@@ -1,5 +1,6 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
+import org.json.JSONArray;
 import org.json.JSONObject;
 
 public class JSONUtil {
@@ -23,4 +24,26 @@ public class JSONUtil {
             return defaultValue;
         }
     }
+
+    //获取Json对象
+    public static JSONObject getJsonObject(JSONObject json,String key){
+        try{
+            return json.has(key)?json.getJSONObject(key):null;
+        }catch (Exception e){
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    //获取Json对象
+    public static JSONArray getJsonArray(JSONObject json, String key){
+        try{
+            return json.has(key)?json.getJSONArray(key):null;
+        }catch (Exception e){
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
 }

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/JsUtil.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import android.app.Activity;
 import android.content.Context;

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/Juge.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 public class Juge {
     //判断当前是不是纯IP地址

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/MacUtil.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import android.Manifest;
 import android.annotation.SuppressLint;

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/MathUtil.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import java.util.regex.Pattern;
 

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/Md5Util.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import java.io.File;
 import java.io.FileInputStream;

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/MessageCode.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 public class MessageCode {
     public final static int EXCEPTION_ERROR = -1;       //异常抛出

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/web/MyRequest.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.web;
+package com.haochuan.core.util;
 
 import com.yanzhenjie.nohttp.Headers;
 import com.yanzhenjie.nohttp.RequestMethod;

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/RegexUtil.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import java.util.regex.Pattern;
 

+ 1 - 1
app/src/main/java/com/haochuan/hciptvbasic/Util/ScreenSnap.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import android.content.Context;
 import android.graphics.Point;

+ 2 - 2
app/src/main/java/com/haochuan/hciptvbasic/Util/ToolsUtil.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.Util;
+package com.haochuan.core.util;
 
 import android.app.Activity;
 import android.content.Context;
@@ -10,7 +10,7 @@ import android.os.Bundle;
 import android.text.TextUtils;
 import android.util.Base64;
 
-import com.haochuan.hciptvbasic.web.MyRequest;
+import com.haochuan.core.Logger;
 import com.yanzhenjie.nohttp.NoHttp;
 import com.yanzhenjie.nohttp.RequestMethod;
 import com.yanzhenjie.nohttp.rest.OnResponseListener;

+ 6 - 0
core/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#008577</color>
+    <color name="colorPrimaryDark">#00574B</color>
+    <color name="colorAccent">#D81B60</color>
+</resources>

+ 3 - 0
core/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">core</string>
+</resources>

+ 17 - 0
core/src/test/java/com/haochuan/core/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.haochuan.core;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 1 - 0
gsyvideo/.gitignore

@@ -0,0 +1 @@
+/build

+ 42 - 0
gsyvideo/build.gradle

@@ -0,0 +1,42 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion versions.compileSdk
+    defaultConfig {
+        minSdkVersion versions.minSdk
+        targetSdkVersion versions.targetSdk
+        versionCode versions.versionCode
+        versionName versions.versionName
+        testInstrumentationRunner lib.test.test_runner
+    }
+
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+
+        debug {
+            minifyEnabled false
+            buildConfigField "Boolean", "isDebug", "true"     //app全局是否调试,调试版本开启
+        }
+    }
+
+    compileOptions {
+        sourceCompatibility versions.Java
+        targetCompatibility versions.Java
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+    implementation lib.support.appcompat
+    testImplementation lib.test.junit
+    androidTestImplementation lib.test.runner
+    androidTestImplementation lib.test.espresso
+    implementation lib.dependency_library.GSYVideoPlayer
+    implementation project(path: ':core')
+}

+ 21 - 0
gsyvideo/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 27 - 0
gsyvideo/src/androidTest/java/com/haochuan/gsyvideo/ExampleInstrumentedTest.java

@@ -0,0 +1,27 @@
+package com.haochuan.gsyvideo;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.haochuan.gsyvideo", appContext.getPackageName());
+    }
+}

+ 11 - 0
gsyvideo/src/main/AndroidManifest.xml

@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.haochuan.gsyvideo">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme" />
+</manifest>

+ 2 - 3
app/src/main/java/com/haochuan/hciptvbasic/video/EmptyControlVideoView.java

@@ -1,11 +1,11 @@
-package com.haochuan.hciptvbasic.video;
+package com.haochuan.gsyvideo;
 
 import android.content.Context;
 import android.util.AttributeSet;
 
 import androidx.annotation.NonNull;
 
-import com.haochuan.hciptvbasic.R;
+import com.haochuan.core.IVideoPlayer;
 import com.shuyu.gsyvideoplayer.utils.Debuger;
 import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
 
@@ -83,7 +83,6 @@ public class EmptyControlVideoView extends StandardGSYVideoPlayer {
             }else{
                 seekTo(startTime);
             }
-
         }
     }
 

+ 15 - 12
app/src/main/java/com/haochuan/hciptvbasic/video/HCGsyVideoPlayer.java

@@ -1,4 +1,4 @@
-package com.haochuan.hciptvbasic.video;
+package com.haochuan.gsyvideo;
 
 import android.content.Context;
 import android.util.AttributeSet;
@@ -7,10 +7,12 @@ import android.view.View;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.haochuan.hciptvbasic.R;
-import com.haochuan.hciptvbasic.Util.Logger;
+import com.haochuan.core.BaseMediaPlayer;
+import com.haochuan.core.IVideoPlayer;
+import com.haochuan.core.Logger;
 
-public class HCGsyVideoPlayer extends BaseMediaPlayer {
+
+public class HCGsyVideoPlayer extends BaseMediaPlayer{
 
     private EmptyControlVideoView mEmptyControlVideo;        //GSY播放器实例
 
@@ -30,6 +32,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
     }
 
 
+
     /*
     * 初始化
     * */
@@ -39,6 +42,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         mEmptyControlVideo.enableDebug();
     }
 
+    @Override
     public void setVideoPlayerListener(@NonNull IVideoPlayer iVideoPlayer){
         if(mEmptyControlVideo != null){
             mEmptyControlVideo.setVideoPlayerListener(iVideoPlayer);
@@ -50,7 +54,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
 
     /*----------------------------从父类继承 播放器功能函数----------------------------------*/
     @Override
-    public void play(@NonNull String url) {
+    public void play(String url,String examineId,String examineType) {
         mEmptyControlVideo.setUp(url,false,"");
         mEmptyControlVideo.startPlayLogic();
     }
@@ -91,17 +95,17 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         mEmptyControlVideo.setSpeed(speed);
     }
 
-    @Override
+
     public boolean isPlaying() {
         return mEmptyControlVideo.isPlaying();
     }
 
-    @Override
+
     public boolean isPrePared() {
         return mEmptyControlVideo.isPrePared();
     }
 
-    @Override
+
     public int getDuration() {
         if(isPrePared()){
             return mEmptyControlVideo.getDuration();
@@ -111,7 +115,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         }
     }
 
-    @Override
+
     public int getCurrentPlayPosition() {
         if(isPrePared()){
             return mEmptyControlVideo.getCurrentPositionWhenPlaying();
@@ -121,15 +125,14 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         }
     }
 
-    @Override
+
     public int getCurrentStatus() {
         return mEmptyControlVideo.getCurrentStatus();
     }
 
-    @Override
+
     public void release(){
         mEmptyControlVideo.release();
     }
 
-
 }

+ 1 - 1
app/src/main/res/layout/player_gsy_hc.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent" android:layout_height="match_parent">
-    <com.haochuan.hciptvbasic.video.EmptyControlVideoView
+    <com.haochuan.gsyvideo.EmptyControlVideoView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/empty_control_video"

+ 15 - 0
gsyvideo/src/main/res/layout/view_video_control_empty.xml

@@ -0,0 +1,15 @@
+<?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"
+    android:background="@android:color/black">
+
+    <FrameLayout
+        android:id="@+id/surface_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center">
+
+    </FrameLayout>
+
+</RelativeLayout>

+ 6 - 0
gsyvideo/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#008577</color>
+    <color name="colorPrimaryDark">#00574B</color>
+    <color name="colorAccent">#D81B60</color>
+</resources>

+ 3 - 0
gsyvideo/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">GsyVideo</string>
+</resources>

+ 17 - 0
gsyvideo/src/test/java/com/haochuan/gsyvideo/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.haochuan.gsyvideo;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 1 - 1
settings.gradle

@@ -1 +1 @@
-include ':app'
+include ':app', ':gsyvideo', ':core', ':weilai_video', ':systemvideo'

+ 1 - 0
systemvideo/.gitignore

@@ -0,0 +1 @@
+/build

+ 40 - 0
systemvideo/build.gradle

@@ -0,0 +1,40 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion versions.compileSdk
+    defaultConfig {
+        minSdkVersion versions.minSdk
+        targetSdkVersion versions.targetSdk
+        versionCode versions.versionCode
+        versionName versions.versionName
+        testInstrumentationRunner lib.test.test_runner
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+
+        debug {
+            minifyEnabled false
+            buildConfigField "Boolean", "isDebug", "true"     //app全局是否调试,调试版本开启
+        }
+    }
+
+    compileOptions {
+        sourceCompatibility versions.Java
+        targetCompatibility versions.Java
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+    implementation lib.support.appcompat
+    testImplementation lib.test.junit
+    androidTestImplementation lib.test.runner
+    androidTestImplementation lib.test.espresso
+    implementation project(path: ':core')
+}

+ 21 - 0
systemvideo/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 27 - 0
systemvideo/src/androidTest/java/com/haochuan/systemvideo/ExampleInstrumentedTest.java

@@ -0,0 +1,27 @@
+package com.haochuan.systemvideo;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.haochuan.systemvideo", appContext.getPackageName());
+    }
+}

+ 11 - 0
systemvideo/src/main/AndroidManifest.xml

@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.haochuan.systemvideo">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme" />
+</manifest>

+ 49 - 0
systemvideo/src/main/java/com/haochuan/systemvideo/ErrorMessage.java

@@ -0,0 +1,49 @@
+package com.haochuan.systemvideo;
+
+import android.media.MediaPlayer;
+
+public class ErrorMessage {
+
+    public static final int EXTRA_ERROR_IO = MediaPlayer.MEDIA_ERROR_IO;
+    public static final String MSG_ERROR_IO = "文件/网络连接异常。";
+
+    public static final int EXTRA_ERROR_MALFORMED = MediaPlayer.MEDIA_ERROR_MALFORMED;
+    public static final String MSG_ERROR_MALFORMED = "比特流不符合相关的编码标准或文件规范。";
+
+    public static final int EXTRA_ERROR_UNSUPPORTED = MediaPlayer.MEDIA_ERROR_UNSUPPORTED;
+    public static final String MSG_ERROR_UNSUPPORTED = "比特流符合相关的编码标准或文件规范,但媒体框架不支持该功能。";
+
+    public static final int EXTRA_ERROR_TIMED_OUT = MediaPlayer.MEDIA_ERROR_TIMED_OUT;
+    public static final String MSG_ERROR_TIMED_OUT = "有些操作需要很长时间才能完成,通常超过3-5秒。";
+
+    public static final int EXTRA_ERROR_SYSTEM = -2147483648; // - low-level system error.
+    public static final String MSG_ERROR_SYSTEM = "低级系统错误。";
+
+
+
+    public static final int WHAT_ERROR_UNKNOWN = MediaPlayer.MEDIA_ERROR_UNKNOWN;
+    public static final String MSG_ERROR_UNKNOWN = "未指定的媒体播放器错误。";
+
+    public static final int WHAT_ERROR_SERVER_DIED = MediaPlayer.MEDIA_ERROR_SERVER_DIED;
+    public static final String MSG_ERROR_SERVER_DIED = "媒体服务器已挂。应用程序必须释放MediaPlayer对象并实例化一个新对象。";
+
+
+    public static final int INFO_VIDEO_TRACK_LAGGING = MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING;
+    public static final String MSG_ERROR_VIDEO_TRACK_LAGGING = "视频对于解码器而言过于复杂:它无法足够快地解码帧。可能只有音频在这个阶段播放得很好。";
+
+    public static final int INFO_BAD_INTERLEAVING = MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING;
+    public static final String MSG_ERROR_BAD_INTERLEAVING = "错误的交织意味着媒体已经被不正确地交织或者根本不被交织,例如,所有的视频样本首先是所有的音频样本。视频正在播放,但可能会发生大量磁盘搜索。";
+
+    public static final int INFO_NOT_SEEKABLE = MediaPlayer.MEDIA_INFO_NOT_SEEKABLE;
+    public static final String MSG_ERROR_NOT_SEEKABLE = "无法搜索媒体(例如直播)。";
+
+    public static final int INFO_NOT_UNSUPPORTED_SUBTITLE = MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+    public static final String MSG_ERROR_UNSUPPORTED_SUBTITLE = "媒体框架不支持字幕轨道。";
+
+    public static final int INFO_NOT_SUBTITLE_TIMED_OUT = MediaPlayer.MEDIA_INFO_SUBTITLE_TIMED_OUT;
+    public static final String MSG_ERROR_SUBTITLE_TIMED_OUT = "阅读字幕轨道需要太长时间。";
+
+    public static final int INFO_NOT_NETWORK_BANDWIDTH = 703;// - bandwidth information is available (as extra kbps)
+    public static final String MSG_ERROR_NETWORK_BANDWIDTH = "- 带宽信息可用(额外kbps)";
+}
+

+ 170 - 0
systemvideo/src/main/java/com/haochuan/systemvideo/SystemVideoPlayer.java

@@ -0,0 +1,170 @@
+package com.haochuan.systemvideo;
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.VideoView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.haochuan.core.BaseMediaPlayer;
+import com.haochuan.core.IVideoPlayer;
+import com.haochuan.core.Logger;
+
+public class SystemVideoPlayer extends BaseMediaPlayer {
+
+    //全局参数
+    private VideoView videoView;   //系统播放器对象
+    private IVideoPlayer iVideoPlayer; //播放器事件监控
+    private MediaPlayer mediaPlayer;
+    private int playerStatus = 0;
+    protected boolean mHadPrepared = false;                 //Prepared
+    private int startTime = 0;//播放器开始的时间,单位毫秒
+
+    public SystemVideoPlayer(@NonNull Context context) {
+        super(context);
+        init(context);
+    }
+
+    public SystemVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public SystemVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+    private void init(Context context){
+        View videoGroup = View.inflate(getContext(), R.layout.layout_system_video, this);
+        videoView = videoGroup.findViewById(R.id.sys_video);
+        initVideoView();
+        videoView.resume();
+    }
+
+    private void initVideoView(){
+        videoView.setOnPreparedListener((mp) ->{
+            mediaPlayer = mp;
+            iVideoPlayer.onPlaying();
+            playerStatus = 2;
+            mHadPrepared = true;
+        });
+
+        videoView.setOnInfoListener((mp,what,extra) -> {
+            mediaPlayer = mp;
+            switch (what){          //信息类型
+                case MediaPlayer.MEDIA_INFO_BUFFERING_START:
+                    // MediaPlayer暂时暂停内部播放以缓冲更多数据。
+                    iVideoPlayer.onPlayingBuffering();
+                    playerStatus = 4;
+                    break;
+                case MediaPlayer.MEDIA_INFO_BUFFERING_END:
+                    // 填充缓冲区后,MediaPlayer正在恢复播放。
+                    iVideoPlayer.onPlaying();
+                    playerStatus = 2;
+                    break;
+                default:
+                    break;
+            }
+            return true;
+        });
+
+        videoView.setOnErrorListener((mp,what,extra) -> {
+            mediaPlayer = mp;
+            iVideoPlayer.onError(what,extra);
+            playerStatus = 6;
+            mHadPrepared = false;
+            return true;
+        });
+
+        videoView.setOnCompletionListener((mp) ->{
+            mediaPlayer = mp;
+            iVideoPlayer.onCompletion();
+            mHadPrepared = false;
+            playerStatus = 5;
+        });
+    }
+
+    /*-------------------------BaseMediaPlayer继承函数----------------------*/
+
+    @Override
+    public void play(String url, String examineId, String examineType) {
+        videoView.setVideoPath(url);
+        videoView.start();
+        playerStatus = 1;   //视频准备中;
+    }
+
+    @Override
+    public void setStartTime(int time) {
+
+    }
+
+    @Override
+    public void resume() {
+        if(isPrePared()){
+            videoView.start();
+            playerStatus = 2;   //播放中;
+        }else{
+            Logger.w("视频未准备好,不能继续播放");
+        }
+    }
+
+    @Override
+    public void pause() {
+        if(isPrePared()){
+            videoView.pause();
+            playerStatus = 3;   //暂停中;
+        }else{
+            Logger.w("视频未准备好,不能暂停");
+        }
+    }
+
+    @Override
+    public void seek(int position) {
+        if(isPrePared()){
+            videoView.seekTo(position);
+        }else{
+            Logger.w("视频未准备好,不能seek");
+        }
+    }
+
+    @Override
+    public void release() {
+        videoView.stopPlayback();
+        videoView.suspend();
+        mHadPrepared = false;
+    }
+
+    @Override
+    public boolean isPlaying() {
+        return mediaPlayer.isPlaying();
+    }
+
+    @Override
+    public boolean isPrePared() {
+        return mHadPrepared;
+    }
+
+    @Override
+    public int getDuration() {
+        return mediaPlayer.getDuration();
+    }
+
+    @Override
+    public int getCurrentPlayPosition() {
+        return mediaPlayer.getCurrentPosition();
+    }
+
+    @Override
+    public int getCurrentStatus() {
+        return playerStatus;
+    }
+
+    @Override
+    public void setVideoPlayerListener(@NonNull IVideoPlayer iVideoPlayer) {
+        this.iVideoPlayer = iVideoPlayer;
+    }
+
+}

+ 11 - 0
systemvideo/src/main/res/layout/layout_system_video.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <VideoView
+        android:id="@+id/sys_video"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="center"/>
+</merge>

+ 6 - 0
systemvideo/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#008577</color>
+    <color name="colorPrimaryDark">#00574B</color>
+    <color name="colorAccent">#D81B60</color>
+</resources>

+ 3 - 0
systemvideo/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">systemvideo</string>
+</resources>

+ 11 - 0
systemvideo/src/main/res/values/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 17 - 0
systemvideo/src/test/java/com/haochuan/systemvideo/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.haochuan.systemvideo;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}

+ 1 - 0
weilai_video/.gitignore

@@ -0,0 +1 @@
+/build

+ 69 - 0
weilai_video/build.gradle

@@ -0,0 +1,69 @@
+apply plugin: 'com.android.library'
+
+android {
+    compileSdkVersion versions.compileSdk
+    defaultConfig {
+        minSdkVersion versions.minSdk
+        targetSdkVersion versions.targetSdk
+        versionCode versions.versionCode
+        versionName versions.versionName
+        testInstrumentationRunner lib.test.test_runner
+
+        //暂时用黑龙江移动-电竞部落的未来电视数据
+        buildConfigField "String", "icntv_app_id", "\"5aa0b1a82cf0a\""
+        buildConfigField "String", "icntv_app_key", "\"7ce511f43f89232cf3291c3b001ad6c7\""
+        buildConfigField "String", "icntv_app_secret", "\"84f2343b883f2383213ebf549f56cfdf\""
+        buildConfigField "String", "icntv_app_channel", "\"2626023001\""
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+        debug {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    sourceSets {
+        main {
+            jniLibs.srcDirs = ['libs']
+        }
+    }
+
+    compileOptions {
+        sourceCompatibility versions.Java
+        targetCompatibility versions.Java
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+
+        debug {
+            buildConfigField "Boolean", "isDebug", "true"     //app全局是否调试,调试版本开启
+        }
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+    implementation lib.support.appcompat
+    testImplementation lib.test.junit
+    androidTestImplementation lib.test.runner
+    androidTestImplementation lib.test.espresso
+
+    implementation files('libs/adsdk.jar')
+    implementation files('libs/icntvplayersdk.jar')
+    implementation files('libs/logsdk.jar')
+    implementation files('libs/ottlogin.jar')
+    implementation files('libs/upgradeSDK.jar')
+    implementation files('libs/universal-image-loader-1.9.5.jar')
+    implementation project(path: ':core')
+}

BIN=BIN
weilai_video/libs/adsdk.jar


BIN=BIN
weilai_video/libs/armeabi-v7a/libadsdk.so


BIN=BIN
weilai_video/libs/armeabi-v7a/liblogsdk.so


BIN=BIN
weilai_video/libs/armeabi-v7a/libottlogin.so


BIN=BIN
weilai_video/libs/armeabi-v7a/libupgradesdk.so


BIN=BIN
weilai_video/libs/icntvplayersdk.jar


BIN=BIN
weilai_video/libs/logsdk.jar


BIN=BIN
weilai_video/libs/ottlogin.jar


BIN=BIN
weilai_video/libs/universal-image-loader-1.9.5.jar


BIN=BIN
weilai_video/libs/upgradeSDK.jar


+ 29 - 0
weilai_video/proguard-rules.pro

@@ -0,0 +1,29 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
+
+#---------- 未来sdk -----------#
+-dontwarn tv.icntv.**
+-keep class tv.icntv.**{*;}
+
+-dontwarn tv.newtv.**
+-keep class tv.newtv.**{*;}
+

+ 27 - 0
weilai_video/src/androidTest/java/com/haochuan/weilai_video/ExampleInstrumentedTest.java

@@ -0,0 +1,27 @@
+package com.haochuan.weilai_video;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getTargetContext();
+
+        assertEquals("com.haochuan.weilai_video", appContext.getPackageName());
+    }
+}

+ 11 - 0
weilai_video/src/main/AndroidManifest.xml

@@ -0,0 +1,11 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.haochuan.weilai_video">
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme" />
+</manifest>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 408 - 0
weilai_video/src/main/java/com/haochuan/weilai_video/CNTVLogin.java


+ 281 - 0
weilai_video/src/main/java/com/haochuan/weilai_video/WeiLaiVideoPlayer.java

@@ -0,0 +1,281 @@
+package com.haochuan.weilai_video;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.haochuan.core.BaseMediaPlayer;
+import com.haochuan.core.IVideoPlayer;
+import com.haochuan.core.Logger;
+import com.haochuan.core.util.JSONUtil;
+
+import org.json.JSONObject;
+
+import tv.icntv.been.IcntvPlayerInfo;
+import tv.icntv.icntvplayersdk.IcntvPlayer;
+import tv.icntv.icntvplayersdk.iICntvPlayInterface;
+
+import static com.haochuan.core.util.MessageCode.PLAYER_OBJ_NULL;
+
+public class WeiLaiVideoPlayer extends BaseMediaPlayer {
+    //全局参数
+    private IcntvPlayer icntvPlayer = null;             //cntv播放器实例
+    private FrameLayout icntvPlayerContainer = null;    //cntv播放器容器
+    private IVideoPlayer iVideoPlayer;
+    protected boolean mHadPrepared = false;                 //Prepared
+    private int playerStatus = 0;
+    private int startTime = 0;                                 //播放器开始的时间,单位毫秒
+
+
+    public WeiLaiVideoPlayer(@NonNull Context context) {
+        super(context);
+        init(context);
+    }
+
+    public WeiLaiVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public WeiLaiVideoPlayer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init(context);
+    }
+
+
+    /*
+     * 初始化
+     * */
+    private void init(Context context){
+        View.inflate(context, R.layout.player_wl,this);
+        icntvPlayerContainer = findViewById(R.id.video_view);
+    }
+
+    /*
+    * 设置事件接口
+    * */
+    @Override
+    public void setVideoPlayerListener(@NonNull IVideoPlayer iVideoPlayer){
+       this.iVideoPlayer = iVideoPlayer;
+    }
+
+
+
+    @Override
+    public void play(String url,String examineId,String examineType) {
+        initIcntvPlayer(url,examineId,examineType);
+    }
+
+    @Override
+    public void setStartTime(int time) {
+        this.startTime = time;
+    }
+
+    @Override
+    public void resume() {
+        if(isPrePared()){
+            if(!icntvPlayer.isPlaying()){
+                icntvPlayer.startVideo();
+                playerStatus = 2;   //播放中
+            }
+        }else{
+            Logger.w("视频未准备,不能执行resume");
+        }
+    }
+
+    @Override
+    public void pause() {
+        if(isPrePared()){
+            if(icntvPlayer.isPlaying()){
+                icntvPlayer.pauseVideo();
+                playerStatus = 3;   //暂停中
+            }
+        }else{
+            Logger.w("视频未准备,不能暂停");
+        }
+    }
+
+    @Override
+    public void seek(int position) {
+        if(isPrePared()){
+            icntvPlayer.seekTo(position);
+        }else{
+            Logger.w("视频未准备,不能拖动");
+        }
+    }
+
+    @Override
+    public void release() {
+        cntvPlayerRelease();
+    }
+
+    @Override
+    public boolean isPlaying() {
+        if(isPrePared()){
+            return icntvPlayer.isPlaying();
+        }else{
+            return false;
+        }
+    }
+
+    @Override
+    public boolean isPrePared() {
+        return mHadPrepared;
+    }
+
+    @Override
+    public int getDuration() {
+        if(isPrePared()){
+            return icntvPlayer.getDuration();
+        }else{
+            return 0;
+        }
+    }
+
+    @Override
+    public int getCurrentPlayPosition() {
+        if(isPrePared()){
+            return icntvPlayer.getCurrentPosition();
+        }else{
+            return 0;
+        }
+    }
+
+    @Override
+    public int getCurrentStatus() {
+        return playerStatus;
+    }
+
+
+    /*---------------------------功能函数------------------------------------*/
+
+    /*
+    * 初始化icntvPlayer对象
+    * */
+    private void initIcntvPlayer(String url,String examineId,String examineType){
+        try{
+            IcntvPlayerInfo icntvPlayerInfo = new IcntvPlayerInfo();    //播放器所需传入参数实例
+            icntvPlayerInfo.setPlayUrl(url);
+            icntvPlayerInfo.setApp_id(BuildConfig.icntv_app_id);
+            icntvPlayerInfo.setCheckType(examineType);
+            icntvPlayerInfo.setProgramID(examineId);
+            icntvPlayerInfo.setDuration(0);      //还未实现,等待接口更新
+            if (icntvPlayer != null) {
+                cntvPlayerRelease();
+                icntvPlayer = null;
+            }
+            icntvPlayer = new IcntvPlayer(getContext(), icntvPlayerContainer, icntvPlayerInfo, iICntvPlayInterface);
+            iVideoPlayer.onPreparing();
+            playerStatus = 1;   //视频准备中;
+        }catch (Exception e){
+            e.printStackTrace();
+            Logger.e(e.getMessage());
+        }
+    }
+
+    /**
+     * 销毁CNTV播放器
+     */
+    public void cntvPlayerRelease() {
+        if (icntvPlayer == null) {
+            return;
+        }
+        if (icntvPlayer.isPlaying()) {
+            icntvPlayer.pauseVideo();
+        }
+        icntvPlayer.release();
+        icntvPlayer = null;
+        mHadPrepared = false;
+        playerStatus = 6;
+    }
+
+    /*
+    * 在播放器准备好后,跳转到传入的startTime处
+    * */
+    private void seekToStartTime(){
+        if(icntvPlayer == null){
+            Logger.e(PLAYER_OBJ_NULL,"icntvPlayer is null, can`t seekToStartTime");
+            return;
+        }
+        if(startTime > 0){
+            if(startTime >= getDuration()){
+                //如果开始时间大于或者等于视频总时长,则跳转到距离结束5秒的位置
+                icntvPlayer.seekTo(getDuration() -5000);
+            }else{
+                icntvPlayer.seekTo(startTime);
+            }
+        }
+    }
+
+    /*
+    * 处理未来播放器错误
+    * */
+    private void handleError(int i, int i1, String s){
+        String cnTvError = "";
+        switch (i) {
+            case 1001:
+                cnTvError = "未来电视播放错误. " + "错误类型:"
+                        + i + "; 错误值:" + i1 + "; 错误消息:" + "CDN视频源调度失败";
+                break;
+            case 123456:
+                cnTvError = "未来电视播放错误. " + "错误类型:"
+                        + i + "; 错误值:" + i1 + "; 错误消息:" + "SDK鉴权失败";
+                break;
+            default:
+                cnTvError = s;
+                break;
+        }
+        Logger.e(cnTvError);
+        iVideoPlayer.onError(i,i1);
+    }
+
+
+    /*------------------------接口实现----------------------------------*/
+    private iICntvPlayInterface iICntvPlayInterface = new iICntvPlayInterface() {
+        @Override
+        public void onPrepared() {
+            mHadPrepared = true;
+            iVideoPlayer.onPlaying();
+            playerStatus = 2;
+            seekToStartTime();
+        }
+
+        @Override
+        public void onCompletion() {
+            iVideoPlayer.onCompletion();
+            playerStatus = 5;
+        }
+
+        @Override
+        public void onBufferStart(String s) {
+            iVideoPlayer.onPlayingBuffering();
+            playerStatus = 4;
+        }
+
+        @Override
+        public void onBufferEnd(String s) {
+            iVideoPlayer.onPlaying();
+            playerStatus = 2;
+        }
+
+        @Override
+        public void onError(int i, int i1, String s) {
+            mHadPrepared = false;
+            playerStatus = 6;
+            handleError(i,i1,s);
+        }
+
+        @Override
+        public void onTimeout() {
+            iVideoPlayer.onError(100,10001);
+            mHadPrepared = false;
+            playerStatus = 6;
+        }
+    };
+}

+ 81 - 0
weilai_video/src/main/java/com/haochuan/weilai_video/store/LocalStore.java

@@ -0,0 +1,81 @@
+package com.haochuan.weilai_video.store;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import java.nio.file.FileAlreadyExistsException;
+
+
+/**
+ * Created by yunhaipiaodi on 2017/9/26.
+ */
+@SuppressWarnings("unused")
+public class LocalStore {
+
+    private static LocalStore instance;
+    private String shareName = "cntv";
+
+
+    private String HAS_AD = "hasAd";
+    private String KEY_OPEN_AD = "openAdJson";
+    private String AD_PLAY_TIME = "adPlayTime";
+    private String AD_IMAGE_PATH = "adImagePath";
+
+
+    public static LocalStore getInstance() {
+        if (instance == null) {
+            instance = new LocalStore();
+        }
+        return instance;
+    }
+
+    public void putHasAd(Context context,boolean hasAd){
+        context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .edit()
+                .putBoolean(HAS_AD,hasAd)
+                .commit();
+    }
+
+    public boolean getHasAd(Context context){
+        return context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .getBoolean(HAS_AD, false);
+    }
+
+    public void putOpenAdJson(Context context,String openAdJson) {
+        context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .edit()
+                .putString(KEY_OPEN_AD,openAdJson)
+                .commit();
+    }
+
+    public String getOpenAdJson(Context context) {
+        return context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .getString(KEY_OPEN_AD, "");
+    }
+
+    public void putAdPlayTime(Context context,int adPlayTime) {
+        context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .edit()
+                .putInt(AD_PLAY_TIME,adPlayTime)
+                .commit();
+    }
+
+    public int getAdPlayTime(Context context) {
+        return context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .getInt(AD_PLAY_TIME, 0);
+    }
+
+    public void putAdImagePath(Context context,String adImagePath) {
+        context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .edit()
+                .putString(AD_IMAGE_PATH,adImagePath)
+                .commit();
+    }
+
+    public String getAdImagePath(Context context) {
+        return context.getSharedPreferences(shareName,Context.MODE_PRIVATE)
+                .getString(AD_IMAGE_PATH, "");
+    }
+
+
+}

+ 128 - 0
weilai_video/src/main/java/com/haochuan/weilai_video/util/AdDataUtil.java

@@ -0,0 +1,128 @@
+package com.haochuan.weilai_video.util;
+
+import android.text.TextUtils;
+
+import com.haochuan.core.Logger;
+import com.haochuan.core.util.JSONUtil;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public class AdDataUtil {
+    public static int getStatus(String json){
+        try{
+            return JSONUtil.getInt(new JSONObject(json),"status",0);
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+
+    }
+    public static  String getOpenAdJson(String json){
+        try{
+            JSONObject jsonObject = new JSONObject(json);
+            JSONObject adspacesJson = JSONUtil.getJsonObject(jsonObject,"adspaces");
+            if(adspacesJson == null){
+                Logger.e("getOpenAdJson,adspaces is not exist ,return");
+                return "";
+            }
+            JSONArray openArray = JSONUtil.getJsonArray(adspacesJson,"open");
+            if(openArray == null){
+                Logger.e("getOpenAdJson,open is not exist ,return");
+                return "";
+            }
+            if(openArray.length() == 0){
+                Logger.e("getOpenAdJson,open array is 0 length ,return");
+                return "";
+            }
+            return openArray.getJSONObject(0).toString();
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static  String getMid(String openAdJson){
+        try{
+            JSONObject jsonObject = new JSONObject(openAdJson);
+            return JSONUtil.getString(jsonObject,"mid","");
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static  String getAid(String openAdJson){
+        try{
+            JSONObject jsonObject = new JSONObject(openAdJson);
+            return JSONUtil.getString(jsonObject,"aid","");
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static  String getMaterialFirst(String openAdJson){
+        try{
+            JSONObject jsonObject = new JSONObject(openAdJson);
+            JSONArray materialArray = JSONUtil.getJsonArray(jsonObject,"materials");
+            if(materialArray == null){
+                Logger.e("getMaterialFirst,materials is not exist ,return");
+                return "";
+            }
+            if(materialArray.length() == 0){
+                Logger.e("getMaterialFirst,materials array is 0 length ,return");
+                return "";
+            }
+            return materialArray.getJSONObject(0).toString();
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static  String getAdImageUrl(String openAdJson){
+        try{
+            String materialJson = getMaterialFirst(openAdJson);
+            if(TextUtils.isEmpty(materialJson)){
+                Logger.e("getAdImageUrl,material is not exist ,return");
+                return "";
+            }
+            JSONObject jsonObject = new JSONObject(materialJson);
+            return JSONUtil.getString(jsonObject,"file_path","");
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public static  int getAdShowTime(String openAdJson){
+        try{
+            String materialJson = getMaterialFirst(openAdJson);
+            if(TextUtils.isEmpty(materialJson)){
+                Logger.e("getAdShowTime,material is not exist ,return");
+                return 0;
+            }
+            JSONObject jsonObject = new JSONObject(materialJson);
+            return JSONUtil.getInt(jsonObject,"play_time",0);
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    public static  String getMaterialId(String openAdJson){
+        try{
+            String materialJson = getMaterialFirst(openAdJson);
+            if(TextUtils.isEmpty(materialJson)){
+                Logger.e("getMaterialId,material is not exist ,return");
+                return "";
+            }
+            JSONObject jsonObject = new JSONObject(materialJson);
+            return JSONUtil.getString(jsonObject,"id","");
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+}

+ 69 - 0
weilai_video/src/main/java/com/haochuan/weilai_video/util/ReportCNTVLog.java

@@ -0,0 +1,69 @@
+package com.haochuan.weilai_video.util;
+
+import com.haochuan.weilai_video.BuildConfig;
+
+import tv.icntv.logsdk.logSDK;
+
+public class ReportCNTVLog {
+
+
+    public void reportHomeLog(String  extVersionType,String extVersionCode) {
+        reportLog(88, String.format("0,%s", BuildConfig.VERSION_NAME));//上报进入 APK 日志
+        reportLog(0, "0");//进入首页
+        reportLog(10, String.format("0,%s,%s", extVersionType, extVersionCode));//认证成功
+    }
+
+    public void reportExitLog() {
+        reportLog(88, "1");//上报退出 APK 日志
+    }
+
+    /**
+     * 上传收藏/取消记录
+     *
+     * @param isCollected 是否收藏操作
+     * @param id          视频id
+     */
+    public void reportCollectedOrNotLog(boolean isCollected, String id) {
+        reportLog(5, String.format("%s, %s", isCollected ? 0 : 1, id));
+    }
+
+    /**
+     * 上传添加历史记录
+     *
+     * @param id 视频id
+     */
+    public void reportAddHistoryLog(String id) {
+        reportLog(15, String.format("0, %s", id));
+    }
+
+    /**
+     * 上传清空历史记录
+     */
+    public void reportClearAllHistoryLog() {
+        reportLog(15, "2, 0");
+    }
+
+    /**
+     * 上传搜索日志
+     *
+     * @param keyword 关键字
+     */
+    public void reportSearchLog(String keyword) {
+        reportLog(2, keyword);
+    }
+
+
+
+    /**
+     * 上传日志
+     * @param type 日志类型,详情请查看未来sdk提供的文档
+     * @param event 日志事件,详情请查看未来sdk提供的文档
+     */
+    public void reportLog(int type, String event) {
+        try {
+            logSDK.getInstance().logUpload(type, event);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 9 - 0
weilai_video/src/main/res/drawable-v24/bg_ad_time.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <corners android:radius="8dp" />
+    <solid android:color="#ffffff" />
+    <stroke
+        android:width="1dp"
+        android:color="#625987" />
+</shape>

+ 10 - 0
weilai_video/src/main/res/layout/player_wl.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+    <!--视频容器-->
+    <FrameLayout
+        android:id="@+id/video_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/background_dark"/>
+</FrameLayout>

+ 6 - 0
weilai_video/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#008577</color>
+    <color name="colorPrimaryDark">#00574B</color>
+    <color name="colorAccent">#D81B60</color>
+</resources>

+ 3 - 0
weilai_video/src/main/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="app_name">weilai_video</string>
+</resources>

+ 11 - 0
weilai_video/src/main/res/values/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 17 - 0
weilai_video/src/test/java/com/haochuan/weilai_video/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.haochuan.weilai_video;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+public class ExampleUnitTest {
+    @Test
+    public void addition_isCorrect() {
+        assertEquals(4, 2 + 2);
+    }
+}