Selaa lähdekoodia

完善音视频播放器架构修改

yangchong 4 vuotta sitten
vanhempi
commit
4a40508179
96 muutettua tiedostoa jossa 1482 lisäystä ja 346 poistoa
  1. 7 4
      AudioPlayer/build.gradle
  2. 0 8
      AudioPlayer/src/main/java/com/yc/audioplayer/AbstractAudio.java
  3. 0 10
      AudioPlayer/src/main/java/com/yc/audioplayer/IPlayListener.java
  4. 18 28
      AudioPlayer/src/main/java/com/yc/audioplayer/bean/AudioPlayData.java
  5. 10 0
      AudioPlayer/src/main/java/com/yc/audioplayer/bean/AudioTtsPriority.java
  6. 65 0
      AudioPlayer/src/main/java/com/yc/audioplayer/delegate/AudioServiceDelegate.java
  7. 20 18
      AudioPlayer/src/main/java/com/yc/audioplayer/deque/AudioTtsDeque.java
  8. 22 18
      AudioPlayer/src/main/java/com/yc/audioplayer/dispatch/AudioTaskDispatcher.java
  9. 7 5
      AudioPlayer/src/main/java/com/yc/audioplayer/inter/InterAudio.java
  10. 17 0
      AudioPlayer/src/main/java/com/yc/audioplayer/inter/InterPlayListener.java
  11. 26 11
      AudioPlayer/src/main/java/com/yc/audioplayer/manager/AudioManager.java
  12. 157 0
      AudioPlayer/src/main/java/com/yc/audioplayer/player/DefaultTtsPlayer.java
  13. 19 9
      AudioPlayer/src/main/java/com/yc/audioplayer/player/MediaAudioPlayer.java
  14. 98 0
      AudioPlayer/src/main/java/com/yc/audioplayer/spi/AudioService.java
  15. 100 0
      AudioPlayer/src/main/java/com/yc/audioplayer/spi/AudioServiceImpl.java
  16. 77 0
      AudioPlayer/src/main/java/com/yc/audioplayer/spi/AudioServiceProvider.java
  17. 11 0
      AudioPlayer/src/main/java/com/yc/audioplayer/wrapper/AbstractAudioWrapper.java
  18. 17 14
      Demo/build.gradle
  19. 1 0
      Demo/src/main/AndroidManifest.xml
  20. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/BuriedPointEventImpl.java
  21. 8 5
      Demo/src/main/java/com/yc/ycvideoplayer/MainActivity.java
  22. 115 0
      Demo/src/main/java/com/yc/ycvideoplayer/audio/AudioActivity.java
  23. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/m3u8/M3u8Activity.java
  24. 37 0
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/activity/TypeActivity.java
  25. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/list/PlayerMonitor.java
  26. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/list/RecyclerViewFragment.java
  27. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/surface/MySurfaceView.java
  28. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/tiktok/TikTok2Activity.java
  29. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/tiktok/TikTokView.java
  30. 1 1
      Demo/src/main/java/com/yc/ycvideoplayer/oldPlayer/FloatPlayerView.java
  31. 81 0
      Demo/src/main/res/layout/activity_audio.xml
  32. 8 0
      Demo/src/main/res/layout/activity_main.xml
  33. BIN
      Demo/src/main/res/raw/ns_long_du_tip.mp3
  34. BIN
      Demo/src/main/res/raw/ns_no_answer_call_later.wav
  35. BIN
      Demo/src/main/res/raw/timeout.wav
  36. 8 6
      MusicPlayer/build.gradle
  37. 0 32
      VideoBarrage/build.gradle
  38. 5 8
      VideoCache/build.gradle
  39. 0 0
      VideoDanMu/VideoBarrage/.gitignore
  40. 15 0
      VideoDanMu/VideoBarrage/README.md
  41. 27 0
      VideoDanMu/VideoBarrage/build.gradle
  42. 0 0
      VideoDanMu/VideoBarrage/consumer-rules.pro
  43. 0 0
      VideoDanMu/VideoBarrage/proguard-rules.pro
  44. 0 0
      VideoDanMu/VideoBarrage/src/main/AndroidManifest.xml
  45. 0 0
      VideoDanMu/VideoBarrage/src/main/java/com/yc/videobarrage/Test.java
  46. 6 0
      VideoGradle/video.gradle
  47. 15 0
      VideoKernel/README.md
  48. 7 5
      VideoKernel/build.gradle
  49. 1 1
      VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoMediaPlayer.java
  50. 1 1
      VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkVideoPlayer.java
  51. 15 0
      VideoM3u8/README.md
  52. 6 5
      VideoM3u8/build.gradle
  53. 1 0
      VideoMonitor/.gitignore
  54. 15 0
      VideoMonitor/README.md
  55. 26 0
      VideoMonitor/build.gradle
  56. 0 0
      VideoMonitor/consumer-rules.pro
  57. 21 0
      VideoMonitor/proguard-rules.pro
  58. 27 0
      VideoMonitor/src/androidTest/java/com/yc/videomonitor/ExampleInstrumentedTest.java
  59. 2 0
      VideoMonitor/src/main/AndroidManifest.xml
  60. 17 0
      VideoMonitor/src/test/java/com/yc/videomonitor/ExampleUnitTest.java
  61. 9 7
      VideoPlayer/build.gradle
  62. 1 1
      VideoPlayer/src/main/java/com/yc/video/controller/BaseVideoController.java
  63. 1 1
      VideoPlayer/src/main/java/com/yc/video/controller/GestureVideoController.java
  64. 1 1
      VideoPlayer/src/main/java/com/yc/video/old/controller/VideoPlayerController.java
  65. 1 1
      VideoPlayer/src/main/java/com/yc/video/old/other/BatterReceiver.java
  66. 1 1
      VideoPlayer/src/main/java/com/yc/video/old/other/NetChangedReceiver.java
  67. 1 1
      VideoPlayer/src/main/java/com/yc/video/old/player/OldVideoPlayer.java
  68. 1 1
      VideoPlayer/src/main/java/com/yc/video/old/player/VideoMediaPlayer.java
  69. 1 1
      VideoPlayer/src/main/java/com/yc/video/old/surface/VideoTextureView.java
  70. 1 1
      VideoPlayer/src/main/java/com/yc/video/player/VideoPlayer.java
  71. 1 1
      VideoPlayer/src/main/java/com/yc/video/player/VideoViewManager.java
  72. 7 8
      VideoRecorder/build.gradle
  73. 15 0
      VideoScreen/README.md
  74. 6 5
      VideoScreen/build.gradle
  75. 6 5
      VideoSqlLite/build.gradle
  76. 15 0
      VideoTool/README.md
  77. 7 6
      VideoTool/build.gradle
  78. 79 0
      VideoTool/src/main/java/com/yc/videotool/ClickUtils.java
  79. 0 9
      VideoTool/src/main/java/com/yc/videotool/Tool.java
  80. 1 1
      VideoTool/src/main/java/com/yc/videotool/VideoLogUtils.java
  81. 10 6
      VideoView/src/main/java/com/yc/videoview/FloatLifecycle.java
  82. 14 7
      VideoView/src/main/java/com/yc/videoview/FloatPhone.java
  83. 12 5
      VideoView/src/main/java/com/yc/videoview/FloatToast.java
  84. 0 31
      VideoView/src/main/java/com/yc/videoview/FloatView.java
  85. 2 0
      VideoView/src/main/java/com/yc/videoview/FloatWindow.java
  86. 0 27
      VideoView/src/main/java/com/yc/videoview/IFloatWindow.java
  87. 16 4
      VideoView/src/main/java/com/yc/videoview/IFloatWindowImpl.java
  88. 0 11
      VideoView/src/main/java/com/yc/videoview/LifecycleListener.java
  89. 4 1
      VideoView/src/main/java/com/yc/videoview/MoveType.java
  90. 3 3
      VideoView/src/main/java/com/yc/videoview/SmallWindowTouch.java
  91. 1 1
      VideoView/src/main/java/com/yc/videoview/WindowScreen.java
  92. 39 0
      VideoView/src/main/java/com/yc/videoview/abs/AbsFloatView.java
  93. 37 0
      VideoView/src/main/java/com/yc/videoview/inter/IFloatWindow.java
  94. 19 0
      VideoView/src/main/java/com/yc/videoview/inter/ILifecycleListener.java
  95. 21 0
      read/61.如何打造全局悬浮窗.md
  96. 5 3
      settings.gradle

+ 7 - 4
AudioPlayer/build.gradle

@@ -5,22 +5,25 @@ apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 android {
     compileSdkVersion project.ext.androidCompileSdkVersion
     buildToolsVersion project.ext.androidBuildToolsVersion
+
     defaultConfig {
         minSdkVersion project.ext.androidMinSdkVersion
         targetSdkVersion project.ext.androidTargetSdkVersion
-        versionCode 1
-        versionName "1.0.0"
+        versionCode 2
+        versionName "1.0.2"
     }
 
     buildTypes {
         release {
             minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
         }
     }
 }
 
 dependencies {
-    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation fileTree(dir: "libs", include: ["*.jar"])
     implementation project.ext.AppDependencies['appcompat']
+    implementation project.ext.AppDependencies['media']
+    implementation project(':VideoTool')
 }

+ 0 - 8
AudioPlayer/src/main/java/com/yc/audioplayer/AbstractAudio.java

@@ -1,8 +0,0 @@
-package com.yc.audioplayer;
-
-
-public abstract class AbstractAudio implements IAudio, IPlayListener {
-
-    public final Object mMutex = new Object();
-
-}

+ 0 - 10
AudioPlayer/src/main/java/com/yc/audioplayer/IPlayListener.java

@@ -1,10 +0,0 @@
-package com.yc.audioplayer;
-
-
-public interface IPlayListener {
-
-    /**
-     * 播放完成
-     */
-    void onCompleted();
-}

