Skip to content
8 changes: 4 additions & 4 deletions app/src/main/java/org/schabi/newpipe/RouterActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ public Consumer<Info> getResultHandler(Choice choice) {
playQueue = new SinglePlayQueue((StreamInfo) info);

if (playerChoice.equals(videoPlayerKey)) {
NavigationHelper.playOnMainPlayer(this, playQueue);
NavigationHelper.playOnMainPlayer(this, playQueue, true);
} else if (playerChoice.equals(backgroundPlayerKey)) {
NavigationHelper.enqueueOnBackgroundPlayer(this, playQueue, true);
} else if (playerChoice.equals(popupPlayerKey)) {
Expand All @@ -587,11 +587,11 @@ public Consumer<Info> getResultHandler(Choice choice) {
playQueue = info instanceof ChannelInfo ? new ChannelPlayQueue((ChannelInfo) info) : new PlaylistPlayQueue((PlaylistInfo) info);

if (playerChoice.equals(videoPlayerKey)) {
NavigationHelper.playOnMainPlayer(this, playQueue);
NavigationHelper.playOnMainPlayer(this, playQueue, true);
} else if (playerChoice.equals(backgroundPlayerKey)) {
NavigationHelper.playOnBackgroundPlayer(this, playQueue);
NavigationHelper.playOnBackgroundPlayer(this, playQueue, true);
} else if (playerChoice.equals(popupPlayerKey)) {
NavigationHelper.playOnPopupPlayer(this, playQueue);
NavigationHelper.playOnPopupPlayer(this, playQueue, true);
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public Flowable<List<StreamHistoryEntity>> listByService(int serviceId) {
" ORDER BY " + STREAM_ACCESS_DATE + " DESC")
public abstract Flowable<List<StreamHistoryEntry>> getHistory();

@Query("SELECT * FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID +
" = :streamId ORDER BY " + STREAM_ACCESS_DATE + " DESC LIMIT 1")
@Nullable
public abstract StreamHistoryEntity getLatestEntry(final long streamId);

@Query("DELETE FROM " + STREAM_HISTORY_TABLE + " WHERE " + JOIN_STREAM_ID + " = :streamId")
public abstract int deleteStreamHistory(final long streamId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.support.annotation.Nullable;

import java.util.concurrent.TimeUnit;

import static android.arch.persistence.room.ForeignKey.CASCADE;
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID;
Expand All @@ -22,6 +25,12 @@ public class StreamStateEntity {
final public static String JOIN_STREAM_ID = "stream_id";
final public static String STREAM_PROGRESS_TIME = "progress_time";


/** Playback state will not be saved, if playback time less than this threshold */
private static final int PLAYBACK_SAVE_THRESHOLD_START_SECONDS = 5;
/** Playback state will not be saved, if time left less than this threshold */
private static final int PLAYBACK_SAVE_THRESHOLD_END_SECONDS = 10;

@ColumnInfo(name = JOIN_STREAM_ID)
private long streamUid;

Expand All @@ -48,4 +57,18 @@ public long getProgressTime() {
public void setProgressTime(long progressTime) {
this.progressTime = progressTime;
}

public boolean isValid(int durationInSeconds) {
final int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(progressTime);
return seconds > PLAYBACK_SAVE_THRESHOLD_START_SECONDS
&& seconds < durationInSeconds - PLAYBACK_SAVE_THRESHOLD_END_SECONDS;
}

@Override
public boolean equals(@Nullable Object obj) {
if (obj instanceof StreamStateEntity) {
return ((StreamStateEntity) obj).streamUid == streamUid
&& ((StreamStateEntity) obj).progressTime == progressTime;
} else return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,14 @@
import org.schabi.newpipe.util.ShareUtils;
import org.schabi.newpipe.util.StreamItemAdapter;
import org.schabi.newpipe.util.StreamItemAdapter.StreamSizeWrapper;
import org.schabi.newpipe.views.AnimatedProgressBar;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import icepick.State;
import io.reactivex.Single;
Expand All @@ -118,7 +120,7 @@ public class VideoDetailFragment
private static final int RELATED_STREAMS_UPDATE_FLAG = 0x1;
private static final int RESOLUTIONS_MENU_UPDATE_FLAG = 0x2;
private static final int TOOLBAR_ITEMS_UPDATE_FLAG = 0x4;
private static final int COMMENTS_UPDATE_FLAG = 0x4;
private static final int COMMENTS_UPDATE_FLAG = 0x8;

private boolean autoPlayEnabled;
private boolean showRelatedStreams;
Expand All @@ -136,6 +138,8 @@ public class VideoDetailFragment
private Disposable currentWorker;
@NonNull
private CompositeDisposable disposables = new CompositeDisposable();
@Nullable
private Disposable positionSubscriber = null;

private List<VideoStream> sortedVideoStreams;
private int selectedVideoStreamIndex = -1;
Expand All @@ -153,6 +157,7 @@ public class VideoDetailFragment
private View thumbnailBackgroundButton;
private ImageView thumbnailImageView;
private ImageView thumbnailPlayButton;
private AnimatedProgressBar positionView;

private View videoTitleRoot;
private TextView videoTitleTextView;
Expand All @@ -165,6 +170,7 @@ public class VideoDetailFragment
private TextView detailControlsDownload;
private TextView appendControlsDetail;
private TextView detailDurationView;
private TextView detailPositionView;

private LinearLayout videoDescriptionRootLayout;
private TextView videoUploadDateView;
Expand Down Expand Up @@ -259,6 +265,8 @@ public void onResume() {
// Check if it was loading when the fragment was stopped/paused,
if (wasLoading.getAndSet(false)) {
selectAndLoadVideo(serviceId, url, name);
} else if (currentInfo != null) {
updateProgressInfo(currentInfo);
}
}

Expand All @@ -268,8 +276,10 @@ public void onDestroy() {
PreferenceManager.getDefaultSharedPreferences(activity)
.unregisterOnSharedPreferenceChangeListener(this);

if (positionSubscriber != null) positionSubscriber.dispose();
if (currentWorker != null) currentWorker.dispose();
if (disposables != null) disposables.clear();
positionSubscriber = null;
currentWorker = null;
disposables = null;
}
Expand Down Expand Up @@ -462,13 +472,15 @@ protected void initViews(View rootView, Bundle savedInstanceState) {
videoTitleTextView = rootView.findViewById(R.id.detail_video_title_view);
videoTitleToggleArrow = rootView.findViewById(R.id.detail_toggle_description_view);
videoCountView = rootView.findViewById(R.id.detail_view_count_view);
positionView = rootView.findViewById(R.id.position_view);

detailControlsBackground = rootView.findViewById(R.id.detail_controls_background);
detailControlsPopup = rootView.findViewById(R.id.detail_controls_popup);
detailControlsAddToPlaylist = rootView.findViewById(R.id.detail_controls_playlist_append);
detailControlsDownload = rootView.findViewById(R.id.detail_controls_download);
appendControlsDetail = rootView.findViewById(R.id.touch_append_detail);
detailDurationView = rootView.findViewById(R.id.detail_duration_view);
detailPositionView = rootView.findViewById(R.id.detail_position_view);

videoDescriptionRootLayout = rootView.findViewById(R.id.detail_description_root_layout);
videoUploadDateView = rootView.findViewById(R.id.detail_upload_date_view);
Expand Down Expand Up @@ -536,10 +548,10 @@ private void showStreamDialog(final StreamInfoItem item) {
final DialogInterface.OnClickListener actions = (DialogInterface dialogInterface, int i) -> {
switch (i) {
case 0:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item), true);
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(getActivity(), new SinglePlayQueue(item), true);
break;
case 2:
if (getFragmentManager() != null) {
Expand Down Expand Up @@ -890,11 +902,11 @@ private void openPopupPlayer(final boolean append) {

final PlayQueue itemQueue = new SinglePlayQueue(currentInfo);
if (append) {
NavigationHelper.enqueueOnPopupPlayer(activity, itemQueue);
NavigationHelper.enqueueOnPopupPlayer(activity, itemQueue, false);
} else {
Toast.makeText(activity, R.string.popup_playing_toast, Toast.LENGTH_SHORT).show();
final Intent intent = NavigationHelper.getPlayerIntent(
activity, PopupVideoPlayer.class, itemQueue, getSelectedVideoStream().resolution
activity, PopupVideoPlayer.class, itemQueue, getSelectedVideoStream().resolution, true
);
activity.startService(intent);
}
Expand All @@ -914,9 +926,9 @@ private void openVideoPlayer() {
private void openNormalBackgroundPlayer(final boolean append) {
final PlayQueue itemQueue = new SinglePlayQueue(currentInfo);
if (append) {
NavigationHelper.enqueueOnBackgroundPlayer(activity, itemQueue);
NavigationHelper.enqueueOnBackgroundPlayer(activity, itemQueue, false);
} else {
NavigationHelper.playOnBackgroundPlayer(activity, itemQueue);
NavigationHelper.playOnBackgroundPlayer(activity, itemQueue, true);
}
}

Expand All @@ -926,7 +938,7 @@ private void openNormalPlayer() {
mIntent = NavigationHelper.getPlayerIntent(activity,
MainVideoPlayer.class,
playQueue,
getSelectedVideoStream().getResolution());
getSelectedVideoStream().getResolution(), true);
startActivity(mIntent);
}

Expand Down Expand Up @@ -1032,6 +1044,8 @@ public void showLoading() {
animateView(spinnerToolbar, false, 200);
animateView(thumbnailPlayButton, false, 50);
animateView(detailDurationView, false, 100);
animateView(detailPositionView, false, 100);
animateView(positionView, false, 50);

videoTitleTextView.setText(name != null ? name : "");
videoTitleTextView.setMaxLines(1);
Expand Down Expand Up @@ -1146,6 +1160,7 @@ public void handleResult(@NonNull StreamInfo info) {
videoUploadDateView.setText(Localization.localizeDate(activity, info.getUploadDate()));
}
prepareDescription(info.getDescription());
updateProgressInfo(info);

animateView(spinnerToolbar, true, 500);
setupActionBar(info);
Expand Down Expand Up @@ -1250,4 +1265,37 @@ public void onBlockedByGemaError() {

showError(getString(R.string.blocked_by_gema), false, R.drawable.gruese_die_gema);
}

private void updateProgressInfo(@NonNull final StreamInfo info) {
if (positionSubscriber != null) {
positionSubscriber.dispose();
}
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
final boolean playbackResumeEnabled =
prefs.getBoolean(activity.getString(R.string.enable_watch_history_key), true)
&& prefs.getBoolean(activity.getString(R.string.enable_playback_resume_key), true);
if (!playbackResumeEnabled || info.getDuration() <= 0) {
positionView.setVisibility(View.INVISIBLE);
detailPositionView.setVisibility(View.GONE);
return;
}
final HistoryRecordManager recordManager = new HistoryRecordManager(requireContext());
positionSubscriber = recordManager.loadStreamState(info)
.subscribeOn(Schedulers.io())
.onErrorComplete()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(state -> {
final int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(state.getProgressTime());
positionView.setMax((int) info.getDuration());
positionView.setProgressAnimated(seconds);
detailPositionView.setText(Localization.getDurationString(seconds));
animateView(positionView, true, 500);
animateView(detailPositionView, true, 500);
}, e -> {
if (DEBUG) e.printStackTrace();
}, () -> {
animateView(positionView, false, 500);
animateView(detailPositionView, false, 500);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ public void onAttach(Context context) {
infoListAdapter = new InfoListAdapter(activity);
}

@Override
public void onDetach() {
infoListAdapter.dispose();
super.onDetach();
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -94,6 +100,8 @@ public void onResume() {
}
updateFlags = 0;
}

itemsList.post(infoListAdapter::updateStates);
}

/*//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -266,13 +274,13 @@ protected void showStreamDialog(final StreamInfoItem item) {
final DialogInterface.OnClickListener actions = (dialogInterface, i) -> {
switch (i) {
case 0:
NavigationHelper.playOnBackgroundPlayer(context, new SinglePlayQueue(item));
NavigationHelper.playOnBackgroundPlayer(context, new SinglePlayQueue(item), true);
break;
case 1:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item), true);
break;
case 2:
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item), true);
break;
case 3:
if (getFragmentManager() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,19 +170,19 @@ protected void showStreamDialog(final StreamInfoItem item) {
final int index = Math.max(infoListAdapter.getItemsList().indexOf(item), 0);
switch (i) {
case 0:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item), false);
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item), false);
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index), true);
break;
case 3:
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index), true);
break;
case 4:
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index), true);
break;
case 5:
if (getFragmentManager() != null) {
Expand Down Expand Up @@ -440,11 +440,11 @@ public void handleResult(@NonNull ChannelInfo result) {
monitorSubscription(result);

headerPlayAllButton.setOnClickListener(
view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
view -> NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false));
headerPopupButton.setOnClickListener(
view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
view -> NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
headerBackgroundButton.setOnClickListener(
view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
view -> NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false));
}

private PlayQueue getPlayQueue() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,22 @@ protected void showStreamDialog(final StreamInfoItem item) {
final int index = Math.max(infoListAdapter.getItemsList().indexOf(item), 0);
switch (i) {
case 0:
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item));
NavigationHelper.enqueueOnBackgroundPlayer(context, new SinglePlayQueue(item), false);
break;
case 1:
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item));
NavigationHelper.enqueueOnPopupPlayer(activity, new SinglePlayQueue(item), false);
break;
case 2:
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index));
NavigationHelper.playOnMainPlayer(context, getPlayQueue(index), true);
break;
case 3:
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index));
NavigationHelper.playOnBackgroundPlayer(context, getPlayQueue(index), true);
break;
case 4:
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index));
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(index), true);
break;
case 5:
ShareUtils.shareUrl(this.getContext(), item.getName(), item.getUrl());
ShareUtils.shareUrl(requireContext(), item.getName(), item.getUrl());
break;
default:
break;
Expand Down Expand Up @@ -301,19 +301,19 @@ public void handleResult(@NonNull final PlaylistInfo result) {
.subscribe(getPlaylistBookmarkSubscriber());

headerPlayAllButton.setOnClickListener(view ->
NavigationHelper.playOnMainPlayer(activity, getPlayQueue()));
NavigationHelper.playOnMainPlayer(activity, getPlayQueue(), false));
headerPopupButton.setOnClickListener(view ->
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue()));
NavigationHelper.playOnPopupPlayer(activity, getPlayQueue(), false));
headerBackgroundButton.setOnClickListener(view ->
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue()));
NavigationHelper.playOnBackgroundPlayer(activity, getPlayQueue(), false));

headerPopupButton.setOnLongClickListener(view -> {
NavigationHelper.enqueueOnPopupPlayer(activity, getPlayQueue());
NavigationHelper.enqueueOnPopupPlayer(activity, getPlayQueue(), true);
return true;
});

headerBackgroundButton.setOnLongClickListener(view -> {
NavigationHelper.enqueueOnBackgroundPlayer(activity, getPlayQueue());
NavigationHelper.enqueueOnBackgroundPlayer(activity, getPlayQueue(), true);
return true;
});
}
Expand Down
Loading