Commit cac98eccb272cfb50216dcd2bb9d358e54dae2a7

Authored by 韩亚云
2 parents 595a51fb 273f0cf5

Merge branch 'master' of bj.gitlab.cnlive.com:cnlive-team/newModuleStrike

Showing 17 changed files with 274 additions and 86 deletions
.idea/inspectionProfiles/Project_Default.xml 0 → 100644
  1 +<component name="InspectionProjectProfileManager">
  2 + <profile version="1.0">
  3 + <option name="myName" value="Project Default" />
  4 + <inspection_tool class="AndroidLintLockedOrientationActivity" enabled="false" level="ERROR" enabled_by_default="false" />
  5 + <inspection_tool class="AndroidLintSourceLockedOrientationActivity" enabled="false" level="ERROR" enabled_by_default="false" />
  6 + </profile>
  7 +</component>
0 \ No newline at end of file 8 \ No newline at end of file
app/strike/src/main/AndroidManifest.xml
@@ -34,20 +34,20 @@ @@ -34,20 +34,20 @@
34 </provider> 34 </provider>
35 <activity 35 <activity
36 android:name="com.cnlive.strike.demo.activity.tiktok.TikTokViewPager2Activity" 36 android:name="com.cnlive.strike.demo.activity.tiktok.TikTokViewPager2Activity"
37 - android:screenOrientation="fullSensor" /> 37 + android:screenOrientation="portrait" />
38 <activity 38 <activity
39 android:name="com.cnlive.strike.demo.activity.tiktok.TikTokRecycleActivity" 39 android:name="com.cnlive.strike.demo.activity.tiktok.TikTokRecycleActivity"
40 - android:screenOrientation="fullSensor" /> 40 + android:screenOrientation="portrait" />
41 <activity 41 <activity
42 android:name="com.cnlive.strike.demo.activity.tiktok.DemoTikTokActivity" 42 android:name="com.cnlive.strike.demo.activity.tiktok.DemoTikTokActivity"
43 - android:screenOrientation="fullSensor" /> 43 + android:screenOrientation="portrait" />
44 <activity 44 <activity
45 android:name="com.cnlive.strike.demo.activity.tiktok.TikTokVerticalViewPagerActivity" 45 android:name="com.cnlive.strike.demo.activity.tiktok.TikTokVerticalViewPagerActivity"
46 - android:screenOrientation="fullSensor" /> 46 + android:screenOrientation="portrait"/>
47 <activity 47 <activity
48 android:name="com.cnlive.strike.demo.activity.ExoPlayerActivity" 48 android:name="com.cnlive.strike.demo.activity.ExoPlayerActivity"
49 android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" 49 android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
50 - android:screenOrientation="fullSensor" /> 50 + android:screenOrientation="portrait" />
51 <activity android:name="com.cnlive.strike.demo.activity.CNplayerActivity" /> 51 <activity android:name="com.cnlive.strike.demo.activity.CNplayerActivity" />
52 <activity android:name="com.cnlive.strike.demo.activity.DemoAnimActivity" /> 52 <activity android:name="com.cnlive.strike.demo.activity.DemoAnimActivity" />
53 <activity 53 <activity
app/strike/src/main/java/com/cnlive/strike/DemoApplication.java
@@ -101,7 +101,7 @@ public class DemoApplication extends BaseApplication { @@ -101,7 +101,7 @@ public class DemoApplication extends BaseApplication {
101 // .setPlayerFactory(ThunderMediaPlayerFactory.create()) 101 // .setPlayerFactory(ThunderMediaPlayerFactory.create())
102 .setPlayerFactory(ExoMediaPlayerFactory.create()) 102 .setPlayerFactory(ExoMediaPlayerFactory.create())
103 .setRenderViewFactory(TextureRenderViewFactory.create()) 103 .setRenderViewFactory(TextureRenderViewFactory.create())
104 - .setEnableOrientation(true) 104 + .setEnableOrientation(false)
105 // .setEnableAudioFocus(false) 105 // .setEnableAudioFocus(false)
106 // .setScreenScaleType(VideoView.SCREEN_SCALE_MATCH_PARENT) 106 // .setScreenScaleType(VideoView.SCREEN_SCALE_MATCH_PARENT)
107 // .setAdaptCutout(false) 107 // .setAdaptCutout(false)
app/strike/src/main/java/com/cnlive/strike/demo/activity/ExoPlayerActivity.java
@@ -18,10 +18,13 @@ import com.google.android.exoplayer2.source.hls.HlsMediaSource; @@ -18,10 +18,13 @@ import com.google.android.exoplayer2.source.hls.HlsMediaSource;
18 import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; 18 import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
19 import com.google.android.exoplayer2.util.Util; 19 import com.google.android.exoplayer2.util.Util;
20 import com.google.android.exoplayer2.video.VideoListener; 20 import com.google.android.exoplayer2.video.VideoListener;
  21 +import com.libs.video.util.cache.PreloadManager;
21 import com.libs.video.util.cache.ProxyVideoCacheManager; 22 import com.libs.video.util.cache.ProxyVideoCacheManager;
22 import com.libs.video.video.exoplayer.component.DefaultErrorView; 23 import com.libs.video.video.exoplayer.component.DefaultErrorView;
23 import com.libs.video.video.exoplayer.component.DefaultYoukuPrepareView; 24 import com.libs.video.video.exoplayer.component.DefaultYoukuPrepareView;
24 import com.libs.video.video.exoplayer.play.CNVideoView; 25 import com.libs.video.video.exoplayer.play.CNVideoView;
  26 +import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaSourceHelper;
  27 +import com.libs.video.video.exoplayer.util.PlayCacheUtils;
25 import com.libs.video.video.test.CNLiveVideoView; 28 import com.libs.video.video.test.CNLiveVideoView;
26 import com.libs.video.video.test.VideoPlayer; 29 import com.libs.video.video.test.VideoPlayer;
27 import com.libs.video.video.exoplayer.component.DefaultAdControlView; 30 import com.libs.video.video.exoplayer.component.DefaultAdControlView;
@@ -44,6 +47,7 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl @@ -44,6 +47,7 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
44 private static final String URL_AD = "https://gslb.miaopai.com/stream/IR3oMYDhrON5huCmf7sHCfnU5YKEkgO2.mp4"; 47 private static final String URL_AD = "https://gslb.miaopai.com/stream/IR3oMYDhrON5huCmf7sHCfnU5YKEkgO2.mp4";
45 48
46 private StandardVideoController mController; 49 private StandardVideoController mController;
  50 + private PreloadManager mPreloadManager;
47 51
48 @Override 52 @Override
49 protected int getBindLayoutId() { 53 protected int getBindLayoutId() {
@@ -82,7 +86,6 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl @@ -82,7 +86,6 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
82 player.prepare(hlsMediaSource); 86 player.prepare(hlsMediaSource);
83 87
84 88
85 -  
86 mController = new StandardVideoController(this); 89 mController = new StandardVideoController(this);
87 DefaultAdControlView adControlView = new DefaultAdControlView(this); 90 DefaultAdControlView adControlView = new DefaultAdControlView(this);
88 adControlView.setListener(new DefaultAdControlView.AdControlListener() { 91 adControlView.setListener(new DefaultAdControlView.AdControlListener() {
@@ -96,15 +99,13 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl @@ -96,15 +99,13 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
96 playVideo(); 99 playVideo();
97 } 100 }
98 }); 101 });
99 - DefaultErrorView errorView=new DefaultErrorView(this);  
100 - mController.addControlComponent(adControlView,new DefaultYoukuPrepareView(me),errorView); 102 + DefaultErrorView errorView = new DefaultErrorView(this);
  103 + mController.addControlComponent(adControlView, new DefaultYoukuPrepareView(me), errorView);
101 //直播 104 //直播
102 - HttpProxyCacheServer cacheServer = ProxyVideoCacheManager.getProxy(this);  
103 - String proxyUrl = cacheServer.getProxyUrl(URL_AD);  
104 - binding.playerView.setUrl(proxyUrl);  
105 -// binding.playerView.setUrl("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8"); 105 +// binding.playerView.setUrl(proxyUrl);
  106 + binding.playerView.setUrl("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8", true);
106 binding.playerView.setVideoController(mController); 107 binding.playerView.setVideoController(mController);
107 - binding.playerView.setScreenScaleType(CNVideoView.SCREEN_SCALE_16_9); 108 +// binding.playerView.setScreenScaleType(CNVideoView.SCREEN_SCALE_16_9);
108 binding.playerView.start(); 109 binding.playerView.start();
109 //监听播放结束 110 //监听播放结束
110 // binding.playerView.addOnStateChangeListener(new CNVideoView.SimpleOnStateChangeListener() { 111 // binding.playerView.addOnStateChangeListener(new CNVideoView.SimpleOnStateChangeListener() {
@@ -154,7 +155,7 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl @@ -154,7 +155,7 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
154 private void playVideo() { 155 private void playVideo() {
155 binding.playerView.release(); 156 binding.playerView.release();
156 mController.removeAllControlComponent(); 157 mController.removeAllControlComponent();
157 - mController.addDefaultControlComponent("正片", true); 158 + mController.addDefaultControlComponent("正片", false);
158 //重新设置数据 159 //重新设置数据
159 // List<String> list = new ArrayList<>(); 160 // List<String> list = new ArrayList<>();
160 // list.add("http://sbslive.cnrmobile.com/storage/storage4/76/23/10/14de52115893fb5371b7e064f910ab7b.3gp"); 161 // list.add("http://sbslive.cnrmobile.com/storage/storage4/76/23/10/14de52115893fb5371b7e064f910ab7b.3gp");
@@ -162,8 +163,8 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl @@ -162,8 +163,8 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
162 // list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8"); 163 // list.add("http://ffyl.vods2.cnlive.com/223/vod/2018/1120/223_88c98ab1395f4762b703fbdd9d59d2e5/ff80808166c2a45201672f14a9933131_800.m3u8");
163 // list.add("http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8"); 164 // list.add("http://ivi.bupt.edu.cn/hls/cctv1hd.m3u8");
164 // binding.playerView.setDataSource(list); 165 // binding.playerView.setDataSource(list);
165 - binding.playerView.setUrl("rtmp://tyzg.rtmps2.cnlive.com/live-tyzg-577/577_999");  
166 - 166 + binding.playerView.setUrl("https://qq.com-ok-qq.com/20191005/24249_f5e36323/index.m3u8", true);
  167 +// binding.playerView.setUrl("rtmp://tyzg.rtmps2.cnlive.com/live-tyzg-577/577_999");
167 //开始播放 168 //开始播放
168 binding.playerView.start(); 169 binding.playerView.start();
169 } 170 }
@@ -187,4 +188,6 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl @@ -187,4 +188,6 @@ public class ExoPlayerActivity extends BaseActivity implements VideoListener, Pl
187 // }); 188 // });
188 } 189 }
189 190
  191 +
  192 +
