summaryrefslogtreecommitdiff
path: root/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2021-05-14 21:39:27 +0200
committerByteHamster <info@bytehamster.com>2021-05-14 22:07:35 +0200
commitc3d7209f09f3b6c3974ada7836fe08f9d131e09b (patch)
tree56d7fce2d5a3aefcd05e7becc5b8794cfcd9cab8 /app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
parent362e66cf0857cf7432303c5e47e806d808224d3d (diff)
downloadAntennaPod-c3d7209f09f3b6c3974ada7836fe08f9d131e09b.zip
Moved all code from MediaPlayerActivity to VideoPlayerActivity
Diffstat (limited to 'app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java547
1 files changed, 513 insertions, 34 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
index b3bf0ebc8..dc4345c21 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/VideoplayerActivity.java
@@ -1,7 +1,9 @@
package de.danoeh.antennapod.activity;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
import android.content.Intent;
+import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.media.AudioManager;
import android.os.Build;
@@ -9,12 +11,19 @@ import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.MenuInflater;
import android.view.animation.AlphaAnimation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.EditText;
+import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.cardview.widget.CardView;
+import androidx.core.app.ActivityOptionsCompat;
import androidx.core.view.WindowCompat;
import androidx.appcompat.app.ActionBar;
import android.util.Log;
@@ -33,21 +42,51 @@ import android.widget.ProgressBar;
import android.widget.SeekBar;
import java.lang.ref.WeakReference;
+import java.text.NumberFormat;
import java.util.concurrent.atomic.AtomicBoolean;
+import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
+import com.bumptech.glide.Glide;
import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.core.event.PlaybackPositionEvent;
+import de.danoeh.antennapod.core.event.ServiceEvent;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.util.Converter;
+import de.danoeh.antennapod.core.util.FeedItemUtil;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.core.util.ShareUtils;
+import de.danoeh.antennapod.core.util.StorageUtils;
+import de.danoeh.antennapod.core.util.TimeSpeedConverter;
import de.danoeh.antennapod.core.util.gui.PictureInPictureUtil;
+import de.danoeh.antennapod.core.util.playback.MediaPlayerError;
+import de.danoeh.antennapod.core.util.playback.PlaybackController;
+import de.danoeh.antennapod.dialog.PlaybackControlsDialog;
+import de.danoeh.antennapod.dialog.ShareDialog;
+import de.danoeh.antennapod.dialog.SkipPreferenceDialog;
+import de.danoeh.antennapod.dialog.SleepTimerDialog;
+import de.danoeh.antennapod.model.feed.FeedItem;
+import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.ui.appstartintent.MainActivityStarter;
import de.danoeh.antennapod.view.AspectRatioVideoView;
+import de.danoeh.antennapod.view.PlayButton;
+import io.reactivex.Observable;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+import org.apache.commons.lang3.StringUtils;
+import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
/**
* Activity for playing video files.
*/
-public class VideoplayerActivity extends MediaplayerActivity {
+public class VideoplayerActivity extends CastEnabledActivity implements SeekBar.OnSeekBarChangeListener {
private static final String TAG = "VideoplayerActivity";
/**
@@ -68,6 +107,23 @@ public class VideoplayerActivity extends MediaplayerActivity {
private ProgressBar progressIndicator;
private FrameLayout videoframe;
private ImageView skipAnimationView;
+ private TextView txtvPosition;
+ private TextView txtvLength;
+ private SeekBar sbPosition;
+ private ImageButton butRev;
+ private TextView txtvRev;
+ private PlayButton butPlay;
+ private ImageButton butFF;
+ private TextView txtvFF;
+ private ImageButton butSkip;
+ private CardView cardViewSeek;
+ private TextView txtvSeek;
+
+ private PlaybackController controller;
+ private boolean showTimeLeft = false;
+ private boolean isFavorite = false;
+ private Disposable disposable;
+ private float prog;
@SuppressLint("AppCompatMethod")
@Override
@@ -75,13 +131,21 @@ public class VideoplayerActivity extends MediaplayerActivity {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY); // has to be called before setting layout content
+ setTheme(R.style.Theme_AntennaPod_VideoPlayer);
super.onCreate(savedInstanceState);
+
+ Log.d(TAG, "onCreate()");
+ StorageUtils.checkStorageAvailability(this);
+
+ getWindow().setFormat(PixelFormat.TRANSPARENT);
+ setupGUI();
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(0x80000000));
}
@Override
protected void onResume() {
super.onResume();
+ StorageUtils.checkStorageAvailability(this);
if (PlaybackService.isCasting()) {
Intent intent = PlaybackService.getPlayerActivityIntent(this);
if (!intent.getComponent().getClassName().equals(VideoplayerActivity.class.getName())) {
@@ -94,6 +158,14 @@ public class VideoplayerActivity extends MediaplayerActivity {
@Override
protected void onStop() {
+ if (controller != null) {
+ controller.release();
+ controller = null; // prevent leak
+ }
+ if (disposable != null) {
+ disposable.dispose();
+ }
+ EventBus.getDefault().unregister(this);
super.onStop();
if (!PictureInPictureUtil.isInPictureInPictureMode(this)) {
videoControlsHider.stop();
@@ -110,6 +182,16 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
@Override
+ protected void onStart() {
+ super.onStart();
+ controller = newPlaybackController();
+ controller.init();
+ loadMediaInfo();
+ onPositionObserverUpdate();
+ EventBus.getDefault().register(this);
+ }
+
+ @Override
protected void onPause() {
if (!PictureInPictureUtil.isInPictureInPictureMode(this)) {
if (controller != null && controller.getStatus() == PlayerStatus.PLAYING) {
@@ -126,9 +208,94 @@ public class VideoplayerActivity extends MediaplayerActivity {
super.onDestroy();
}
+ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ @Override
+ public void onTrimMemory(int level) {
+ super.onTrimMemory(level);
+ Glide.get(this).trimMemory(level);
+ }
+
@Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ Glide.get(this).clearMemory();
+ }
+
+ private PlaybackController newPlaybackController() {
+ return new PlaybackController(this) {
+ @Override
+ public void onPositionObserverUpdate() {
+ VideoplayerActivity.this.onPositionObserverUpdate();
+ }
+
+ @Override
+ public void onBufferStart() {
+ VideoplayerActivity.this.onBufferStart();
+ }
+
+ @Override
+ public void onBufferEnd() {
+ VideoplayerActivity.this.onBufferEnd();
+ }
+
+ @Override
+ public void onBufferUpdate(float progress) {
+ if (sbPosition != null) {
+ sbPosition.setSecondaryProgress((int) (progress * sbPosition.getMax()));
+ }
+ }
+
+ @Override
+ public void handleError(int code) {
+ VideoplayerActivity.this.handleError(code);
+ }
+
+ @Override
+ public void onReloadNotification(int code) {
+ VideoplayerActivity.this.onReloadNotification(code);
+ }
+
+ @Override
+ public void onSleepTimerUpdate() {
+ supportInvalidateOptionsMenu();
+ }
+
+ @Override
+ protected void updatePlayButtonShowsPlay(boolean showPlay) {
+ butPlay.setIsShowPlay(showPlay);
+ }
+
+ @Override
+ public void loadMediaInfo() {
+ VideoplayerActivity.this.loadMediaInfo();
+ }
+
+ @Override
+ public void onAwaitingVideoSurface() {
+ VideoplayerActivity.this.onAwaitingVideoSurface();
+ }
+
+ @Override
+ public void onPlaybackEnd() {
+ finish();
+ }
+
+ @Override
+ protected void setScreenOn(boolean enable) {
+ super.setScreenOn(enable);
+ VideoplayerActivity.this.setScreenOn(enable);
+ }
+ };
+ }
+
protected void loadMediaInfo() {
- super.loadMediaInfo();
+ Log.d(TAG, "loadMediaInfo()");
+ if (controller == null || controller.getMedia() == null) {
+ return;
+ }
+ showTimeLeft = UserPreferences.shouldShowRemainingTime();
+ onPositionObserverUpdate();
+ checkFavorite();
Playable media = controller.getMedia();
if (media != null) {
getSupportActionBar().setSubtitle(media.getEpisodeTitle());
@@ -136,12 +303,90 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
}
- @Override
protected void setupGUI() {
if (isSetup.getAndSet(true)) {
return;
}
- super.setupGUI();
+ setContentView(R.layout.videoplayer_activity);
+ sbPosition = findViewById(R.id.sbPosition);
+ txtvPosition = findViewById(R.id.txtvPosition);
+ cardViewSeek = findViewById(R.id.cardViewSeek);
+ txtvSeek = findViewById(R.id.txtvSeek);
+
+ showTimeLeft = UserPreferences.shouldShowRemainingTime();
+ Log.d("timeleft", showTimeLeft ? "true" : "false");
+ txtvLength = findViewById(R.id.txtvLength);
+ if (txtvLength != null) {
+ txtvLength.setOnClickListener(v -> {
+ showTimeLeft = !showTimeLeft;
+ Playable media = controller.getMedia();
+ if (media == null) {
+ return;
+ }
+
+ TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
+ String length;
+ if (showTimeLeft) {
+ int remainingTime = converter.convert(
+ media.getDuration() - media.getPosition());
+
+ length = "-" + Converter.getDurationStringLong(remainingTime);
+ } else {
+ int duration = converter.convert(media.getDuration());
+ length = Converter.getDurationStringLong(duration);
+ }
+ txtvLength.setText(length);
+
+ UserPreferences.setShowRemainTimeSetting(showTimeLeft);
+ Log.d("timeleft on click", showTimeLeft ? "true" : "false");
+ });
+ }
+
+ butRev = findViewById(R.id.butRev);
+ txtvRev = findViewById(R.id.txtvRev);
+ if (txtvRev != null) {
+ txtvRev.setText(NumberFormat.getInstance().format(UserPreferences.getRewindSecs()));
+ }
+ butPlay = findViewById(R.id.butPlay);
+ butPlay.setIsVideoScreen(true);
+ butFF = findViewById(R.id.butFF);
+ txtvFF = findViewById(R.id.txtvFF);
+ if (txtvFF != null) {
+ txtvFF.setText(NumberFormat.getInstance().format(UserPreferences.getFastForwardSecs()));
+ }
+ butSkip = findViewById(R.id.butSkip);
+
+ // SEEKBAR SETUP
+
+ sbPosition.setOnSeekBarChangeListener(this);
+
+ // BUTTON SETUP
+
+ if (butRev != null) {
+ butRev.setOnClickListener(v -> onRewind());
+ butRev.setOnLongClickListener(v -> {
+ SkipPreferenceDialog.showSkipPreference(VideoplayerActivity.this,
+ SkipPreferenceDialog.SkipDirection.SKIP_REWIND, txtvRev);
+ return true;
+ });
+ }
+
+ butPlay.setOnClickListener(v -> onPlayPause());
+
+ if (butFF != null) {
+ butFF.setOnClickListener(v -> onFastForward());
+ butFF.setOnLongClickListener(v -> {
+ SkipPreferenceDialog.showSkipPreference(VideoplayerActivity.this,
+ SkipPreferenceDialog.SkipDirection.SKIP_FORWARD, txtvFF);
+ return false;
+ });
+ }
+
+ if (butSkip != null) {
+ butSkip.setOnClickListener(v ->
+ IntentUtils.sendLocalBroadcast(VideoplayerActivity.this, PlaybackService.ACTION_SKIP_CURRENT_EPISODE));
+ }
+
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
controls = findViewById(R.id.controls);
videoOverlay = findViewById(R.id.overlay);
@@ -163,7 +408,6 @@ public class VideoplayerActivity extends MediaplayerActivity {
videoview.setAvailableSize(videoframe.getWidth(), videoframe.getHeight()));
}
- @Override
protected void onAwaitingVideoSurface() {
setupVideoAspectRatio();
if (videoSurfaceCreated && controller != null) {
@@ -273,24 +517,45 @@ public class VideoplayerActivity extends MediaplayerActivity {
videoControlsShowing = !videoControlsShowing;
}
- @Override
- protected void onRewind() {
- super.onRewind();
+ void onRewind() {
+ if (controller == null) {
+ return;
+ }
+ int curr = controller.getPosition();
+ controller.seekTo(curr - UserPreferences.getRewindSecs() * 1000);
setupVideoControlsToggler();
}
- @Override
- protected void onPlayPause() {
- super.onPlayPause();
+ void onPlayPause() {
+ if(controller == null) {
+ return;
+ }
+ controller.init();
+ controller.playPause();
setupVideoControlsToggler();
}
- @Override
- protected void onFastForward() {
- super.onFastForward();
+ void onFastForward() {
+ if (controller == null) {
+ return;
+ }
+ int curr = controller.getPosition();
+ controller.seekTo(curr + UserPreferences.getFastForwardSecs() * 1000);
setupVideoControlsToggler();
}
+ private void handleError(int errorCode) {
+ final AlertDialog.Builder errorDialog = new AlertDialog.Builder(this);
+ errorDialog.setTitle(R.string.error_label);
+ errorDialog.setMessage(MediaPlayerError.getErrorString(this, errorCode));
+ errorDialog.setNeutralButton("OK",
+ (dialog, which) -> {
+ dialog.dismiss();
+ finish();
+ }
+ );
+ errorDialog.create().show();
+ }
private final SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
@@ -321,8 +586,6 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
};
-
- @Override
protected void onReloadNotification(int notificationCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && PictureInPictureUtil.isInPictureInPictureMode(this)) {
if (notificationCode == PlaybackService.EXTRA_CODE_AUDIO
@@ -339,24 +602,10 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
}
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- super.onStartTrackingTouch(seekBar);
- videoControlsHider.stop();
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- super.onStopTrackingTouch(seekBar);
- setupVideoControlsToggler();
- }
-
- @Override
protected void onBufferStart() {
progressIndicator.setVisibility(View.VISIBLE);
}
- @Override
protected void onBufferEnd() {
progressIndicator.setVisibility(View.INVISIBLE);
}
@@ -395,9 +644,7 @@ public class VideoplayerActivity extends MediaplayerActivity {
hideVideoControls(true);
}
- @Override
- protected void setScreenOn(boolean enable) {
- super.setScreenOn(enable);
+ private void setScreenOn(boolean enable) {
if (enable) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
@@ -405,9 +652,58 @@ public class VideoplayerActivity extends MediaplayerActivity {
}
}
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onEventMainThread(PlaybackPositionEvent event) {
+ onPositionObserverUpdate();
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onPlaybackServiceChanged(ServiceEvent event) {
+ if (event.action == ServiceEvent.Action.SERVICE_SHUT_DOWN) {
+ finish();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ requestCastButton(menu);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.mediaplayer, menu);
+ return true;
+ }
+
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
+ if (controller == null) {
+ return false;
+ }
+ Playable media = controller.getMedia();
+ boolean isFeedMedia = (media instanceof FeedMedia);
+
+ menu.findItem(R.id.open_feed_item).setVisible(isFeedMedia); // FeedMedia implies it belongs to a Feed
+
+ boolean hasWebsiteLink = ( getWebsiteLinkWithFallback(media) != null );
+ menu.findItem(R.id.visit_website_item).setVisible(hasWebsiteLink);
+
+ boolean isItemAndHasLink = isFeedMedia &&
+ ShareUtils.hasLinkToShare(((FeedMedia) media).getItem());
+
+ boolean isItemHasDownloadLink = isFeedMedia && ((FeedMedia) media).getDownload_url() != null;
+
+ menu.findItem(R.id.share_item).setVisible(hasWebsiteLink || isItemAndHasLink || isItemHasDownloadLink);
+
+ menu.findItem(R.id.add_to_favorites_item).setVisible(false);
+ menu.findItem(R.id.remove_from_favorites_item).setVisible(false);
+ if (isFeedMedia) {
+ menu.findItem(R.id.add_to_favorites_item).setVisible(!isFavorite);
+ menu.findItem(R.id.remove_from_favorites_item).setVisible(isFavorite);
+ }
+
+ menu.findItem(R.id.set_sleeptimer_item).setVisible(!controller.sleepTimerActive());
+ menu.findItem(R.id.disable_sleeptimer_item).setVisible(controller.sleepTimerActive());
+
if (PictureInPictureUtil.supportsPictureInPicture(this)) {
menu.findItem(R.id.player_go_to_picture_in_picture).setVisible(true);
}
@@ -421,7 +717,190 @@ public class VideoplayerActivity extends MediaplayerActivity {
compatEnterPictureInPicture();
return true;
}
- return super.onOptionsItemSelected(item);
+ if (controller == null) {
+ return false;
+ }
+ Playable media = controller.getMedia();
+ if (item.getItemId() == android.R.id.home) {
+ Intent intent = new Intent(VideoplayerActivity.this,
+ MainActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ View cover = findViewById(R.id.imgvCover);
+ if (cover != null) {
+ ActivityOptionsCompat options = ActivityOptionsCompat
+ .makeSceneTransitionAnimation(VideoplayerActivity.this, cover, "coverTransition");
+ startActivity(intent, options.toBundle());
+ } else {
+ startActivity(intent);
+ }
+ finish();
+ return true;
+ } else {
+ if (media != null) {
+ final @Nullable FeedItem feedItem = getFeedItem(media); // some options option requires FeedItem
+ switch (item.getItemId()) {
+ case R.id.add_to_favorites_item:
+ if (feedItem != null) {
+ DBWriter.addFavoriteItem(feedItem);
+ isFavorite = true;
+ invalidateOptionsMenu();
+ }
+ break;
+ case R.id.remove_from_favorites_item:
+ if (feedItem != null) {
+ DBWriter.removeFavoriteItem(feedItem);
+ isFavorite = false;
+ invalidateOptionsMenu();
+ }
+ break;
+ case R.id.disable_sleeptimer_item: // Fall-through
+ case R.id.set_sleeptimer_item:
+ new SleepTimerDialog().show(getSupportFragmentManager(), "SleepTimerDialog");
+ break;
+ case R.id.audio_controls:
+ PlaybackControlsDialog dialog = PlaybackControlsDialog.newInstance();
+ dialog.show(getSupportFragmentManager(), "playback_controls");
+ break;
+ case R.id.open_feed_item:
+ if (feedItem != null) {
+ Intent intent = MainActivity.getIntentToOpenFeed(this, feedItem.getFeedId());
+ startActivity(intent);
+ }
+ break;
+ case R.id.visit_website_item:
+ IntentUtils.openInBrowser(VideoplayerActivity.this, getWebsiteLinkWithFallback(media));
+ break;
+ case R.id.share_item:
+ if (feedItem != null) {
+ ShareDialog shareDialog = ShareDialog.newInstance(feedItem);
+ shareDialog.show(getSupportFragmentManager(), "ShareEpisodeDialog");
+ }
+ break;
+ default:
+ return false;
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ private static String getWebsiteLinkWithFallback(Playable media) {
+ if (media == null) {
+ return null;
+ } else if (StringUtils.isNotBlank(media.getWebsiteLink())) {
+ return media.getWebsiteLink();
+ } else if (media instanceof FeedMedia) {
+ return FeedItemUtil.getLinkWithFallback(((FeedMedia)media).getItem());
+ }
+ return null;
+ }
+
+ void onPositionObserverUpdate() {
+ if (controller == null || txtvPosition == null || txtvLength == null) {
+ return;
+ }
+
+ TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
+ int currentPosition = converter.convert(controller.getPosition());
+ int duration = converter.convert(controller.getDuration());
+ int remainingTime = converter.convert(
+ controller.getDuration() - controller.getPosition());
+ Log.d(TAG, "currentPosition " + Converter.getDurationStringLong(currentPosition));
+ if (currentPosition == PlaybackService.INVALID_TIME ||
+ duration == PlaybackService.INVALID_TIME) {
+ Log.w(TAG, "Could not react to position observer update because of invalid time");
+ return;
+ }
+ txtvPosition.setText(Converter.getDurationStringLong(currentPosition));
+ if (showTimeLeft) {
+ txtvLength.setText("-" + Converter.getDurationStringLong(remainingTime));
+ } else {
+ txtvLength.setText(Converter.getDurationStringLong(duration));
+ }
+ updateProgressbarPosition(currentPosition, duration);
+ }
+
+ private void updateProgressbarPosition(int position, int duration) {
+ Log.d(TAG, "updateProgressbarPosition(" + position + ", " + duration + ")");
+ if(sbPosition == null) {
+ return;
+ }
+ float progress = ((float) position) / duration;
+ sbPosition.setProgress((int) (progress * sbPosition.getMax()));
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (controller == null || txtvLength == null) {
+ return;
+ }
+ if (fromUser) {
+ prog = progress / ((float) seekBar.getMax());
+ TimeSpeedConverter converter = new TimeSpeedConverter(controller.getCurrentPlaybackSpeedMultiplier());
+ int position = converter.convert((int) (prog * controller.getDuration()));
+ txtvSeek.setText(Converter.getDurationStringLong(position));
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ cardViewSeek.setScaleX(.8f);
+ cardViewSeek.setScaleY(.8f);
+ cardViewSeek.animate()
+ .setInterpolator(new FastOutSlowInInterpolator())
+ .alpha(1f).scaleX(1f).scaleY(1f)
+ .setDuration(200)
+ .start();
+ videoControlsHider.stop();
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ if (controller != null) {
+ controller.seekTo((int) (prog * controller.getDuration()));
+ }
+ cardViewSeek.setScaleX(1f);
+ cardViewSeek.setScaleY(1f);
+ cardViewSeek.animate()
+ .setInterpolator(new FastOutSlowInInterpolator())
+ .alpha(0f).scaleX(.8f).scaleY(.8f)
+ .setDuration(200)
+ .start();
+ setupVideoControlsToggler();
+ }
+
+ private void checkFavorite() {
+ FeedItem feedItem = getFeedItem(controller.getMedia());
+ if (feedItem == null) {
+ return;
+ }
+ if (disposable != null) {
+ disposable.dispose();
+ }
+ disposable = Observable.fromCallable(() -> DBReader.getFeedItem(feedItem.getId()))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ item -> {
+ boolean isFav = item.isTagged(FeedItem.TAG_FAVORITE);
+ if (isFavorite != isFav) {
+ isFavorite = isFav;
+ invalidateOptionsMenu();
+ }
+ }, error -> Log.e(TAG, Log.getStackTraceString(error)));
+ }
+
+ @Nullable
+ private static FeedItem getFeedItem(@Nullable Playable playable) {
+ if (playable instanceof FeedMedia) {
+ return ((FeedMedia) playable).getItem();
+ } else {
+ return null;
+ }
}
private void compatEnterPictureInPicture() {