Add comments to PlaybackResolver and remove useless @NonNull

This commit is contained in:
Stypox 2022-05-21 12:00:02 +02:00 committed by AudricV
parent 8445c381c5
commit e5ffa2aa09
No known key found for this signature in database
GPG Key ID: DA92EC7905614198
1 changed files with 105 additions and 78 deletions

View File

@ -8,6 +8,8 @@ import static org.schabi.newpipe.player.helper.PlayerDataSource.LIVE_STREAM_EDGE
import android.net.Uri; import android.net.Uri;
import android.util.Log; import android.util.Log;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
@ -41,20 +43,23 @@ import org.schabi.newpipe.player.mediaitem.MediaItemTag;
import org.schabi.newpipe.player.mediaitem.StreamInfoTag; import org.schabi.newpipe.player.mediaitem.StreamInfoTag;
import org.schabi.newpipe.util.StreamTypeUtil; import org.schabi.newpipe.util.StreamTypeUtil;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Objects; import java.util.Objects;
/**
* This interface is just a shorthand for {@link Resolver} with {@link StreamInfo} as source and
* {@link MediaSource} as product. It contains many static methods that can be used by classes
* implementing this interface, and nothing else.
*/
public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> { public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
String TAG = PlaybackResolver.class.getSimpleName(); String TAG = PlaybackResolver.class.getSimpleName();
@NonNull
private static StringBuilder commonCacheKeyOf(@NonNull final StreamInfo info, //region Cache key generation
@NonNull final Stream stream, private static StringBuilder commonCacheKeyOf(final StreamInfo info,
final Stream stream,
final boolean resolutionOrBitrateUnknown) { final boolean resolutionOrBitrateUnknown) {
// stream info service id // stream info service id
final StringBuilder cacheKey = new StringBuilder(info.getServiceId()); final StringBuilder cacheKey = new StringBuilder(info.getServiceId());
@ -91,9 +96,20 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
return cacheKey; return cacheKey;
} }
@NonNull /**
static String cacheKeyOf(@NonNull final StreamInfo info, * Builds the cache key of a video stream. A cache key is unique to the features of the
@NonNull final VideoStream videoStream) { * provided video stream, and when possible independent of <i>transient</i> parameters (such as
* the url of the stream). This ensures that there are no conflicts, but also that the cache is
* used as much as possible: the same cache should be used for two streams which have the same
* features but e.g. a different url, since the url might have been reloaded in the meantime,
* but the stream actually referenced by the url is still the same.
*
* @param info the stream info, to distinguish between streams with the same features but coming
* from different stream infos
* @param videoStream the video stream for which the cache key should be created
* @return a key to be used to store the cache of the provided video stream
*/
static String cacheKeyOf(final StreamInfo info, final VideoStream videoStream) {
final boolean resolutionUnknown = videoStream.getResolution().equals(RESOLUTION_UNKNOWN); final boolean resolutionUnknown = videoStream.getResolution().equals(RESOLUTION_UNKNOWN);
final StringBuilder cacheKey = commonCacheKeyOf(info, videoStream, resolutionUnknown); final StringBuilder cacheKey = commonCacheKeyOf(info, videoStream, resolutionUnknown);
@ -110,9 +126,20 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
return cacheKey.toString(); return cacheKey.toString();
} }
@NonNull /**
static String cacheKeyOf(@NonNull final StreamInfo info, * Builds the cache key of an audio stream. A cache key is unique to the features of the
@NonNull final AudioStream audioStream) { * provided audio stream, and when possible independent of <i>transient</i> parameters (such as
* the url of the stream). This ensures that there are no conflicts, but also that the cache is
* used as much as possible: the same cache should be used for two streams which have the same
* features but e.g. a different url, since the url might have been reloaded in the meantime,
* but the stream actually referenced by the url is still the same.
*
* @param info the stream info, to distinguish between streams with the same features but coming
* from different stream infos
* @param audioStream the audio stream for which the cache key should be created
* @return a key to be used to store the cache of the provided audio stream
*/
static String cacheKeyOf(final StreamInfo info, final AudioStream audioStream) {
final boolean averageBitrateUnknown = audioStream.getAverageBitrate() == UNKNOWN_BITRATE; final boolean averageBitrateUnknown = audioStream.getAverageBitrate() == UNKNOWN_BITRATE;
final StringBuilder cacheKey = commonCacheKeyOf(info, audioStream, averageBitrateUnknown); final StringBuilder cacheKey = commonCacheKeyOf(info, audioStream, averageBitrateUnknown);
@ -124,10 +151,13 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
return cacheKey.toString(); return cacheKey.toString();
} }
//endregion
//region Live media sources
@Nullable @Nullable
static MediaSource maybeBuildLiveMediaSource(@NonNull final PlayerDataSource dataSource, static MediaSource maybeBuildLiveMediaSource(final PlayerDataSource dataSource,
@NonNull final StreamInfo info) { final StreamInfo info) {
final StreamType streamType = info.getStreamType(); final StreamType streamType = info.getStreamType();
if (!StreamTypeUtil.isLiveStream(streamType)) { if (!StreamTypeUtil.isLiveStream(streamType)) {
return null; return null;
@ -143,11 +173,10 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
return null; return null;
} }
@NonNull static MediaSource buildLiveMediaSource(final PlayerDataSource dataSource,
static MediaSource buildLiveMediaSource(@NonNull final PlayerDataSource dataSource, final String sourceUrl,
@NonNull final String sourceUrl,
@C.ContentType final int type, @C.ContentType final int type,
@NonNull final MediaItemTag metadata) { final MediaItemTag metadata) {
final MediaSource.Factory factory; final MediaSource.Factory factory;
switch (type) { switch (type) {
case C.TYPE_SS: case C.TYPE_SS:
@ -159,7 +188,7 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
case C.TYPE_HLS: case C.TYPE_HLS:
factory = dataSource.getLiveHlsMediaSourceFactory(); factory = dataSource.getLiveHlsMediaSourceFactory();
break; break;
default: case C.TYPE_OTHER: case C.TYPE_RTSP: default:
throw new IllegalStateException("Unsupported type: " + type); throw new IllegalStateException("Unsupported type: " + type);
} }
@ -173,13 +202,15 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
.build()) .build())
.build()); .build());
} }
//endregion
@NonNull
static MediaSource buildMediaSource(@NonNull final PlayerDataSource dataSource, //region Generic media sources
@NonNull final Stream stream, static MediaSource buildMediaSource(final PlayerDataSource dataSource,
@NonNull final StreamInfo streamInfo, final Stream stream,
@NonNull final String cacheKey, final StreamInfo streamInfo,
@NonNull final MediaItemTag metadata) final String cacheKey,
final MediaItemTag metadata)
throws IOException { throws IOException {
if (streamInfo.getService() == ServiceList.YouTube) { if (streamInfo.getService() == ServiceList.YouTube) {
return createYoutubeMediaSource(stream, streamInfo, dataSource, cacheKey, metadata); return createYoutubeMediaSource(stream, streamInfo, dataSource, cacheKey, metadata);
@ -201,12 +232,11 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
@NonNull private static ProgressiveMediaSource buildProgressiveMediaSource(
private static <T extends Stream> ProgressiveMediaSource buildProgressiveMediaSource( final PlayerDataSource dataSource,
@NonNull final PlayerDataSource dataSource, final Stream stream,
@NonNull final T stream, final String cacheKey,
@NonNull final String cacheKey, final MediaItemTag metadata) throws IOException {
@NonNull final MediaItemTag metadata) throws IOException {
final String url = stream.getContent(); final String url = stream.getContent();
if (isNullOrEmpty(url)) { if (isNullOrEmpty(url)) {
@ -223,12 +253,11 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
@NonNull private static DashMediaSource buildDashMediaSource(final PlayerDataSource dataSource,
private static <T extends Stream> DashMediaSource buildDashMediaSource( final Stream stream,
@NonNull final PlayerDataSource dataSource, final String cacheKey,
@NonNull final T stream, final MediaItemTag metadata)
@NonNull final String cacheKey, throws IOException {
@NonNull final MediaItemTag metadata) throws IOException {
final boolean isUrlStream = stream.isUrl(); final boolean isUrlStream = stream.isUrl();
if (isUrlStream && isNullOrEmpty(stream.getContent())) { if (isUrlStream && isNullOrEmpty(stream.getContent())) {
throw new IOException("Try to generate a DASH media source from an empty string or " throw new IOException("Try to generate a DASH media source from an empty string or "
@ -260,10 +289,8 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
@NonNull private static DashManifest createDashManifest(final String manifestContent,
private static <T extends Stream> DashManifest createDashManifest( final Stream stream) throws IOException {
@NonNull final String manifestContent,
@NonNull final T stream) throws IOException {
try { try {
final ByteArrayInputStream dashManifestInput = new ByteArrayInputStream( final ByteArrayInputStream dashManifestInput = new ByteArrayInputStream(
manifestContent.getBytes(StandardCharsets.UTF_8)); manifestContent.getBytes(StandardCharsets.UTF_8));
@ -278,12 +305,11 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
@NonNull private static HlsMediaSource buildHlsMediaSource(final PlayerDataSource dataSource,
private static <T extends Stream> HlsMediaSource buildHlsMediaSource( final Stream stream,
@NonNull final PlayerDataSource dataSource, final String cacheKey,
@NonNull final T stream, final MediaItemTag metadata)
@NonNull final String cacheKey, throws IOException {
@NonNull final MediaItemTag metadata) throws IOException {
final boolean isUrlStream = stream.isUrl(); final boolean isUrlStream = stream.isUrl();
if (isUrlStream && isNullOrEmpty(stream.getContent())) { if (isUrlStream && isNullOrEmpty(stream.getContent())) {
throw new IOException("Try to generate an HLS media source from an empty string or " throw new IOException("Try to generate an HLS media source from an empty string or "
@ -324,12 +350,11 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
@NonNull private static SsMediaSource buildSSMediaSource(final PlayerDataSource dataSource,
private static <T extends Stream> SsMediaSource buildSSMediaSource( final Stream stream,
@NonNull final PlayerDataSource dataSource, final String cacheKey,
@NonNull final T stream, final MediaItemTag metadata)
@NonNull final String cacheKey, throws IOException {
@NonNull final MediaItemTag metadata) throws IOException {
final boolean isUrlStream = stream.isUrl(); final boolean isUrlStream = stream.isUrl();
if (isUrlStream && isNullOrEmpty(stream.getContent())) { if (isUrlStream && isNullOrEmpty(stream.getContent())) {
throw new IOException("Try to generate an SmoothStreaming media source from an empty " throw new IOException("Try to generate an SmoothStreaming media source from an empty "
@ -370,13 +395,16 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
.build()); .build());
} }
} }
//endregion
private static <T extends Stream> MediaSource createYoutubeMediaSource(
final T stream, //region YouTube media sources
private static MediaSource createYoutubeMediaSource(final Stream stream,
final StreamInfo streamInfo, final StreamInfo streamInfo,
final PlayerDataSource dataSource, final PlayerDataSource dataSource,
final String cacheKey, final String cacheKey,
final MediaItemTag metadata) throws IOException { final MediaItemTag metadata)
throws IOException {
if (!(stream instanceof AudioStream || stream instanceof VideoStream)) { if (!(stream instanceof AudioStream || stream instanceof VideoStream)) {
throw new IOException("Try to generate a DASH manifest of a YouTube " throw new IOException("Try to generate a DASH manifest of a YouTube "
+ stream.getClass() + " " + stream.getContent()); + stream.getClass() + " " + stream.getContent());
@ -414,12 +442,12 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
private static <T extends Stream> MediaSource createYoutubeMediaSourceOfVideoStreamType( private static MediaSource createYoutubeMediaSourceOfVideoStreamType(
@NonNull final PlayerDataSource dataSource, final PlayerDataSource dataSource,
@NonNull final T stream, final Stream stream,
@NonNull final StreamInfo streamInfo, final StreamInfo streamInfo,
@NonNull final String cacheKey, final String cacheKey,
@NonNull final MediaItemTag metadata) throws IOException { final MediaItemTag metadata) throws IOException {
final DeliveryMethod deliveryMethod = stream.getDeliveryMethod(); final DeliveryMethod deliveryMethod = stream.getDeliveryMethod();
switch (deliveryMethod) { switch (deliveryMethod) {
case PROGRESSIVE_HTTP: case PROGRESSIVE_HTTP:
@ -480,13 +508,12 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
} }
} }
@NonNull private static DashMediaSource buildYoutubeManualDashMediaSource(
private static <T extends Stream> DashMediaSource buildYoutubeManualDashMediaSource( final PlayerDataSource dataSource,
@NonNull final PlayerDataSource dataSource, final DashManifest dashManifest,
@NonNull final DashManifest dashManifest, final Stream stream,
@NonNull final T stream, final String cacheKey,
@NonNull final String cacheKey, final MediaItemTag metadata) {
@NonNull final MediaItemTag metadata) {
return dataSource.getYoutubeDashMediaSourceFactory().createMediaSource(dashManifest, return dataSource.getYoutubeDashMediaSourceFactory().createMediaSource(dashManifest,
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
@ -495,12 +522,11 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
.build()); .build());
} }
@NonNull private static ProgressiveMediaSource buildYoutubeProgressiveMediaSource(
private static <T extends Stream> ProgressiveMediaSource buildYoutubeProgressiveMediaSource( final PlayerDataSource dataSource,
@NonNull final PlayerDataSource dataSource, final Stream stream,
@NonNull final T stream, final String cacheKey,
@NonNull final String cacheKey, final MediaItemTag metadata) {
@NonNull final MediaItemTag metadata) {
return dataSource.getYoutubeProgressiveMediaSourceFactory() return dataSource.getYoutubeProgressiveMediaSourceFactory()
.createMediaSource(new MediaItem.Builder() .createMediaSource(new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
@ -508,4 +534,5 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} }
//endregion
} }