+ 18 - 28
AudioPlayer/src/main/java/com/yc/audioplayer/PlayData.java → AudioPlayer/src/main/java/com/yc/audioplayer/bean/AudioPlayData.java

@@ -1,43 +1,34 @@
-package com.yc.audioplayer;
+package com.yc.audioplayer.bean;
 
 /**
  * 链表结果的播放数据
  */
-public class PlayData {
+public class AudioPlayData {
 
-    public enum TtsPriority {
+    public AudioTtsPriority mPriority = AudioTtsPriority.NORMAL_PRIORITY;
 
-        NORMAL_PRIORITY,
-
-        MIDDLE_PRIORITY,
-
-        HIGH_PRIORITY
-    }
-
-    TtsPriority mPriority = TtsPriority.NORMAL_PRIORITY;
-
-    boolean mPlayTts = true;
+    public boolean mPlayTts = true;
 
     private String mTts;
 
     private int mRawId;
 
-    private PlayData mCurrent;
+    private AudioPlayData mCurrent;
 
-    private PlayData mNext;
+    private AudioPlayData mNext;
 
-    PlayData() {
+    private AudioPlayData() {
         mCurrent = this;
         mCurrent.mNext = mNext;
     }
 
-    PlayData(int mRawId) {
+    private AudioPlayData(int mRawId) {
         this();
         this.mRawId = mRawId;
         this.mPlayTts = false;
     }
 
-    PlayData(String mTts) {
+    private AudioPlayData(String mTts) {
         this();
         this.mTts = mTts;
         this.mPlayTts = true;
@@ -51,18 +42,17 @@ public class PlayData {
         return mRawId;
     }
 
-    public PlayData getNext() {
+    public AudioPlayData getNext() {
         return mNext;
     }
 
     public static class Builder {
 
-        private PlayData mHeaderPlayData;
-
-        private PlayData mCurrentPlayData;
-        private TtsPriority mPriority;
+        private AudioPlayData mHeaderPlayData;
+        private AudioPlayData mCurrentPlayData;
+        private AudioTtsPriority mPriority;
 
-        public Builder(TtsPriority priority) {
+        public Builder(AudioTtsPriority priority) {
             this.mPriority = priority;
         }
 
@@ -70,7 +60,7 @@ public class PlayData {
         }
 
         public Builder tts(String string) {
-            PlayData data = new PlayData(string);
+            AudioPlayData data = new AudioPlayData(string);
             if (mHeaderPlayData == null) {
                 mHeaderPlayData = data;
                 mCurrentPlayData = data;
@@ -85,7 +75,7 @@ public class PlayData {
         }
 
         public Builder rawId(int rawId) {
-            PlayData data = new PlayData(rawId);
+            AudioPlayData data = new AudioPlayData(rawId);
             if (mHeaderPlayData == null) {
                 if (mPriority != null) {
                     data.mPriority = mPriority;
@@ -99,7 +89,7 @@ public class PlayData {
             return this;
         }
 
-        public PlayData build() {
+        public AudioPlayData build() {
             return mHeaderPlayData;
         }
 
@@ -107,7 +97,7 @@ public class PlayData {
 
     @Override
     public String toString() {
-        return "PlayData{" +
+        return "AudioPlayData{" +
             "priority=" + mPriority +
             ", mTts='" + mTts + '\'' +
             ", mRawId=" + mRawId +

+ 10 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/bean/AudioTtsPriority.java

@@ -0,0 +1,10 @@
+package com.yc.audioplayer.bean;
+
+public enum AudioTtsPriority {
+
+    NORMAL_PRIORITY,
+
+    MIDDLE_PRIORITY,
+
+    HIGH_PRIORITY
+}

+ 65 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/delegate/AudioServiceDelegate.java

@@ -0,0 +1,65 @@
+
+package com.yc.audioplayer.delegate;
+
+import android.content.Context;
+
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.inter.InterAudio;
+import com.yc.audioplayer.inter.InterPlayListener;
+
+public final class AudioServiceDelegate implements InterAudio {
+
+    private final InterAudio mDelegate ;
+
+    public AudioServiceDelegate(InterAudio iAudio) {
+        this.mDelegate = iAudio;
+    }
+
+    @Override
+    public final void init(final InterPlayListener arg0, final Context arg1) {
+        if (null != this.mDelegate) {
+            this.mDelegate.init(arg0, arg1);
+        }
+    }
+
+    @Override
+    public final void play(final AudioPlayData arg0) {
+        if (null != this.mDelegate) {
+            this.mDelegate.play(arg0);
+        }
+    }
+
+    @Override
+    public final void stop() {
+        if (null != this.mDelegate) {
+            this.mDelegate.stop();
+        }
+    }
+
+    @Override
+    public final void release() {
+        if (null != this.mDelegate) {
+            this.mDelegate.release();
+        }
+    }
+
+    @Override
+    public final void pause() {
+        if (null != this.mDelegate) {
+            this.mDelegate.pause();
+        }
+    }
+
+    @Override
+    public final void resumeSpeaking() {
+        if (null != this.mDelegate) {
+            this.mDelegate.resumeSpeaking();
+        }
+    }
+
+    @Override
+    public final boolean isPlaying() {
+        return null != this.mDelegate && this.mDelegate.isPlaying();
+    }
+
+}

+ 20 - 18
AudioPlayer/src/main/java/com/yc/audioplayer/TtsDeque.java → AudioPlayer/src/main/java/com/yc/audioplayer/deque/AudioTtsDeque.java

@@ -1,34 +1,36 @@
-package com.yc.audioplayer;
+package com.yc.audioplayer.deque;
+
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.videotool.VideoLogUtils;
 
 import java.util.concurrent.LinkedBlockingDeque;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-public class TtsDeque {
+public class AudioTtsDeque {
 
-    private Logger mLogger = LogService.getLogger(TtsDeque.class.getSimpleName());
-    private Lock mLock = new ReentrantLock();
+    private final Lock mLock = new ReentrantLock();
     private final Condition mNotEmpty = mLock.newCondition();
-    private LinkedBlockingDeque<PlayData> mHighDeque = new LinkedBlockingDeque<>();
-    private LinkedBlockingDeque<PlayData> mMiddleDeque = new LinkedBlockingDeque<>();
-    private LinkedBlockingDeque<PlayData> mNormalDeque = new LinkedBlockingDeque<>();
+    private final LinkedBlockingDeque<AudioPlayData> mHighDeque = new LinkedBlockingDeque<>();
+    private final LinkedBlockingDeque<AudioPlayData> mMiddleDeque = new LinkedBlockingDeque<>();
+    private final LinkedBlockingDeque<AudioPlayData> mNormalDeque = new LinkedBlockingDeque<>();
 
-    public void add(PlayData tts) {
+    public void add(AudioPlayData tts) {
         mLock.lock();
         try {
             switch (tts.mPriority) {
                 case HIGH_PRIORITY:
                     mHighDeque.add(tts);
-                    mLogger.debug("TTS queue add high: " + tts.getTts());
+                    VideoLogUtils.d("TTS queue add high: " + tts.getTts());
                     break;
                 case MIDDLE_PRIORITY:
                     mMiddleDeque.add(tts);
-                    mLogger.debug("TTS queue add  middle: " + tts.getTts());
+                    VideoLogUtils.d("TTS queue add  middle: " + tts.getTts());
                     break;
                 case NORMAL_PRIORITY:
                     mNormalDeque.add(tts);
-                    mLogger.debug("TTS queue add  normal: " + tts.getTts());
+                    VideoLogUtils.d("TTS queue add  normal: " + tts.getTts());
                     break;
             }
             mNotEmpty.signal();
@@ -37,30 +39,30 @@ public class TtsDeque {
         }
     }
 
-    public PlayData get() throws InterruptedException {
-        PlayData data;
+    public AudioPlayData get() throws InterruptedException {
+        AudioPlayData data;
         mLock.lock();
         try {
             while ((data = getTts()) == null) {
-                mLogger.debug("TTS queue no data to play ");
+                VideoLogUtils.d("TTS queue no data to play ");
                 mNotEmpty.await();
             }
-            mLogger.debug("TTS queue  will play is" + data.getTts() + " rawId " + data.getRawId());
+            VideoLogUtils.d("TTS queue  will play is" + data.getTts() + " rawId " + data.getRawId());
         } finally {
             mLock.unlock();
         }
         return data;
     }
 
-    public PlayData getTts() {
-        PlayData tts = mHighDeque.poll();
+    public AudioPlayData getTts() {
+        AudioPlayData tts = mHighDeque.poll();
         if (tts == null) {
             tts = mMiddleDeque.poll();
         }
         if (tts == null) {
             tts = mNormalDeque.poll();
         }
-        mLogger.debug("TTS queue get data is " + tts);
+        VideoLogUtils.d("TTS queue get data is " + tts);
         return tts;
     }
 

+ 22 - 18
AudioPlayer/src/main/java/com/yc/audioplayer/AudioTaskDispatcher.java → AudioPlayer/src/main/java/com/yc/audioplayer/dispatch/AudioTaskDispatcher.java

@@ -1,21 +1,20 @@
-package com.yc.audioplayer;
+package com.yc.audioplayer.dispatch;
 
 import android.os.Process;
 
-import com.didi.foundation.sdk.log.LogService;
-import com.didi.sdk.logging.Logger;
+import com.yc.audioplayer.deque.AudioTtsDeque;
+import com.yc.audioplayer.manager.AudioManager;
+import com.yc.audioplayer.wrapper.AbstractAudioWrapper;
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.inter.InterPlayListener;
+import com.yc.videotool.VideoLogUtils;
 
-/**
- * @author nate
- * @since 2018/8/28.
- */
-public class AudioTaskDispatcher implements IPlayListener {
 
-    private Logger mLogger = LogService.getLogger(AudioTaskDispatcher.class.getSimpleName());
-    private TtsDeque mTaskDeque ;
-    private PlayData mCurrentPlayData;
-    private AbstractAudio mAudioManager;
+public class AudioTaskDispatcher implements InterPlayListener {
 
+    private AudioTtsDeque mTaskDeque ;
+    private AudioPlayData mCurrentPlayData;
+    private AbstractAudioWrapper mAudioManager;
     private boolean mRunning = true;
     private Thread mTtsThread;
 
@@ -35,22 +34,27 @@ public class AudioTaskDispatcher implements IPlayListener {
         mAudioManager.onCompleted();
     }
 
+    @Override
+    public void onError(String error) {
+
+    }
+
     public void initialize(final AudioManager manager) {
         this.mAudioManager = manager;
-        this.mTaskDeque = new TtsDeque();
+        this.mTaskDeque = new AudioTtsDeque();
         this.mRunning = true;
-        mLogger.debug("AudioTaskDispatcher initialize: ");
+        VideoLogUtils.d("AudioTaskDispatcher initialize: ");
         this.mTtsThread = new Thread() {
             @Override
             public void run() {
                 Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
                 while (mRunning) {
                     try {
-                        mLogger.debug("AudioTaskDispatcher is running ");
+                        VideoLogUtils.d("AudioTaskDispatcher is running ");
                         mCurrentPlayData = mTaskDeque.get();
                         mAudioManager.play(mCurrentPlayData);
                         synchronized (manager.mMutex) {
-                            mLogger.debug("AudioTaskDispatcher is wait  " + mCurrentPlayData.getTts());
+                            VideoLogUtils.d("AudioTaskDispatcher is wait  " + mCurrentPlayData.getTts());
                             manager.mMutex.wait();
                         }
                     } catch (InterruptedException e) {
@@ -63,14 +67,14 @@ public class AudioTaskDispatcher implements IPlayListener {
         this.mTtsThread.start();
     }
 
-    public void addTask(PlayData data) {
+    public void addTask(AudioPlayData data) {
         if (data == null) {
             return;
         }
         if (mCurrentPlayData != null && data.mPriority.ordinal() > mCurrentPlayData.mPriority.ordinal()) {
             mAudioManager.stop();
         }
-        mLogger.debug("AudioTaskDispatcher data: " + data.getTts() + data.mPriority);
+        VideoLogUtils.d("AudioTaskDispatcher data: " + data.getTts() + data.mPriority);
         mTaskDeque.add(data);
     }
 

+ 7 - 5
AudioPlayer/src/main/java/com/yc/audioplayer/IAudio.java → AudioPlayer/src/main/java/com/yc/audioplayer/inter/InterAudio.java

@@ -1,21 +1,23 @@
-package com.yc.audioplayer;
+package com.yc.audioplayer.inter;
 
 import android.content.Context;
 
+import com.yc.audioplayer.bean.AudioPlayData;
+
 
 /**
  * 音频播放接口定义
  */
-public interface IAudio {
+public interface InterAudio {
 
-    void init(IPlayListener next, Context context);
+    void init(InterPlayListener next, Context context);
 
     /**
      * 播放数据
      *
-     * @param data {@link PlayData}
+     * @param data {@link AudioPlayData}
      */
-    void play(PlayData data);
+    void play(AudioPlayData data);
 
     /**
      * 停止播放

+ 17 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/inter/InterPlayListener.java

@@ -0,0 +1,17 @@
+package com.yc.audioplayer.inter;
+
+
+public interface InterPlayListener {
+
+    /**
+     * 播放完成
+     */
+    void onCompleted();
+
+    /**
+     * 播放失败
+     * @param error                         失败信息
+     */
+    void onError(String error);
+
+}

+ 26 - 11
AudioPlayer/src/main/java/com/yc/audioplayer/AudioManager.java → AudioPlayer/src/main/java/com/yc/audioplayer/manager/AudioManager.java

@@ -1,28 +1,38 @@
-package com.yc.audioplayer;
+package com.yc.audioplayer.manager;
 
 import android.content.Context;
 
+import com.yc.audioplayer.delegate.AudioServiceDelegate;
+import com.yc.audioplayer.player.DefaultTtsPlayer;
+import com.yc.audioplayer.player.MediaAudioPlayer;
+import com.yc.audioplayer.wrapper.AbstractAudioWrapper;
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.inter.InterAudio;
+import com.yc.audioplayer.inter.InterPlayListener;
 
-public class AudioManager extends AbstractAudio {
 
-    private final IAudio mTtsEngine;
-    private final IAudio mMediaPlayer;
-    private PlayData mCurrentData;
-    private IAudio mCurrentAudio;
+public class AudioManager extends AbstractAudioWrapper {
+
+    private final InterAudio mTtsEngine;
+    private final InterAudio mMediaPlayer;
+    private AudioPlayData mCurrentData;
+    private InterAudio mCurrentAudio;
     private PlayStateListener mPlayStateListener;
 
-    public AudioManager() {
-        mTtsEngine = IAudioService.getInstance();
-        mMediaPlayer = new MediaAudio();
+    public AudioManager(Context context) {
+        mTtsEngine = new AudioServiceDelegate(new DefaultTtsPlayer(context));
+        //创建音频播放器
+        mMediaPlayer = new MediaAudioPlayer();
     }
+
     @Override
-    public void init(IPlayListener next, Context context) {
+    public void init(InterPlayListener next, Context context) {
         mTtsEngine.init(next, context);
         mMediaPlayer.init(next, context);
     }
 
     @Override
-    public void play(PlayData data) {
+    public void play(AudioPlayData data) {
         if (null != mPlayStateListener) {
             mPlayStateListener.onStartPlay();
         }
@@ -81,6 +91,11 @@ public class AudioManager extends AbstractAudio {
         }
     }
 
+    @Override
+    public void onError(String error) {
+
+    }
+
     public void setPlayStateListener(PlayStateListener playStateListener) {
         this.mPlayStateListener = playStateListener;
     }

+ 157 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/player/DefaultTtsPlayer.java

@@ -0,0 +1,157 @@
+package com.yc.audioplayer.player;
+
+import android.content.Context;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+
+
+import com.yc.audioplayer.wrapper.AbstractAudioWrapper;
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.inter.InterPlayListener;
+import com.yc.videotool.VideoLogUtils;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+
+public class DefaultTtsPlayer extends AbstractAudioWrapper implements TextToSpeech.OnInitListener {
+
+    private TextToSpeech mTts;
+
+    /**
+     * 初始化是否完成
+     */
+    private volatile boolean mReady = false;
+    private final Context mContext;
+    private InterPlayListener mPlayListener;
+    private final OnCompleteListener mOnCompleteListener = new OnCompleteListener();
+
+    public DefaultTtsPlayer(Context context) {
+        this.mContext = context;
+    }
+
+    @Override
+    public void init(InterPlayListener next, Context context) {
+        mPlayListener = next;
+        this.mTts = new TextToSpeech(context, this);
+    }
+
+    @Override
+    public boolean isPlaying() {
+        return mTts.isSpeaking();
+    }
+
+    @Override
+    public void onCompleted() {
+        if (mPlayListener != null) {
+            mPlayListener.onCompleted();
+        }
+        mReady = true;
+    }
+
+    @Override
+    public void onError(String error) {
+
+    }
+
+    @Override
+    public void onInit(final int status) {
+        try {
+            if (!mReady  && (TextToSpeech.SUCCESS == status) && this.mTts != null) {
+                VideoLogUtils.i("Initialize TTS success");
+                final Locale locale = mContext.getApplicationContext().getResources().getConfiguration().locale;
+                if (locale != null) {
+                    VideoLogUtils.i("tts isLanguageAvailable " + mTts.isLanguageAvailable(locale) +
+                        "; variant is " + locale.getVariant() + "; locale is " + locale + " ; country  is " + locale
+                        .getCountry());
+                }
+                switch (this.mTts.setLanguage(null != locale ? locale : Locale.getDefault())) {
+                    case TextToSpeech.LANG_MISSING_DATA:
+                        VideoLogUtils.i("TTS set language: Language missing data");
+                        break;
+                    case TextToSpeech.LANG_NOT_SUPPORTED:
+                        VideoLogUtils.i("TTS set language: Language not supported");
+                        break;
+                    case TextToSpeech.LANG_AVAILABLE:
+                        VideoLogUtils.i("TTS set language: Language available");
+                        break;
+                    case TextToSpeech.LANG_COUNTRY_AVAILABLE:
+                        VideoLogUtils.i("TTS set language: Language country available");
+                        break;
+                    case TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE:
+                        VideoLogUtils.i("TTS set language: Language country var available");
+                        break;
+                    default:
+                        VideoLogUtils.i("TTS set language: Unknown error");
+                        break;
+                }
+            } else {
+                VideoLogUtils.i("Initialize TTS error");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            VideoLogUtils.i(e.getMessage());
+        }
+
+    }
+
+    @Override
+    public void pause() {
+        mTts.stop();
+    }
+
+    @Override
+    public void play(AudioPlayData data) {
+        synchronized (this.mTts) {
+            if (this.mTts.isSpeaking()) {
+                this.mTts.stop();
+            }
+
+            this.mTts.setOnUtteranceProgressListener(mOnCompleteListener);
+            HashMap<String, String> map = new HashMap<>();
+            map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, data.getTts());
+            this.mTts.speak(data.getTts(), TextToSpeech.QUEUE_FLUSH, map);
+        }
+    }
+
+    @Override
+    public void release() {
+        this.mTts.shutdown();
+        this.mReady = false;
+    }
+
+    @Override
+    public void resumeSpeaking() {
+
+    }
+
+    @Override
+    public void stop() {
+        mTts.stop();
+    }
+    
+    private final class OnCompleteListener extends UtteranceProgressListener {
+
+        OnCompleteListener() {
+
+        }
+
+        @Override
+        public void onDone(final String utteranceId) {
+            VideoLogUtils.i("TTSPlayer OnCompleteListener onDone");
+            onCompleted();
+        }
+
+        @Override
+        public void onError(final String utteranceId) {
+            VideoLogUtils.i("TTSPlayer OnCompleteListener onError");
+            onCompleted();
+        }
+
+        @Override
+        public void onStart(final String utteranceId) {
+
+        }
+    }
+
+}

+ 19 - 9
AudioPlayer/src/main/java/com/yc/audioplayer/MediaAudio.java → AudioPlayer/src/main/java/com/yc/audioplayer/player/MediaAudioPlayer.java

@@ -1,4 +1,4 @@
-package com.yc.audioplayer;
+package com.yc.audioplayer.player;
 
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
@@ -6,12 +6,16 @@ import android.media.AudioManager;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnCompletionListener;
 
+import com.yc.audioplayer.wrapper.AbstractAudioWrapper;
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.inter.InterPlayListener;
+import com.yc.videotool.VideoLogUtils;
 
-public class MediaAudio extends AbstractAudio {
 
-    private IPlayListener mPlayListener;
+public class MediaAudioPlayer extends AbstractAudioWrapper {
+
+    private InterPlayListener mPlayListener;
     private Context mContext;
-    private Logger mLogger = LogService.getLogger(MediaAudio.class.getSimpleName());
 
     private MediaPlayer mMediaPlayer;
     private boolean mPause = false;
@@ -37,11 +41,12 @@ public class MediaAudio extends AbstractAudio {
         }
     };
 
-    MediaAudio() {
+    public MediaAudioPlayer() {
+
     }
 
     @Override
-    public void init(IPlayListener next, Context context) {
+    public void init(InterPlayListener next, Context context) {
         this.mPlayListener = next;
         this.mContext = context;
     }
@@ -50,8 +55,8 @@ public class MediaAudio extends AbstractAudio {
      * 播放raw资源
      */
     @Override
-    public void play(PlayData data) {
-        mLogger.debug("MediaPlay: play resourceId is" + data.getRawId());
+    public void play(AudioPlayData data) {
+        VideoLogUtils.d("MediaPlay: play resourceId is" + data.getRawId());
         if (data.getRawId() <= 0) {
             return;
         }
@@ -78,7 +83,7 @@ public class MediaAudio extends AbstractAudio {
                 mMediaPlayer.prepare();
             } catch (Throwable e) {
                 e.printStackTrace();
-                mLogger.debug("MediaPlay: play fail");
+                VideoLogUtils.d("MediaPlay: play fail");
                 onCompleted();
             }
         }
@@ -139,4 +144,9 @@ public class MediaAudio extends AbstractAudio {
         }
     }
 
+    @Override
+    public void onError(String error) {
+
+    }
+
 }

+ 98 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/spi/AudioService.java

@@ -0,0 +1,98 @@
+package com.yc.audioplayer.spi;
+
+import android.content.Context;
+
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.manager.AudioManager;
+
+public final class AudioService implements AudioServiceProvider {
+
+    private AudioServiceProvider mDelegate;
+
+    private AudioService() {
+        if (mDelegate == null){
+            mDelegate = new AudioServiceImpl();
+        }
+    }
+
+    public static AudioService getInstance() {
+        return Singleton.INSTANCE;
+    }
+
+    @Override
+    public final void init(final Context arg0) {
+        if (null != this.mDelegate) {
+            this.mDelegate.init(arg0);
+        }
+    }
+
+    @Override
+    public final boolean isInit() {
+        return null != this.mDelegate && this.mDelegate.isInit();
+    }
+
+    @Override
+    public final void stop() {
+        if (null != this.mDelegate) {
+            this.mDelegate.stop();
+        }
+    }
+
+    @Override
+    public final void pause() {
+        if (null != this.mDelegate) {
+            this.mDelegate.pause();
+        }
+    }
+
+    @Override
+    public final void resume() {
+        if (null != this.mDelegate) {
+            this.mDelegate.resume();
+        }
+    }
+
+    @Override
+    public final void release() {
+        if (null != this.mDelegate) {
+            this.mDelegate.release();
+        }
+    }
+
+    @Override
+    public final boolean isPlaying() {
+        return null != this.mDelegate && this.mDelegate.isPlaying();
+    }
+
+    @Override
+    public final void play(final AudioPlayData arg0) {
+        if (null != this.mDelegate) {
+            this.mDelegate.play(arg0);
+        }
+    }
+
+    @Override
+    public final void playTts(final String arg0) {
+        if (null != this.mDelegate) {
+            this.mDelegate.playTts(arg0);
+        }
+    }
+
+    @Override
+    public final void playAudioResource(final int arg0) {
+        if (null != this.mDelegate) {
+            this.mDelegate.playAudioResource(arg0);
+        }
+    }
+
+    @Override
+    public final void setPlayStateListener(final AudioManager.PlayStateListener arg0) {
+        if (null != this.mDelegate) {
+            this.mDelegate.setPlayStateListener(arg0);
+        }
+    }
+
+    private static final class Singleton {
+        static final AudioService INSTANCE = new AudioService();
+    }
+}

+ 100 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/spi/AudioServiceImpl.java

@@ -0,0 +1,100 @@
+package com.yc.audioplayer.spi;
+
+import android.content.Context;
+
+import com.yc.audioplayer.dispatch.AudioTaskDispatcher;
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.manager.AudioManager;
+import com.yc.videotool.VideoLogUtils;
+
+public class AudioServiceImpl implements AudioServiceProvider {
+
+    private AudioManager mAudioManager;
+    private final AudioTaskDispatcher mAudioTaskDispatcher = AudioTaskDispatcher.getInstance();
+    private boolean mReady = false;
+    private Context mContext;
+
+    @Override
+    public void init(Context context) {
+        mAudioManager = new AudioManager(context);
+        mAudioManager.init(mAudioTaskDispatcher, context);
+        mAudioTaskDispatcher.initialize(mAudioManager);
+        mContext = context;
+        mReady = true;
+    }
+
+    @Override
+    public boolean isInit() {
+        return mReady;
+    }
+
+    @Override
+    public void stop() {
+        if (mReady) {
+            mAudioManager.stop();
+        }
+    }
+
+    @Override
+    public void pause() {
+        if (mReady) {
+            mAudioManager.pause();
+        }
+    }
+
+    @Override
+    public void resume() {
+        if (mReady) {
+            mAudioManager.resumeSpeaking();
+        }
+    }
+
+    @Override
+    public void release() {
+        mAudioManager.release();
+        mAudioTaskDispatcher.release();
+        mReady = false;
+    }
+
+    @Override
+    public boolean isPlaying() {
+        return mReady && mAudioManager.isPlaying();
+    }
+
+    @Override
+    public void play(AudioPlayData data) {
+        if (data == null) {
+            return;
+        }
+        if (!mReady) {
+            VideoLogUtils.d("audio not init!");
+            return;
+        }
+        mAudioTaskDispatcher.addTask(data);
+    }
+
+    @Override
+    public void playTts(String tts) {
+        AudioPlayData data = new AudioPlayData
+            .Builder()
+            .tts(tts)
+            .build();
+        play(data);
+    }
+
+    @Override
+    public void playAudioResource(int rawId) {
+        AudioPlayData data = new AudioPlayData
+            .Builder()
+            .rawId(rawId)
+            .build();
+        play(data);
+    }
+
+    @Override
+    public void setPlayStateListener(AudioManager.PlayStateListener playStateListener) {
+        if (null != mAudioManager) {
+            mAudioManager.setPlayStateListener(playStateListener);
+        }
+    }
+}

+ 77 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/spi/AudioServiceProvider.java

@@ -0,0 +1,77 @@
+package com.yc.audioplayer.spi;
+
+import android.content.Context;
+
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.manager.AudioManager;
+
+public interface AudioServiceProvider {
+
+    /**
+     * 初始化语音服务
+     *
+     * @param context {@link Context}
+     */
+    void init(Context context);
+
+    /**
+     * 是否已经初始化
+     * true 是
+     */
+    boolean isInit();
+
+    /**
+     * 停止播放
+     */
+    void stop();
+
+    /**
+     * 暂停播放
+     */
+    void pause();
+
+    /**
+     * 恢复播放
+     */
+    void resume();
+
+    /**
+     * 恢复播放
+     */
+    void release();
+
+    /**
+     * 是否正在播放
+     *
+     * @return true 正在播放
+     */
+    boolean isPlaying();
+
+    /**
+     * 播放数据
+     *
+     * @param data {@link AudioPlayData}
+     */
+    void play(AudioPlayData data);
+
+    /**
+     * 播放tts
+     *
+     * @param tts tts文本
+     */
+    void playTts(String tts);
+
+    /**
+     * 播放音频资源
+     *
+     * @param rawId 资源文件
+     */
+    void playAudioResource(int rawId);
+
+    /**
+     * 监听单条PlayData播放状态
+     * @param playStateListener 监听器
+     */
+    void setPlayStateListener(AudioManager.PlayStateListener playStateListener);
+
+}

+ 11 - 0
AudioPlayer/src/main/java/com/yc/audioplayer/wrapper/AbstractAudioWrapper.java

@@ -0,0 +1,11 @@
+package com.yc.audioplayer.wrapper;
+
+
+import com.yc.audioplayer.inter.InterAudio;
+import com.yc.audioplayer.inter.InterPlayListener;
+
+public abstract class AbstractAudioWrapper implements InterAudio, InterPlayListener {
+
+    public final Object mMutex = new Object();
+
+}

+ 17 - 14
Demo/build.gradle

@@ -58,26 +58,29 @@ dependencies {
     implementation 'com.github.ctiao:DanmakuFlameMaster:0.9.25'
     implementation 'com.github.ctiao:ndkbitmap-armv7a:0.9.21'
 
-
-//    implementation project(path: ':VideoCache')
-//    implementation project(path: ':VideoPlayer')
-//    implementation project(path: ':VideoKernel')
+    implementation project(path: ':VideoCache')
+    implementation project(path: ':VideoPlayer')
+    implementation project(path: ':VideoKernel')
     implementation project(path: ':VideoView')
-//    implementation project(path: ':MusicPlayer')
-//    implementation project(path: ':VideoM3u8')
-//    implementation project(path: ':VideoSqlLite')
-
-    implementation 'cn.yc:MusicPlayer:1.0.2'
-    implementation 'cn.yc:VideoPlayer:3.1.0'
-    implementation 'cn.yc:VideoCache:3.0.5'
-    implementation 'cn.yc:VideoKernel:3.0.6'
+    implementation project(path: ':MusicPlayer')
+    implementation project(path: ':VideoM3u8')
+    implementation project(path: ':VideoSqlLite')
+    implementation project(path: ':AudioPlayer')
+    implementation project(path: ':VideoTool')
+
+//    implementation 'cn.yc:MusicPlayer:1.0.2'
+//    implementation 'cn.yc:VideoPlayer:3.1.0'
+//    implementation 'cn.yc:VideoCache:3.0.5'
+//    implementation 'cn.yc:VideoKernel:3.0.6'
 //    implementation 'cn.yc:VideoView:3.0.5'
-    implementation 'cn.yc:VideoM3u8:1.0.0'
-    implementation 'cn.yc:VideoSqlLite:1.0.2'
+//    implementation 'cn.yc:VideoM3u8:1.0.0'
+//    implementation 'cn.yc:VideoSqlLite:1.0.2'
+
 
     //自己封装的库,都有对应的案例项目【欢迎star】:https://github.com/yangchong211
     implementation 'cn.yc:YCStatusBarLib:1.5.0'
     implementation 'com.yc:PagerLib:1.0.4'
     implementation 'cn.yc:YCStateLib:1.2.2'
 
+
 }

+ 1 - 0
Demo/src/main/AndroidManifest.xml

@@ -127,6 +127,7 @@
             android:screenOrientation="portrait"/>
         <activity android:name="com.yc.ycvideoplayer.music.MusicPlayerActivity"/>
         <activity android:name="com.yc.ycvideoplayer.m3u8.M3u8Activity"/>
+        <activity android:name="com.yc.ycvideoplayer.audio.AudioActivity"/>
     </application>
 
 </manifest>

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/BuriedPointEventImpl.java

@@ -1,6 +1,6 @@
 package com.yc.ycvideoplayer;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import com.yc.video.config.BuriedPointEvent;
 import com.yc.videosqllite.manager.LocationManager;

+ 8 - 5
Demo/src/main/java/com/yc/ycvideoplayer/MainActivity.java

@@ -1,6 +1,5 @@
 package com.yc.ycvideoplayer;
 
-import android.annotation.SuppressLint;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -23,22 +22,21 @@ import androidx.appcompat.app.AppCompatActivity;
 
 import org.yc.ycvideoplayer.R;
 
-import com.yc.kernel.utils.VideoLogUtils;
 import com.yc.music.model.AudioBean;
 import com.yc.music.service.PlayService;
 import com.yc.music.tool.BaseAppHelper;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.videoview.FloatWindow;
 import com.yc.videoview.MoveType;
 import com.yc.videoview.WindowScreen;
 import com.yc.videoview.WindowUtil;
+import com.yc.ycvideoplayer.audio.AudioActivity;
 import com.yc.ycvideoplayer.demo.DemoActivity;
 import com.yc.ycvideoplayer.m3u8.M3u8Activity;
 import com.yc.ycvideoplayer.music.MusicPlayerActivity;
 import com.yc.ycvideoplayer.newPlayer.activity.TypeActivity;
 import com.yc.ycvideoplayer.oldPlayer.OldActivity;
 
-import java.text.SimpleDateFormat;
-import java.util.Date;
 import java.util.List;
 
 import cn.ycbjie.ycstatusbarlib.bar.StateAppBar;
@@ -60,6 +58,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
     private TextView mTv4;
     private TextView mTv5;
     private TextView mTv6;
+    private TextView mTv7;
     private PlayServiceConnection mPlayServiceConnection;
 
 
@@ -87,6 +86,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         mTv4 = (TextView) findViewById(R.id.tv_4);
         mTv5 = (TextView) findViewById(R.id.tv_5);
         mTv6 = (TextView) findViewById(R.id.tv_6);
+        mTv7 = findViewById(R.id.tv_7);
 
         mTv1.setOnClickListener(this);
         mTv2.setOnClickListener(this);
@@ -94,6 +94,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
         mTv4.setOnClickListener(this);
         mTv5.setOnClickListener(this);
         mTv6.setOnClickListener(this);
+        mTv7.setOnClickListener(this);
     }
 
     @Override
@@ -123,7 +124,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
                         windowDialog();
                     }
                 }
-
+                break;
+            case R.id.tv_7:
+                startActivity(AudioActivity.class);
                 break;
         }
     }

+ 115 - 0
Demo/src/main/java/com/yc/ycvideoplayer/audio/AudioActivity.java

@@ -0,0 +1,115 @@
+package com.yc.ycvideoplayer.audio;
+
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.yc.audioplayer.manager.AudioManager;
+import com.yc.audioplayer.spi.AudioService;
+import com.yc.audioplayer.bean.AudioPlayData;
+import com.yc.audioplayer.bean.AudioTtsPriority;
+
+import org.yc.ycvideoplayer.R;
+
+public class AudioActivity extends AppCompatActivity implements View.OnClickListener {
+
+    private Button btnInit;
+    private Button btnSpeakTts;
+    private Button btnSpeakMedia;
+    private Button btnMixPlay;
+    private Button btnPause;
+    private Button btnResume;
+    private Button btnStop;
+    private Button btnHighPriority;
+    private Button btnRelease;
+    private Button btnBrazil;
+    private Button btnTts;
+
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_audio);
+
+        btnInit = findViewById(R.id.btn_init);
+        btnSpeakTts = findViewById(R.id.btn_speak_tts);
+        btnSpeakMedia = findViewById(R.id.btn_speak_media);
+        btnMixPlay = findViewById(R.id.btn_mix_play);
+        btnPause = findViewById(R.id.btn_pause);
+        btnResume = findViewById(R.id.btn_resume);
+        btnStop = findViewById(R.id.btn_stop);
+        btnHighPriority = findViewById(R.id.btn_high_priority);
+        btnRelease = findViewById(R.id.btn_release);
+        btnBrazil = findViewById(R.id.btn_brazil);
+        btnTts = findViewById(R.id.btn_tts);
+
+        btnInit.setOnClickListener(this);
+        btnSpeakTts.setOnClickListener(this);
+        btnSpeakMedia.setOnClickListener(this);
+        btnMixPlay.setOnClickListener(this);
+        btnPause.setOnClickListener(this);
+        btnResume.setOnClickListener(this);
+        btnStop.setOnClickListener(this);
+        btnHighPriority.setOnClickListener(this);
+        btnRelease.setOnClickListener(this);
+        btnBrazil.setOnClickListener(this);
+        btnTts.setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v == btnInit){
+            AudioService.getInstance().init(this);
+            AudioService.getInstance().setPlayStateListener(new AudioManager.PlayStateListener() {
+                @Override
+                public void onStartPlay() {
+
+                }
+
+                @Override
+                public void onCompletePlay() {
+
+                }
+            });
+        } else if (v == btnSpeakTts){
+            AudioPlayData playData = new AudioPlayData.Builder()
+                    .tts("当前只有做国际版业务时,才需要调用此函数。别的业务线或其他情况下禁止调用此函数。2.若需要调用,请在初始化阶段")
+                    .build();
+            AudioService.getInstance().play(playData);
+        } else if (v == btnSpeakMedia){
+            AudioPlayData playData = new AudioPlayData.Builder()
+                    .rawId(R.raw.timeout)
+                    .build();
+            AudioService.getInstance().play(playData);
+        } else if (v == btnMixPlay){
+            AudioPlayData data = new AudioPlayData.Builder(AudioTtsPriority.HIGH_PRIORITY)
+                    .tts("我是一个混合的协议")
+                    .rawId(R.raw.timeout)
+                    .tts("Hello TTS Service").build();
+            AudioService.getInstance().play(data);
+        } else if (v == btnPause){
+            AudioService.getInstance().pause();
+        } else if (v == btnResume){
+            AudioService.getInstance().resume();
+        } else if (v == btnStop){
+            AudioService.getInstance().stop();
+        } else if (v == btnHighPriority){
+            AudioPlayData playData =new AudioPlayData.Builder(AudioTtsPriority.HIGH_PRIORITY)
+                    .tts("Fire in the home! Fire in the home ")
+                    .build();
+            AudioService.getInstance().play(playData);
+        } else if (v == btnRelease){
+            AudioService.getInstance().release();
+        } else if (v == btnBrazil){
+            AudioPlayData playData = new AudioPlayData.Builder()
+                    .tts("vire à esquerda na parada de ônibus")
+                    .build();
+            AudioService.getInstance().play(playData);
+        } else if (v == btnTts){
+            AudioService.getInstance().playTts("逗比,这个是tts");
+        }
+    }
+}

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/m3u8/M3u8Activity.java

@@ -9,7 +9,7 @@ import android.widget.TextView;
 
 import androidx.appcompat.app.AppCompatActivity;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.m3u8.bean.M3u8;
 import com.yc.m3u8.inter.OnDownloadListener;
 import com.yc.m3u8.inter.OnM3u8InfoListener;

+ 37 - 0
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/activity/TypeActivity.java

@@ -3,6 +3,7 @@ package com.yc.ycvideoplayer.newPlayer.activity;
 import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.os.Bundle;
+import android.view.KeyEvent;
 import android.view.View;
 import android.widget.TextView;
 
@@ -273,4 +274,40 @@ public class TypeActivity extends AppCompatActivity implements View.OnClickListe
     }
 
 
+
+    /**
+     * 再点一次退出程序时间设置
+     */
+    private static final long WAIT_TIME = 2000L;
+    private long touchTime = 0;
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            //双击返回桌面
+            if (System.currentTimeMillis() - touchTime < WAIT_TIME) {
+                //finish();
+                //可将activity 退到后台,注意不是finish()退出。
+                //判断Activity是否是task根
+                //使用moveTaskToBack是为了让app退出时,不闪屏,退出柔和一些
+                if (this.isTaskRoot()){
+                    //参数为false——代表只有当前activity是task根,指应用启动的第一个activity时,才有效;
+                    moveTaskToBack(false);
+                } else {
+                    //参数为true——则忽略这个限制,任何activity都可以有效。
+                    //使用此方法,便不会执行Activity的onDestroy()方法
+                    moveTaskToBack(true);
+                }
+                //注意这里是finish所有activity,然后杀死进程
+                //ActivityManageUtils.getInstance().appExit(this);
+            } else {
+                touchTime = System.currentTimeMillis();
+                //参考易车,抖音自定义吐司
+                BaseToast.showRoundRectToast("再按一次退出");
+            }
+            return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
+
+
 }

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/list/PlayerMonitor.java

@@ -5,7 +5,7 @@ import android.view.animation.Animation;
 
 import androidx.annotation.NonNull;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import com.yc.video.bridge.ControlWrapper;
 import com.yc.video.ui.view.InterControlView;

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/list/RecyclerViewFragment.java

@@ -14,7 +14,7 @@ import androidx.fragment.app.Fragment;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.ycvideoplayer.ConstantVideo;
 
 import org.yc.ycvideoplayer.R;

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/surface/MySurfaceView.java

@@ -12,7 +12,7 @@ import android.view.SurfaceView;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import org.yc.ycvideoplayer.R;
 

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/tiktok/TikTok2Activity.java

@@ -9,7 +9,7 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.viewpager.widget.ViewPager;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import com.yc.ycvideoplayer.ConstantVideo;
 import org.yc.ycvideoplayer.R;

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/newPlayer/tiktok/TikTokView.java

@@ -14,7 +14,7 @@ import android.widget.Toast;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import org.yc.ycvideoplayer.R;
 

+ 1 - 1
Demo/src/main/java/com/yc/ycvideoplayer/oldPlayer/FloatPlayerView.java

@@ -7,7 +7,7 @@ import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.FrameLayout;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.old.controller.VideoPlayerController;
 import com.yc.video.old.listener.OnPlayerStatesListener;

+ 81 - 0
Demo/src/main/res/layout/activity_audio.xml

@@ -0,0 +1,81 @@
+<?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">
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:orientation="vertical">
+
+        <Button
+            android:id="@+id/btn_init"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="init" />
+
+        <Button
+            android:id="@+id/btn_speak_tts"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="speak tts" />
+
+        <Button
+            android:id="@+id/btn_speak_media"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="speak mp3 " />
+
+        <Button
+            android:id="@+id/btn_mix_play"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="mix play" />
+
+        <Button
+            android:id="@+id/btn_pause"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="pause" />
+
+        <Button
+            android:id="@+id/btn_resume"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="resume" />
+
+        <Button
+            android:id="@+id/btn_stop"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="stop" />
+
+        <Button
+            android:id="@+id/btn_high_priority"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="HIGH_PRIORITY" />
+
+        <Button
+            android:id="@+id/btn_release"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="release" />
+        <Button
+            android:id="@+id/btn_brazil"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="葡萄牙语言"/>
+        <Button
+            android:id="@+id/btn_tts"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="play_tts"/>
+    </LinearLayout>
+
+</RelativeLayout>

+ 8 - 0
Demo/src/main/res/layout/activity_main.xml

@@ -83,6 +83,14 @@
                 android:padding="10dp"
                 android:background="@color/colorAccent"
                 android:text="6.悬浮窗"/>
+            <TextView
+                android:id="@+id/tv_7"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="10dp"
+                android:padding="10dp"
+                android:background="@color/colorAccent"
+                android:text="7.语音播报测试"/>
         </LinearLayout>
     </ScrollView>
 

BIN
Demo/src/main/res/raw/ns_long_du_tip.mp3


BIN
Demo/src/main/res/raw/ns_no_answer_call_later.wav


BIN
Demo/src/main/res/raw/timeout.wav


+ 8 - 6
MusicPlayer/build.gradle

@@ -1,12 +1,14 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
+
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.3"
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
 
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 2
         versionName "1.0.2"
     }
@@ -21,8 +23,8 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation 'androidx.appcompat:appcompat:1.2.0'
-    implementation 'androidx.media:media:1.0.1'
+    implementation project.ext.AppDependencies['appcompat']
+    implementation project.ext.AppDependencies['media']
 }
 
 /** 以下开始是将Android Library上传到jcenter的相关配置**/

+ 0 - 32
VideoBarrage/build.gradle

@@ -1,32 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.3"
-
-    defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
-        versionCode 1
-        versionName "1.0"
-
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-        consumerProguardFiles "consumer-rules.pro"
-    }
-
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
-        }
-    }
-}
-
-dependencies {
-    implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation 'androidx.appcompat:appcompat:1.2.0'
-    testImplementation 'junit:junit:4.12'
-    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
-
-}

+ 5 - 8
VideoCache/build.gradle

@@ -1,17 +1,14 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.3"
-
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 31
         versionName "3.0.1"
-
-        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
-        consumerProguardFiles "consumer-rules.pro"
     }
 
     buildTypes {

+ 0 - 0
VideoBarrage/.gitignore → VideoDanMu/VideoBarrage/.gitignore


+ 15 - 0
VideoDanMu/VideoBarrage/README.md

@@ -0,0 +1,15 @@
+# 视频弹幕介绍文档
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 27 - 0
VideoDanMu/VideoBarrage/build.gradle

@@ -0,0 +1,27 @@
+apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
+
+
+android {
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
+    defaultConfig {
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
+        versionCode 1
+        versionName "1.0"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    implementation fileTree(dir: "libs", include: ["*.jar"])
+    implementation project.ext.AppDependencies['appcompat']
+    implementation project(path: ':ndkbitmap-armv7a')
+}

+ 0 - 0
VideoBarrage/consumer-rules.pro → VideoDanMu/VideoBarrage/consumer-rules.pro


+ 0 - 0
VideoBarrage/proguard-rules.pro → VideoDanMu/VideoBarrage/proguard-rules.pro


+ 0 - 0
VideoBarrage/src/main/AndroidManifest.xml → VideoDanMu/VideoBarrage/src/main/AndroidManifest.xml


+ 0 - 0
VideoBarrage/src/main/java/com/yc/videobarrage/Test.java → VideoDanMu/VideoBarrage/src/main/java/com/yc/videobarrage/Test.java


+ 6 - 0
VideoGradle/video.gradle

@@ -8,11 +8,17 @@ ext {
 
     constraintLayoutVersion = '1.1.3'
     appcompatVersion = '1.2.0'
+    annotationVersion = '1.1.0'
+    cardviewVersion = '1.0.0'
+    mediaVersion = '1.0.1'
 
     /**主app-start*/
     AppDependencies = [
             constraintLayout    : "androidx.constraintlayout:constraintlayout:${constraintLayoutVersion}",
             appcompat           : "androidx.appcompat:appcompat:${appcompatVersion}",
+            annotation          : "androidx.annotation:annotation:${annotationVersion}",
+            cardview            : "androidx.cardview:cardview:${cardviewVersion}",
+            media               : "androidx.media:media:${mediaVersion}",
     ]
 
 }

+ 15 - 0
VideoKernel/README.md

@@ -0,0 +1,15 @@
+# 视频内核介绍文档
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 7 - 5
VideoKernel/build.gradle

@@ -1,12 +1,12 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.0"
-
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 36
         versionName "3.0.6"
     }
@@ -42,6 +42,8 @@ dependencies {
     //exoplayer-smoothstreaming:支持SmoothStreaming内容
     api "com.google.android.exoplayer:exoplayer-smoothstreaming:2.11.3"
     api "com.google.android.exoplayer:extension-rtmp:2.11.3"
+
+    implementation project(':VideoTool')
 }
 
 

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoMediaPlayer.java

@@ -29,7 +29,7 @@ import com.google.android.exoplayer2.video.VideoListener;
 import com.yc.kernel.inter.AbstractVideoPlayer;
 import com.yc.kernel.inter.VideoPlayerListener;
 import com.yc.kernel.utils.PlayerConstant;
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import java.util.Map;
 

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkVideoPlayer.java

@@ -28,7 +28,7 @@ import android.view.SurfaceHolder;
 import com.yc.kernel.inter.AbstractVideoPlayer;
 import com.yc.kernel.inter.VideoPlayerListener;
 import com.yc.kernel.utils.PlayerConstant;
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import java.util.Map;
 import tv.danmaku.ijk.media.player.IMediaPlayer;

+ 15 - 0
VideoM3u8/README.md

@@ -0,0 +1,15 @@
+# 视频m3u8介绍文档
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 6 - 5
VideoM3u8/build.gradle

@@ -1,11 +1,12 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion '29.0.0'
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 1
         versionName "1.0.0"
     }
@@ -20,7 +21,7 @@ android {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation 'androidx.appcompat:appcompat:1.2.0'
+    implementation project.ext.AppDependencies['appcompat']
     api files('libs/commons-io-2.5.jar')
 }
 

+ 1 - 0
VideoMonitor/.gitignore

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

+ 15 - 0
VideoMonitor/README.md

@@ -0,0 +1,15 @@
+# 视频监控库介绍文档
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 26 - 0
VideoMonitor/build.gradle

@@ -0,0 +1,26 @@
+apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
+
+android {
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
+    defaultConfig {
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
+        versionCode 1
+        versionName "1.0"
+    }
+
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+        }
+    }
+
+}
+
+dependencies {
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
+    implementation project.ext.AppDependencies['appcompat']
+}

+ 0 - 0
VideoMonitor/consumer-rules.pro


+ 21 - 0
VideoMonitor/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
VideoMonitor/src/androidTest/java/com/yc/videomonitor/ExampleInstrumentedTest.java

@@ -0,0 +1,27 @@
+package com.yc.videomonitor;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.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.getInstrumentation().getTargetContext();
+
+        assertEquals("com.yc.videomonitor.test", appContext.getPackageName());
+    }
+}

+ 2 - 0
VideoMonitor/src/main/AndroidManifest.xml

@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.yc.videomonitor" />

+ 17 - 0
VideoMonitor/src/test/java/com/yc/videomonitor/ExampleUnitTest.java

@@ -0,0 +1,17 @@
+package com.yc.videomonitor;
+
+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);
+    }
+}

+ 9 - 7
VideoPlayer/build.gradle

@@ -1,11 +1,12 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion '29.0.0'
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 40
         versionName "3.1.0"
     }
@@ -20,10 +21,11 @@ android {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation 'androidx.appcompat:appcompat:1.2.0'
-    implementation 'androidx.annotation:annotation:1.1.0'
-    implementation 'androidx.cardview:cardview:1.0.0'
+    implementation project.ext.AppDependencies['appcompat']
+    implementation project.ext.AppDependencies['annotation']
+    implementation project.ext.AppDependencies['cardview']
     implementation project(':VideoKernel')
+    implementation project(path: ':VideoTool')
 
     /*//这两个是必须要加的,其它的可供选择
     //ijk播放器

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/controller/BaseVideoController.java

@@ -41,7 +41,7 @@ import com.yc.video.tool.NetworkUtils;
 import com.yc.video.tool.PlayerUtils;
 import com.yc.video.ui.view.InterControlView;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 import java.util.Iterator;
 import java.util.LinkedHashMap;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/controller/GestureVideoController.java

@@ -28,7 +28,7 @@ import android.view.WindowManager;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.tool.PlayerUtils;
 import com.yc.video.ui.view.InterControlView;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/old/controller/VideoPlayerController.java

@@ -35,7 +35,7 @@ import android.widget.TextView;
 import androidx.annotation.DrawableRes;
 import androidx.annotation.IntRange;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.video.tool.BaseToast;
 import com.yc.video.tool.PlayerUtils;
 

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/old/other/BatterReceiver.java

@@ -25,7 +25,7 @@ import com.yc.video.config.ConstantKeys;
 import com.yc.video.old.controller.AbsVideoPlayerController;
 import com.yc.video.old.player.OldVideoPlayer;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 /**
  * <pre>

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/old/other/NetChangedReceiver.java

@@ -25,7 +25,7 @@ import com.yc.video.old.controller.AbsVideoPlayerController;
 import com.yc.video.old.player.OldVideoPlayer;
 import com.yc.video.tool.NetworkUtils;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 /**
  * <pre>

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/old/player/OldVideoPlayer.java

@@ -28,7 +28,7 @@ import android.view.KeyEvent;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.old.controller.AbsVideoPlayerController;
 import com.yc.video.tool.BaseToast;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/old/player/VideoMediaPlayer.java

@@ -9,7 +9,7 @@ import android.view.Surface;
 
 import androidx.annotation.RequiresApi;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.video.config.ConstantKeys;
 import com.yc.video.old.surface.VideoTextureView;
 import com.yc.video.tool.BaseToast;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/old/surface/VideoTextureView.java

@@ -23,7 +23,7 @@ import android.view.Gravity;
 import android.view.TextureView;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 
 /**
  * <pre>

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/player/VideoPlayer.java

@@ -41,7 +41,7 @@ import com.yc.video.tool.PlayerUtils;
 import com.yc.video.tool.VideoException;
 import com.yc.kernel.inter.VideoPlayerListener;
 import com.yc.kernel.utils.PlayerConstant;
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;

+ 1 - 1
VideoPlayer/src/main/java/com/yc/video/player/VideoViewManager.java

@@ -17,7 +17,7 @@ package com.yc.video.player;
 
 import android.app.Application;
 
-import com.yc.kernel.utils.VideoLogUtils;
+import com.yc.videotool.VideoLogUtils;
 import com.yc.video.config.VideoPlayerConfig;
 
 import java.util.LinkedHashMap;

+ 7 - 8
VideoRecorder/build.gradle

@@ -1,12 +1,14 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
+
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.3"
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
 
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 1
         versionName "1.0"
 
@@ -24,9 +26,6 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation 'androidx.appcompat:appcompat:1.2.0'
-    testImplementation 'junit:junit:4.12'
-    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
-    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+    implementation project.ext.AppDependencies['appcompat']
 
 }

+ 15 - 0
VideoScreen/README.md

@@ -0,0 +1,15 @@
+# 视频监控库介绍文档
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 6 - 5
VideoScreen/build.gradle

@@ -1,12 +1,13 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion '29.0.0'
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
 
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 1
         versionName "1.0"
     }
@@ -21,5 +22,5 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation 'androidx.appcompat:appcompat:1.2.0'
+    implementation project.ext.AppDependencies['appcompat']
 }

+ 6 - 5
VideoSqlLite/build.gradle

@@ -1,12 +1,13 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.3"
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
 
     defaultConfig {
-        minSdkVersion 17
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 2
         versionName "1.0.2"
     }
@@ -21,7 +22,7 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation 'androidx.annotation:annotation:1.1.0'
+    implementation project.ext.AppDependencies['annotation']
 }
 
 

+ 15 - 0
VideoTool/README.md

@@ -0,0 +1,15 @@
+# 视频工具库介绍文档
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 7 - 6
VideoTool/build.gradle

@@ -1,12 +1,14 @@
 apply plugin: 'com.android.library'
+apply from: rootProject.projectDir.absolutePath + "/VideoGradle/video.gradle"
+
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "29.0.3"
+    compileSdkVersion project.ext.androidCompileSdkVersion
+    buildToolsVersion project.ext.androidBuildToolsVersion
 
     defaultConfig {
-        minSdkVersion 16
-        targetSdkVersion 29
+        minSdkVersion project.ext.androidMinSdkVersion
+        targetSdkVersion project.ext.androidTargetSdkVersion
         versionCode 1
         versionName "1.0"
 
@@ -25,8 +27,7 @@ android {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-
-    implementation 'androidx.appcompat:appcompat:1.2.0'
+    implementation project.ext.AppDependencies['appcompat']
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'androidx.test.ext:junit:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

+ 79 - 0
VideoTool/src/main/java/com/yc/videotool/ClickUtils.java

@@ -0,0 +1,79 @@
+package com.yc.videotool;
+
+import android.text.TextUtils;
+
+import java.util.HashMap;
+
+
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 防暴力点击
+ *     revise:
+ * </pre>
+ */
+public final class ClickUtils {
+
+    /**
+     * 默认最大点击间隔时间
+     */
+    private static final int MAX_INTERVAL = 500;
+    /**
+     * 最后一次点击的时间戳
+     */
+    private static long mLastClickTime;
+    /**
+     * tag标记的集合
+     */
+    private static final HashMap<String, Long> tagMaps = new HashMap<>();
+
+    /**
+     * 判断一个控件是否短时间内重复点击
+     * @return                      true表示是重复点击
+     */
+    public static boolean isFastDoubleClick() {
+        return isFastDoubleClick(MAX_INTERVAL);
+    }
+
+    /**
+     * 判断一个控件是否xx时间内重复点击
+     * @param maxInterval           设置间隔时间
+     * @return                      true表示是重复点击
+     */
+    public static boolean isFastDoubleClick(int maxInterval) {
+        long current = System.currentTimeMillis();
+        long interval = current - mLastClickTime;
+        if ((interval > 0) && (interval < maxInterval)) {
+            return true;
+        }
+        mLastClickTime = current;
+        return false;
+    }
+
+    /**
+     * 判断一个控件是否xx时间内重复点击
+     * @param maxInterval           设置间隔时间
+     * @param tag                   标记
+     * @return                      true表示是重复点击
+     */
+    public static boolean isFastDoubleClickWithTag(int maxInterval, String tag) {
+        if (TextUtils.isEmpty(tag)) {
+            return true;
+        }
+        long current = System.currentTimeMillis();
+        long interval = 0;
+        if (tagMaps.containsKey(tag)) {
+            // 获取上次保存时间离现在的时间间距.
+            interval = current - tagMaps.get(tag);
+        }
+        if ((interval > 0) && (interval < maxInterval)) {
+            return true;
+        }
+        // 放入当前tag对应的时间
+        tagMaps.put(tag, current);
+        return false;
+    }
+
+}

+ 0 - 9
VideoTool/src/main/java/com/yc/videotool/Tool.java

@@ -1,9 +0,0 @@
-package com.yc.videotool;
-
-public final class Tool {
-
-    /**
-     * 工具基础库介绍
-     */
-
-}

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/utils/VideoLogUtils.java → VideoTool/src/main/java/com/yc/videotool/VideoLogUtils.java

@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */
-package com.yc.kernel.utils;
+package com.yc.videotool;
 
 import android.util.Log;
 

+ 10 - 6
VideoView/src/main/java/com/yc/videoview/FloatLifecycle.java

@@ -12,6 +12,8 @@ import android.os.Handler;
 
 import androidx.annotation.RequiresApi;
 
+import com.yc.videoview.inter.ILifecycleListener;
+
 /**
  * 用于控制悬浮窗显示周期
  * 使用了三种方法针对返回桌面时隐藏悬浮按钮
@@ -26,22 +28,24 @@ public class FloatLifecycle extends BroadcastReceiver implements Application.Act
     private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
     private static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
     private static final long delay = 300;
-    private Handler mHandler;
-    private Class[] activities;
-    private boolean showFlag;
+    private final Handler mHandler;
+    private final Class[] activities;
+    private final boolean showFlag;
     private int startCount;
     private int resumeCount;
     private boolean appBackground;
-    private LifecycleListener mLifecycleListener;
+    private final ILifecycleListener mLifecycleListener;
 
 
-    FloatLifecycle(Context applicationContext, boolean showFlag, Class[] activities, LifecycleListener lifecycleListener) {
+    FloatLifecycle(Context applicationContext, boolean showFlag, Class[] activities,
+                   ILifecycleListener lifecycleListener) {
         this.showFlag = showFlag;
         this.activities = activities;
         mLifecycleListener = lifecycleListener;
         mHandler = new Handler();
         ((Application) applicationContext).registerActivityLifecycleCallbacks(this);
-        applicationContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
+        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        applicationContext.registerReceiver(this, intentFilter);
     }
 
 

+ 14 - 7
VideoView/src/main/java/com/yc/videoview/FloatPhone.java

@@ -6,11 +6,18 @@ import android.os.Build;
 import android.view.View;
 import android.view.WindowManager;
 
+import com.yc.videoview.abs.AbsFloatView;
+
 /**
- * 7.1及以上需申请权限
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 抽象view类的实现类
+ *     revise: 7.1及以上需申请权限
+ * </pre>
  */
-
-public class FloatPhone extends FloatView {
+public class FloatPhone extends AbsFloatView {
 
     private final Context mContext;
     private final WindowManager mWindowManager;
@@ -112,25 +119,25 @@ public class FloatPhone extends FloatView {
     }
 
     @Override
-    void updateX(int x) {
+    public void updateX(int x) {
         mLayoutParams.x = mX = x;
         mWindowManager.updateViewLayout(mView, mLayoutParams);
 
     }
 
     @Override
-    void updateY(int y) {
+    public void updateY(int y) {
         mLayoutParams.y = mY = y;
         mWindowManager.updateViewLayout(mView, mLayoutParams);
     }
 
     @Override
-    int getX() {
+    public int getX() {
         return mX;
     }
 
     @Override
-    int getY() {
+    public int getY() {
         return mY;
     }
 }

+ 12 - 5
VideoView/src/main/java/com/yc/videoview/FloatToast.java

@@ -5,17 +5,24 @@ import android.view.View;
 import android.view.WindowManager;
 import android.widget.Toast;
 
+import com.yc.videoview.abs.AbsFloatView;
+
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
+
 /**
- * 自定义 toast 方式,无需申请权限
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 自定义 toast 方式,无需申请权限
+ *     revise:
+ * </pre>
  */
+public class FloatToast extends AbsFloatView {
 
-public class FloatToast extends FloatView {
-
-
-    private Toast toast;
+    private final Toast toast;
     private Object mTN;
     private Method show;
     private Method hide;

+ 0 - 31
VideoView/src/main/java/com/yc/videoview/FloatView.java

@@ -1,31 +0,0 @@
-package com.yc.videoview;
-
-import android.view.View;
-
-
-public abstract class FloatView {
-
-    abstract void setSize(int width, int height);
-
-    abstract void setView(View view);
-
-    abstract void setGravity(int gravity, int xOffset, int yOffset);
-
-    abstract void init();
-
-    abstract void dismiss();
-
-    void updateXY(int x, int y) {}
-
-    void updateX(int x) {}
-
-    void updateY(int y) {}
-
-    int getX() {
-        return 0;
-    }
-
-    int getY() {
-        return 0;
-    }
-}

+ 2 - 0
VideoView/src/main/java/com/yc/videoview/FloatWindow.java

@@ -12,6 +12,8 @@ import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.yc.videoview.inter.IFloatWindow;
+
 import java.util.HashMap;
 import java.util.Map;
 

+ 0 - 27
VideoView/src/main/java/com/yc/videoview/IFloatWindow.java

@@ -1,27 +0,0 @@
-package com.yc.videoview;
-
-import android.view.View;
-
-
-public abstract class IFloatWindow {
-
-    public abstract void show();
-
-    public abstract void hide();
-
-    public abstract int getX();
-
-    public abstract int getY();
-
-    public abstract void updateX(int x);
-
-    public abstract void updateX(@WindowScreen.screenType int screenType, float ratio);
-
-    public abstract void updateY(int y);
-
-    public abstract void updateY(@WindowScreen.screenType int screenType, float ratio);
-
-    public abstract View getView();
-
-    abstract void dismiss();
-}

+ 16 - 4
VideoView/src/main/java/com/yc/videoview/IFloatWindowImpl.java

@@ -11,12 +11,24 @@ import android.view.MotionEvent;
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
 
+import com.yc.videoview.abs.AbsFloatView;
+import com.yc.videoview.inter.IFloatWindow;
+import com.yc.videoview.inter.ILifecycleListener;
 
-public class IFloatWindowImpl extends IFloatWindow {
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 定义悬浮Window接口类的具体实现类
+ *     revise:
+ * </pre>
+ */
+public class IFloatWindowImpl implements IFloatWindow {
 
 
     private FloatWindow.Builder mB;
-    private FloatView mFloatView;
+    private AbsFloatView mFloatView;
     private FloatLifecycle mFloatLifecycle;
     private boolean isShow;
     private boolean once = true;
@@ -44,7 +56,7 @@ public class IFloatWindowImpl extends IFloatWindow {
         mFloatView.setGravity(mB.gravity, mB.xOffset, mB.yOffset);
         mFloatView.setView(mB.mView);
         mFloatLifecycle = new FloatLifecycle(mB.mApplicationContext,
-                mB.mShow, mB.mActivities, new LifecycleListener() {
+                mB.mShow, mB.mActivities, new ILifecycleListener() {
             @Override
             public void onShow() {
                 show();
@@ -91,7 +103,7 @@ public class IFloatWindowImpl extends IFloatWindow {
     }
 
     @Override
-    void dismiss() {
+    public void dismiss() {
         mFloatView.dismiss();
         isShow = false;
     }

+ 0 - 11
VideoView/src/main/java/com/yc/videoview/LifecycleListener.java

@@ -1,11 +0,0 @@
-package com.yc.videoview;
-
-
-interface LifecycleListener {
-
-    void onShow();
-
-    void onHide();
-
-    void onPostHide();
-}

+ 4 - 1
VideoView/src/main/java/com/yc/videoview/MoveType.java

@@ -16,5 +16,8 @@ public class MoveType {
 
     @IntDef({fixed, free, active, slide, back})
     @Retention(RetentionPolicy.SOURCE)
-    @interface MOVE_TYPE {}
+    public @interface MOVE_TYPE {
+
+    }
+
 }

+ 3 - 3
VideoView/src/main/java/com/yc/videoview/SmallWindowTouch.java

@@ -18,10 +18,10 @@ import android.widget.FrameLayout;
 public class SmallWindowTouch implements View.OnTouchListener {
 
     private int mDownX, mDownY;
-    private int mMarginLeft, mMarginTop;
+    private final int mMarginLeft;
+    private final int mMarginTop;
     private int _xDelta, _yDelta;
-    private View mView;
-
+    private final View mView;
 
     public SmallWindowTouch(View view, int marginLeft, int marginTop) {
         super();

+ 1 - 1
VideoView/src/main/java/com/yc/videoview/WindowScreen.java

@@ -13,5 +13,5 @@ public class WindowScreen {
 
     @IntDef({WIDTH, HEIGHT})
     @Retention(RetentionPolicy.SOURCE)
-    @interface screenType {}
+    public @interface screenType {}
 }

+ 39 - 0
VideoView/src/main/java/com/yc/videoview/abs/AbsFloatView.java

@@ -0,0 +1,39 @@
+package com.yc.videoview.abs;
+
+import android.view.View;
+
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 抽象view类
+ *     revise: 定义抽象方法和普通方法
+ * </pre>
+ */
+public abstract class AbsFloatView {
+
+    public abstract void setSize(int width, int height);
+
+    public abstract void setView(View view);
+
+    public abstract void setGravity(int gravity, int xOffset, int yOffset);
+
+    public abstract void init();
+
+    public abstract void dismiss();
+
+    public void updateXY(int x, int y) {}
+
+    public void updateX(int x) {}
+
+    public void updateY(int y) {}
+
+    public int getX() {
+        return 0;
+    }
+
+    public int getY() {
+        return 0;
+    }
+}

+ 37 - 0
VideoView/src/main/java/com/yc/videoview/inter/IFloatWindow.java

@@ -0,0 +1,37 @@
+package com.yc.videoview.inter;
+
+import android.view.View;
+
+import com.yc.videoview.WindowScreen;
+
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 定义悬浮Window接口类
+ *     revise:
+ * </pre>
+ */
+public interface IFloatWindow {
+
+    void show();
+
+    void hide();
+
+    int getX();
+
+    int getY();
+
+    void updateX(int x);
+
+    void updateX(@WindowScreen.screenType int screenType, float ratio);
+
+    void updateY(int y);
+
+    void updateY(@WindowScreen.screenType int screenType, float ratio);
+
+    View getView();
+
+    void dismiss();
+}

+ 19 - 0
VideoView/src/main/java/com/yc/videoview/inter/ILifecycleListener.java

@@ -0,0 +1,19 @@
+package com.yc.videoview.inter;
+
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2017/10/21
+ *     desc  : 定义生命周期接口类
+ *     revise:
+ * </pre>
+ */
+public interface ILifecycleListener {
+
+    void onShow();
+
+    void onHide();
+
+    void onPostHide();
+}

+ 21 - 0
read/61.如何打造全局悬浮窗.md

@@ -0,0 +1,21 @@
+# 如何打造全局悬浮窗
+#### 目录介绍
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 5 - 3
settings.gradle

@@ -1,4 +1,4 @@
-
+include ':ndkbitmap-armv7a'
 //视频弹幕
 include ':VideoBarrage'
 //视频录频
@@ -20,7 +20,9 @@ include ':VideoCache'
 //视频播放器
 include ':VideoPlayer'
 include ':Demo'
-//视频工具
-include ':VideoTool'
 //音频播放
 include ':AudioPlayer'
+//视频工具库
+include ':VideoTool'
+//视频监控库【在完善中】
+include ':VideoMonitor'