190 } 193 }
cloud/video/src/main/java/com/danikula/videocache/StorageUtils.java
@@ -37,7 +37,7 @@ public final class StorageUtils { @@ -37,7 +37,7 @@ public final class StorageUtils {
37 * <i>("/Android/data/[app_package_name]/cache")</i> (if card is mounted and app has appropriate permission) or 37 * <i>("/Android/data/[app_package_name]/cache")</i> (if card is mounted and app has appropriate permission) or
38 * on device's file system depending incoming parameters. 38 * on device's file system depending incoming parameters.
39 * 39 *
40 - * @param context Application context 40 + * @param context Application context
41 * @return Cache {@link File directory}.<br /> 41 * @return Cache {@link File directory}.<br />
42 * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and 42 * <b>NOTE:</b> Can be null in some unpredictable cases (if SD card is unmounted and
43 * {@link Context#getCacheDir() Context.getCacheDir()} returns null). 43 * {@link Context#getCacheDir() Context.getCacheDir()} returns null).
@@ -58,6 +58,26 @@ public final class StorageUtils { @@ -58,6 +58,26 @@ public final class StorageUtils {
58 } 58 }
59 59
60 /** 60 /**
  61 + * 获取缓存路径
  62 + *
  63 + * @param context
  64 + * @return
  65 + */
  66 + public static String getCacheDirectoryPath(Context context) {
  67 + String appCacheDir = null;
  68 + if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
  69 + appCacheDir = context.getExternalCacheDir().getAbsolutePath();
  70 + }
  71 + if (appCacheDir == null) {
  72 + appCacheDir = context.getCacheDir().getAbsolutePath();
  73 + }
  74 + if (appCacheDir == null) {
  75 + appCacheDir = "/data/data/" + context.getPackageName() + "/cache/";
  76 + }
  77 + return appCacheDir;
  78 + }
  79 +
  80 + /**
61 * delete directory 81 * delete directory
62 */ 82 */
63 public static boolean deleteFiles(File root) { 83 public static boolean deleteFiles(File root) {
cloud/video/src/main/java/com/libs/video/util/cache/ProxyVideoCacheManager.java
@@ -20,7 +20,7 @@ public class ProxyVideoCacheManager { @@ -20,7 +20,7 @@ public class ProxyVideoCacheManager {
20 20
21 private static HttpProxyCacheServer newProxy(Context context) { 21 private static HttpProxyCacheServer newProxy(Context context) {
22 return new HttpProxyCacheServer.Builder(context) 22 return new HttpProxyCacheServer.Builder(context)
23 - .maxCacheSize(512 * 1024 * 1024) // 512MB for cache 23 + .maxCacheSize(1024 * 1024 * 1024) // 512MB for cache
24 //缓存路径,不设置默认在sd_card/Android/data/[app_package_name]/cache中 24 //缓存路径,不设置默认在sd_card/Android/data/[app_package_name]/cache中
25 // .cacheDirectory() 25 // .cacheDirectory()
26 .build(); 26 .build();
cloud/video/src/main/java/com/libs/video/video/exoplayer/PlayErrorException.java
@@ -5,8 +5,6 @@ import android.text.TextUtils; @@ -5,8 +5,6 @@ import android.text.TextUtils;
5 5
6 import androidx.annotation.IntDef; 6 import androidx.annotation.IntDef;
7 7
8 -import com.cnlive.core.libs.base.util.StatusBarConfig;  
9 -  
10 import java.lang.annotation.Retention; 8 import java.lang.annotation.Retention;
11 import java.lang.annotation.RetentionPolicy; 9 import java.lang.annotation.RetentionPolicy;
12 10
@@ -19,26 +17,20 @@ public class PlayErrorException extends Exception { @@ -19,26 +17,20 @@ public class PlayErrorException extends Exception {
19 public static final int TYPE_OUT_OF_MEMORY = 2;//内存溢出 17 public static final int TYPE_OUT_OF_MEMORY = 2;//内存溢出
20 public static final int TYPE_UNEXPECTED_ERROR = 3;//未知错误 18 public static final int TYPE_UNEXPECTED_ERROR = 3;//未知错误
21 public static final int TYPE_RENDERER_ERROR = 4;//渲染异常 19 public static final int TYPE_RENDERER_ERROR = 4;//渲染异常
22 - public static final int TYPE_MediaPlayer_IOException = 5;  
23 - public static final int TYPE_MediaPlayer_IllegalArgumentException = 6;  
24 - public static final int TYPE_MediaPlayer_SecurityException = 7;  
25 - public static final int TYPE_MediaPlayer_IllegalStateException = 8;  
26 - public static final int TYPE_MediaPlayer_unknownException = 9;  
27 - public static final int TYPE_MediaPlayer_ON_ERROR = 10;  
28 -  
29 - 20 + public static final int TYPE_IllegalArgumentException = 5;
  21 + public static final int TYPE_SecurityException = 6;
  22 + public static final int TYPE_IllegalStateException = 7;
  23 + public static final int TYPE_TIMED_OUT_ERROR = 9;//播放超时错误
  24 + public static final int TYPE_MEDIA_UNSUPPORTED_ERROR = 10;//不支持的媒体类型
  25 + public static final int TYPE_MEDIA_SERVER_DIED_ERROR = 11;//媒体服务器挂机(应用必须释放对象,然后开启新的实例)
  26 + public static final int TYPE_OTHER_ERROR = 12;//其他错误
30 private int errorType;//错误类型 27 private int errorType;//错误类型
31 private String errorMsg;//错误信息 28 private String errorMsg;//错误信息
32 29
33 30
34 - private MediaPlayer mediaPlayer;  
35 - private int mediaPlayer_what;  
36 - private int mediaPlayer_extra;  
37 -  
38 -  
39 @IntDef({TYPE_NETWORK_ERROR, TYPE_SOURCE_ERROR, TYPE_OUT_OF_MEMORY, TYPE_UNEXPECTED_ERROR, TYPE_RENDERER_ERROR, 31 @IntDef({TYPE_NETWORK_ERROR, TYPE_SOURCE_ERROR, TYPE_OUT_OF_MEMORY, TYPE_UNEXPECTED_ERROR, TYPE_RENDERER_ERROR,
40 - TYPE_MediaPlayer_IOException, TYPE_MediaPlayer_IllegalArgumentException, TYPE_MediaPlayer_SecurityException,  
41 - TYPE_MediaPlayer_IllegalStateException, TYPE_MediaPlayer_unknownException, TYPE_MediaPlayer_ON_ERROR}) 32 + TYPE_IllegalArgumentException, TYPE_SecurityException, TYPE_IllegalStateException,
  33 + TYPE_TIMED_OUT_ERROR,TYPE_MEDIA_UNSUPPORTED_ERROR,TYPE_MEDIA_SERVER_DIED_ERROR,TYPE_OTHER_ERROR})
42 @Retention(RetentionPolicy.SOURCE) 34 @Retention(RetentionPolicy.SOURCE)
43 public @interface Type { 35 public @interface Type {
44 } 36 }
@@ -70,27 +62,4 @@ public class PlayErrorException extends Exception { @@ -70,27 +62,4 @@ public class PlayErrorException extends Exception {
70 this.errorMsg = errorMsg; 62 this.errorMsg = errorMsg;
71 } 63 }
72 64
73 - public MediaPlayer getMediaPlayer() {  
74 - return mediaPlayer;  
75 - }  
76 -  
77 - public void setMediaPlayer(MediaPlayer mediaPlayer) {  
78 - this.mediaPlayer = mediaPlayer;  
79 - }  
80 -  
81 - public int getMediaPlayer_what() {  
82 - return mediaPlayer_what;  
83 - }  
84 -  
85 - public void setMediaPlayer_what(int mediaPlayer_what) {  
86 - this.mediaPlayer_what = mediaPlayer_what;  
87 - }  
88 -  
89 - public int getMediaPlayer_extra() {  
90 - return mediaPlayer_extra;  
91 - }  
92 -  
93 - public void setMediaPlayer_extra(int mediaPlayer_extra) {  
94 - this.mediaPlayer_extra = mediaPlayer_extra;  
95 - }  
96 } 65 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/component/DebugInfoView.java
@@ -13,7 +13,7 @@ import android.widget.TextView; @@ -13,7 +13,7 @@ import android.widget.TextView;
13 import com.libs.video.video.exoplayer.PlayErrorException; 13 import com.libs.video.video.exoplayer.PlayErrorException;
14 import com.libs.video.video.exoplayer.controller.ControlWrapper; 14 import com.libs.video.video.exoplayer.controller.ControlWrapper;
15 import com.libs.video.video.exoplayer.controller.IControlComponent; 15 import com.libs.video.video.exoplayer.controller.IControlComponent;
16 -import com.libs.video.video.exoplayer.play.AndroidMediaPlayerFactory; 16 +import com.libs.video.video.exoplayer.playerCore.mediaplayer.AndroidMediaPlayerFactory;
17 import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaPlayerFactory; 17 import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaPlayerFactory;
18 import com.libs.video.video.exoplayer.util.PlayerUtils; 18 import com.libs.video.video.exoplayer.util.PlayerUtils;
19 19
cloud/video/src/main/java/com/libs/video/video/exoplayer/controller/MediaPlayerControl.java
@@ -9,7 +9,6 @@ import com.libs.video.video.exoplayer.play.AbstractPlayer; @@ -9,7 +9,6 @@ import com.libs.video.video.exoplayer.play.AbstractPlayer;
9 */ 9 */
10 public interface MediaPlayerControl { 10 public interface MediaPlayerControl {
11 11
12 -// int getMediaCount();  
13 12
14 void start(); 13 void start();
15 14
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/AbstractPlayer.java
1 package com.libs.video.video.exoplayer.play; 1 package com.libs.video.video.exoplayer.play;
2 2
  3 +import android.content.Context;
3 import android.content.res.AssetFileDescriptor; 4 import android.content.res.AssetFileDescriptor;
4 import android.view.Surface; 5 import android.view.Surface;
5 import android.view.SurfaceHolder; 6 import android.view.SurfaceHolder;
@@ -53,11 +54,29 @@ public abstract class AbstractPlayer { @@ -53,11 +54,29 @@ public abstract class AbstractPlayer {
53 */ 54 */
54 public abstract void setDataSource(String path, Map<String, String> headers); 55 public abstract void setDataSource(String path, Map<String, String> headers);
55 56
  57 +
  58 + public abstract void setDataSource(String path, Map<String, String> headers, boolean isCache);
  59 +
56 /** 60 /**
57 * 用于播放raw和asset里面的视频文件 61 * 用于播放raw和asset里面的视频文件
58 */ 62 */
59 public abstract void setDataSource(AssetFileDescriptor fd); 63 public abstract void setDataSource(AssetFileDescriptor fd);
60 64
  65 +// /**
  66 +// * 清除全部视频缓存
  67 +// *
  68 +// * @param context
  69 +// */
  70 +// public abstract void clearAllCache(Context context);
  71 +//
  72 +// /**
  73 +// * 根据url清除指定视频缓存
  74 +// *
  75 +// * @param context
  76 +// * @param url
  77 +// */
  78 +// public abstract void clearDefaultCache(Context context, String url);
  79 +
61 /** 80 /**
62 * 播放 81 * 播放
63 */ 82 */
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/CNVideoView.java
@@ -128,6 +128,8 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -128,6 +128,8 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
128 */ 128 */
129 private int mPlayerBackgroundColor; 129 private int mPlayerBackgroundColor;
130 130
  131 + private boolean isCache;//是否边缓存边播放
  132 +
131 // private List<String> dataSource; 133 // private List<String> dataSource;
132 // private int curentPlayIndex; 134 // private int curentPlayIndex;
133 135
@@ -237,7 +239,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -237,7 +239,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
237 if (mProgressManager != null) { 239 if (mProgressManager != null) {
238 mCurrentPosition = mProgressManager.getSavedProgress(mUrl); 240 mCurrentPosition = mProgressManager.getSavedProgress(mUrl);
239 } 241 }
240 - initPlayer(); 242 + initPlayer();
241 //添加渲染视图 243 //添加渲染视图
242 addDisplay(); 244 addDisplay();
243 startPrepare(false); 245 startPrepare(false);
@@ -272,7 +274,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -272,7 +274,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
272 * 初始化播放器 274 * 初始化播放器
273 */ 275 */
274 protected void initPlayer() { 276 protected void initPlayer() {
275 - if (null==mMediaPlayer){ 277 + if (null == mMediaPlayer) {
276 //初始化播放器 278 //初始化播放器
277 mMediaPlayer = mPlayerFactory.createPlayer(getContext()); 279 mMediaPlayer = mPlayerFactory.createPlayer(getContext());
278 } 280 }
@@ -341,7 +343,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -341,7 +343,7 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
341 mMediaPlayer.setDataSource(mAssetFileDescriptor); 343 mMediaPlayer.setDataSource(mAssetFileDescriptor);
342 return true; 344 return true;
343 } else if (!TextUtils.isEmpty(mUrl)) { 345 } else if (!TextUtils.isEmpty(mUrl)) {
344 - mMediaPlayer.setDataSource(mUrl, mHeaders); 346 + mMediaPlayer.setDataSource(mUrl, mHeaders, isCache);
345 return true; 347 return true;
346 } 348 }
347 return false; 349 return false;
@@ -657,13 +659,24 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -657,13 +659,24 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
657 /** 659 /**
658 * 设置视频地址 660 * 设置视频地址
659 */ 661 */
660 - public void setUrl(String url) { 662 + public void setUrl(String url, boolean isCache) {
  663 + this.isCache = isCache;
661 // dataSource.clear(); 664 // dataSource.clear();
662 // dataSource.add(url); 665 // dataSource.add(url);
663 // curentPlayIndex = 0; 666 // curentPlayIndex = 0;
664 setUrl(url, null); 667 setUrl(url, null);
665 } 668 }
666 669
  670 + /**
  671 + * 设置视频地址
  672 + */
  673 + public void setUrl(String url) {
  674 + this.isCache = false;
  675 +// dataSource.clear();
  676 +// dataSource.add(url);
  677 +// curentPlayIndex = 0;
  678 + setUrl(url, null);
  679 + }
667 // public void setDataSource(List<String> url) { 680 // public void setDataSource(List<String> url) {
668 // dataSource.clear(); 681 // dataSource.clear();
669 // dataSource.addAll(url); 682 // dataSource.addAll(url);
@@ -944,14 +957,14 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -944,14 +957,14 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
944 * 设置控制器,传null表示移除控制器 957 * 设置控制器,传null表示移除控制器
945 */ 958 */
946 public void setVideoController(@Nullable BaseVideoController mediaController) { 959 public void setVideoController(@Nullable BaseVideoController mediaController) {
947 - if (null==mMediaPlayer){ 960 + if (null == mMediaPlayer) {
948 //初始化播放器 961 //初始化播放器
949 mMediaPlayer = mPlayerFactory.createPlayer(getContext()); 962 mMediaPlayer = mPlayerFactory.createPlayer(getContext());
950 } 963 }
951 mPlayerContainer.removeView(mVideoController); 964 mPlayerContainer.removeView(mVideoController);
952 mVideoController = mediaController; 965 mVideoController = mediaController;
953 if (mediaController != null) { 966 if (mediaController != null) {
954 - mediaController.setMediaPlayer(this,mMediaPlayer); 967 + mediaController.setMediaPlayer(this, mMediaPlayer);
955 LayoutParams params = new LayoutParams( 968 LayoutParams params = new LayoutParams(
956 ViewGroup.LayoutParams.MATCH_PARENT, 969 ViewGroup.LayoutParams.MATCH_PARENT,
957 ViewGroup.LayoutParams.MATCH_PARENT); 970 ViewGroup.LayoutParams.MATCH_PARENT);
@@ -1150,8 +1163,9 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout @@ -1150,8 +1163,9 @@ public class CNVideoView&lt;P extends AbstractPlayer&gt; extends FrameLayout
1150 /** 1163 /**
1151 * 视频缩放类型 1164 * 视频缩放类型
1152 */ 1165 */
1153 - @IntDef({SCREEN_SCALE_DEFAULT,SCREEN_SCALE_16_9,SCREEN_SCALE_4_3,SCREEN_SCALE_MATCH_PARENT,SCREEN_SCALE_ORIGINAL,SCREEN_SCALE_CENTER_CROP}) 1166 + @IntDef({SCREEN_SCALE_DEFAULT, SCREEN_SCALE_16_9, SCREEN_SCALE_4_3, SCREEN_SCALE_MATCH_PARENT, SCREEN_SCALE_ORIGINAL, SCREEN_SCALE_CENTER_CROP})
1154 @Retention(RetentionPolicy.SOURCE) 1167 @Retention(RetentionPolicy.SOURCE)
1155 public @interface screenScalType { 1168 public @interface screenScalType {
1156 } 1169 }
  1170 +
1157 } 1171 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/VideoViewConfig.java
@@ -2,6 +2,7 @@ package com.libs.video.video.exoplayer.play; @@ -2,6 +2,7 @@ package com.libs.video.video.exoplayer.play;
2 2
3 3
4 4
  5 +import com.libs.video.video.exoplayer.playerCore.mediaplayer.AndroidMediaPlayerFactory;
5 import com.libs.video.video.exoplayer.render.RenderViewFactory; 6 import com.libs.video.video.exoplayer.render.RenderViewFactory;
6 import com.libs.video.video.exoplayer.render.texture.TextureRenderViewFactory; 7 import com.libs.video.video.exoplayer.render.texture.TextureRenderViewFactory;
7 8
cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/exoplayer/ExoMediaPlayer.java
@@ -31,6 +31,7 @@ import com.google.android.exoplayer2.video.VideoListener; @@ -31,6 +31,7 @@ import com.google.android.exoplayer2.video.VideoListener;
31 import com.libs.video.video.exoplayer.PlayErrorException; 31 import com.libs.video.video.exoplayer.PlayErrorException;
32 import com.libs.video.video.exoplayer.play.AbstractPlayer; 32 import com.libs.video.video.exoplayer.play.AbstractPlayer;
33 import com.libs.video.video.exoplayer.play.VideoViewManager; 33 import com.libs.video.video.exoplayer.play.VideoViewManager;
  34 +import com.libs.video.video.exoplayer.util.PlayCacheUtils;
34 35
35 import java.util.Map; 36 import java.util.Map;
36 37
@@ -80,7 +81,6 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla @@ -80,7 +81,6 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla
80 Clock.DEFAULT) 81 Clock.DEFAULT)
81 .build(); 82 .build();
82 setOptions(); 83 setOptions();
83 -  
84 //播放器日志 84 //播放器日志
85 if (VideoViewManager.getConfig().mIsEnableLog && mTrackSelector instanceof MappingTrackSelector) { 85 if (VideoViewManager.getConfig().mIsEnableLog && mTrackSelector instanceof MappingTrackSelector) {
86 exoPlayer.addAnalyticsListener(new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer")); 86 exoPlayer.addAnalyticsListener(new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer"));
@@ -114,10 +114,16 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla @@ -114,10 +114,16 @@ public class ExoMediaPlayer extends AbstractPlayer implements VideoListener, Pla
114 } 114 }
115 115
116 @Override 116 @Override
  117 + public void setDataSource(String path, Map<String, String> headers, boolean isCache) {
  118 + mMediaSource = mMediaSourceHelper.getMediaSource(path, headers,isCache);
  119 + }
  120 +
  121 + @Override
117 public void setDataSource(AssetFileDescriptor fd) { 122 public void setDataSource(AssetFileDescriptor fd) {
118 //no support 123 //no support
119 } 124 }
120 125
  126 +
121 @Override 127 @Override
122 public void start() { 128 public void start() {
123 if (exoPlayer == null) 129 if (exoPlayer == null)
cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/exoplayer/ExoMediaSourceHelper.java
@@ -4,6 +4,7 @@ import android.content.Context; @@ -4,6 +4,7 @@ import android.content.Context;
4 import android.net.Uri; 4 import android.net.Uri;
5 import android.text.TextUtils; 5 import android.text.TextUtils;
6 6
  7 +import com.danikula.videocache.StorageUtils;
7 import com.google.android.exoplayer2.C; 8 import com.google.android.exoplayer2.C;
8 import com.google.android.exoplayer2.database.ExoDatabaseProvider; 9 import com.google.android.exoplayer2.database.ExoDatabaseProvider;
9 import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory; 10 import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory;
@@ -36,6 +37,8 @@ public final class ExoMediaSourceHelper { @@ -36,6 +37,8 @@ public final class ExoMediaSourceHelper {
36 private Context mAppContext; 37 private Context mAppContext;
37 private HttpDataSource.Factory mHttpDataSourceFactory; 38 private HttpDataSource.Factory mHttpDataSourceFactory;
38 private Cache mCache; 39 private Cache mCache;
  40 + private final int CACHE_SIZE = 1024;//缓存大小1G
  41 + public static final String CACHE_DIR = "exo-video-cache";
39 42
40 private ExoMediaSourceHelper(Context context) { 43 private ExoMediaSourceHelper(Context context) {
41 mAppContext = context.getApplicationContext(); 44 mAppContext = context.getApplicationContext();
@@ -117,11 +120,15 @@ public final class ExoMediaSourceHelper { @@ -117,11 +120,15 @@ public final class ExoMediaSourceHelper {
117 CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); 120 CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
118 } 121 }
119 122
120 - private Cache newCache() {  
121 - return new SimpleCache(  
122 - new File(mAppContext.getExternalCacheDir(), "exo-video-cache"),//缓存目录  
123 - new LeastRecentlyUsedCacheEvictor(512 * 1024 * 1024),//缓存大小,默认512M,使用LRU算法实现  
124 - new ExoDatabaseProvider(mAppContext)); 123 + public Cache newCache() {
  124 + if (null == mCache) {
  125 + return new SimpleCache(
  126 + new File(StorageUtils.getCacheDirectoryPath(mAppContext), CACHE_DIR),//缓存目录
  127 + new LeastRecentlyUsedCacheEvictor(CACHE_SIZE * 1024 * 1024),//缓存大小,默认512M,使用LRU算法实现
  128 + new ExoDatabaseProvider(mAppContext));
  129 + } else {
  130 + return mCache;
  131 + }
125 } 132 }
126 133
127 /** 134 /**
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/AndroidMediaPlayer.java renamed to cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/mediaplayer/AndroidMediaPlayer.java
1 -package com.libs.video.video.exoplayer.play; 1 +package com.libs.video.video.exoplayer.playerCore.mediaplayer;
2 2
3 import android.content.Context; 3 import android.content.Context;
4 import android.content.res.AssetFileDescriptor; 4 import android.content.res.AssetFileDescriptor;
@@ -6,10 +6,16 @@ import android.media.AudioManager; @@ -6,10 +6,16 @@ import android.media.AudioManager;
6 import android.media.MediaPlayer; 6 import android.media.MediaPlayer;
7 import android.net.Uri; 7 import android.net.Uri;
8 import android.os.Build; 8 import android.os.Build;
  9 +import android.text.TextUtils;
9 import android.view.Surface; 10 import android.view.Surface;
10 import android.view.SurfaceHolder; 11 import android.view.SurfaceHolder;
11 12
  13 +import com.danikula.videocache.HttpProxyCacheServer;
  14 +import com.danikula.videocache.StorageUtils;
  15 +import com.libs.video.util.cache.ProxyVideoCacheManager;
12 import com.libs.video.video.exoplayer.PlayErrorException; 16 import com.libs.video.video.exoplayer.PlayErrorException;
  17 +import com.libs.video.video.exoplayer.play.AbstractPlayer;
  18 +import com.libs.video.video.exoplayer.util.PlayCacheUtils;
13 19
14 import java.io.IOException; 20 import java.io.IOException;
15 import java.util.Map; 21 import java.util.Map;
@@ -48,6 +54,20 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -48,6 +54,20 @@ public class AndroidMediaPlayer extends AbstractPlayer {
48 } 54 }
49 55
50 @Override 56 @Override
  57 + public void setDataSource(String path, Map<String, String> headers, boolean isCache) {
  58 + try {
  59 + if (isCache) {
  60 + mMediaPlayer.setDataSource(mAppContext, Uri.parse(PlayCacheUtils.getCachePath(mAppContext,path)), headers);
  61 + } else {
  62 + //不缓存
  63 + mMediaPlayer.setDataSource(mAppContext, Uri.parse(path), headers);
  64 + }
  65 + } catch (IOException e) {
  66 + e.printStackTrace();
  67 + }
  68 + }
  69 +
  70 + @Override
51 public void setDataSource(AssetFileDescriptor fd) { 71 public void setDataSource(AssetFileDescriptor fd) {
52 try { 72 try {
53 mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); 73 mMediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
@@ -56,6 +76,7 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -56,6 +76,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
56 } 76 }
57 } 77 }
58 78
  79 +
59 /** 80 /**
60 * 获取当前异常 81 * 获取当前异常
61 * 82 *
@@ -64,15 +85,16 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -64,15 +85,16 @@ public class AndroidMediaPlayer extends AbstractPlayer {
64 private void getException(Exception e) { 85 private void getException(Exception e) {
65 PlayErrorException errorException = null; 86 PlayErrorException errorException = null;
66 if (e instanceof IOException) { 87 if (e instanceof IOException) {
67 - errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IOException, e.getMessage()); 88 + //资源错误
  89 + errorException = new PlayErrorException(PlayErrorException.TYPE_SOURCE_ERROR, e.getMessage());
68 } else if (e instanceof IllegalArgumentException) { 90 } else if (e instanceof IllegalArgumentException) {
69 - errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IllegalArgumentException, e.getMessage()); 91 + errorException = new PlayErrorException(PlayErrorException.TYPE_IllegalArgumentException, e.getMessage());
70 } else if (e instanceof SecurityException) { 92 } else if (e instanceof SecurityException) {
71 - errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_SecurityException, e.getMessage()); 93 + errorException = new PlayErrorException(PlayErrorException.TYPE_SecurityException, e.getMessage());
72 } else if (e instanceof IllegalStateException) { 94 } else if (e instanceof IllegalStateException) {
73 - errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IllegalStateException, e.getMessage()); 95 + errorException = new PlayErrorException(PlayErrorException.TYPE_IllegalStateException, e.getMessage());
74 } else { 96 } else {
75 - errorException = new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_unknownException, e.getMessage()); 97 + errorException = new PlayErrorException(PlayErrorException.TYPE_UNEXPECTED_ERROR, e.getMessage());
76 } 98 }
77 mPlayerEventListener.onError(errorException); 99 mPlayerEventListener.onError(errorException);
78 } 100 }
@@ -132,7 +154,7 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -132,7 +154,7 @@ public class AndroidMediaPlayer extends AbstractPlayer {
132 try { 154 try {
133 mMediaPlayer.seekTo((int) time); 155 mMediaPlayer.seekTo((int) time);
134 } catch (IllegalStateException e) { 156 } catch (IllegalStateException e) {
135 - mPlayerEventListener.onError(new PlayErrorException(PlayErrorException.TYPE_MediaPlayer_IllegalStateException, e.getMessage())); 157 + mPlayerEventListener.onError(new PlayErrorException(PlayErrorException.TYPE_IllegalStateException, e.getMessage()));
136 158
137 } 159 }
138 } 160 }
@@ -226,10 +248,28 @@ public class AndroidMediaPlayer extends AbstractPlayer { @@ -226,10 +248,28 @@ public class AndroidMediaPlayer extends AbstractPlayer {
226 @Override 248 @Override
227 public boolean onError(MediaPlayer mp, int what, int extra) { 249 public boolean onError(MediaPlayer mp, int what, int extra) {
228 PlayErrorException errorException = new PlayErrorException(); 250 PlayErrorException errorException = new PlayErrorException();
229 - errorException.setErrorType(PlayErrorException.TYPE_MediaPlayer_ON_ERROR);  
230 - errorException.setMediaPlayer(mp);  
231 - errorException.setMediaPlayer_what(what);  
232 - errorException.setMediaPlayer_extra(extra); 251 + switch (what) {
  252 + //播放超时错误
  253 + case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
  254 + errorException.setErrorType(PlayErrorException.TYPE_TIMED_OUT_ERROR);
  255 + errorException.setErrorMsg("播放超时错误");
  256 + break;
  257 + //不支持的媒体类型
  258 + case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
  259 + errorException.setErrorType(PlayErrorException.TYPE_MEDIA_UNSUPPORTED_ERROR);
  260 + errorException.setErrorMsg("不支持的媒体类型");
  261 + break;
  262 + //媒体服务器挂机(应用必须释放对象,然后开启新的实例)
  263 + case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
  264 + errorException.setErrorType(PlayErrorException.TYPE_MEDIA_SERVER_DIED_ERROR);
  265 + errorException.setErrorMsg("媒体服务器挂机(应用必须释放对象,然后开启新的实例)");
  266 + break;
  267 + default:
  268 + errorException.setErrorType(PlayErrorException.TYPE_OTHER_ERROR);
  269 + errorException.setErrorMsg("其他错误:" + what);
  270 + break;
  271 + }
  272 +
233 mPlayerEventListener.onError(errorException); 273 mPlayerEventListener.onError(errorException);
234 return true; 274 return true;
235 } 275 }
cloud/video/src/main/java/com/libs/video/video/exoplayer/play/AndroidMediaPlayerFactory.java renamed to cloud/video/src/main/java/com/libs/video/video/exoplayer/playerCore/mediaplayer/AndroidMediaPlayerFactory.java
1 -package com.libs.video.video.exoplayer.play; 1 +package com.libs.video.video.exoplayer.playerCore.mediaplayer;
2 2
3 import android.content.Context; 3 import android.content.Context;
4 4
  5 +import com.libs.video.video.exoplayer.play.PlayerFactory;
  6 +
5 public class AndroidMediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> { 7 public class AndroidMediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> {
6 8
7 public static AndroidMediaPlayerFactory create() { 9 public static AndroidMediaPlayerFactory create() {
cloud/video/src/main/java/com/libs/video/video/exoplayer/util/PlayCacheUtils.java 0 → 100644
  1 +package com.libs.video.video.exoplayer.util;
  2 +
  3 +import android.content.Context;
  4 +import android.text.TextUtils;
  5 +
  6 +import com.danikula.videocache.HttpProxyCacheServer;
  7 +import com.danikula.videocache.StorageUtils;
  8 +import com.libs.video.util.cache.ProxyVideoCacheManager;
  9 +import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaPlayerFactory;
  10 +import com.libs.video.video.exoplayer.playerCore.exoplayer.ExoMediaSourceHelper;
  11 +import com.libs.video.video.exoplayer.playerCore.mediaplayer.AndroidMediaPlayerFactory;
  12 +
  13 +import java.io.File;
  14 +
  15 +/**
  16 + * 播放缓存工具
  17 + */
  18 +public class PlayCacheUtils {
  19 + public static String getCachePath(Context mAppContext, String path) {
  20 + String result = "";
  21 + if (null == mAppContext || TextUtils.isEmpty(path)) {
  22 + return result;
  23 + }
  24 + if (path.contains("m3u8")) {
  25 + result = path;
  26 + } else if (null != mAppContext && !TextUtils.isDigitsOnly(path) && !path.contains(StorageUtils.getCacheDirectoryPath(mAppContext))) {
  27 + HttpProxyCacheServer cacheServer = ProxyVideoCacheManager.getProxy(mAppContext);
  28 + if (!cacheServer.isCached(path)) {
  29 + String proxyUrl = cacheServer.getProxyUrl(path);
  30 + result = proxyUrl;
  31 + }
  32 + }
  33 + return result;
  34 + }
  35 +
  36 + /**
  37 + * 目前exoplayer是全部删除
  38 + *
  39 + * @param context
  40 + * @param url
  41 + */
  42 + public void clearDefaultCache(Context context, String url) {
  43 + //获取当前播放核心
  44 + Object object = PlayerFactoryUtils.getCurrentPlayerFactory();
  45 + if (null != object) {
  46 + if (object instanceof ExoMediaPlayerFactory) {
  47 + File file = new File(StorageUtils.getCacheDirectoryPath(context), ExoMediaSourceHelper.CACHE_DIR);//缓存目录
  48 + if (null == file) {
  49 + return;
  50 + }
  51 + if (file.exists()) {
  52 + deleteFile(file);
  53 + }
  54 + } else if (object instanceof AndroidMediaPlayerFactory) {
  55 + ProxyVideoCacheManager.clearDefaultCache(context, url);
  56 + }
  57 + }
  58 + }
  59 +
  60 + public static void clearAllCache(Context context) {
  61 + //获取当前播放核心
  62 +// Object object = PlayerFactoryUtils.getCurrentPlayerFactory();
  63 +// if (null != object) {
  64 +// if (object instanceof ExoMediaPlayerFactory) {
  65 + File file = new File(StorageUtils.getCacheDirectoryPath(context), ExoMediaSourceHelper.CACHE_DIR);//缓存目录
  66 + if (null == file) {
  67 + return;
  68 + }
  69 + if (file.exists()) {
  70 + deleteFile(file);
  71 + }
  72 +// } else if (object instanceof AndroidMediaPlayerFactory) {
  73 + ProxyVideoCacheManager.clearAllCache(context);
  74 +// }
  75 +// }
  76 +
  77 +
  78 + }
  79 +
  80 + /**
  81 + * 删除文件
  82 + *
  83 + * @param file
  84 + */
  85 + private static void deleteFile(File file) {
  86 + if (file.exists()) { // 判断文件是否存在
  87 + if (file.isFile()) { // 判断是否是文件
  88 + file.delete(); // delete()方法 你应该知道 是删除的意思;
  89 + } else if (file.isDirectory()) { // 否则如果它是一个目录
  90 + File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
  91 + for (File file1 : files) { // 遍历目录下所有的文件
  92 + deleteFile(file1); // 把每个文件 用这个方法进行迭代
  93 + }
  94 + }
  95 + file.delete();
  96 + } else {
  97 +
  98 + }
  99 + }
  100 +
  101 +}