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,73 +249,49 @@ 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());
if (isNullOrEmpty(url)) {
throw new ResolverException(
"Try to generate a progressive media source from an empty string or from a "
+ "null object");
} else {
return dataSource.getProgressiveMediaSourceFactory().createMediaSource( return dataSource.getProgressiveMediaSourceFactory().createMediaSource(
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(Uri.parse(url)) .setUri(Uri.parse(stream.getContent()))
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} }
}
private static DashMediaSource buildDashMediaSource(final PlayerDataSource dataSource, private static DashMediaSource buildDashMediaSource(final PlayerDataSource dataSource,
final Stream stream, final Stream stream,
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 { try {
return dataSource.getDashMediaSourceFactory().createMediaSource( return dataSource.getDashMediaSourceFactory().createMediaSource(
createDashManifest(stream.getContent(), stream), createDashManifest(stream.getContent(), stream),
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(uri) .setUri(manifestUrlToUri(stream.getManifestUrl()))
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} catch (final IOException e) { } catch (final IOException e) {
throw new ResolverException( throw new ResolverException(
"Could not create a DASH media source/manifest from the manifest text"); "Could not create a DASH media source/manifest from the manifest text", e);
}
} }
} }
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,67 +299,50 @@ 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 = final NonUriHlsDataSourceFactory.Builder hlsDataSourceFactoryBuilder =
new NonUriHlsDataSourceFactory.Builder(); new NonUriHlsDataSourceFactory.Builder();
hlsDataSourceFactoryBuilder.setPlaylistString(stream.getContent()); hlsDataSourceFactoryBuilder.setPlaylistString(stream.getContent());
String manifestUrl = stream.getManifestUrl();
if (manifestUrl == null) {
manifestUrl = "";
}
return dataSource.getHlsMediaSourceFactory(hlsDataSourceFactoryBuilder) return dataSource.getHlsMediaSourceFactory(hlsDataSourceFactoryBuilder)
.createMediaSource(new MediaItem.Builder() .createMediaSource(new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(Uri.parse(manifestUrl)) .setUri(manifestUrlToUri(stream.getManifestUrl()))
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .build());
} }
}
private static SsMediaSource buildSSMediaSource(final PlayerDataSource dataSource, private static SsMediaSource buildSSMediaSource(final PlayerDataSource dataSource,
final Stream stream, final Stream stream,
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 Uri manifestUri = manifestUrlToUri(stream.getManifestUrl());
final SsManifest smoothStreamingManifest; final SsManifest smoothStreamingManifest;
try { try {
final ByteArrayInputStream smoothStreamingManifestInput = new ByteArrayInputStream( final ByteArrayInputStream smoothStreamingManifestInput = new ByteArrayInputStream(
stream.getContent().getBytes(StandardCharsets.UTF_8)); stream.getContent().getBytes(StandardCharsets.UTF_8));
smoothStreamingManifest = new SsManifestParser().parse(uri, smoothStreamingManifest = new SsManifestParser().parse(manifestUri,
smoothStreamingManifestInput); smoothStreamingManifestInput);
} catch (final IOException e) { } catch (final IOException e) {
throw new ResolverException("Error when parsing manual SS manifest", e); throw new ResolverException("Error when parsing manual SS manifest", e);
@ -394,11 +352,10 @@ public interface PlaybackResolver extends Resolver<StreamInfo, MediaSource> {
smoothStreamingManifest, smoothStreamingManifest,
new MediaItem.Builder() new MediaItem.Builder()
.setTag(metadata) .setTag(metadata)
.setUri(uri) .setUri(manifestUri)
.setCustomCacheKey(cacheKey) .setCustomCacheKey(cacheKey)
.build()); .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);