diff --git a/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java b/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java index c0a2963f6..419bee40d 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java +++ b/app/src/main/java/com/fongmi/android/tv/player/ExoUtil.java @@ -2,20 +2,31 @@ package com.fongmi.android.tv.player; import android.graphics.Color; import android.net.Uri; +import android.text.TextUtils; import com.fongmi.android.tv.App; import com.fongmi.android.tv.bean.Result; import com.fongmi.android.tv.utils.FileUtil; +import com.google.android.exoplayer2.C; +import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.PlaybackException; +import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.database.DatabaseProvider; import com.google.android.exoplayer2.database.StandaloneDatabaseProvider; +import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory; +import com.google.android.exoplayer2.extractor.ExtractorsFactory; +import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory; +import com.google.android.exoplayer2.extractor.ts.TsExtractor; import com.google.android.exoplayer2.source.DefaultMediaSourceFactory; import com.google.android.exoplayer2.source.MediaSource; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.ui.CaptionStyleCompat; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSource; import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; +import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.cache.Cache; import com.google.android.exoplayer2.upstream.cache.CacheDataSource; import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor; @@ -23,53 +34,75 @@ import com.google.android.exoplayer2.upstream.cache.SimpleCache; import com.google.android.exoplayer2.util.MimeTypes; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; public class ExoUtil { + private static HttpDataSource.Factory httpDataSourceFactory; + private static DataSource.Factory dataSourceFactory; + private static ExtractorsFactory extractorsFactory; private static DatabaseProvider database; private static Cache cache; + public static TrackSelector buildTrackSelector() { + DefaultTrackSelector trackSelector = new DefaultTrackSelector(App.get()); + trackSelector.setParameters(trackSelector.buildUponParameters().setPreferredTextLanguage("zh").setIgnoredTextSelectionFlags(C.SELECTION_FLAG_DEFAULT | C.SELECTION_FLAG_FORCED)); + return trackSelector; + } + + public static RenderersFactory buildRenderersFactory() { + return new DefaultRenderersFactory(App.get()).setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON); + } + public static CaptionStyleCompat getCaptionStyle() { return new CaptionStyleCompat(Color.WHITE, Color.TRANSPARENT, Color.TRANSPARENT, CaptionStyleCompat.EDGE_TYPE_OUTLINE, Color.BLACK, null); } public static MediaSource getSource(Result result, int errorCode) { - return getSource(result.getHeaders(), result.getPlayUrl() + result.getUrl(), errorCode, getConfig(result)); + return getSource(result.getHeaders(), result.getPlayUrl() + result.getUrl(), result.getSub(), errorCode); } public static MediaSource getSource(Map headers, String url, int errorCode) { - return getSource(headers, url, errorCode, Collections.emptyList()); + return getSource(headers, url, null, errorCode); + } + + private static MediaSource getSource(Map headers, String url, String sub, int errorCode) { + return new DefaultMediaSourceFactory(getDataSourceFactory(headers), getExtractorsFactory()).createMediaSource(getMediaItem(url, sub, errorCode)); } - private static MediaSource getSource(Map headers, String url, int errorCode, List config) { + private static MediaItem getMediaItem(String url, String sub, int errorCode) { MediaItem.Builder builder = new MediaItem.Builder().setUri(Uri.parse(url.trim())); if (errorCode == PlaybackException.ERROR_CODE_PARSING_MANIFEST_MALFORMED) builder.setMimeType(MimeTypes.APPLICATION_OCTET); else if (errorCode == PlaybackException.ERROR_CODE_PARSING_CONTAINER_UNSUPPORTED) builder.setMimeType(MimeTypes.APPLICATION_M3U8); - if (config.size() > 0) builder.setSubtitleConfigurations(config); - return new DefaultMediaSourceFactory(getDataSourceFactory(headers)).createMediaSource(builder.build()); + if (!TextUtils.isEmpty(sub)) builder.setSubtitleConfigurations(getSubtitles(sub)); + return builder.build(); } - private static List getConfig(Result result) { - if (result.getSub().isEmpty()) return Collections.emptyList(); + private static List getSubtitles(String sub) { List items = new ArrayList<>(); - String[] subs = result.getSub().split("\\$\\$\\$"); - for (String sub : subs) { - String[] divide = sub.split("#"); - items.add(new MediaItem.SubtitleConfiguration.Builder(Uri.parse(divide[2])).setLabel(divide[0]).setMimeType(divide[1]).setLanguage("zh").build()); - } + for (String text : sub.split("\\$\\$\\$")) items.add(getSubtitle(text.split("#"))); return items; } - private static synchronized DataSource.Factory getHttpDataSourceFactory(Map headers) { - return new DefaultHttpDataSource.Factory().setDefaultRequestProperties(headers).setConnectTimeoutMs(5000).setReadTimeoutMs(5000).setAllowCrossProtocolRedirects(true); + private static MediaItem.SubtitleConfiguration getSubtitle(String[] split) { + return new MediaItem.SubtitleConfiguration.Builder(Uri.parse(split[2])).setLabel(split[0]).setMimeType(split[1]).setLanguage("zh").build(); + } + + private static synchronized ExtractorsFactory getExtractorsFactory() { + if (extractorsFactory == null) extractorsFactory = new DefaultExtractorsFactory().setTsExtractorFlags(DefaultTsPayloadReaderFactory.FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS).setTsExtractorTimestampSearchBytes(TsExtractor.DEFAULT_TIMESTAMP_SEARCH_BYTES * 3); + return extractorsFactory; + } + + private static synchronized HttpDataSource.Factory getHttpDataSourceFactory() { + if (httpDataSourceFactory == null) httpDataSourceFactory = new DefaultHttpDataSource.Factory().setConnectTimeoutMs(5000).setReadTimeoutMs(5000).setAllowCrossProtocolRedirects(true); + return httpDataSourceFactory; } private static synchronized DataSource.Factory getDataSourceFactory(Map headers) { - DefaultDataSource.Factory upstreamFactory = new DefaultDataSource.Factory(App.get(), getHttpDataSourceFactory(headers)); - return buildReadOnlyCacheDataSource(upstreamFactory, getCache()); + if (dataSourceFactory == null) dataSourceFactory = buildReadOnlyCacheDataSource(new DefaultDataSource.Factory(App.get(), getHttpDataSourceFactory()), getCache()); + httpDataSourceFactory.setDefaultRequestProperties(headers); + return dataSourceFactory; } private static CacheDataSource.Factory buildReadOnlyCacheDataSource(DataSource.Factory upstreamFactory, Cache cache) { diff --git a/app/src/main/java/com/fongmi/android/tv/player/Players.java b/app/src/main/java/com/fongmi/android/tv/player/Players.java index 06efcda66..0a3d5d8ea 100644 --- a/app/src/main/java/com/fongmi/android/tv/player/Players.java +++ b/app/src/main/java/com/fongmi/android/tv/player/Players.java @@ -12,12 +12,10 @@ import com.fongmi.android.tv.utils.Prefers; import com.fongmi.android.tv.utils.ResUtil; import com.github.catvod.crawler.SpiderDebug; import com.google.android.exoplayer2.DefaultLoadControl; -import com.google.android.exoplayer2.DefaultRenderersFactory; import com.google.android.exoplayer2.ExoPlayer; import com.google.android.exoplayer2.PlaybackException; import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.analytics.AnalyticsListener; -import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.util.Util; import java.util.Formatter; @@ -61,10 +59,7 @@ public class Players implements Player.Listener, IMediaPlayer.OnInfoListener, IM } public void setupExo() { - DefaultTrackSelector selector = new DefaultTrackSelector(App.get()); - selector.setParameters(selector.getParameters().buildUpon().setPreferredTextLanguage("zh").build()); - DefaultRenderersFactory factory = new DefaultRenderersFactory(App.get()).setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON); - exoPlayer = new ExoPlayer.Builder(App.get()).setLoadControl(new DefaultLoadControl()).setRenderersFactory(factory).setTrackSelector(selector).build(); + exoPlayer = new ExoPlayer.Builder(App.get()).setLoadControl(new DefaultLoadControl()).setRenderersFactory(ExoUtil.buildRenderersFactory()).setTrackSelector(ExoUtil.buildTrackSelector()).build(); exoPlayer.addAnalyticsListener(this); exoPlayer.setPlayWhenReady(true); exoPlayer.addListener(this);