Migrate to AndroidX Media3.

This commit is contained in:
Docile-Alligator 2024-05-12 22:52:04 -04:00
parent 4abb494709
commit ff91d33a88
41 changed files with 382 additions and 291 deletions

View File

@ -85,11 +85,11 @@ dependencies {
/** ExoPlayer **/
def exoplayerVersion = "2.19.1"
implementation "com.google.android.exoplayer:exoplayer-core:$exoplayerVersion"
implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayerVersion"
implementation "com.google.android.exoplayer:exoplayer-hls:$exoplayerVersion"
implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayerVersion"
implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:$exoplayerVersion"
implementation "androidx.media3:media3-exoplayer:1.1.1"
implementation "androidx.media3:media3-exoplayer-dash:1.1.1"
implementation "androidx.media3:media3-exoplayer-hls:1.1.1"
implementation "androidx.media3:media3-ui:1.1.1"
implementation "androidx.media3:media3-exoplayer-smoothstreaming:1.1.1"
/** Third-party **/

View File

@ -4,12 +4,13 @@ import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.database.StandaloneDatabaseProvider;
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.preference.PreferenceManager;
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider;
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import java.io.File;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
@ -162,11 +163,13 @@ abstract class AppModule {
return new File(appCache, "/exoplayer");
}
@OptIn(markerClass = UnstableApi.class)
@Provides
static StandaloneDatabaseProvider provideExoDatabaseProvider(Application application) {
return new StandaloneDatabaseProvider(application);
}
@OptIn(markerClass = UnstableApi.class)
@Provides
@Singleton
static SimpleCache provideSimpleCache(StandaloneDatabaseProvider standaloneDatabaseProvider,
@ -176,6 +179,7 @@ abstract class AppModule {
standaloneDatabaseProvider);
}
@OptIn(markerClass = UnstableApi.class)
@Provides
static Config providesMediaConfig(Application application, SimpleCache simpleCache) {
return new Config.Builder(application)

View File

@ -16,19 +16,21 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.core.content.ContextCompat;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultDataSourceFactory;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
@ -132,6 +134,7 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF
private ExoPlayer player;
private ActivityPostVideoBinding binding;
@OptIn(markerClass = UnstableApi.class)
@Override
protected void onCreate(Bundle savedInstanceState) {
((Infinity) getApplication()).getAppComponent().inject(this);
@ -447,6 +450,7 @@ public class PostVideoActivity extends BaseActivity implements FlairBottomSheetF
}
}
@OptIn(markerClass = UnstableApi.class)
private void loadVideo() {
binding.selectVideoConstraintLayoutPostVideoActivity.setVisibility(View.GONE);
binding.selectAgainTextViewPostVideoActivity.setVisibility(View.VISIBLE);

View File

@ -32,6 +32,7 @@ import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
@ -43,29 +44,30 @@ import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.TrackSelectionOverride;
import androidx.media3.common.Tracks;
import androidx.media3.common.VideoSize;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.hls.HlsMediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.ui.PlayerControlView;
import androidx.media3.ui.PlayerView;
import androidx.media3.ui.TrackSelectionDialogBuilder;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionOverride;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoSize;
import com.google.android.material.button.MaterialButton;
import com.google.common.collect.ImmutableList;
import com.otaliastudios.zoom.ZoomEngine;
@ -152,6 +154,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
private Uri mVideoUri;
private ExoPlayer player;
@UnstableApi
private DefaultTrackSelector trackSelector;
private DataSource.Factory dataSourceFactory;
@ -202,9 +205,11 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
@Inject
Executor mExecutor;
@UnstableApi
@Inject
SimpleCache mSimpleCache;
@OptIn(markerClass = UnstableApi.class)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -462,9 +467,9 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
}
});
} else {
StyledPlayerView videoPlayerView = findViewById(R.id.player_view_view_video_activity);
PlayerView videoPlayerView = findViewById(R.id.player_view_view_video_activity);
videoPlayerView.setPlayer(player);
videoPlayerView.setControllerVisibilityListener(new StyledPlayerView.ControllerVisibilityListener() {
videoPlayerView.setControllerVisibilityListener(new PlayerView.ControllerVisibilityListener() {
@Override
public void onVisibilityChanged(int visibility) {
switch (visibility) {
@ -686,6 +691,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
playbackSpeedBottomSheetFragment.show(getSupportFragmentManager(), playbackSpeedBottomSheetFragment.getTag());
}
@OptIn(markerClass = UnstableApi.class)
private int inferPrimaryTrackType(Format format) {
int trackType = MimeTypes.getTrackType(format.sampleMimeType);
if (trackType != C.TRACK_TYPE_UNKNOWN) {
@ -710,6 +716,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
binding.getProgressBar().setVisibility(View.VISIBLE);
FetchRedgifsVideoLinks.fetchRedgifsVideoLinks(mExecutor, new Handler(), mRedgifsRetrofit,
mCurrentAccountSharedPreferences, redgifsId, new FetchRedgifsVideoLinks.FetchRedgifsVideoLinksListener() {
@OptIn(markerClass = UnstableApi.class)
@Override
public void success(String webm, String mp4) {
binding.getProgressBar().setVisibility(View.GONE);
@ -742,6 +749,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
String postId = segments.get(commentsIndex + 1);
FetchPost.fetchPost(mExecutor, new Handler(), mRetrofit, postId, null, Account.ANONYMOUS_ACCOUNT,
new FetchPost.FetchPostListener() {
@OptIn(markerClass = UnstableApi.class)
@Override
public void fetchPostSuccess(Post post) {
videoFallbackDirectUrl = post.getVideoFallBackDirectUrl();
@ -807,6 +815,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
binding.getProgressBar().setVisibility(View.VISIBLE);
FetchStreamableVideo.fetchStreamableVideo(mExecutor, new Handler(), mStreamableApiProvider, shortCode,
new FetchStreamableVideo.FetchStreamableVideoListener() {
@OptIn(markerClass = UnstableApi.class)
@Override
public void success(StreamableVideo streamableVideo) {
if (streamableVideo.mp4 == null && streamableVideo.mp4Mobile == null) {
@ -831,6 +840,7 @@ public class ViewVideoActivity extends AppCompatActivity implements CustomFontRe
});
}
@OptIn(markerClass = UnstableApi.class)
private void loadFallbackVideo(Bundle savedInstanceState) {
if (videoFallbackDirectUrl != null) {
MediaItem mediaItem = player.getCurrentMediaItem();

View File

@ -25,12 +25,21 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.Barrier;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.ui.AspectRatioFrameLayout;
import androidx.media3.ui.DefaultTimeBar;
import androidx.media3.ui.PlayerView;
import androidx.media3.ui.TimeBar;
import androidx.paging.PagingDataAdapter;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ItemTouchHelper;
@ -45,14 +54,6 @@ import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.DefaultTimeBar;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.ui.TimeBar;
import com.google.android.exoplayer2.util.Util;
import com.google.android.material.button.MaterialButton;
import com.google.common.collect.ImmutableList;
import com.libRG.CustomTextView;
@ -491,6 +492,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@OptIn(markerClass = UnstableApi.class)
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -554,6 +556,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof PostBaseViewHolder) {
@ -2210,6 +2213,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
this.mEasierToWatchInFullScreen = easierToWatchInFullScreen;
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof PostBaseViewHolder) {
@ -3111,11 +3115,12 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostBaseVideoAutoplayViewHolder extends PostBaseViewHolder implements ToroPlayer {
AspectRatioFrameLayout aspectRatioFrameLayout;
GifImageView previewImageView;
ImageView errorLoadingVideoImageView;
StyledPlayerView videoPlayer;
PlayerView videoPlayer;
ImageView muteButton;
ImageView fullscreenButton;
ImageView playPauseButton;
@ -3131,6 +3136,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
private Drawable playDrawable;
private Drawable pauseDrawable;
@OptIn(markerClass = UnstableApi.class)
PostBaseVideoAutoplayViewHolder(View rootView,
AspectRatioGifImageView iconGifImageView,
TextView subredditTextView,
@ -3148,7 +3154,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
AspectRatioFrameLayout aspectRatioFrameLayout,
GifImageView previewImageView,
ImageView errorLoadingVideoImageView,
StyledPlayerView videoPlayer,
PlayerView videoPlayer,
ImageView muteButton,
ImageView fullscreenButton,
ImageView playPauseButton,
@ -3443,6 +3449,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostVideoAutoplayViewHolder extends PostBaseVideoAutoplayViewHolder {
PostVideoAutoplayViewHolder(ItemPostVideoTypeAutoplayBinding binding) {
super(binding.getRoot(),
@ -3477,6 +3484,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostVideoAutoplayLegacyControllerViewHolder extends PostBaseVideoAutoplayViewHolder {
PostVideoAutoplayLegacyControllerViewHolder(ItemPostVideoTypeAutoplayLegacyControllerBinding binding) {
super(binding.getRoot(),
@ -4762,11 +4770,12 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostCard2BaseVideoAutoplayViewHolder extends PostBaseViewHolder implements ToroPlayer {
AspectRatioFrameLayout aspectRatioFrameLayout;
GifImageView previewImageView;
ImageView errorLoadingRedgifsImageView;
StyledPlayerView videoPlayer;
PlayerView videoPlayer;
ImageView muteButton;
ImageView fullscreenButton;
ImageView playPauseButton;
@ -4784,6 +4793,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
private Drawable playDrawable;
private Drawable pauseDrawable;
@OptIn(markerClass = UnstableApi.class)
PostCard2BaseVideoAutoplayViewHolder(View itemView,
AspectRatioGifImageView iconGifImageView,
TextView subredditTextView,
@ -4801,7 +4811,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
AspectRatioFrameLayout aspectRatioFrameLayout,
GifImageView previewImageView,
ImageView errorLoadingRedgifsImageView,
StyledPlayerView videoPlayer,
PlayerView videoPlayer,
ImageView muteButton,
ImageView fullscreenButton,
ImageView playPauseButton,
@ -5098,6 +5108,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostCard2VideoAutoplayViewHolder extends PostCard2BaseVideoAutoplayViewHolder {
PostCard2VideoAutoplayViewHolder(ItemPostCard2VideoAutoplayBinding binding) {
super(binding.getRoot(),
@ -5133,6 +5144,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostCard2VideoAutoplayLegacyControllerViewHolder extends PostCard2BaseVideoAutoplayViewHolder {
PostCard2VideoAutoplayLegacyControllerViewHolder(ItemPostCard2VideoAutoplayLegacyControllerBinding binding) {
super(binding.getRoot(),
@ -5788,11 +5800,12 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostMaterial3CardBaseVideoAutoplayViewHolder extends PostMaterial3CardBaseViewHolder implements ToroPlayer {
AspectRatioFrameLayout aspectRatioFrameLayout;
GifImageView previewImageView;
ImageView errorLoadingRedgifsImageView;
StyledPlayerView videoPlayer;
PlayerView videoPlayer;
ImageView muteButton;
ImageView fullscreenButton;
ImageView playPauseButton;
@ -5818,7 +5831,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
AspectRatioFrameLayout aspectRatioFrameLayout,
GifImageView previewImageView,
ImageView errorLoadingRedgifsImageView,
StyledPlayerView videoPlayer,
PlayerView videoPlayer,
ImageView muteButton,
ImageView fullscreenButton,
ImageView playPauseButton,
@ -6130,6 +6143,7 @@ public class HistoryPostRecyclerViewAdapter extends PagingDataAdapter<Post, Recy
}
}
@UnstableApi
class PostMaterial3CardVideoAutoplayLegacyControllerViewHolder extends PostMaterial3CardBaseVideoAutoplayViewHolder {
PostMaterial3CardVideoAutoplayLegacyControllerViewHolder(ItemPostCard3VideoTypeAutoplayLegacyControllerBinding binding) {
super(binding.getRoot(),

View File

@ -25,9 +25,19 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.ui.AspectRatioFrameLayout;
import androidx.media3.ui.DefaultTimeBar;
import androidx.media3.ui.PlayerView;
import androidx.media3.ui.TimeBar;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.PagerSnapHelper;
import androidx.recyclerview.widget.RecyclerView;
@ -39,14 +49,6 @@ import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.DefaultTimeBar;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.ui.TimeBar;
import com.google.android.exoplayer2.util.Util;
import com.google.android.material.button.MaterialButton;
import com.google.common.collect.ImmutableList;
import com.libRG.CustomTextView;
@ -463,6 +465,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
}
}
@OptIn(markerClass = UnstableApi.class)
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -512,6 +515,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
}
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof PostDetailBaseViewHolder) {
@ -1020,6 +1024,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
}
}
@OptIn(markerClass = UnstableApi.class)
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
if (holder instanceof PostDetailBaseViewHolder) {
@ -1592,10 +1597,11 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
}
}
@UnstableApi
class PostDetailBaseVideoAutoplayViewHolder extends PostDetailBaseViewHolder implements ToroPlayer {
public Call<String> fetchRedgifsOrStreamableVideoCall;
AspectRatioFrameLayout aspectRatioFrameLayout;
StyledPlayerView playerView;
PlayerView playerView;
GifImageView previewImageView;
ImageView mErrorLoadingRedgifsImageView;
ImageView muteButton;
@ -1628,7 +1634,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
CustomTextView flairTextView,
TextView upvoteRatioTextView,
AspectRatioFrameLayout aspectRatioFrameLayout,
StyledPlayerView playerView,
PlayerView playerView,
GifImageView previewImageView,
ImageView errorLoadingRedgifsImageView,
ImageView muteButton,
@ -1913,6 +1919,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
}
}
@UnstableApi
class PostDetailVideoAutoplayViewHolder extends PostDetailBaseVideoAutoplayViewHolder {
PostDetailVideoAutoplayViewHolder(@NonNull ItemPostDetailVideoAutoplayBinding binding) {
super(binding.getRoot(),
@ -1949,6 +1956,7 @@ public class PostDetailRecyclerViewAdapter extends RecyclerView.Adapter<Recycler
}
}
@UnstableApi
class PostDetailVideoAutoplayLegacyControllerViewHolder extends PostDetailBaseVideoAutoplayViewHolder {
PostDetailVideoAutoplayLegacyControllerViewHolder(ItemPostDetailVideoAutoplayLegacyControllerBinding binding) {
super(binding.getRoot(),

View File

@ -30,7 +30,14 @@ import androidx.constraintlayout.widget.Barrier;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.Util;
import androidx.media3.ui.AspectRatioFrameLayout;
import androidx.media3.ui.DefaultTimeBar;
import androidx.media3.ui.PlayerView;
import androidx.media3.ui.TimeBar;
import androidx.paging.PagingDataAdapter;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ItemTouchHelper;
@ -45,14 +52,6 @@ import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.DefaultTimeBar;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.ui.TimeBar;
import com.google.android.exoplayer2.util.Util;
import com.google.android.material.button.MaterialButton;
import com.google.common.collect.ImmutableList;
import com.libRG.CustomTextView;
@ -3277,7 +3276,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
AspectRatioFrameLayout aspectRatioFrameLayout;
GifImageView previewImageView;
ImageView errorLoadingRedgifsImageView;
StyledPlayerView videoPlayer;
PlayerView videoPlayer;
ImageView muteButton;
ImageView fullscreenButton;
ImageView playPauseButton;
@ -3310,7 +3309,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
AspectRatioFrameLayout aspectRatioFrameLayout,
GifImageView previewImageView,
ImageView errorLoadingRedgifsImageView,
StyledPlayerView videoPlayer,
PlayerView videoPlayer,
ImageView muteButton,
ImageView fullscreenButton,
ImageView playPauseButton,
@ -4997,7 +4996,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
AspectRatioFrameLayout aspectRatioFrameLayout;
GifImageView previewImageView;
ImageView errorLoadingRedgifsImageView;
StyledPlayerView videoPlayer;
PlayerView videoPlayer;
ImageView muteButton;
ImageView fullscreenButton;
ImageView playPauseButton;
@ -5031,7 +5030,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
AspectRatioFrameLayout aspectRatioFrameLayout,
GifImageView previewImageView,
ImageView errorLoadingRedgifsImageView,
StyledPlayerView videoPlayer,
PlayerView videoPlayer,
ImageView muteButton,
ImageView fullscreenButton,
ImageView playPauseButton,
@ -6055,7 +6054,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
AspectRatioFrameLayout aspectRatioFrameLayout;
GifImageView previewImageView;
ImageView errorLoadingRedgifsImageView;
StyledPlayerView videoPlayer;
PlayerView videoPlayer;
ImageView muteButton;
ImageView fullscreenButton;
ImageView playPauseButton;
@ -6081,7 +6080,7 @@ public class PostRecyclerViewAdapter extends PagingDataAdapter<Post, RecyclerVie
AspectRatioFrameLayout aspectRatioFrameLayout,
GifImageView previewImageView,
ImageView errorLoadingRedgifsImageView,
StyledPlayerView videoPlayer,
PlayerView videoPlayer,
ImageView muteButton,
ImageView fullscreenButton,
ImageView playPauseButton,

View File

@ -3,9 +3,8 @@ package ml.docilealligator.infinityforreddit.customviews;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.Player;
import androidx.media3.common.Player;
import androidx.media3.exoplayer.ExoPlayer;
import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils;
import ml.docilealligator.infinityforreddit.videoautoplay.Config;

View File

@ -23,21 +23,22 @@ import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.Fragment;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.trackselection.TrackSelector;
import androidx.media3.ui.PlayerView;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.Util;
import com.google.android.material.button.MaterialButton;
import com.google.common.collect.ImmutableList;
@ -76,6 +77,7 @@ public class ViewImgurVideoFragment extends Fragment {
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@UnstableApi
@Inject
SimpleCache mSimpleCache;
private ViewImgurVideoFragmentBindingAdapter binding;
@ -118,7 +120,7 @@ public class ViewImgurVideoFragment extends Fragment {
}
}
binding.getRoot().setControllerVisibilityListener(new StyledPlayerView.ControllerVisibilityListener() {
binding.getRoot().setControllerVisibilityListener(new PlayerView.ControllerVisibilityListener() {
@Override
public void onVisibilityChanged(int visibility) {
switch (visibility) {

View File

@ -2,7 +2,8 @@ package ml.docilealligator.infinityforreddit.fragments;
import android.widget.TextView;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import androidx.media3.ui.PlayerView;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.button.MaterialButton;
@ -28,7 +29,7 @@ class ViewImgurVideoFragmentBindingAdapter {
playbackSpeedButton = binding.getRoot().findViewById(R.id.playback_speed_image_view_exo_playback_control_view);
}
StyledPlayerView getRoot() {
PlayerView getRoot() {
return binding.getRoot();
}

View File

@ -20,24 +20,26 @@ import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.Fragment;
import androidx.media3.common.MediaItem;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.trackselection.TrackSelector;
import androidx.media3.ui.PlayerView;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.Util;
import com.google.android.material.button.MaterialButton;
import com.google.common.collect.ImmutableList;
@ -79,6 +81,7 @@ public class ViewRedditGalleryVideoFragment extends Fragment {
@Inject
@Named("default")
SharedPreferences mSharedPreferences;
@UnstableApi
@Inject
SimpleCache mSimpleCache;
private ViewRedditGalleryVideoFragmentBindingAdapter binding;
@ -88,6 +91,7 @@ public class ViewRedditGalleryVideoFragment extends Fragment {
}
@OptIn(markerClass = UnstableApi.class)
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@ -123,7 +127,7 @@ public class ViewRedditGalleryVideoFragment extends Fragment {
}
}
binding.getPlayerView().setControllerVisibilityListener((StyledPlayerView.ControllerVisibilityListener) visibility -> {
binding.getPlayerView().setControllerVisibilityListener((PlayerView.ControllerVisibilityListener) visibility -> {
switch (visibility) {
case View.GONE:
activity.getWindow().getDecorView().setSystemUiVisibility(

View File

@ -4,7 +4,8 @@ import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import androidx.media3.ui.PlayerView;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.button.MaterialButton;
@ -35,7 +36,7 @@ class ViewRedditGalleryVideoFragmentBindingAdapter {
return binding.getRoot();
}
StyledPlayerView getPlayerView() {
PlayerView getPlayerView() {
return binding.playerViewViewRedditGalleryVideoFragment;
}

View File

@ -20,12 +20,12 @@ import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.TransferListener;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.upstream.BandwidthMeter;
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;
/**
* Abstract the {@link DefaultBandwidthMeter}, provide a wider use.
@ -34,6 +34,7 @@ import com.google.android.exoplayer2.upstream.TransferListener;
* @since 3.4.0
*/
@UnstableApi
@SuppressWarnings("WeakerAccess") //
public final class BaseMeter<T extends BandwidthMeter> implements BandwidthMeter, TransferListener {

View File

@ -16,26 +16,27 @@
package ml.docilealligator.infinityforreddit.videoautoplay;
import static com.google.android.exoplayer2.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
import static androidx.media3.exoplayer.DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
import static ml.docilealligator.infinityforreddit.videoautoplay.ToroUtil.checkNotNull;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.core.util.ObjectsCompat;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory.ExtensionRendererMode;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.cache.Cache;
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;
/**
* Necessary configuration for {@link ExoCreator} to produces {@link SimpleExoPlayer} and
* Necessary configuration for {@link ExoCreator} to produces {@link ExoPlayer} and
* {@link MediaSource}. Instance of this class must be construct using {@link Builder}.
*
* @author eneim (2018/01/23).
@ -49,19 +50,23 @@ public final class Config {
private final Context context;
// primitive flags
@ExtensionRendererMode final int extensionMode;
@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,
@ -77,6 +82,7 @@ public final class Config {
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;
@ -91,6 +97,7 @@ public final class Config {
return ObjectsCompat.equals(dataSourceFactory, config.dataSourceFactory);
}
@OptIn(markerClass = UnstableApi.class)
@Override public int hashCode() {
int result = extensionMode;
result = 31 * result + meter.hashCode();
@ -101,6 +108,7 @@ public final class Config {
return result;
}
@OptIn(markerClass = UnstableApi.class)
@SuppressWarnings("unused") public Builder newBuilder() {
return new Builder(context).setCache(this.cache)
.setExtensionMode(this.extensionMode)
@ -124,6 +132,7 @@ public final class Config {
this(null);
}
@OptIn(markerClass = UnstableApi.class)
public Builder(@Nullable Context context) {
this.context = context != null ? context.getApplicationContext() : null;
DefaultBandwidthMeter bandwidthMeter =
@ -131,14 +140,19 @@ public final class Config {
meter = new BaseMeter<>(bandwidthMeter);
}
@ExtensionRendererMode private int extensionMode = EXTENSION_RENDERER_MODE_OFF;
@UnstableApi
@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;
public Builder setExtensionMode(@ExtensionRendererMode int extensionMode) {
@OptIn(markerClass = UnstableApi.class)
public Builder setExtensionMode(@DefaultRenderersFactory.ExtensionRendererMode int extensionMode) {
this.extensionMode = extensionMode;
return this;
}
@ -148,6 +162,7 @@ public final class Config {
return this;
}
@OptIn(markerClass = UnstableApi.class)
public Builder setLoadControl(@NonNull LoadControl loadControl) {
this.loadControl = checkNotNull(loadControl, "Need non-null LoadControl");
return this;
@ -165,11 +180,13 @@ public final class Config {
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, loadControl, dataSourceFactory,
mediaSourceBuilder, cache);

View File

@ -25,23 +25,23 @@ import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.util.Util;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
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.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;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSourceEventListener;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.trackselection.TrackSelector;
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;
import java.io.IOException;
@ -54,6 +54,7 @@ import ml.docilealligator.infinityforreddit.utils.APIUtils;
* @since 3.4.0
*/
@UnstableApi
@SuppressWarnings({"unused", "WeakerAccess"}) //
public class DefaultExoCreator implements ExoCreator, MediaSourceEventListener {

View File

@ -21,13 +21,12 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.MediaSource;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.MediaSource;
/**
* A simple interface whose implementation helps Client to easily create {@link SimpleExoPlayer}
* A simple interface whose implementation helps Client to easily create {@link ExoPlayer}
* instance, {@link MediaSource} instance or specifically a {@link Playable} instance.
*
* Most of the time, Client just needs to request for a {@link Playable} for a specific Uri.
@ -47,11 +46,11 @@ public interface ExoCreator {
@Nullable Context getContext();
/**
* Create a new {@link SimpleExoPlayer} instance. This method should always create new instance of
* {@link SimpleExoPlayer}, but client should use {@link ExoCreator} indirectly via
* Create a new {@link ExoPlayer} instance. This method should always create new instance of
* {@link ExoPlayer}, but client should use {@link ExoCreator} indirectly via
* {@link ToroExo}.
*
* @return a new {@link SimpleExoPlayer} instance.
* @return a new {@link ExoPlayer} instance.
*/
@NonNull
ExoPlayer createPlayer();

View File

@ -16,7 +16,7 @@
package ml.docilealligator.infinityforreddit.videoautoplay;
import static com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS;
import static androidx.media3.exoplayer.trackselection.MappingTrackSelector.MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS;
import static ml.docilealligator.infinityforreddit.videoautoplay.ToroExo.toro;
import android.net.Uri;
@ -24,18 +24,20 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.media3.common.C;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.Tracks;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlaybackException;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.BehindLiveWindowException;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.trackselection.MappingTrackSelector;
import androidx.media3.exoplayer.trackselection.TrackSelector;
import androidx.media3.ui.PlayerView;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.common.collect.ImmutableList;
import ml.docilealligator.infinityforreddit.R;
@ -48,6 +50,7 @@ import ml.docilealligator.infinityforreddit.R;
* @since 3.4.0
*/
@OptIn(markerClass = UnstableApi.class)
@SuppressWarnings("WeakerAccess")
public class ExoPlayable extends PlayableImpl {
@ -62,7 +65,7 @@ public class ExoPlayable extends PlayableImpl {
/**
* Construct an instance of {@link ExoPlayable} from an {@link ExoCreator} and {@link Uri}. The
* {@link ExoCreator} is used to request {@link SimpleExoPlayer} instance, while {@link Uri}
* {@link ExoCreator} is used to request {@link ExoPlayer} instance, while {@link Uri}
* defines the media to play.
*
* @param creator the {@link ExoCreator} instance.
@ -85,7 +88,7 @@ public class ExoPlayable extends PlayableImpl {
}
@Override
public void setPlayerView(@Nullable StyledPlayerView playerView) {
public void setPlayerView(@Nullable PlayerView playerView) {
// This will also clear these flags
if (playerView != this.playerView) {
this.lastSeenTrackGroupArray = null;
@ -132,7 +135,7 @@ public class ExoPlayable extends PlayableImpl {
if (!(creator instanceof DefaultExoCreator)) return;
TrackSelector selector = ((DefaultExoCreator) creator).getTrackSelector();
if (selector instanceof DefaultTrackSelector) {
MappedTrackInfo trackInfo = ((DefaultTrackSelector) selector).getCurrentMappedTrackInfo();
MappingTrackSelector.MappedTrackInfo trackInfo = ((DefaultTrackSelector) selector).getCurrentMappedTrackInfo();
if (trackInfo != null) {
if (trackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO) == RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
onErrorMessage(toro.getString(R.string.error_unsupported_video));

View File

@ -23,9 +23,10 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.PlayerView;
import ml.docilealligator.infinityforreddit.videoautoplay.annotations.RemoveIn;
import ml.docilealligator.infinityforreddit.videoautoplay.helper.ToroPlayerHelper;
@ -44,6 +45,7 @@ import ml.docilealligator.infinityforreddit.videoautoplay.widget.Container;
public class ExoPlayerViewHelper extends ToroPlayerHelper {
@NonNull private final ExoPlayable playable;
@UnstableApi
@NonNull private final MyEventListeners listeners;
private final boolean lazyPrepare;
@ -74,10 +76,11 @@ public class ExoPlayerViewHelper extends ToroPlayerHelper {
this(player, new ExoPlayable(creator, uri, fileExt));
}
@OptIn(markerClass = UnstableApi.class)
public ExoPlayerViewHelper(@NonNull ToroPlayer player, @NonNull ExoPlayable playable) {
super(player);
//noinspection ConstantConditions
if (player.getPlayerView() == null || !(player.getPlayerView() instanceof StyledPlayerView)) {
if (player.getPlayerView() == null || !(player.getPlayerView() instanceof PlayerView)) {
throw new IllegalArgumentException("Require non-null PlayerView");
}
@ -86,15 +89,17 @@ public class ExoPlayerViewHelper extends ToroPlayerHelper {
this.lazyPrepare = true;
}
@OptIn(markerClass = UnstableApi.class)
@Override protected void initialize(@NonNull PlaybackInfo playbackInfo) {
playable.setPlaybackInfo(playbackInfo);
playable.addEventListener(listeners);
playable.addErrorListener(super.getErrorListeners());
playable.addOnVolumeChangeListener(super.getVolumeChangeListeners());
playable.prepare(!lazyPrepare);
playable.setPlayerView((StyledPlayerView) player.getPlayerView());
playable.setPlayerView((PlayerView) player.getPlayerView());
}
@OptIn(markerClass = UnstableApi.class)
@Override public void release() {
super.release();
playable.setPlayerView(null);
@ -140,16 +145,19 @@ public class ExoPlayerViewHelper extends ToroPlayerHelper {
this.playable.setPlaybackInfo(playbackInfo);
}
@OptIn(markerClass = UnstableApi.class)
public void addEventListener(@NonNull Playable.EventListener listener) {
//noinspection ConstantConditions
if (listener != null) this.listeners.add(listener);
}
@OptIn(markerClass = UnstableApi.class)
public void removeEventListener(Playable.EventListener listener) {
this.listeners.remove(listener);
}
// A proxy, to also hook into ToroPlayerHelper's state change event.
@UnstableApi
private class MyEventListeners extends Playable.EventListeners {
MyEventListeners() {

View File

@ -17,7 +17,8 @@
package ml.docilealligator.infinityforreddit.videoautoplay;
import static android.text.TextUtils.isEmpty;
import static com.google.android.exoplayer2.util.Util.inferContentType;
import static androidx.media3.common.util.Util.inferContentType;
import android.content.Context;
import android.net.Uri;
@ -25,20 +26,21 @@ import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.ContentType;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.LoopingMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
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 androidx.annotation.OptIn;
import androidx.media3.common.C;
import androidx.media3.common.C.ContentType;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.DataSource;
import androidx.media3.exoplayer.dash.DashMediaSource;
import androidx.media3.exoplayer.dash.DefaultDashChunkSource;
import androidx.media3.exoplayer.hls.HlsMediaSource;
import androidx.media3.exoplayer.smoothstreaming.DefaultSsChunkSource;
import androidx.media3.exoplayer.smoothstreaming.SsMediaSource;
import androidx.media3.exoplayer.source.LoopingMediaSource;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSourceEventListener;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
/**
* @author eneim (2018/01/24).
@ -47,6 +49,7 @@ import com.google.android.exoplayer2.upstream.DataSource;
public interface MediaSourceBuilder {
@OptIn(markerClass = UnstableApi.class)
@NonNull
MediaSource buildMediaSource(@NonNull Context context, @NonNull Uri uri,
@Nullable String fileExt, @Nullable Handler handler,
@ -55,13 +58,14 @@ public interface MediaSourceBuilder {
@Nullable MediaSourceEventListener listener);
MediaSourceBuilder DEFAULT = new MediaSourceBuilder() {
@OptIn(markerClass = UnstableApi.class)
@NonNull
@Override
public MediaSource buildMediaSource(@NonNull Context context, @NonNull Uri uri,
@Nullable String ext, @Nullable Handler handler,
@NonNull DataSource.Factory manifestDataSourceFactory,
@NonNull DataSource.Factory mediaDataSourceFactory, MediaSourceEventListener listener) {
@ContentType int type = isEmpty(ext) ? inferContentType(uri) : inferContentType("." + ext);
@ContentType int type = isEmpty(ext) ? inferContentType(uri) : inferContentType(Uri.parse("." + ext));
MediaSource result;
switch (type) {
case C.CONTENT_TYPE_SS:
@ -93,6 +97,7 @@ public interface MediaSourceBuilder {
MediaSourceBuilder LOOPING = new MediaSourceBuilder() {
@OptIn(markerClass = UnstableApi.class)
@NonNull
@Override
public MediaSource buildMediaSource(@NonNull Context context, @NonNull Uri uri,

View File

@ -19,21 +19,21 @@ package ml.docilealligator.infinityforreddit.videoautoplay;
import androidx.annotation.FloatRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.MetadataOutput;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.CueGroup;
import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.video.VideoSize;
import androidx.media3.common.Metadata;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.Timeline;
import androidx.media3.common.Tracks;
import androidx.media3.common.VideoSize;
import androidx.media3.common.text.Cue;
import androidx.media3.common.text.CueGroup;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.metadata.MetadataOutput;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.text.TextOutput;
import androidx.media3.ui.PlayerView;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
@ -43,7 +43,7 @@ import ml.docilealligator.infinityforreddit.videoautoplay.media.PlaybackInfo;
import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo;
/**
* Define an interface to control a playback, specific for {@link SimpleExoPlayer} and {@link StyledPlayerView}.
* Define an interface to control a playback, specific for {@link ExoPlayer} and {@link PlayerView}.
* <p>
* This interface is designed to be reused across Config change. Implementation must not hold any
* strong reference to Activity, and if it supports any kind of that, make sure to implicitly clean
@ -57,13 +57,13 @@ import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo;
public interface Playable {
/**
* Prepare the resource for a {@link SimpleExoPlayer}. This method should:
* - Request for new {@link SimpleExoPlayer} instance if there is not a usable one.
* Prepare the resource for a {@link ExoPlayer}. This method should:
* - Request for new {@link ExoPlayer} instance if there is not a usable one.
* - Configure {@link EventListener} for it.
* - If there is non-trivial PlaybackInfo, update it to the SimpleExoPlayer.
* - If there is non-trivial PlaybackInfo, update it to the ExoPlayer.
* - If client request to prepare MediaSource, then prepare it.
* <p>
* This method must be called before {@link #setPlayerView(com.google.android.exoplayer2.ui.StyledPlayerView)}.
* This method must be called before {@link #setPlayerView(PlayerView)}.
*
* @param prepareSource if {@code true}, also prepare the MediaSource when preparing the Player,
* if {@code false} just do nothing for the MediaSource.
@ -71,24 +71,24 @@ public interface Playable {
void prepare(boolean prepareSource);
/**
* Set the {@link StyledPlayerView} for this Playable. It is expected that a playback doesn't require a
* UI, so this setup is optional. But it must be called after the SimpleExoPlayer is prepared,
* Set the {@link PlayerView} for this Playable. It is expected that a playback doesn't require a
* UI, so this setup is optional. But it must be called after the ExoPlayer is prepared,
* that is after {@link #prepare(boolean)} and before {@link #release()}.
* <p>
* Changing the PlayerView during playback is expected, though not always recommended, especially
* on old Devices with low Android API.
*
* @param playerView the PlayerView to set to the SimpleExoPlayer.
* @param playerView the PlayerView to set to the ExoPlayer.
*/
void setPlayerView(@Nullable StyledPlayerView playerView);
void setPlayerView(@Nullable PlayerView playerView);
/**
* Get current {@link StyledPlayerView} of this Playable.
* Get current {@link PlayerView} of this Playable.
*
* @return current PlayerView instance of this Playable.
*/
@Nullable
StyledPlayerView getPlayerView();
PlayerView getPlayerView();
/**
* Start the playback. If the {@link MediaSource} is not prepared, then also prepare it.
@ -102,13 +102,13 @@ public interface Playable {
/**
* Reset all resource, so that the playback can start all over again. This is to cleanup the
* playback for reuse. The SimpleExoPlayer instance must be still usable without calling
* playback for reuse. The ExoPlayer instance must be still usable without calling
* {@link #prepare(boolean)}.
*/
void reset();
/**
* Release all resource. After this, the SimpleExoPlayer is released to the Player pool and the
* Release all resource. After this, the ExoPlayer is released to the Player pool and the
* Playable must call {@link #prepare(boolean)} again to use it again.
*/
void release();
@ -210,6 +210,7 @@ public interface Playable {
void removeErrorListener(@Nullable ToroPlayer.OnErrorListener listener);
// Combine necessary interfaces.
@UnstableApi
interface EventListener extends Player.Listener, TextOutput, MetadataOutput {
@Override
@ -231,6 +232,7 @@ public interface Playable {
/**
* Default empty implementation
*/
@UnstableApi
class DefaultEventListener implements EventListener {
@Override
public void onTimelineChanged(@NonNull Timeline timeline, int reason) {
@ -301,6 +303,7 @@ public interface Playable {
/**
* List of EventListener
*/
@UnstableApi
class EventListeners extends CopyOnWriteArraySet<EventListener> implements EventListener {
EventListeners() {

View File

@ -26,12 +26,13 @@ import android.net.Uri;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import androidx.annotation.OptIn;
import androidx.media3.common.C;
import androidx.media3.common.PlaybackParameters;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.ui.PlayerView;
import ml.docilealligator.infinityforreddit.videoautoplay.media.PlaybackInfo;
import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo;
@ -47,6 +48,7 @@ import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo;
* @author eneim (2018/02/25).
*/
@SuppressWarnings("WeakerAccess") //
@OptIn(markerClass = UnstableApi.class)
class PlayableImpl implements Playable {
private final PlaybackInfo playbackInfo = new PlaybackInfo(); // never expose to outside.
@ -61,7 +63,7 @@ class PlayableImpl implements Playable {
protected ToroExoPlayer player; // on-demand, cached
protected MediaSource mediaSource; // on-demand, since we do not reuse MediaSource now.
protected StyledPlayerView playerView; // on-demand, not always required.
protected PlayerView playerView; // on-demand, not always required.
private boolean sourcePrepared = false;
private boolean listenerApplied = false;
@ -83,13 +85,13 @@ class PlayableImpl implements Playable {
@CallSuper
@Override
public void setPlayerView(@Nullable StyledPlayerView playerView) {
public void setPlayerView(@Nullable PlayerView playerView) {
if (this.playerView == playerView) return;
if (playerView == null) {
this.playerView.setPlayer(null);
} else {
if (this.player != null) {
StyledPlayerView.switchTargetView(this.player.getPlayer(), this.playerView, playerView);
PlayerView.switchTargetView(this.player.getPlayer(), this.playerView, playerView);
}
}
@ -97,7 +99,7 @@ class PlayableImpl implements Playable {
}
@Override
public final StyledPlayerView getPlayerView() {
public final PlayerView getPlayerView() {
return this.playerView;
}

View File

@ -25,13 +25,13 @@ import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.annotation.RestrictTo;
import androidx.annotation.StringRes;
import androidx.core.util.Pools;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.util.Util;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.ExoPlayer;
import java.net.CookieHandler;
import java.net.CookieManager;
@ -44,8 +44,8 @@ import ml.docilealligator.infinityforreddit.utils.APIUtils;
import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo;
/**
* Global helper class to manage {@link ExoCreator} and {@link SimpleExoPlayer} instances.
* In this setup, {@link ExoCreator} and SimpleExoPlayer pools are cached. A {@link Config}
* Global helper class to manage {@link ExoCreator} and {@link ExoPlayer} instances.
* In this setup, {@link ExoCreator} and ExoPlayer pools are cached. A {@link Config}
* is a key for each {@link ExoCreator}.
* <p>
* A suggested usage is as below:
@ -65,6 +65,7 @@ public final class ToroExo {
private static final String TAG = "ToroExo";
// Magic number: Build.VERSION.SDK_INT / 6 --> API 16 ~ 18 will set pool size to 2, etc.
@UnstableApi
@SuppressWarnings("WeakerAccess") //
static final int MAX_POOL_SIZE = Math.max(Util.SDK_INT / 6, getRuntime().availableProcessors());
@SuppressLint("StaticFieldLeak") //
@ -107,6 +108,7 @@ public final class ToroExo {
/**
* Utility method to produce {@link ExoCreator} instance from a {@link Config}.
*/
@OptIn(markerClass = UnstableApi.class)
public ExoCreator getCreator(Config config) {
ExoCreator creator = this.creators.get(config);
if (creator == null) {
@ -131,14 +133,14 @@ public final class ToroExo {
}
/**
* Request an instance of {@link SimpleExoPlayer}. It can be an existing instance cached by Pool
* Request an instance of {@link ExoPlayer}. It can be an existing instance cached by Pool
* or new one.
* <p>
* The creator may or may not be the one created by either {@link #getCreator(Config)} or
* {@link #getDefaultCreator()}.
*
* @param creator the {@link ExoCreator} that is scoped to the {@link SimpleExoPlayer} config.
* @return an usable {@link SimpleExoPlayer} instance.
* @param creator the {@link ExoCreator} that is scoped to the {@link ExoPlayer} config.
* @return an usable {@link ExoPlayer} instance.
*/
@NonNull //
public ToroExoPlayer requestPlayer(@NonNull ExoCreator creator) {
@ -151,7 +153,7 @@ public final class ToroExo {
* Release player to Pool attached to the creator.
*
* @param creator the {@link ExoCreator} that created the player.
* @param player the {@link SimpleExoPlayer} to be released back to the Pool
* @param player the {@link ExoPlayer} to be released back to the Pool
* @return true if player is released to relevant Pool, false otherwise.
*/
@SuppressWarnings({"WeakerAccess", "UnusedReturnValue"}) //
@ -175,6 +177,7 @@ public final class ToroExo {
}
/// internal APIs
@OptIn(markerClass = UnstableApi.class)
private Pools.Pool<ExoPlayer> getPool(ExoCreator creator) {
Pools.Pool<ExoPlayer> pool = playerPools.get(creator);
if (pool == null) {

View File

@ -23,18 +23,18 @@ import android.os.Looper;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.LoadControl;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.LoadControl;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.trackselection.TrackSelector;
import androidx.media3.exoplayer.upstream.BandwidthMeter;
import ml.docilealligator.infinityforreddit.videoautoplay.media.VolumeInfo;
/**
* A custom {@link SimpleExoPlayer} that also notify the change of Volume.
* A custom {@link ExoPlayer} that also notify the change of Volume.
*
* @author eneim (2018/03/27).
*/
@ -43,9 +43,10 @@ public class ToroExoPlayer {
private final ExoPlayer player;
@OptIn(markerClass = UnstableApi.class)
public ToroExoPlayer(Context context, RenderersFactory renderersFactory,
TrackSelector trackSelector, LoadControl loadControl, BandwidthMeter bandwidthMeter,
Looper looper) {
TrackSelector trackSelector, LoadControl loadControl, BandwidthMeter bandwidthMeter,
Looper looper) {
player = new ExoPlayer.Builder(context).setRenderersFactory(renderersFactory).setTrackSelector(trackSelector).setLoadControl(loadControl).setBandwidthMeter(bandwidthMeter).setLooper(looper).build();
}

View File

@ -143,7 +143,7 @@ public abstract class ToroPlayerHelper {
/**
* Initialize the necessary resource for the incoming playback. For example, prepare the
* ExoPlayer instance for SimpleExoPlayerView. The initialization is feed by an initial playback
* ExoPlayer instance for ExoPlayerView. The initialization is feed by an initial playback
* info, telling if the playback should start from a specific position or from beginning.
*
* Normally this info can be obtained from cache if there is cache manager, or {@link PlaybackInfo#SCRAP}

View File

@ -266,7 +266,7 @@
android:fontFamily="?attr/font_family"
android:visibility="gone" />
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_post_video_activity"
android:layout_width="match_parent"
android:layout_height="400dp"

View File

@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_view_video_activity"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -29,12 +29,14 @@
app:verticalPanEnabled="true"
app:zoomEnabled="true" />
<com.google.android.exoplayer2.ui.PlayerControlView
<androidx.media3.ui.PlayerControlView
android:id="@+id/player_control_view_view_video_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:controller_layout_id="@layout/exo_playback_control_view" />
android:animateLayoutChanges="true"
app:controller_layout_id="@layout/exo_playback_control_view"
app:animation_enabled="false" />
<ProgressBar
android:id="@+id/progress_bar_view_video_activity"

View File

@ -89,7 +89,7 @@
app:layout_constraintBottom_toTopOf="@id/exo_progress"
app:layout_constraintEnd_toEndOf="parent" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
<androidx.media3.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="match_parent"
android:layout_height="24dp"

View File

@ -75,7 +75,7 @@
</RelativeLayout>
<com.google.android.exoplayer2.ui.DefaultTimeBar
<androidx.media3.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="wrap_content"
android:layout_height="26dp"/>

View File

@ -128,7 +128,7 @@
android:textColor="#FFFFFF"
android:fontFamily="?attr/font_family" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
<androidx.media3.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_weight="1"

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.exoplayer2.ui.StyledPlayerView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.media3.ui.PlayerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"

View File

@ -6,7 +6,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".fragments.ViewRedditGalleryVideoFragment">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_view_reddit_gallery_video_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -19,14 +19,14 @@
app:cardCornerRadius="8dp"
style="?attr/materialCardViewElevatedStyle">
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_card_2_video_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_card_2_video_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -53,7 +53,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -19,14 +19,14 @@
app:cardCornerRadius="8dp"
style="?attr/materialCardViewElevatedStyle">
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_card_2_video_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_card_2_video_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -53,7 +53,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
</com.google.android.material.card.MaterialCardView>

View File

@ -17,14 +17,14 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_card_3_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_card_3_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -51,7 +51,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"

View File

@ -17,14 +17,14 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_card_3_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_card_3_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -51,7 +51,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"

View File

@ -194,14 +194,14 @@
</com.nex3z.flowlayout.FlowLayout>
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_detail_video_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_detail_video_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -227,7 +227,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/content_markdown_view_item_post_detail_video_autoplay"

View File

@ -194,14 +194,14 @@
</com.nex3z.flowlayout.FlowLayout>
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_detail_video_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_detail_video_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -228,7 +228,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/content_markdown_view_item_post_detail_video_autoplay"

View File

@ -184,14 +184,14 @@
</com.nex3z.flowlayout.FlowLayout>
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -218,7 +218,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottom_constraint_layout_item_post_video_type_autoplay"

View File

@ -184,14 +184,14 @@
</com.nex3z.flowlayout.FlowLayout>
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout
<androidx.media3.ui.AspectRatioFrameLayout
android:id="@+id/aspect_ratio_frame_layout_item_post_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#000000"
app:resize_mode="fixed_width">
<com.google.android.exoplayer2.ui.StyledPlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/player_view_item_post_video_type_autoplay"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -218,7 +218,7 @@
android:src="@drawable/ic_error_white_36dp"
android:visibility="gone" />
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
</androidx.media3.ui.AspectRatioFrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottom_constraint_layout_item_post_video_type_autoplay"

View File

@ -524,12 +524,12 @@
</style>
<style name="ToroMediaButton.Play">
<item name="android:src">@drawable/exo_controls_play</item>
<item name="android:src">@drawable/ic_play_arrow_24dp</item>
<item name="android:contentDescription">@string/exo_controls_play_description</item>
</style>
<style name="ToroMediaButton.Pause">
<item name="android:src">@drawable/exo_controls_pause</item>
<item name="android:src">@drawable/ic_pause_24dp</item>
<item name="android:contentDescription">@string/exo_controls_pause_description</item>
</style>