Skip to content

Commit ba804c7

Browse files
committed
Use a enum to understand better what source type is used.
This commit also allows a seamless transition for livestreams.
1 parent 3db3716 commit ba804c7

2 files changed

Lines changed: 96 additions & 79 deletions

File tree

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
import org.schabi.newpipe.player.resolver.AudioPlaybackResolver;
179179
import org.schabi.newpipe.player.resolver.MediaSourceTag;
180180
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver;
181+
import org.schabi.newpipe.player.resolver.VideoPlaybackResolver.SourceType;
181182
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHelper;
182183
import org.schabi.newpipe.player.seekbarpreview.SeekbarPreviewThumbnailHolder;
183184
import org.schabi.newpipe.util.DeviceUtils;
@@ -3293,8 +3294,9 @@ public MediaSource sourceOf(final PlayQueueItem item, final StreamInfo info) {
32933294
if (audioPlayerSelected()) {
32943295
return audioResolver.resolve(info);
32953296
} else {
3296-
if (isAudioOnly
3297-
&& !videoResolver.wasLastResolvedVideoAndAudioSeparated().orElse(false)) {
3297+
if (isAudioOnly && videoResolver.getStreamSourceType().orElse(
3298+
SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY)
3299+
== SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY) {
32983300
// If the current info has only video streams with audio and if the stream is
32993301
// played as audio, we need to use the audio resolver, otherwise the video stream
33003302
// will be played in background.
@@ -4196,18 +4198,30 @@ Otherwise the video renderer will be just disabled (because there is no
41964198
stream will be fetched and the video stream will be fetched again when the user return to a
41974199
video player.
41984200
4199-
For audio streams: nothing is done, it's not needed to reload the player with the same
4200-
audio stream.
4201+
For audio streams and audio live streams: nothing is done, it's not needed to reload the
4202+
player with the same audio stream.
4203+
4204+
For video live streams: the play queue manager is not reloaded if the stream source is a
4205+
live source (see VideoPlaybackResolver#resolve()) and if that's not the case, the
4206+
requirements for video streams is applied.
42014207
42024208
In the case where we don't know the index of the video renderer, the play queue manager
42034209
is also reloaded. */
42044210

42054211
final StreamType streamType = info.getStreamType();
4212+
final SourceType sourceType = videoResolver.getStreamSourceType()
4213+
.orElse(SourceType.VIDEO_WITH_SEPARATED_AUDIO);
42064214

4215+
final boolean isVideoWithSeparatedAudioOrVideoWithNoSeparatedAudioStreams =
4216+
sourceType == SourceType.VIDEO_WITH_SEPARATED_AUDIO
4217+
|| (sourceType == SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY
4218+
&& isNullOrEmpty(info.getAudioStreams()));
42074219
final boolean isVideoStreamTypeAndIsVideoOnlyStreamOrNoAudioStreamsAvailable =
4208-
(streamType == StreamType.VIDEO_STREAM || streamType == StreamType.LIVE_STREAM)
4209-
&& (videoResolver.wasLastResolvedVideoAndAudioSeparated().orElse(false)
4210-
|| isNullOrEmpty(info.getAudioStreams()));
4220+
streamType == StreamType.VIDEO_STREAM
4221+
&& isVideoWithSeparatedAudioOrVideoWithNoSeparatedAudioStreams
4222+
|| (streamType == StreamType.LIVE_STREAM
4223+
&& (sourceType == SourceType.LIVE_STREAM
4224+
|| isVideoWithSeparatedAudioOrVideoWithNoSeparatedAudioStreams));
42114225

42124226
if (videoRenderIndex != RENDERER_UNAVAILABLE
42134227
&& isVideoStreamTypeAndIsVideoOnlyStreamOrNoAudioStreamsAvailable) {

app/src/main/java/org/schabi/newpipe/player/resolver/VideoPlaybackResolver.java

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@ public class VideoPlaybackResolver implements PlaybackResolver {
3232
private final PlayerDataSource dataSource;
3333
@NonNull
3434
private final QualityResolver qualityResolver;
35+
private SourceType streamSourceType;
3536

3637
@Nullable
3738
private String playbackQuality;
3839

39-
private Boolean wasLastResolvedVideoAndAudioSeparated;
40+
public enum SourceType {
41+
LIVE_STREAM,
42+
VIDEO_WITH_SEPARATED_AUDIO,
43+
VIDEO_WITH_AUDIO_OR_AUDIO_ONLY
44+
}
4045

4146
public VideoPlaybackResolver(@NonNull final Context context,
4247
@NonNull final PlayerDataSource dataSource,
@@ -49,81 +54,79 @@ public VideoPlaybackResolver(@NonNull final Context context,
4954
@Override
5055
@Nullable
5156
public MediaSource resolve(@NonNull final StreamInfo info) {
52-
boolean isVideoAndAudioSeparated = false;
53-
try {
54-
final MediaSource liveSource = maybeBuildLiveMediaSource(dataSource, info);
55-
if (liveSource != null) {
56-
return liveSource;
57-
}
57+
final MediaSource liveSource = maybeBuildLiveMediaSource(dataSource, info);
58+
if (liveSource != null) {
59+
streamSourceType = SourceType.LIVE_STREAM;
60+
return liveSource;
61+
}
5862

59-
final List<MediaSource> mediaSources = new ArrayList<>();
60-
61-
// Create video stream source
62-
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
63-
info.getVideoStreams(), info.getVideoOnlyStreams(), false, true);
64-
final int index;
65-
if (videos.isEmpty()) {
66-
index = -1;
67-
} else if (playbackQuality == null) {
68-
index = qualityResolver.getDefaultResolutionIndex(videos);
69-
} else {
70-
index = qualityResolver.getOverrideResolutionIndex(videos, getPlaybackQuality());
71-
}
72-
final MediaSourceTag tag = new MediaSourceTag(info, videos, index);
73-
@Nullable final VideoStream video = tag.getSelectedVideoStream();
74-
75-
if (video != null) {
76-
final MediaSource streamSource = buildMediaSource(dataSource, video.getUrl(),
77-
PlayerHelper.cacheKeyOf(info, video),
78-
MediaFormat.getSuffixById(video.getFormatId()), tag);
79-
mediaSources.add(streamSource);
80-
}
63+
final List<MediaSource> mediaSources = new ArrayList<>();
64+
65+
// Create video stream source
66+
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
67+
info.getVideoStreams(), info.getVideoOnlyStreams(), false, true);
68+
final int index;
69+
if (videos.isEmpty()) {
70+
index = -1;
71+
} else if (playbackQuality == null) {
72+
index = qualityResolver.getDefaultResolutionIndex(videos);
73+
} else {
74+
index = qualityResolver.getOverrideResolutionIndex(videos, getPlaybackQuality());
75+
}
76+
final MediaSourceTag tag = new MediaSourceTag(info, videos, index);
77+
@Nullable final VideoStream video = tag.getSelectedVideoStream();
78+
79+
if (video != null) {
80+
final MediaSource streamSource = buildMediaSource(dataSource, video.getUrl(),
81+
PlayerHelper.cacheKeyOf(info, video),
82+
MediaFormat.getSuffixById(video.getFormatId()), tag);
83+
mediaSources.add(streamSource);
84+
}
8185

82-
// Create optional audio stream source
83-
final List<AudioStream> audioStreams = info.getAudioStreams();
84-
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
85-
ListHelper.getDefaultAudioFormat(context, audioStreams));
86-
// Use the audio stream if there is no video stream, or
87-
// Merge with audio stream in case if video does not contain audio
88-
if (audio != null && (video == null || video.isVideoOnly)) {
89-
final MediaSource audioSource = buildMediaSource(dataSource, audio.getUrl(),
90-
PlayerHelper.cacheKeyOf(info, audio),
91-
MediaFormat.getSuffixById(audio.getFormatId()), tag);
92-
mediaSources.add(audioSource);
93-
isVideoAndAudioSeparated = true;
94-
}
86+
// Create optional audio stream source
87+
final List<AudioStream> audioStreams = info.getAudioStreams();
88+
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
89+
ListHelper.getDefaultAudioFormat(context, audioStreams));
90+
// Use the audio stream if there is no video stream, or
91+
// Merge with audio stream in case if video does not contain audio
92+
if (audio != null && (video == null || video.isVideoOnly)) {
93+
final MediaSource audioSource = buildMediaSource(dataSource, audio.getUrl(),
94+
PlayerHelper.cacheKeyOf(info, audio),
95+
MediaFormat.getSuffixById(audio.getFormatId()), tag);
96+
mediaSources.add(audioSource);
97+
streamSourceType = SourceType.VIDEO_WITH_SEPARATED_AUDIO;
98+
} else {
99+
streamSourceType = SourceType.VIDEO_WITH_AUDIO_OR_AUDIO_ONLY;
100+
}
95101

96-
// If there is no audio or video sources, then this media source cannot be played back
97-
if (mediaSources.isEmpty()) {
98-
return null;
99-
}
100-
// Below are auxiliary media sources
101-
102-
// Create subtitle sources
103-
if (info.getSubtitles() != null) {
104-
for (final SubtitlesStream subtitle : info.getSubtitles()) {
105-
final String mimeType = PlayerHelper.subtitleMimeTypesOf(subtitle.getFormat());
106-
if (mimeType == null) {
107-
continue;
108-
}
109-
final MediaSource textSource = dataSource.getSampleMediaSourceFactory()
110-
.createMediaSource(
111-
new MediaItem.Subtitle(Uri.parse(subtitle.getUrl()),
112-
mimeType,
113-
PlayerHelper.captionLanguageOf(context, subtitle)),
114-
TIME_UNSET);
115-
mediaSources.add(textSource);
102+
// If there is no audio or video sources, then this media source cannot be played back
103+
if (mediaSources.isEmpty()) {
104+
return null;
105+
}
106+
// Below are auxiliary media sources
107+
108+
// Create subtitle sources
109+
if (info.getSubtitles() != null) {
110+
for (final SubtitlesStream subtitle : info.getSubtitles()) {
111+
final String mimeType = PlayerHelper.subtitleMimeTypesOf(subtitle.getFormat());
112+
if (mimeType == null) {
113+
continue;
116114
}
115+
final MediaSource textSource = dataSource.getSampleMediaSourceFactory()
116+
.createMediaSource(
117+
new MediaItem.Subtitle(Uri.parse(subtitle.getUrl()),
118+
mimeType,
119+
PlayerHelper.captionLanguageOf(context, subtitle)),
120+
TIME_UNSET);
121+
mediaSources.add(textSource);
117122
}
123+
}
118124

119-
if (mediaSources.size() == 1) {
120-
return mediaSources.get(0);
121-
} else {
122-
return new MergingMediaSource(mediaSources.toArray(
123-
new MediaSource[0]));
124-
}
125-
} finally {
126-
wasLastResolvedVideoAndAudioSeparated = isVideoAndAudioSeparated;
125+
if (mediaSources.size() == 1) {
126+
return mediaSources.get(0);
127+
} else {
128+
return new MergingMediaSource(mediaSources.toArray(
129+
new MediaSource[0]));
127130
}
128131
}
129132

@@ -134,8 +137,8 @@ public MediaSource resolve(@NonNull final StreamInfo info) {
134137
* @return {@link Optional#empty()} if nothing was resolved, otherwise {@code true} or
135138
* {@code false}
136139
*/
137-
public Optional<Boolean> wasLastResolvedVideoAndAudioSeparated() {
138-
return Optional.ofNullable(wasLastResolvedVideoAndAudioSeparated);
140+
public Optional<SourceType> getStreamSourceType() {
141+
return Optional.ofNullable(streamSourceType);
139142
}
140143

141144
@Nullable

0 commit comments

Comments
 (0)