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
final StreamInfo streamInfo, private static MediaSource createYoutubeMediaSource(final Stream stream,
final PlayerDataSource dataSource, final StreamInfo streamInfo,
final String cacheKey, final PlayerDataSource dataSource,
final MediaItemTag metadata) throws IOException { final String cacheKey,
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
} }