Resolver: Cleaned up ``isVideoStreamVideoOnly``
* Replaced by ``wasLastResolvedVideoAndAudioSeparated`` * Uses an ``Optional`` instead (we can't determine if the video and audio streams are separated when we did not fetch it)
This commit is contained in:
parent
a489f40b76
commit
bb27bf9d34
|
@ -3293,7 +3293,8 @@ public final class Player implements
|
|||
if (audioPlayerSelected()) {
|
||||
return audioResolver.resolve(info);
|
||||
} else {
|
||||
if (isAudioOnly && !videoResolver.isVideoStreamVideoOnly()) {
|
||||
if (isAudioOnly
|
||||
&& !videoResolver.wasLastResolvedVideoAndAudioSeparated().orElse(false)) {
|
||||
return audioResolver.resolve(info);
|
||||
}
|
||||
|
||||
|
@ -4189,8 +4190,9 @@ public final class Player implements
|
|||
|
||||
final boolean isVideoStreamTypeAndIsVideoOnlyStreamOrNoAudioStreamsAvailable =
|
||||
(streamType == StreamType.VIDEO_STREAM || streamType == StreamType.LIVE_STREAM)
|
||||
&& (videoResolver.isVideoStreamVideoOnly()
|
||||
&& (videoResolver.wasLastResolvedVideoAndAudioSeparated().orElse(false)
|
||||
|| isNullOrEmpty(info.getAudioStreams()));
|
||||
|
||||
if (videoRenderIndex != RENDERER_UNAVAILABLE
|
||||
&& isVideoStreamTypeAndIsVideoOnlyStreamOrNoAudioStreamsAvailable) {
|
||||
final TrackGroupArray videoTrackGroupArray = Objects.requireNonNull(
|
||||
|
|
|
@ -44,9 +44,4 @@ public class AudioPlaybackResolver implements PlaybackResolver {
|
|||
return buildMediaSource(dataSource, audio.getUrl(), PlayerHelper.cacheKeyOf(info, audio),
|
||||
MediaFormat.getSuffixById(audio.getFormatId()), tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideoStreamVideoOnly() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,4 @@ import androidx.annotation.Nullable;
|
|||
public interface Resolver<Source, Product> {
|
||||
@Nullable
|
||||
Product resolve(@NonNull Source source);
|
||||
|
||||
boolean isVideoStreamVideoOnly();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.schabi.newpipe.util.ListHelper;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.android.exoplayer2.C.TIME_UNSET;
|
||||
|
||||
|
@ -35,7 +36,7 @@ public class VideoPlaybackResolver implements PlaybackResolver {
|
|||
@Nullable
|
||||
private String playbackQuality;
|
||||
|
||||
private boolean isVideoStreamVideoOnly = false;
|
||||
private Boolean wasLastResolvedVideoAndAudioSeparated;
|
||||
|
||||
public VideoPlaybackResolver(@NonNull final Context context,
|
||||
@NonNull final PlayerDataSource dataSource,
|
||||
|
@ -48,83 +49,93 @@ public class VideoPlaybackResolver implements PlaybackResolver {
|
|||
@Override
|
||||
@Nullable
|
||||
public MediaSource resolve(@NonNull final StreamInfo info) {
|
||||
isVideoStreamVideoOnly = false;
|
||||
final MediaSource liveSource = maybeBuildLiveMediaSource(dataSource, info);
|
||||
if (liveSource != null) {
|
||||
return liveSource;
|
||||
}
|
||||
|
||||
final List<MediaSource> mediaSources = new ArrayList<>();
|
||||
|
||||
// Create video stream source
|
||||
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
|
||||
info.getVideoStreams(), info.getVideoOnlyStreams(), false, true);
|
||||
final int index;
|
||||
if (videos.isEmpty()) {
|
||||
index = -1;
|
||||
} else if (playbackQuality == null) {
|
||||
index = qualityResolver.getDefaultResolutionIndex(videos);
|
||||
} else {
|
||||
index = qualityResolver.getOverrideResolutionIndex(videos, getPlaybackQuality());
|
||||
}
|
||||
final MediaSourceTag tag = new MediaSourceTag(info, videos, index);
|
||||
@Nullable final VideoStream video = tag.getSelectedVideoStream();
|
||||
|
||||
if (video != null) {
|
||||
final MediaSource streamSource = buildMediaSource(dataSource, video.getUrl(),
|
||||
PlayerHelper.cacheKeyOf(info, video),
|
||||
MediaFormat.getSuffixById(video.getFormatId()), tag);
|
||||
mediaSources.add(streamSource);
|
||||
}
|
||||
|
||||
// Create optional audio stream source
|
||||
final List<AudioStream> audioStreams = info.getAudioStreams();
|
||||
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
|
||||
ListHelper.getDefaultAudioFormat(context, audioStreams));
|
||||
// Use the audio stream if there is no video stream, or
|
||||
// Merge with audio stream in case if video does not contain audio
|
||||
if (audio != null && (video == null || video.isVideoOnly)) {
|
||||
final MediaSource audioSource = buildMediaSource(dataSource, audio.getUrl(),
|
||||
PlayerHelper.cacheKeyOf(info, audio),
|
||||
MediaFormat.getSuffixById(audio.getFormatId()), tag);
|
||||
mediaSources.add(audioSource);
|
||||
isVideoStreamVideoOnly = true;
|
||||
}
|
||||
|
||||
// If there is no audio or video sources, then this media source cannot be played back
|
||||
if (mediaSources.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// Below are auxiliary media sources
|
||||
|
||||
// Create subtitle sources
|
||||
if (info.getSubtitles() != null) {
|
||||
for (final SubtitlesStream subtitle : info.getSubtitles()) {
|
||||
final String mimeType = PlayerHelper.subtitleMimeTypesOf(subtitle.getFormat());
|
||||
if (mimeType == null) {
|
||||
continue;
|
||||
}
|
||||
final MediaSource textSource = dataSource.getSampleMediaSourceFactory()
|
||||
.createMediaSource(
|
||||
new MediaItem.Subtitle(Uri.parse(subtitle.getUrl()),
|
||||
mimeType,
|
||||
PlayerHelper.captionLanguageOf(context, subtitle)),
|
||||
TIME_UNSET);
|
||||
mediaSources.add(textSource);
|
||||
boolean isVideoAndAudioSeparated = false;
|
||||
try {
|
||||
final MediaSource liveSource = maybeBuildLiveMediaSource(dataSource, info);
|
||||
if (liveSource != null) {
|
||||
return liveSource;
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaSources.size() == 1) {
|
||||
return mediaSources.get(0);
|
||||
} else {
|
||||
return new MergingMediaSource(mediaSources.toArray(
|
||||
new MediaSource[0]));
|
||||
final List<MediaSource> mediaSources = new ArrayList<>();
|
||||
|
||||
// Create video stream source
|
||||
final List<VideoStream> videos = ListHelper.getSortedStreamVideosList(context,
|
||||
info.getVideoStreams(), info.getVideoOnlyStreams(), false, true);
|
||||
final int index;
|
||||
if (videos.isEmpty()) {
|
||||
index = -1;
|
||||
} else if (playbackQuality == null) {
|
||||
index = qualityResolver.getDefaultResolutionIndex(videos);
|
||||
} else {
|
||||
index = qualityResolver.getOverrideResolutionIndex(videos, getPlaybackQuality());
|
||||
}
|
||||
final MediaSourceTag tag = new MediaSourceTag(info, videos, index);
|
||||
@Nullable final VideoStream video = tag.getSelectedVideoStream();
|
||||
|
||||
if (video != null) {
|
||||
final MediaSource streamSource = buildMediaSource(dataSource, video.getUrl(),
|
||||
PlayerHelper.cacheKeyOf(info, video),
|
||||
MediaFormat.getSuffixById(video.getFormatId()), tag);
|
||||
mediaSources.add(streamSource);
|
||||
}
|
||||
|
||||
// Create optional audio stream source
|
||||
final List<AudioStream> audioStreams = info.getAudioStreams();
|
||||
final AudioStream audio = audioStreams.isEmpty() ? null : audioStreams.get(
|
||||
ListHelper.getDefaultAudioFormat(context, audioStreams));
|
||||
// Use the audio stream if there is no video stream, or
|
||||
// Merge with audio stream in case if video does not contain audio
|
||||
if (audio != null && (video == null || video.isVideoOnly)) {
|
||||
final MediaSource audioSource = buildMediaSource(dataSource, audio.getUrl(),
|
||||
PlayerHelper.cacheKeyOf(info, audio),
|
||||
MediaFormat.getSuffixById(audio.getFormatId()), tag);
|
||||
mediaSources.add(audioSource);
|
||||
isVideoAndAudioSeparated = true;
|
||||
}
|
||||
|
||||
// If there is no audio or video sources, then this media source cannot be played back
|
||||
if (mediaSources.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// Below are auxiliary media sources
|
||||
|
||||
// Create subtitle sources
|
||||
if (info.getSubtitles() != null) {
|
||||
for (final SubtitlesStream subtitle : info.getSubtitles()) {
|
||||
final String mimeType = PlayerHelper.subtitleMimeTypesOf(subtitle.getFormat());
|
||||
if (mimeType == null) {
|
||||
continue;
|
||||
}
|
||||
final MediaSource textSource = dataSource.getSampleMediaSourceFactory()
|
||||
.createMediaSource(
|
||||
new MediaItem.Subtitle(Uri.parse(subtitle.getUrl()),
|
||||
mimeType,
|
||||
PlayerHelper.captionLanguageOf(context, subtitle)),
|
||||
TIME_UNSET);
|
||||
mediaSources.add(textSource);
|
||||
}
|
||||
}
|
||||
|
||||
if (mediaSources.size() == 1) {
|
||||
return mediaSources.get(0);
|
||||
} else {
|
||||
return new MergingMediaSource(mediaSources.toArray(
|
||||
new MediaSource[0]));
|
||||
}
|
||||
} finally {
|
||||
wasLastResolvedVideoAndAudioSeparated = isVideoAndAudioSeparated;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVideoStreamVideoOnly() {
|
||||
return isVideoStreamVideoOnly;
|
||||
/**
|
||||
* Determines if the last resolved StreamInfo had separated audio and video streams
|
||||
* (or only audio).
|
||||
*
|
||||
* @return {@link Optional#empty()} if nothing was resolved
|
||||
* otherwise <code>true</code> or <code>false</code>
|
||||
*/
|
||||
public Optional<Boolean> wasLastResolvedVideoAndAudioSeparated() {
|
||||
return Optional.ofNullable(wasLastResolvedVideoAndAudioSeparated);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
Loading…
Reference in New Issue