mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-30 23:03:00 +00:00 
			
		
		
		
	Save playback state even if stream is finished and add isFinished()
This commit is contained in:
		| @@ -10,6 +10,7 @@ import io.reactivex.rxjava3.core.Flowable | ||||
| import org.schabi.newpipe.database.feed.model.FeedEntity | ||||
| import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity | ||||
| import org.schabi.newpipe.database.stream.StreamWithState | ||||
| import org.schabi.newpipe.database.stream.model.StreamStateEntity | ||||
| import org.schabi.newpipe.database.subscription.SubscriptionEntity | ||||
| import java.time.OffsetDateTime | ||||
|  | ||||
| @@ -79,6 +80,9 @@ abstract class FeedDAO { | ||||
|  | ||||
|         WHERE ( | ||||
|             sh.stream_id IS NULL | ||||
|             OR sst.stream_id IS NULL | ||||
|             OR sst.progress_time < s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS} | ||||
|             OR sst.progress_time < s.duration * 1000 * 3 / 4 | ||||
|             OR s.stream_type = 'LIVE_STREAM' | ||||
|             OR s.stream_type = 'AUDIO_LIVE_STREAM' | ||||
|         ) | ||||
|   | ||||
| @@ -5,8 +5,6 @@ import androidx.room.ColumnInfo; | ||||
| import androidx.room.Entity; | ||||
| import androidx.room.ForeignKey; | ||||
|  | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| import static androidx.room.ForeignKey.CASCADE; | ||||
| import static org.schabi.newpipe.database.stream.model.StreamStateEntity.JOIN_STREAM_ID; | ||||
| import static org.schabi.newpipe.database.stream.model.StreamStateEntity.STREAM_STATE_TABLE; | ||||
| @@ -30,11 +28,13 @@ public class StreamStateEntity { | ||||
|     /** | ||||
|      * Playback state will not be saved, if playback time is less than this threshold. | ||||
|      */ | ||||
|     private static final int PLAYBACK_SAVE_THRESHOLD_START_SECONDS = 5; | ||||
|     private static final long PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS = 5000; // 5000ms = 5s | ||||
|  | ||||
|     /** | ||||
|      * Playback state will not be saved, if time left is less than this threshold. | ||||
|      * @see #isFinished(long) | ||||
|      * @see org.schabi.newpipe.database.feed.dao.FeedDAO#getLiveOrNotPlayedStreams() | ||||
|      */ | ||||
|     private static final int PLAYBACK_SAVE_THRESHOLD_END_SECONDS = 10; | ||||
|     public static final long PLAYBACK_FINISHED_END_MILLISECONDS = 60000; // 60000ms = 60s | ||||
|  | ||||
|     @ColumnInfo(name = JOIN_STREAM_ID) | ||||
|     private long streamUid; | ||||
| @@ -63,10 +63,27 @@ public class StreamStateEntity { | ||||
|         this.progressTime = progressTime; | ||||
|     } | ||||
|  | ||||
|     public boolean isValid(final int durationInSeconds) { | ||||
|         final int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(progressTime); | ||||
|         return seconds > PLAYBACK_SAVE_THRESHOLD_START_SECONDS | ||||
|                 && seconds < durationInSeconds - PLAYBACK_SAVE_THRESHOLD_END_SECONDS; | ||||
|     /** | ||||
|      * The state will be considered valid, and thus be saved, if the progress is more than {@link | ||||
|      * #PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS}. | ||||
|      * @return whether this stream state entity should be saved or not | ||||
|      */ | ||||
|     public boolean isValid() { | ||||
|         return progressTime > PLAYBACK_SAVE_THRESHOLD_START_MILLISECONDS; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The video will be considered as finished, if the time left is less than {@link | ||||
|      * #PLAYBACK_FINISHED_END_MILLISECONDS} and the progress is at least 3/4 of the video length. | ||||
|      * The state will be saved anyway, so that it can be shown under stream info items, but the | ||||
|      * player will not resume if a state is considered as finished. Finished streams are also the | ||||
|      * ones that can be filtered out in the feed fragment. | ||||
|      * @param durationInSeconds the duration of the stream connected with this state, in seconds | ||||
|      * @return whether the stream is finished or not | ||||
|      */ | ||||
|     public boolean isFinished(final long durationInSeconds) { | ||||
|         return progressTime >= durationInSeconds * 1000 - PLAYBACK_FINISHED_END_MILLISECONDS | ||||
|                 && progressTime >= durationInSeconds * 1000 * 3 / 4; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
| @@ -215,7 +215,7 @@ public class HistoryRecordManager { | ||||
|                 .flatMapPublisher(streamStateTable::getState) | ||||
|                 .firstElement() | ||||
|                 .flatMap(list -> list.isEmpty() ? Maybe.empty() : Maybe.just(list.get(0))) | ||||
|                 .filter(state -> state.isValid((int) queueItem.getDuration())) | ||||
|                 .filter(StreamStateEntity::isValid) | ||||
|                 .subscribeOn(Schedulers.io()); | ||||
|     } | ||||
|  | ||||
| @@ -224,7 +224,7 @@ public class HistoryRecordManager { | ||||
|                 .flatMapPublisher(streamStateTable::getState) | ||||
|                 .firstElement() | ||||
|                 .flatMap(list -> list.isEmpty() ? Maybe.empty() : Maybe.just(list.get(0))) | ||||
|                 .filter(state -> state.isValid((int) info.getDuration())) | ||||
|                 .filter(StreamStateEntity::isValid) | ||||
|                 .subscribeOn(Schedulers.io()); | ||||
|     } | ||||
|  | ||||
| @@ -232,7 +232,7 @@ public class HistoryRecordManager { | ||||
|         return Completable.fromAction(() -> database.runInTransaction(() -> { | ||||
|             final long streamId = streamTable.upsert(new StreamEntity(info)); | ||||
|             final StreamStateEntity state = new StreamStateEntity(streamId, progressTime); | ||||
|             if (state.isValid((int) info.getDuration())) { | ||||
|             if (state.isValid()) { | ||||
|                 streamStateTable.upsert(state); | ||||
|             } else { | ||||
|                 streamStateTable.deleteState(streamId); | ||||
|   | ||||
| @@ -671,7 +671,11 @@ public final class Player implements | ||||
|                     //.doFinally() | ||||
|                     .subscribe( | ||||
|                             state -> { | ||||
|                                 newQueue.setRecovery(newQueue.getIndex(), state.getProgressTime()); | ||||
|                                 if (!state.isFinished(newQueue.getItem().getDuration())) { | ||||
|                                     // resume playback only if the stream was not played to the end | ||||
|                                     newQueue.setRecovery(newQueue.getIndex(), | ||||
|                                             state.getProgressTime()); | ||||
|                                 } | ||||
|                                 initPlayback(newQueue, repeatMode, playbackSpeed, playbackPitch, | ||||
|                                         playbackSkipSilence, playWhenReady, isMuted); | ||||
|                             }, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stypox
					Stypox