Skip to content

Commit 360f5ac

Browse files
committed
Save playback state even if stream is finished and add isFinished()
1 parent e846f69 commit 360f5ac

4 files changed

Lines changed: 38 additions & 13 deletions

File tree

app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import io.reactivex.rxjava3.core.Flowable
1010
import org.schabi.newpipe.database.feed.model.FeedEntity
1111
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
1212
import org.schabi.newpipe.database.stream.StreamWithState
13+
import org.schabi.newpipe.database.stream.model.StreamStateEntity
1314
import org.schabi.newpipe.database.subscription.SubscriptionEntity
1415
import java.time.OffsetDateTime
1516

@@ -79,6 +80,9 @@ abstract class FeedDAO {
7980
8081
WHERE (
8182
sh.stream_id IS NULL
83+
OR sst.stream_id IS NULL
84+
OR sst.progress_time < s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS}
85+
OR sst.progress_time < s.duration * 1000 * 3 / 4
8286
OR s.stream_type = 'LIVE_STREAM'
8387
OR s.stream_type = 'AUDIO_LIVE_STREAM'
8488
)

app/src/main/java/org/schabi/newpipe/database/stream/model/StreamStateEntity.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
import androidx.room.Entity;
66
import androidx.room.ForeignKey;
77

8-
import java.util.concurrent.TimeUnit;
9-
108
import static androidx.room.ForeignKey.CASCADE;
119
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID;
1210
import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE;
@@ -30,11 +28,13 @@ public class StreamStateEntity {
3028
/**
3129
* Playback state will not be saved, if playback time is less than this threshold.
3230
*/
33-
private static final int PLAYBACK_SAVE_THRESHOLD_START_SECONDS = 5;
31+
private static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000; // 5000ms = 5s
32+
3433
/**
35-
* Playback state will not be saved, if time left is less than this threshold.
34+
* @see #isFinished(long)
35+
* @see org.schabi.newpipe.database.feed.dao.FeedDAO#getLiveOrNotPlayedStreams()
3636
*/
37-
private static final int PLAYBACK_SAVE_THRESHOLD_END_SECONDS = 10;
37+
public static final long PLAYBACK_FINISHED_END_MILLISECONDS = 60000; // 60000ms = 60s
3838

3939
@ColumnInfo(name = JOIN_STREAM_ID)
4040
private long streamUid;
@@ -63,10 +63,27 @@ public void setProgressTime(final long progressTime) {
6363
this.progressTime = progressTime;
6464
}
6565

66-
public boolean isValid(final int durationInSeconds) {
67-
final int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(progressTime);
68-
return seconds > PLAYBACK_SAVE_THRESHOLD_START_SECONDS
69-
&& seconds < durationInSeconds - PLAYBACK_SAVE_THRESHOLD_END_SECONDS;
66+
/**
67+
* The state will be considered valid, and thus be saved, if the progress is more than {@link
68+
* #PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS}.
69+
* @return whether this stream state entity should be saved or not
70+
*/
71+
public boolean isValid() {
72+
return progressTime > PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS;
73+
}
74+
75+
/**
76+
* The video will be considered as finished, if the time left is less than {@link
77+
* #PLAYBACK_FINISHED_END_MILLISECONDS} and the progress is at least 3/4 of the video length.
78+
* The state will be saved anyway, so that it can be shown under stream info items, but the
79+
* player will not resume if a state is considered as finished. Finished streams are also the
80+
* ones that can be filtered out in the feed fragment.
81+
* @param durationInSeconds the duration of the stream connected with this state, in seconds
82+
* @return whether the stream is finished or not
83+
*/
84+
public boolean isFinished(final long durationInSeconds) {
85+
return progressTime >= durationInSeconds * 1000 - PLAYBACK_FINISHED_END_MILLISECONDS
86+
&& progressTime >= durationInSeconds * 1000 * 3 / 4;
7087
}
7188

7289
@Override

app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public Maybe<StreamStateEntity> loadStreamState(final PlayQueueItem queueItem) {
215215
.flatMapPublisher(streamStateTable::getState)
216216
.firstElement()
217217
.flatMap(list -> list.isEmpty() ? Maybe.empty() : Maybe.just(list.get(0)))
218-
.filter(state -> state.isValid((int) queueItem.getDuration()))
218+
.filter(StreamStateEntity::isValid)
219219
.subscribeOn(Schedulers.io());
220220
}
221221

@@ -224,15 +224,15 @@ public Maybe<StreamStateEntity> loadStreamState(final StreamInfo info) {
224224
.flatMapPublisher(streamStateTable::getState)
225225
.firstElement()
226226
.flatMap(list -> list.isEmpty() ? Maybe.empty() : Maybe.just(list.get(0)))
227-
.filter(state -> state.isValid((int) info.getDuration()))
227+
.filter(StreamStateEntity::isValid)
228228
.subscribeOn(Schedulers.io());
229229
}
230230

231231
public Completable saveStreamState(@NonNull final StreamInfo info, final long progressTime) {
232232
return Completable.fromAction(() -> database.runInTransaction(() -> {
233233
final long streamId = streamTable.upsert(new StreamEntity(info));
234234
final StreamStateEntity state = new StreamStateEntity(streamId, progressTime);
235-
if (state.isValid((int) info.getDuration())) {
235+
if (state.isValid()) {
236236
streamStateTable.upsert(state);
237237
} else {
238238
streamStateTable.deleteState(streamId);

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,11 @@ && isPlaybackResumeEnabled(this)
671671
//.doFinally()
672672
.subscribe(
673673
state -> {
674-
newQueue.setRecovery(newQueue.getIndex(), state.getProgressTime());
674+
if (!state.isFinished(newQueue.getItem().getDuration())) {
675+
// resume playback only if the stream was not played to the end
676+
newQueue.setRecovery(newQueue.getIndex(),
677+
state.getProgressTime());
678+
}
675679
initPlayback(newQueue, repeatMode, playbackSpeed, playbackPitch,
676680
playbackSkipSilence, playWhenReady, isMuted);
677681
},

0 commit comments

Comments
 (0)