Refactor PlaybackResolver and fix cacheKeyOf

In commonCacheKeyOf the result of an Objects.hash() was ignored
This commit is contained in:
Stypox 2022-06-18 18:41:44 +02:00
parent 1e076ea63d
commit 2019af831a
No known key found for this signature in database
GPG key ID: 4BDF1B40A49FDD23

View file

@ -2,7 +2,6 @@ package org.schabi.newpipe.player.resolver;
import static org.schabi.newpipe.extractor.stream.AudioStream.UNKNOWN_BITRATE; import static org.schabi.newpipe.extractor.stream.AudioStream.UNKNOWN_BITRATE;
import static org.schabi.newpipe.extractor.stream.VideoStream.RESOLUTION_UNKNOWN; import static org.schabi.newpipe.extractor.stream.VideoStream.RESOLUTION_UNKNOWN;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import static org.schabi.newpipe.player.helper.PlayerDataSource.LIVE_STREAM_EDGE_GAP_MILLIS; import static org.schabi.newpipe.player.helper.PlayerDataSource.LIVE_STREAM_EDGE_GAP_MILLIS;
import android.net.Uri; import android.net.Uri;
@ -88,7 +87,7 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
// cache useless. // cache useless.
if (resolutionOrBitrateUnknown && mediaFormat == null) { if (resolutionOrBitrateUnknown && mediaFormat == null) {
cacheKey.append(" "); cacheKey.append(" ");
Objects.hash(stream.getContent(), stream.getManifestUrl()); cacheKey.append(Objects.hash(stream.getContent(), stream.getManifestUrl()));
} }
return cacheKey; return cacheKey;
@ -250,20 +249,13 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
final Stream stream, final Stream stream,
final String cacheKey, final String cacheKey,
final MediaItemTag metadata) throws ResolverException { final MediaItemTag metadata) throws ResolverException {
final String url = stream.getContent(); throwResolverExceptionIfUrlNullOrEmpty(stream.getContent());
return dataSource.getProgressiveMediaSourceFactory().createMediaSource(
if (isNullOrEmpty(url)) { new MediaItem.Builder()
throw new ResolverException( .setTag(metadata)
"Try to generate a progressive media source from an empty string or from a " .setUri(Uri.parse(stream.getContent()))
+ "null object"); .setCustomCacheKey(cacheKey)
} else { .build());
return dataSource.getProgressiveMediaSourceFactory().createMediaSource(
new MediaItem.Builder()
.setTag(metadata)
.setUri(Uri.parse(url))
.setCustomCacheKey(cacheKey)
.build());
}
} }
private static DashMediaSource buildDashMediaSource(final PlayerDataSource dataSource, private static DashMediaSource buildDashMediaSource(final PlayerDataSource dataSource,
@ -271,52 +263,35 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
final String cacheKey, final String cacheKey,
final MediaItemTag metadata) final MediaItemTag metadata)
throws ResolverException { throws ResolverException {
final boolean isUrlStream = stream.isUrl();
if (isUrlStream && isNullOrEmpty(stream.getContent())) {
throw new ResolverException(
"Could not build a DASH media source from an empty or a null URL content");
}
if (isUrlStream) { if (stream.isUrl()) {
throwResolverExceptionIfUrlNullOrEmpty(stream.getContent());
return dataSource.getDashMediaSourceFactory().createMediaSource( return dataSource.getDashMediaSourceFactory().createMediaSource(
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(Uri.parse(stream.getContent())) .setUri(Uri.parse(stream.getContent()))
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} else { }
String baseUrl = stream.getManifestUrl();
if (baseUrl == null) {
baseUrl = "";
}
final Uri uri = Uri.parse(baseUrl); try {
return dataSource.getDashMediaSourceFactory().createMediaSource(
try { createDashManifest(stream.getContent(), stream),
return dataSource.getDashMediaSourceFactory().createMediaSource( new MediaItem.Builder()
createDashManifest(stream.getContent(), stream), .setTag(metadata)
new MediaItem.Builder() .setUri(manifestUrlToUri(stream.getManifestUrl()))
.setTag(metadata) .setCustomCacheKey(cacheKey)
.setUri(uri) .build());
.setCustomCacheKey(cacheKey) } catch (final IOException e) {
.build()); throw new ResolverException(
} catch (final IOException e) { "Could not create a DASH media source/manifest from the manifest text", e);
throw new ResolverException(
"Could not create a DASH media source/manifest from the manifest text");
}
} }
} }
private static DashManifest createDashManifest(final String manifestContent, private static DashManifest createDashManifest(final String manifestContent,
final Stream stream) throws IOException { final Stream stream) throws IOException {
final ByteArrayInputStream dashManifestInput = new ByteArrayInputStream( return new DashManifestParser().parse(manifestUrlToUri(stream.getManifestUrl()),
manifestContent.getBytes(StandardCharsets.UTF_8)); new ByteArrayInputStream(manifestContent.getBytes(StandardCharsets.UTF_8)));
String baseUrl = stream.getManifestUrl();
if (baseUrl == null) {
baseUrl = "";
}
return new DashManifestParser().parse(Uri.parse(baseUrl), dashManifestInput);
} }
private static HlsMediaSource buildHlsMediaSource(final PlayerDataSource dataSource, private static HlsMediaSource buildHlsMediaSource(final PlayerDataSource dataSource,
@ -324,34 +299,26 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
final String cacheKey, final String cacheKey,
final MediaItemTag metadata) final MediaItemTag metadata)
throws ResolverException { throws ResolverException {
final boolean isUrlStream = stream.isUrl(); if (stream.isUrl()) {
if (isUrlStream && isNullOrEmpty(stream.getContent())) { throwResolverExceptionIfUrlNullOrEmpty(stream.getContent());
throw new ResolverException(
"Could not build a HLS media source from an empty or a null URL content");
}
if (isUrlStream) {
return dataSource.getHlsMediaSourceFactory(null).createMediaSource( return dataSource.getHlsMediaSourceFactory(null).createMediaSource(
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(Uri.parse(stream.getContent())) .setUri(Uri.parse(stream.getContent()))
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} else {
final NonUriHlsDataSourceFactory.Builder hlsDataSourceFactoryBuilder =
new NonUriHlsDataSourceFactory.Builder();
hlsDataSourceFactoryBuilder.setPlaylistString(stream.getContent());
String manifestUrl = stream.getManifestUrl();
if (manifestUrl == null) {
manifestUrl = "";
}
return dataSource.getHlsMediaSourceFactory(hlsDataSourceFactoryBuilder)
.createMediaSource(new MediaItem.Builder()
.setTag(metadata)
.setUri(Uri.parse(manifestUrl))
.setCustomCacheKey(cacheKey)
.build());
} }
final NonUriHlsDataSourceFactory.Builder hlsDataSourceFactoryBuilder =
new NonUriHlsDataSourceFactory.Builder();
hlsDataSourceFactoryBuilder.setPlaylistString(stream.getContent());
return dataSource.getHlsMediaSourceFactory(hlsDataSourceFactoryBuilder)
.createMediaSource(new MediaItem.Builder()
.setTag(metadata)
.setUri(manifestUrlToUri(stream.getManifestUrl()))
.setCustomCacheKey(cacheKey)
.build());
} }
private static SsMediaSource buildSSMediaSource(final PlayerDataSource dataSource, private static SsMediaSource buildSSMediaSource(final PlayerDataSource dataSource,
@ -359,45 +326,35 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
final String cacheKey, final String cacheKey,
final MediaItemTag metadata) final MediaItemTag metadata)
throws ResolverException { throws ResolverException {
final boolean isUrlStream = stream.isUrl(); if (stream.isUrl()) {
if (isUrlStream && isNullOrEmpty(stream.getContent())) { throwResolverExceptionIfUrlNullOrEmpty(stream.getContent());
throw new ResolverException(
"Could not build a SS media source from an empty or a null URL content");
}
if (isUrlStream) {
return dataSource.getSSMediaSourceFactory().createMediaSource( return dataSource.getSSMediaSourceFactory().createMediaSource(
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(Uri.parse(stream.getContent())) .setUri(Uri.parse(stream.getContent()))
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} else {
String baseUrl = stream.getManifestUrl();
if (baseUrl == null) {
baseUrl = "";
}
final Uri uri = Uri.parse(baseUrl);
final SsManifest smoothStreamingManifest;
try {
final ByteArrayInputStream smoothStreamingManifestInput = new ByteArrayInputStream(
stream.getContent().getBytes(StandardCharsets.UTF_8));
smoothStreamingManifest = new SsManifestParser().parse(uri,
smoothStreamingManifestInput);
} catch (final IOException e) {
throw new ResolverException("Error when parsing manual SS manifest", e);
}
return dataSource.getSSMediaSourceFactory().createMediaSource(
smoothStreamingManifest,
new MediaItem.Builder()
.setTag(metadata)
.setUri(uri)
.setCustomCacheKey(cacheKey)
.build());
} }
final Uri manifestUri = manifestUrlToUri(stream.getManifestUrl());
final SsManifest smoothStreamingManifest;
try {
final ByteArrayInputStream smoothStreamingManifestInput = new ByteArrayInputStream(
stream.getContent().getBytes(StandardCharsets.UTF_8));
smoothStreamingManifest = new SsManifestParser().parse(manifestUri,
smoothStreamingManifestInput);
} catch (final IOException e) {
throw new ResolverException("Error when parsing manual SS manifest", e);
}
return dataSource.getSSMediaSourceFactory().createMediaSource(
smoothStreamingManifest,
new MediaItem.Builder()
.setTag(metadata)
.setUri(manifestUri)
.setCustomCacheKey(cacheKey)
.build());
} }
//endregion //endregion
@ -435,8 +392,6 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
createDashManifest(manifestString, stream), stream, cacheKey, createDashManifest(manifestString, stream), stream, cacheKey,
metadata); metadata);
} catch (final CreationException | IOException | NullPointerException e) { } catch (final CreationException | IOException | NullPointerException e) {
Log.e(TAG, "Error when generating the DASH manifest of YouTube ended live stream",
e);
throw new ResolverException( throw new ResolverException(
"Error when generating the DASH manifest of YouTube ended live stream", e); "Error when generating the DASH manifest of YouTube ended live stream", e);
} }
@ -540,7 +495,23 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
//endregion //endregion
//region resolver exception //region Utils
private static Uri manifestUrlToUri(final String manifestUrl) {
return Uri.parse(Objects.requireNonNullElse(manifestUrl, ""));
}
private static void throwResolverExceptionIfUrlNullOrEmpty(@Nullable final String url)
throws ResolverException {
if (url == null) {
throw new ResolverException("Null stream url");
} else if (url.isEmpty()) {
throw new ResolverException("Empty stream url");
}
}
//endregion
//region Resolver exception
final class ResolverException extends Exception { final class ResolverException extends Exception {
public ResolverException(final String message) { public ResolverException(final String message) {
super(message); super(message);