Refactor PlaybackResolver and fix cacheKeyOf
In commonCacheKeyOf the result of an Objects.hash() was ignored
This commit is contained in:
parent
1e076ea63d
commit
2019af831a
1 changed files with 76 additions and 105 deletions
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue