aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDocile-Alligator <25734209+Docile-Alligator@users.noreply.github.com>2024-07-02 20:41:49 +0000
committerDocile-Alligator <25734209+Docile-Alligator@users.noreply.github.com>2024-07-02 20:41:49 +0000
commitfccf2c57851f3b3f6e3b7e67e34699d945a48234 (patch)
tree5e8b74112d9af3f53bc9d58214df6121c4c1f21d
parentca4e58985f17bcfb0c3eab5b765f9f0cf22ec677 (diff)
downloadinfinity-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().
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java1
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LoopAvailableExoCreator.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/Config.java257
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/DefaultExoCreator.java8
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ExoPlayerViewHelper.java2
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/videoautoplay/ToroExo.java1
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";