33import android .content .Context ;
44import android .util .Log ;
55
6- import androidx .annotation .NonNull ;
76import androidx .annotation .Nullable ;
87
98import com .google .android .exoplayer2 .database .StandaloneDatabaseProvider ;
3130import java .io .File ;
3231
3332public class PlayerDataSource {
33+ public static final String TAG = PlayerDataSource .class .getSimpleName ();
3434
3535 public static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000 ;
3636
@@ -47,7 +47,7 @@ public class PlayerDataSource {
4747 * {@link YoutubeProgressiveDashManifestCreator}, {@link YoutubeOtfDashManifestCreator} and
4848 * {@link YoutubePostLiveStreamDvrDashManifestCreator}.
4949 */
50- private static final int MAXIMUM_SIZE_CACHED_GENERATED_MANIFESTS_PER_CACHE = 500 ;
50+ private static final int MAX_MANIFEST_CACHE_SIZE = 500 ;
5151
5252 /**
5353 * The folder name in which the ExoPlayer cache will be written.
@@ -61,44 +61,53 @@ public class PlayerDataSource {
6161 */
6262 private static SimpleCache cache ;
6363
64- private final int continueLoadingCheckIntervalBytes ;
65- private final CacheFactory .Builder cacheDataSourceFactoryBuilder ;
64+
65+ private final int progressiveLoadIntervalBytes ;
66+
67+ // Generic Data Source Factories (without or with cache)
6668 private final DataSource .Factory cachelessDataSourceFactory ;
69+ private final CacheFactory cacheDataSourceFactory ;
6770
68- public PlayerDataSource (@ NonNull final Context context ,
69- @ NonNull final String userAgent ,
70- @ NonNull final TransferListener transferListener ) {
71- continueLoadingCheckIntervalBytes = PlayerHelper .getProgressiveLoadIntervalBytes (context );
72- final File cacheDir = new File (context .getExternalCacheDir (), CACHE_FOLDER_NAME );
73- if (!cacheDir .exists ()) {
74- //noinspection ResultOfMethodCallIgnored
75- cacheDir .mkdir ();
76- }
71+ // YouTube-specific Data Source Factories (with cache)
72+ // They use YoutubeHttpDataSource.Factory, with different parameters each
73+ private final CacheFactory ytHlsCacheDataSourceFactory ;
74+ private final CacheFactory ytDashCacheDataSourceFactory ;
75+ private final CacheFactory ytProgressiveDashCacheDataSourceFactory ;
7776
78- if (cache == null ) {
79- final LeastRecentlyUsedCacheEvictor evictor
80- = new LeastRecentlyUsedCacheEvictor (PlayerHelper .getPreferredCacheSize ());
81- cache = new SimpleCache (cacheDir , evictor , new StandaloneDatabaseProvider (context ));
82- Log .d (PlayerDataSource .class .getSimpleName (), "initExoPlayerCache: cacheDir = "
83- + cacheDir .getAbsolutePath ());
84- }
8577
86- cacheDataSourceFactoryBuilder = new CacheFactory . Builder ( context , userAgent ,
87- transferListener );
88- cacheDataSourceFactoryBuilder . setSimpleCache ( cache );
78+ public PlayerDataSource ( final Context context ,
79+ final String userAgent ,
80+ final TransferListener transferListener ) {
8981
82+ progressiveLoadIntervalBytes = PlayerHelper .getProgressiveLoadIntervalBytes (context );
83+
84+ // make sure the static cache was created: needed by CacheFactories below
85+ instantiateCacheIfNeeded (context );
86+
87+ // generic data source factories use DefaultHttpDataSource.Factory
9088 cachelessDataSourceFactory = new DefaultDataSource .Factory (context ,
9189 new DefaultHttpDataSource .Factory ().setUserAgent (userAgent ))
9290 .setTransferListener (transferListener );
93-
94- YoutubeProgressiveDashManifestCreator .getCache ().setMaximumSize (
95- MAXIMUM_SIZE_CACHED_GENERATED_MANIFESTS_PER_CACHE );
96- YoutubeOtfDashManifestCreator .getCache ().setMaximumSize (
97- MAXIMUM_SIZE_CACHED_GENERATED_MANIFESTS_PER_CACHE );
91+ cacheDataSourceFactory = new CacheFactory (context , transferListener , cache ,
92+ new DefaultHttpDataSource .Factory ().setUserAgent (userAgent ));
93+
94+ // YouTube-specific data source factories use getYoutubeHttpDataSourceFactory()
95+ ytHlsCacheDataSourceFactory = new CacheFactory (context , transferListener , cache ,
96+ getYoutubeHttpDataSourceFactory (false , false , userAgent ));
97+ ytDashCacheDataSourceFactory = new CacheFactory (context , transferListener , cache ,
98+ getYoutubeHttpDataSourceFactory (true , true , userAgent ));
99+ ytProgressiveDashCacheDataSourceFactory = new CacheFactory (context , transferListener , cache ,
100+ getYoutubeHttpDataSourceFactory (false , true , userAgent ));
101+
102+ // set the maximum size to manifest creators
103+ YoutubeProgressiveDashManifestCreator .getCache ().setMaximumSize (MAX_MANIFEST_CACHE_SIZE );
104+ YoutubeOtfDashManifestCreator .getCache ().setMaximumSize (MAX_MANIFEST_CACHE_SIZE );
98105 YoutubePostLiveStreamDvrDashManifestCreator .getCache ().setMaximumSize (
99- MAXIMUM_SIZE_CACHED_GENERATED_MANIFESTS_PER_CACHE );
106+ MAX_MANIFEST_CACHE_SIZE );
100107 }
101108
109+
110+ //region Live media source factories
102111 public SsMediaSource .Factory getLiveSsMediaSourceFactory () {
103112 return getSSMediaSourceFactory ().setLivePresentationDelayMs (LIVE_STREAM_EDGE_GAP_MILLIS );
104113 }
@@ -118,26 +127,26 @@ public DashMediaSource.Factory getLiveDashMediaSourceFactory() {
118127 getDefaultDashChunkSourceFactory (cachelessDataSourceFactory ),
119128 cachelessDataSourceFactory );
120129 }
130+ //endregion
121131
132+
133+ //region Generic media source factories
122134 public HlsMediaSource .Factory getHlsMediaSourceFactory (
123135 @ Nullable final HlsPlaylistParserFactory hlsPlaylistParserFactory ) {
124- final HlsMediaSource .Factory factory = new HlsMediaSource .Factory (
125- cacheDataSourceFactoryBuilder .build ());
126- if (hlsPlaylistParserFactory != null ) {
127- factory .setPlaylistParserFactory (hlsPlaylistParserFactory );
128- }
136+ final HlsMediaSource .Factory factory = new HlsMediaSource .Factory (cacheDataSourceFactory );
137+ factory .setPlaylistParserFactory (hlsPlaylistParserFactory );
129138 return factory ;
130139 }
131140
132141 public DashMediaSource .Factory getDashMediaSourceFactory () {
133142 return new DashMediaSource .Factory (
134- getDefaultDashChunkSourceFactory (cacheDataSourceFactoryBuilder . build () ),
135- cacheDataSourceFactoryBuilder . build () );
143+ getDefaultDashChunkSourceFactory (cacheDataSourceFactory ),
144+ cacheDataSourceFactory );
136145 }
137146
138147 public ProgressiveMediaSource .Factory getProgressiveMediaSourceFactory () {
139- return new ProgressiveMediaSource .Factory (cacheDataSourceFactoryBuilder . build () )
140- .setContinueLoadingCheckIntervalBytes (continueLoadingCheckIntervalBytes );
148+ return new ProgressiveMediaSource .Factory (cacheDataSourceFactory )
149+ .setContinueLoadingCheckIntervalBytes (progressiveLoadIntervalBytes );
141150 }
142151
143152 public SsMediaSource .Factory getSSMediaSourceFactory () {
@@ -147,42 +156,57 @@ public SsMediaSource.Factory getSSMediaSourceFactory() {
147156 }
148157
149158 public SingleSampleMediaSource .Factory getSingleSampleMediaSourceFactory () {
150- return new SingleSampleMediaSource .Factory (cacheDataSourceFactoryBuilder . build () );
159+ return new SingleSampleMediaSource .Factory (cacheDataSourceFactory );
151160 }
161+ //endregion
152162
153- public DashMediaSource .Factory getYoutubeDashMediaSourceFactory () {
154- cacheDataSourceFactoryBuilder .setUpstreamDataSourceFactory (
155- getYoutubeHttpDataSourceFactory (true , true ));
156- return new DashMediaSource .Factory (
157- getDefaultDashChunkSourceFactory (cacheDataSourceFactoryBuilder .build ()),
158- cacheDataSourceFactoryBuilder .build ());
159- }
160163
164+ //region YouTube media source factories
161165 public HlsMediaSource .Factory getYoutubeHlsMediaSourceFactory () {
162- cacheDataSourceFactoryBuilder .setUpstreamDataSourceFactory (
163- getYoutubeHttpDataSourceFactory (false , false ));
164- return new HlsMediaSource .Factory (cacheDataSourceFactoryBuilder .build ());
166+ return new HlsMediaSource .Factory (ytHlsCacheDataSourceFactory );
167+ }
168+
169+ public DashMediaSource .Factory getYoutubeDashMediaSourceFactory () {
170+ return new DashMediaSource .Factory (
171+ getDefaultDashChunkSourceFactory (ytDashCacheDataSourceFactory ),
172+ ytDashCacheDataSourceFactory );
165173 }
166174
167175 public ProgressiveMediaSource .Factory getYoutubeProgressiveMediaSourceFactory () {
168- cacheDataSourceFactoryBuilder .setUpstreamDataSourceFactory (
169- getYoutubeHttpDataSourceFactory (false , true ));
170- return new ProgressiveMediaSource .Factory (cacheDataSourceFactoryBuilder .build ())
171- .setContinueLoadingCheckIntervalBytes (continueLoadingCheckIntervalBytes );
176+ return new ProgressiveMediaSource .Factory (ytProgressiveDashCacheDataSourceFactory )
177+ .setContinueLoadingCheckIntervalBytes (progressiveLoadIntervalBytes );
172178 }
179+ //endregion
173180
174- @ NonNull
175- private DefaultDashChunkSource .Factory getDefaultDashChunkSourceFactory (
181+
182+ //region Static methods
183+ private static DefaultDashChunkSource .Factory getDefaultDashChunkSourceFactory (
176184 final DataSource .Factory dataSourceFactory ) {
177185 return new DefaultDashChunkSource .Factory (dataSourceFactory );
178186 }
179187
180- @ NonNull
181- private YoutubeHttpDataSource .Factory getYoutubeHttpDataSourceFactory (
188+ private static YoutubeHttpDataSource .Factory getYoutubeHttpDataSourceFactory (
182189 final boolean rangeParameterEnabled ,
183- final boolean rnParameterEnabled ) {
190+ final boolean rnParameterEnabled ,
191+ final String userAgent ) {
184192 return new YoutubeHttpDataSource .Factory ()
185193 .setRangeParameterEnabled (rangeParameterEnabled )
186- .setRnParameterEnabled (rnParameterEnabled );
194+ .setRnParameterEnabled (rnParameterEnabled )
195+ .setUserAgentForNonMobileStreams (userAgent );
196+ }
197+
198+ private static void instantiateCacheIfNeeded (final Context context ) {
199+ if (cache == null ) {
200+ final File cacheDir = new File (context .getExternalCacheDir (), CACHE_FOLDER_NAME );
201+ Log .d (TAG , "instantiateCacheIfNeeded: cacheDir = " + cacheDir .getAbsolutePath ());
202+ if (!cacheDir .exists () && !cacheDir .mkdir ()) {
203+ Log .w (TAG , "instantiateCacheIfNeeded: could not create cache dir" );
204+ }
205+
206+ final LeastRecentlyUsedCacheEvictor evictor
207+ = new LeastRecentlyUsedCacheEvictor (PlayerHelper .getPreferredCacheSize ());
208+ cache = new SimpleCache (cacheDir , evictor , new StandaloneDatabaseProvider (context ));
209+ }
187210 }
211+ //endregion
188212}
0 commit comments