提交 76f94694 编写于 作者: G guoshuyu

增加exo 的cache, cache支持m3u8等

上级 be6030c8
......@@ -47,12 +47,14 @@ public class DetailExoListPlayer extends GSYBaseActivityDetail<GSYExo2PlayerView
initVideo();
List<GSYVideoModel> urls = new ArrayList<>();
urls.add(new GSYVideoModel("https://media6.smartstudy.com/ae/07/3997/2/dest.m3u8", "标题3"));
urls.add(new GSYVideoModel("http://7xse1z.com1.z0.glb.clouddn.com/1491813192", "标题1"));
urls.add(new GSYVideoModel("http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4", "标题2"));
urls.add(new GSYVideoModel("https://res.exexm.com/cw_145225549855002", "标题3"));
urls.add(new GSYVideoModel("http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4", "标题4"));
detailPlayer.setUp(urls, 0);
//使用 exo 的 CacheDataSourceFactory 实现
detailPlayer.setExoCache(true);
//增加封面
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
......@@ -89,6 +91,9 @@ public class DetailExoListPlayer extends GSYBaseActivityDetail<GSYExo2PlayerView
}
/**
* 重载为GSYExoVideoManager的方法处理
*/
......
......@@ -10,6 +10,7 @@ import android.support.annotation.Size;
import android.view.Surface;
import android.view.SurfaceHolder;
import com.danikula.videocache.file.Md5FileNameGenerator;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
......@@ -44,8 +45,14 @@ import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.Util;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.ArrayList;
......@@ -145,7 +152,7 @@ public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev
throw new UnsupportedOperationException("Deprecated, try setDataSource(List<String> uris, Map<String, String> headers)");
}
public void setDataSource(List<String> uris, Map<String, String> headers) {
public void setDataSource(List<String> uris, Map<String, String> headers, boolean cache) {
mHeaders = headers;
this.uris.clear();
if (uris != null) {
......@@ -155,7 +162,7 @@ public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev
}
ConcatenatingMediaSource concatenatedSource = new ConcatenatingMediaSource();
for (String uri : uris) {
MediaSource mediaSource = getMediaSource(Uri.parse(uri).toString(), false);
MediaSource mediaSource = getMediaSource(Uri.parse(uri).toString(), false, cache);
concatenatedSource.addMediaSource(mediaSource);
}
mMediaSource = concatenatedSource;
......@@ -422,24 +429,24 @@ public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev
}
}
private MediaSource getMediaSource(String dataSource, boolean preview) {
private MediaSource getMediaSource(String dataSource, boolean preview, boolean cacheEnable) {
Uri contentUri = Uri.parse(dataSource);
int contentType = inferContentType(dataSource);
MediaSource mediaSource;
switch (contentType) {
case C.TYPE_SS:
mediaSource = new SsMediaSource.Factory(
new DefaultSsChunkSource.Factory(getDataSourceFactory(preview)),
new DefaultSsChunkSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)),
new DefaultDataSourceFactory(mAppContext, null,
getHttpDataSourceFactory(preview))).createMediaSource(contentUri);
break;
case C.TYPE_DASH:
mediaSource = new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(getDataSourceFactory(preview)),
mediaSource = new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)),
new DefaultDataSourceFactory(mAppContext, null,
getHttpDataSourceFactory(preview))).createMediaSource(contentUri);
break;
case C.TYPE_HLS:
mediaSource = new HlsMediaSource.Factory(getDataSourceFactory(preview)).createMediaSource(contentUri);
mediaSource = new HlsMediaSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)).createMediaSource(contentUri);
break;
case TYPE_RTMP:
RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory(null);
......@@ -449,7 +456,7 @@ public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev
break;
case C.TYPE_OTHER:
default:
mediaSource = new ExtractorMediaSource.Factory(getDataSourceFactory(preview))
mediaSource = new ExtractorMediaSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview))
.setExtractorsFactory(new DefaultExtractorsFactory())
.createMediaSource(contentUri);
break;
......@@ -460,6 +467,23 @@ public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev
return mediaSource;
}
private DataSource.Factory getDataSourceFactoryCache(String dataSource, boolean cacheEnable, boolean preview) {
if (cacheEnable) {
String path = mAppContext.getCacheDir().getAbsolutePath();
File cachePath = new File(path + File.pathSeparator + new Md5FileNameGenerator().generate(dataSource));
boolean isLocked = SimpleCache.isCacheFolderLocked(cachePath);
if (!isLocked) {
Cache cache = new SimpleCache(cachePath, new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 100));
return new CacheDataSourceFactory(cache, getDataSourceFactory(preview), CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
} else {
return getDataSourceFactory(preview);
}
} else {
return getDataSourceFactory(preview);
}
}
private DataSource.Factory getDataSourceFactory(boolean preview) {
return new DefaultDataSourceFactory(mAppContext, preview ? null : new DefaultBandwidthMeter(),
getHttpDataSourceFactory(preview));
......
package com.example.gsyvideoplayer.exo;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.media.AudioManager;
import android.text.TextUtils;
import android.util.AttributeSet;
......@@ -10,8 +12,10 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import com.danikula.videocache.HttpProxyCacheServer;
import com.example.gsyvideoplayer.R;
import com.shuyu.gsyvideoplayer.model.GSYVideoModel;
import com.shuyu.gsyvideoplayer.utils.Debuger;
import com.shuyu.gsyvideoplayer.utils.NetworkUtils;
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
import com.shuyu.gsyvideoplayer.video.base.GSYBaseVideoPlayer;
import com.shuyu.gsyvideoplayer.video.base.GSYVideoPlayer;
......@@ -37,6 +41,7 @@ public class GSYExo2PlayerView extends StandardGSYVideoPlayer {
protected List<GSYVideoModel> mUriList = new ArrayList<>();
protected int mPlayPosition;
protected boolean mExoCache = false;
/**
* 1.5.0开始加入,如果需要不同布局区分功能,需要重载
......@@ -121,6 +126,7 @@ public class GSYExo2PlayerView extends StandardGSYVideoPlayer {
GSYExo2PlayerView st = (GSYExo2PlayerView) to;
st.mPlayPosition = sf.mPlayPosition;
st.mUriList = sf.mUriList;
st.mExoCache = sf.mExoCache;
}
@Override
......@@ -173,11 +179,43 @@ public class GSYExo2PlayerView extends StandardGSYVideoPlayer {
Debuger.printfError("********************** urls isEmpty . Do you know why ? **********************");
}
((GSYExoVideoManager)getGSYVideoManager()).prepare(urls, (mMapHeadData == null) ? new HashMap<String, String>() : mMapHeadData, mLooping, mSpeed);
((GSYExoVideoManager)getGSYVideoManager()).prepare(urls, (mMapHeadData == null) ? new HashMap<String, String>() : mMapHeadData, mLooping, mSpeed, mExoCache);
setStateAndUi(CURRENT_STATE_PREPAREING);
}
/**
* 显示wifi确定框,如需要自定义继承重写即可
*/
@Override
protected void showWifiDialog() {
if (!NetworkUtils.isAvailable(mContext)) {
startPlayLogic();
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivityContext());
builder.setMessage(getResources().getString(R.string.tips_not_wifi));
builder.setPositiveButton(getResources().getString(R.string.tips_not_wifi_confirm), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
startPlayLogic();
}
});
builder.setNegativeButton(getResources().getString(R.string.tips_not_wifi_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
public void setExoCache(boolean exoCache) {
this.mExoCache = exoCache;
}
/**********以下重载GSYVideoPlayer的GSYVideoViewBridge相关实现***********/
public void setIjkLibLoader(IjkLibLoader libLoader) {
......@@ -216,4 +254,6 @@ public class GSYExo2PlayerView extends StandardGSYVideoPlayer {
protected int getSmallId() {
return GSYExoVideoManager.SMALL_ID;
}
}
......@@ -15,9 +15,12 @@ public class GSYExoModel extends GSYModel {
List<String> urls = new ArrayList<>();
public GSYExoModel(List<String> urls, Map<String, String> mapHeadData, boolean loop, float speed) {
boolean cache;
public GSYExoModel(List<String> urls, Map<String, String> mapHeadData, boolean loop, float speed, boolean cache) {
super("", mapHeadData, loop, speed);
this.urls = urls;
this.cache = cache;
}
public List<String> getUrls() {
......@@ -27,4 +30,12 @@ public class GSYExoModel extends GSYModel {
public void setUrls(List<String> urls) {
this.urls = urls;
}
public boolean isCache() {
return cache;
}
public void setCache(boolean cache) {
this.cache = cache;
}
}
......@@ -6,7 +6,6 @@ import android.os.Message;
import android.view.Surface;
import com.google.android.exoplayer2.video.DummySurface;
import com.shuyu.gsyvideoplayer.model.GSYModel;
import com.shuyu.gsyvideoplayer.model.VideoOptionModel;
import com.shuyu.gsyvideoplayer.player.IPlayerManager;
......@@ -39,11 +38,11 @@ public class GSYExoPlayerManager implements IPlayerManager {
dummySurface = DummySurface.newInstanceV17(context, false);
}
try {
mediaPlayer.setLooping(((GSYModel) msg.obj).isLooping());
mediaPlayer.setDataSource(((GSYExoModel) msg.obj).getUrls(), ((GSYModel) msg.obj).getMapHeadData());
mediaPlayer.setLooping(((GSYExoModel) msg.obj).isLooping());
mediaPlayer.setDataSource(((GSYExoModel) msg.obj).getUrls(), ((GSYExoModel) msg.obj).getMapHeadData(), ((GSYExoModel) msg.obj).isCache());
//很遗憾,EXO2的setSpeed只能在播放前生效
if (((GSYModel) msg.obj).getSpeed() != 1 && ((GSYModel) msg.obj).getSpeed() > 0) {
mediaPlayer.setSpeed(((GSYModel) msg.obj).getSpeed(), 1);
if (((GSYExoModel) msg.obj).getSpeed() != 1 && ((GSYExoModel) msg.obj).getSpeed() > 0) {
mediaPlayer.setSpeed(((GSYExoModel) msg.obj).getSpeed(), 1);
}
} catch (Exception e) {
e.printStackTrace();
......
......@@ -73,12 +73,12 @@ public class GSYExoVideoManager extends GSYVideoBaseManager {
return new GSYExoPlayerManager();
}
public void prepare(List<String> urls, Map<String, String> mapHeadData, boolean loop, float speed) {
public void prepare(List<String> urls, Map<String, String> mapHeadData, boolean loop, float speed, boolean cache) {
if (urls.size() == 0) return;
Message msg = new Message();
msg.what = HANDLER_PREPARE;
mMapHeadData = mapHeadData;
msg.obj = new GSYExoModel(urls, mapHeadData, loop, speed);
msg.obj = new GSYExoModel(urls, mapHeadData, loop, speed, cache);
sendMessage(msg);
if (needTimeOutOther) {
startTimeOutBuffer();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册