From b8d37b192653881bc07d4e4a68e3a0c045c0c824 Mon Sep 17 00:00:00 2001 From: guoshuyu Date: Fri, 18 May 2018 17:29:21 +0800 Subject: [PATCH] fix exo --- .../gsyvideoplayer/cache/ExoCacheManager.java | 109 +++++++++++++ .../tv/danmaku/ijk/media/exo2/ExoHelper.java | 154 ++++++++++++++++++ .../ijk/media/exo2/IjkExo2MediaPlayer.java | 21 ++- 3 files changed, 277 insertions(+), 7 deletions(-) create mode 100644 gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/cache/ExoCacheManager.java create mode 100644 gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/ExoHelper.java diff --git a/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/cache/ExoCacheManager.java b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/cache/ExoCacheManager.java new file mode 100644 index 0000000..9d5b288 --- /dev/null +++ b/gsyVideoPlayer-java/src/main/java/com/shuyu/gsyvideoplayer/cache/ExoCacheManager.java @@ -0,0 +1,109 @@ +package com.shuyu.gsyvideoplayer.cache; + +import android.content.Context; + +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.util.Map; + +import tv.danmaku.ijk.media.player.IMediaPlayer; + +/** + * Created by guoshuyu on 2018/5/18. + */ + +public class ExoCacheManager implements ICacheManager { + + private static final String TAG = "ExoCacheManager"; + + private Cache mCache; + + protected Map mMapHeadData; + + @Override + public void doCacheLogic(Context context, IMediaPlayer mediaPlayer, String url, Map header, File cachePath) { + + } + + @Override + public void clearCache(Context context, String url) { + + } + + @Override + public void release() { + if (mCache != null) { + try { + mCache.release(); + } catch (Cache.CacheException e) { + e.printStackTrace(); + } + } + } + + @Override + public boolean hadCached() { + return false; + } + + @Override + public void setCacheAvailableListener(ICacheAvailableListener cacheAvailableListener) { + + } + + /** + * 本地缓存目录 + */ + protected Cache getCache(Context context) { + if (mCache == null) { + String path = context.getCacheDir().getAbsolutePath() + File.separator + "exo"; + boolean isLocked = SimpleCache.isCacheFolderLocked(new File(path)); + if (!isLocked) { + mCache = new SimpleCache(new File(path), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 100)); + } + } + return mCache; + } + + /** + * 获取SourceFactory,是否带Cache + */ + private DataSource.Factory getDataSourceFactoryCache(Context context, String dataSource, boolean cacheEnable, boolean preview) { + if (cacheEnable) { + Cache cache = getCache(context); + return new CacheDataSourceFactory(cache, getDataSourceFactory(context, preview), CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); + } else { + return getDataSourceFactory(context, preview); + } + } + + /** + * 获取SourceFactory + */ + private DataSource.Factory getDataSourceFactory(Context context, boolean preview) { + return new DefaultDataSourceFactory(context, preview ? null : new DefaultBandwidthMeter(), + getHttpDataSourceFactory(context, preview)); + } + + private DataSource.Factory getHttpDataSourceFactory(Context context, boolean preview) { + DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, + TAG), preview ? null : new DefaultBandwidthMeter()); + if (mMapHeadData != null && mMapHeadData.size() > 0) { + for (Map.Entry header : mMapHeadData.entrySet()) { + dataSourceFactory.getDefaultRequestProperties().set(header.getKey(), header.getValue()); + } + } + return dataSourceFactory; + } + +} diff --git a/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/ExoHelper.java b/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/ExoHelper.java new file mode 100644 index 0000000..c249c75 --- /dev/null +++ b/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/ExoHelper.java @@ -0,0 +1,154 @@ +package tv.danmaku.ijk.media.exo2; + +import android.content.Context; +import android.net.Uri; + +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.ext.rtmp.RtmpDataSourceFactory; +import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; +import com.google.android.exoplayer2.source.ExtractorMediaSource; +import com.google.android.exoplayer2.source.LoopingMediaSource; +import com.google.android.exoplayer2.source.MediaSource; +import com.google.android.exoplayer2.source.dash.DashMediaSource; +import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource; +import com.google.android.exoplayer2.source.hls.HlsMediaSource; +import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource; +import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource; +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.util.Map; + +/** + * Created by guoshuyu on 2018/5/18. + */ + +public class ExoHelper { + + private static final String TAG = "IjkExo2MediaPlayer"; + + public static final int TYPE_RTMP = 4; + + protected Context mAppContext; + + protected Cache mCache; + + protected Map mMapHeadData; + + public ExoHelper(Context context, Map mapHeadData) { + mAppContext = context.getApplicationContext(); + mMapHeadData = mapHeadData; + } + + + public MediaSource getMediaSource(String dataSource, boolean preview, boolean cacheEnable, boolean isLooping) { + Uri contentUri = Uri.parse(dataSource); + int contentType = inferContentType(dataSource); + MediaSource mediaSource; + switch (contentType) { + case C.TYPE_SS: + mediaSource = new SsMediaSource.Factory( + new DefaultSsChunkSource.Factory(getDataSourceFactoryCache(mAppContext, dataSource, cacheEnable, preview)), + new DefaultDataSourceFactory(mAppContext, null, + getHttpDataSourceFactory(mAppContext, preview))).createMediaSource(contentUri); + break; + case C.TYPE_DASH: + mediaSource = new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(getDataSourceFactoryCache(mAppContext, dataSource, cacheEnable, preview)), + new DefaultDataSourceFactory(mAppContext, null, + getHttpDataSourceFactory(mAppContext, preview))).createMediaSource(contentUri); + break; + case C.TYPE_HLS: + mediaSource = new HlsMediaSource.Factory(getDataSourceFactoryCache(mAppContext, dataSource, cacheEnable, preview)).createMediaSource(contentUri); + break; + case TYPE_RTMP: + RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory(null); + mediaSource = new ExtractorMediaSource.Factory(rtmpDataSourceFactory) + .setExtractorsFactory(new DefaultExtractorsFactory()) + .createMediaSource(contentUri); + break; + case C.TYPE_OTHER: + default: + mediaSource = new ExtractorMediaSource.Factory(getDataSourceFactoryCache(mAppContext, dataSource, cacheEnable, preview)) + .setExtractorsFactory(new DefaultExtractorsFactory()) + .createMediaSource(contentUri); + break; + } + if (isLooping) { + return new LoopingMediaSource(mediaSource); + } + return mediaSource; + } + + @C.ContentType + public static int inferContentType(String fileName) { + fileName = Util.toLowerInvariant(fileName); + if (fileName.endsWith(".mpd")) { + return C.TYPE_DASH; + } else if (fileName.endsWith(".m3u8")) { + return C.TYPE_HLS; + } else if (fileName.endsWith(".ism") || fileName.endsWith(".isml") + || fileName.endsWith(".ism/manifest") || fileName.endsWith(".isml/manifest")) { + return C.TYPE_SS; + } else if (fileName.startsWith("rtmp:")) { + return TYPE_RTMP; + } else { + return C.TYPE_OTHER; + } + } + + + /** + * 本地缓存目录 + */ + public Cache getCache(Context context) { + if (mCache == null) { + String path = context.getCacheDir().getAbsolutePath() + File.separator + "exo"; + boolean isLocked = SimpleCache.isCacheFolderLocked(new File(path)); + if (!isLocked) { + mCache = new SimpleCache(new File(path), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 100)); + } + } + return mCache; + } + + + /** + * 获取SourceFactory,是否带Cache + */ + private DataSource.Factory getDataSourceFactoryCache(Context context, String dataSource, boolean cacheEnable, boolean preview) { + if (cacheEnable) { + Cache cache = getCache(context); + return new CacheDataSourceFactory(cache, getDataSourceFactory(context, preview), CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); + } else { + return getDataSourceFactory(context, preview); + } + } + + /** + * 获取SourceFactory + */ + private DataSource.Factory getDataSourceFactory(Context context, boolean preview) { + return new DefaultDataSourceFactory(context, preview ? null : new DefaultBandwidthMeter(), + getHttpDataSourceFactory(context, preview)); + } + + private DataSource.Factory getHttpDataSourceFactory(Context context, boolean preview) { + DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, + TAG), preview ? null : new DefaultBandwidthMeter()); + if (mMapHeadData != null && mMapHeadData.size() > 0) { + for (Map.Entry header : mMapHeadData.entrySet()) { + dataSourceFactory.getDefaultRequestProperties().set(header.getKey(), header.getValue()); + } + } + return dataSourceFactory; + } +} diff --git a/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java b/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java index 604f429..4d19820 100644 --- a/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java +++ b/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java @@ -100,6 +100,7 @@ public class IjkExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev private boolean mIsPrepareing = true; private boolean mIsBuffering = false; private boolean isLooping = false; + private boolean isPreview = false; private int audioSessionId = C.AUDIO_SESSION_ID_UNSET; @@ -138,11 +139,6 @@ public class IjkExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev if (surface != null && !surface.isValid()) { mSurface = null; } - /*if (mSurface == null) { - mTrackSelector.setParameters(mTrackSelector.buildUponParameters().setRendererDisabled(getVideoRendererIndex(), true)); - } else { - mTrackSelector.setParameters(mTrackSelector.buildUponParameters().setRendererDisabled(getVideoRendererIndex(), false)); - }*/ mInternalPlayer.setVideoSurface(surface); } } @@ -150,12 +146,11 @@ public class IjkExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev @Override public void setDataSource(Context context, Uri uri) { mDataSource = uri.toString(); - mMediaSource = getMediaSource(false); + mMediaSource = getMediaSource(isPreview); } @Override public void setDataSource(Context context, Uri uri, Map headers) { - // TODO: handle headers mHeaders = headers; setDataSource(context, uri); } @@ -375,6 +370,18 @@ public class IjkExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev mInternalPlayer.stop(); } + public void setPreview(boolean preview) { + isPreview = preview; + } + + public MediaSource getMediaSource() { + return mMediaSource; + } + + public void setMediaSource(MediaSource mediaSource) { + this.mMediaSource = mediaSource; + } + /** * 倍速播放 * -- GitLab