diff options
author | Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> | 2024-07-02 20:41:49 +0000 |
---|---|---|
committer | Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> | 2024-07-02 20:41:49 +0000 |
commit | fccf2c57851f3b3f6e3b7e67e34699d945a48234 (patch) | |
tree | 5e8b74112d9af3f53bc9d58214df6121c4c1f21d /app/src/main | |
parent | ca4e58985f17bcfb0c3eab5b765f9f0cf22ec677 (diff) | |
download | infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.tar infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.tar.gz infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.tar.bz2 infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.tar.lz infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.tar.xz infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.tar.zst infinity-for-reddit-fccf2c57851f3b3f6e3b7e67e34699d945a48234.zip |
Fix video autoplay not working in some cases by always providing a new LoadControl in DefaultExoCreator.createPlayer().
Diffstat (limited to 'app/src/main')
6 files changed, 133 insertions, 138 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java index a4b1276e..19b54754 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java @@ -193,6 +193,7 @@ abstract class AppModule { return ToroExo.with(application); } + @OptIn(markerClass = UnstableApi.class) @Provides @Singleton static ExoCreator provideExoCreator(Config config, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LoopAvailableExoCreator.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LoopAvailableExoCreator.java index 237004fa..4e0cedad 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LoopAvailableExoCreator.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LoopAvailableExoCreator.java @@ -4,6 +4,7 @@ import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.media3.common.Player; +import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.ExoPlayer; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; @@ -11,6 +12,7 @@ import ml.docilealligator.infinityforreddit.videoautoplay.Config; import ml.docilealligator.infinityforreddit.videoautoplay.DefaultExoCreator; import ml.docilealligator.infinityforreddit.videoautoplay.ToroExo; +@UnstableApi public class LoopAvailableExoCreator extends DefaultExoCreator { private final SharedPreferences sharedPreferences; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/Config.java b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/Config.java index 361492d9..80ddf9a6 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/Config.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/Config.java @@ -28,10 +28,8 @@ import androidx.core.util.ObjectsCompat; import androidx.media3.common.util.UnstableApi; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.cache.Cache; -import androidx.media3.exoplayer.DefaultLoadControl; import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlayer; -import androidx.media3.exoplayer.LoadControl; import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter; @@ -43,153 +41,148 @@ import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter; * @since 3.4.0 */ +@UnstableApi @SuppressWarnings("SimplifiableIfStatement") // public final class Config { - @Nullable - private final Context context; - - // primitive flags - @DefaultRenderersFactory.ExtensionRendererMode - final int extensionMode; - - // NonNull options - @NonNull final BaseMeter meter; - @UnstableApi - @NonNull final LoadControl loadControl; - @NonNull final MediaSourceBuilder mediaSourceBuilder; - - // Nullable options - @UnstableApi - @Nullable final Cache cache; // null by default - // If null, ExoCreator must come up with a default one. - // This is to help customizing the Data source, for example using OkHttp extension. - @Nullable final DataSource.Factory dataSourceFactory; - - @OptIn(markerClass = UnstableApi.class) - @SuppressWarnings("WeakerAccess") // - Config(@Nullable Context context, int extensionMode, @NonNull BaseMeter meter, - @NonNull LoadControl loadControl, - @Nullable DataSource.Factory dataSourceFactory, - @NonNull MediaSourceBuilder mediaSourceBuilder, - @Nullable Cache cache) { - this.context = context != null ? context.getApplicationContext() : null; - this.extensionMode = extensionMode; - this.meter = meter; - this.loadControl = loadControl; - this.dataSourceFactory = dataSourceFactory; - this.mediaSourceBuilder = mediaSourceBuilder; - this.cache = cache; - } - - @OptIn(markerClass = UnstableApi.class) - @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Config config = (Config) o; - - if (extensionMode != config.extensionMode) return false; - if (!meter.equals(config.meter)) return false; - if (!loadControl.equals(config.loadControl)) return false; - if (!mediaSourceBuilder.equals(config.mediaSourceBuilder)) return false; - if (!ObjectsCompat.equals(cache, config.cache)) return false; - return ObjectsCompat.equals(dataSourceFactory, config.dataSourceFactory); - } - - @OptIn(markerClass = UnstableApi.class) - @Override public int hashCode() { - int result = extensionMode; - result = 31 * result + meter.hashCode(); - result = 31 * result + loadControl.hashCode(); - result = 31 * result + mediaSourceBuilder.hashCode(); - result = 31 * result + (cache != null ? cache.hashCode() : 0); - result = 31 * result + (dataSourceFactory != null ? dataSourceFactory.hashCode() : 0); - return result; - } - - @OptIn(markerClass = UnstableApi.class) - @SuppressWarnings("unused") public Builder newBuilder() { - return new Builder(context).setCache(this.cache) - .setExtensionMode(this.extensionMode) - .setLoadControl(this.loadControl) - .setMediaSourceBuilder(this.mediaSourceBuilder) - .setMeter(this.meter); - } - - /// Builder - @SuppressWarnings({ "unused", "WeakerAccess" }) // - public static final class Builder { - - @Nullable // only for backward compatibility - final Context context; - - /** - * @deprecated Use the constructor with nonnull {@link Context} instead. - */ - @Deprecated - public Builder() { - this(null); - } - - @OptIn(markerClass = UnstableApi.class) - public Builder(@Nullable Context context) { - this.context = context != null ? context.getApplicationContext() : null; - DefaultBandwidthMeter bandwidthMeter = - new DefaultBandwidthMeter.Builder(this.context).build(); - meter = new BaseMeter<>(bandwidthMeter); - } + @Nullable + private final Context context; - @UnstableApi + // primitive flags @DefaultRenderersFactory.ExtensionRendererMode - private int extensionMode = EXTENSION_RENDERER_MODE_OFF; - private BaseMeter meter; - @UnstableApi - private LoadControl loadControl = new DefaultLoadControl(); - private DataSource.Factory dataSourceFactory = null; - private MediaSourceBuilder mediaSourceBuilder = MediaSourceBuilder.DEFAULT; - @UnstableApi - private Cache cache = null; + final int extensionMode; - @OptIn(markerClass = UnstableApi.class) - public Builder setExtensionMode(@DefaultRenderersFactory.ExtensionRendererMode int extensionMode) { - this.extensionMode = extensionMode; - return this; - } + // NonNull options + @NonNull + final BaseMeter meter; + @NonNull + final MediaSourceBuilder mediaSourceBuilder; - public Builder setMeter(@NonNull BaseMeter meter) { - this.meter = checkNotNull(meter, "Need non-null BaseMeter"); - return this; - } + // Nullable options + @UnstableApi + @Nullable + final Cache cache; // null by default + // If null, ExoCreator must come up with a default one. + // This is to help customizing the Data source, for example using OkHttp extension. + @Nullable + final DataSource.Factory dataSourceFactory; @OptIn(markerClass = UnstableApi.class) - public Builder setLoadControl(@NonNull LoadControl loadControl) { - this.loadControl = checkNotNull(loadControl, "Need non-null LoadControl"); - return this; + @SuppressWarnings("WeakerAccess") + Config(@Nullable Context context, int extensionMode, @NonNull BaseMeter meter, + @Nullable DataSource.Factory dataSourceFactory, + @NonNull MediaSourceBuilder mediaSourceBuilder, + @Nullable Cache cache) { + this.context = context != null ? context.getApplicationContext() : null; + this.extensionMode = extensionMode; + this.meter = meter; + this.dataSourceFactory = dataSourceFactory; + this.mediaSourceBuilder = mediaSourceBuilder; + this.cache = cache; } - // Option is Nullable, but if user customize this, it must be a Nonnull one. - public Builder setDataSourceFactory(@NonNull DataSource.Factory dataSourceFactory) { - this.dataSourceFactory = checkNotNull(dataSourceFactory); - return this; + @OptIn(markerClass = UnstableApi.class) + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Config config = (Config) o; + + if (extensionMode != config.extensionMode) return false; + if (!meter.equals(config.meter)) return false; + if (!mediaSourceBuilder.equals(config.mediaSourceBuilder)) return false; + if (!ObjectsCompat.equals(cache, config.cache)) return false; + return ObjectsCompat.equals(dataSourceFactory, config.dataSourceFactory); } - public Builder setMediaSourceBuilder(@NonNull MediaSourceBuilder mediaSourceBuilder) { - this.mediaSourceBuilder = - checkNotNull(mediaSourceBuilder, "Need non-null MediaSourceBuilder"); - return this; + @OptIn(markerClass = UnstableApi.class) + @Override + public int hashCode() { + int result = extensionMode; + result = 31 * result + meter.hashCode(); + result = 31 * result + mediaSourceBuilder.hashCode(); + result = 31 * result + (cache != null ? cache.hashCode() : 0); + result = 31 * result + (dataSourceFactory != null ? dataSourceFactory.hashCode() : 0); + return result; } @OptIn(markerClass = UnstableApi.class) - public Builder setCache(@Nullable Cache cache) { - this.cache = cache; - return this; + @SuppressWarnings("unused") + public Builder newBuilder() { + return new Builder(context).setCache(this.cache) + .setExtensionMode(this.extensionMode) + .setMediaSourceBuilder(this.mediaSourceBuilder) + .setMeter(this.meter); } - @OptIn(markerClass = UnstableApi.class) - public Config build() { - return new Config(context, extensionMode, meter, loadControl, dataSourceFactory, - mediaSourceBuilder, cache); + /// Builder + @UnstableApi + @SuppressWarnings({"unused", "WeakerAccess"}) // + public static final class Builder { + + @Nullable // only for backward compatibility + final Context context; + + /** + * @deprecated Use the constructor with nonnull {@link Context} instead. + */ + @Deprecated + public Builder() { + this(null); + } + + @OptIn(markerClass = UnstableApi.class) + public Builder(@Nullable Context context) { + this.context = context != null ? context.getApplicationContext() : null; + DefaultBandwidthMeter bandwidthMeter = + new DefaultBandwidthMeter.Builder(this.context).build(); + meter = new BaseMeter<>(bandwidthMeter); + } + + @UnstableApi + @DefaultRenderersFactory.ExtensionRendererMode + private int extensionMode = EXTENSION_RENDERER_MODE_OFF; + private BaseMeter meter; + private DataSource.Factory dataSourceFactory = null; + private MediaSourceBuilder mediaSourceBuilder = MediaSourceBuilder.DEFAULT; + @UnstableApi + private Cache cache = null; + + @OptIn(markerClass = UnstableApi.class) + public Builder setExtensionMode(@DefaultRenderersFactory.ExtensionRendererMode int extensionMode) { + this.extensionMode = extensionMode; + return this; + } + + @OptIn(markerClass = UnstableApi.class) + public Builder setMeter(@NonNull BaseMeter meter) { + this.meter = checkNotNull(meter, "Need non-null BaseMeter"); + return this; + } + + // Option is Nullable, but if user customize this, it must be a Nonnull one. + public Builder setDataSourceFactory(@NonNull DataSource.Factory dataSourceFactory) { + this.dataSourceFactory = checkNotNull(dataSourceFactory); + return this; + } + + public Builder setMediaSourceBuilder(@NonNull MediaSourceBuilder mediaSourceBuilder) { + this.mediaSourceBuilder = + checkNotNull(mediaSourceBuilder, "Need non-null MediaSourceBuilder"); + return this; + } + + @OptIn(markerClass = UnstableApi.class) + public Builder setCache(@Nullable Cache cache) { + this.cache = cache; + return this; + } + + @OptIn(markerClass = UnstableApi.class) + public Config build() { + return new Config(context, extensionMode, meter, dataSourceFactory, + mediaSourceBuilder, cache); + } } - } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/DefaultExoCreator.java b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/DefaultExoCreator.java index b86a67e4..7ebd37dd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/DefaultExoCreator.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/DefaultExoCreator.java @@ -31,9 +31,9 @@ import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DefaultDataSource; import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.datasource.cache.CacheDataSource; +import androidx.media3.exoplayer.DefaultLoadControl; import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlayer; -import androidx.media3.exoplayer.LoadControl; import androidx.media3.exoplayer.RenderersFactory; import androidx.media3.exoplayer.source.LoadEventInfo; import androidx.media3.exoplayer.source.MediaLoadData; @@ -61,7 +61,6 @@ public class DefaultExoCreator implements ExoCreator, MediaSourceEventListener { final ToroExo toro; // per application final Config config; private final TrackSelector trackSelector; // 'maybe' stateless - private final LoadControl loadControl; // stateless private final MediaSourceBuilder mediaSourceBuilder; // stateless private final RenderersFactory renderersFactory; // stateless private final DataSource.Factory mediaDataSourceFactory; // stateless @@ -71,7 +70,6 @@ public class DefaultExoCreator implements ExoCreator, MediaSourceEventListener { this.toro = checkNotNull(toro); this.config = checkNotNull(config); trackSelector = new DefaultTrackSelector(toro.context); - loadControl = config.loadControl; mediaSourceBuilder = config.mediaSourceBuilder; DefaultRenderersFactory tempFactory = new DefaultRenderersFactory(this.toro.context); @@ -103,7 +101,6 @@ public class DefaultExoCreator implements ExoCreator, MediaSourceEventListener { if (!toro.equals(that.toro)) return false; if (!trackSelector.equals(that.trackSelector)) return false; - if (!loadControl.equals(that.loadControl)) return false; if (!mediaSourceBuilder.equals(that.mediaSourceBuilder)) return false; if (!renderersFactory.equals(that.renderersFactory)) return false; if (!mediaDataSourceFactory.equals(that.mediaDataSourceFactory)) return false; @@ -114,7 +111,6 @@ public class DefaultExoCreator implements ExoCreator, MediaSourceEventListener { public int hashCode() { int result = toro.hashCode(); result = 31 * result + trackSelector.hashCode(); - result = 31 * result + loadControl.hashCode(); result = 31 * result + mediaSourceBuilder.hashCode(); result = 31 * result + renderersFactory.hashCode(); result = 31 * result + mediaDataSourceFactory.hashCode(); @@ -135,7 +131,7 @@ public class DefaultExoCreator implements ExoCreator, MediaSourceEventListener { @NonNull @Override public ExoPlayer createPlayer() { - return new ToroExoPlayer(toro.context, renderersFactory, trackSelector, loadControl, + return new ToroExoPlayer(toro.context, renderersFactory, trackSelector, new DefaultLoadControl(), new DefaultBandwidthMeter.Builder(toro.context).build(), Util.getCurrentOrMainLooper()).getPlayer(); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ExoPlayerViewHelper.java b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ExoPlayerViewHelper.java index 478b7b0e..6ba68217 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ExoPlayerViewHelper.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ExoPlayerViewHelper.java @@ -59,12 +59,14 @@ public class ExoPlayerViewHelper extends ToroPlayerHelper { this(player, uri, null); } + @OptIn(markerClass = UnstableApi.class) public ExoPlayerViewHelper(@NonNull ToroPlayer player, @NonNull Uri uri, @Nullable String fileExt) { this(player, uri, fileExt, with(player.getPlayerView().getContext()).getDefaultCreator()); } /** Config instance should be kept as global instance. */ + @OptIn(markerClass = UnstableApi.class) public ExoPlayerViewHelper(@NonNull ToroPlayer player, @NonNull Uri uri, @Nullable String fileExt, @NonNull Config config) { this(player, uri, fileExt, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ToroExo.java b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ToroExo.java index 43dbbb1e..727ef105 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ToroExo.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ToroExo.java @@ -60,6 +60,7 @@ import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo; * @since 3.4.0 */ +@UnstableApi public final class ToroExo { private static final String TAG = "ToroExo"; |