Solve some review comments

This commit is contained in:
Stypox 2022-05-18 12:39:41 +02:00 committed by TiA4f8R
parent c33d392958
commit 044639c32b
No known key found for this signature in database
GPG key ID: E6D3E7F5949450DD
5 changed files with 63 additions and 121 deletions

View file

@ -5,6 +5,7 @@ import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException; import com.grack.nanojson.JsonParserException;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.StreamingService; import org.schabi.newpipe.extractor.StreamingService;
@ -80,9 +81,11 @@ public class BandcampRadioStreamExtractor extends BandcampStreamExtractor {
@Nonnull @Nonnull
@Override @Override
public String getUploaderName() { public String getUploaderName() throws ParsingException {
return Jsoup.parse(showInfo.getString("image_caption")) return Jsoup.parse(showInfo.getString("image_caption")).getElementsByTag("a").stream()
.getElementsByTag("a").first().text(); .map(Element::text)
.findFirst()
.orElseThrow(() -> new ParsingException("Could not get uploader name"));
} }
@Nullable @Nullable

View file

@ -4,7 +4,7 @@ package org.schabi.newpipe.extractor.services.youtube;
* Streaming format types used by YouTube in their streams. * Streaming format types used by YouTube in their streams.
* *
* <p> * <p>
* It is different of {@link org.schabi.newpipe.extractor.stream.DeliveryMethod delivery methods}! * It is different from {@link org.schabi.newpipe.extractor.stream.DeliveryMethod delivery methods}!
* </p> * </p>
*/ */
public enum DeliveryType { public enum DeliveryType {

View file

@ -83,59 +83,18 @@ public final class YoutubeDashManifestCreatorsUtils {
*/ */
public static final String ALR_YES = "&alr=yes"; public static final String ALR_YES = "&alr=yes";
/** // XML elements of DASH MPD manifests
* Constant which represents the {@code MPD} element of DASH manifests. // see https://www.brendanlong.com/the-structure-of-an-mpeg-dash-mpd.html
*/
public static final String MPD = "MPD"; public static final String MPD = "MPD";
/**
* Constant which represents the {@code Period} element of DASH manifests.
*/
public static final String PERIOD = "Period"; public static final String PERIOD = "Period";
/**
* Constant which represents the {@code AdaptationSet} element of DASH manifests.
*/
public static final String ADAPTATION_SET = "AdaptationSet"; public static final String ADAPTATION_SET = "AdaptationSet";
/**
* Constant which represents the {@code Role} element of DASH manifests.
*/
public static final String ROLE = "Role"; public static final String ROLE = "Role";
/**
* Constant which represents the {@code Representation} element of DASH manifests.
*/
public static final String REPRESENTATION = "Representation"; public static final String REPRESENTATION = "Representation";
/**
* Constant which represents the {@code AudioChannelConfiguration} element of DASH manifests.
*/
public static final String AUDIO_CHANNEL_CONFIGURATION = "AudioChannelConfiguration"; public static final String AUDIO_CHANNEL_CONFIGURATION = "AudioChannelConfiguration";
/**
* Constant which represents the {@code SegmentTemplate} element of DASH manifests.
*/
public static final String SEGMENT_TEMPLATE = "SegmentTemplate"; public static final String SEGMENT_TEMPLATE = "SegmentTemplate";
/**
* Constant which represents the {@code SegmentTimeline} element of DASH manifests.
*/
public static final String SEGMENT_TIMELINE = "SegmentTimeline"; public static final String SEGMENT_TIMELINE = "SegmentTimeline";
/**
* Constant which represents the {@code SegmentBase} element of DASH manifests.
*/
public static final String BASE_URL = "BaseURL"; public static final String BASE_URL = "BaseURL";
/**
* Constant which represents the {@code SegmentBase} element of DASH manifests.
*/
public static final String SEGMENT_BASE = "SegmentBase"; public static final String SEGMENT_BASE = "SegmentBase";
/**
* Constant which represents the {@code Initialization} element of DASH manifests.
*/
public static final String INITIALIZATION = "Initialization"; public static final String INITIALIZATION = "Initialization";
/** /**
@ -665,7 +624,7 @@ public final class YoutubeDashManifestCreatorsUtils {
if (isHtml5StreamingUrl) { if (isHtml5StreamingUrl) {
baseStreamingUrl += ALR_YES; baseStreamingUrl += ALR_YES;
} }
baseStreamingUrl = appendRnParamAndSqParamIfNeeded(baseStreamingUrl, deliveryType); baseStreamingUrl = appendRnSqParamsIfNeeded(baseStreamingUrl, deliveryType);
final Downloader downloader = NewPipe.getDownloader(); final Downloader downloader = NewPipe.getDownloader();
if (isHtml5StreamingUrl) { if (isHtml5StreamingUrl) {
@ -701,7 +660,7 @@ public final class YoutubeDashManifestCreatorsUtils {
* {@link XMLConstants#ACCESS_EXTERNAL_SCHEMA} in {@link DocumentBuilderFactory} instances. * {@link XMLConstants#ACCESS_EXTERNAL_SCHEMA} in {@link DocumentBuilderFactory} instances.
* *
* @return an instance of {@link Document} secured against XXE attacks on supported platforms, * @return an instance of {@link Document} secured against XXE attacks on supported platforms,
* that should then be convertible to an XML string without security problems * that should then be convertible to an XML string without security problems
*/ */
private static Document newDocument() throws ParserConfigurationException { private static Document newDocument() throws ParserConfigurationException {
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
@ -709,8 +668,8 @@ public final class YoutubeDashManifestCreatorsUtils {
documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
} catch (final Exception ignored) { } catch (final Exception ignored) {
// Ignore exceptions as setting these attributes to secure XML generation is supported // Ignore exceptions as setting these attributes to secure XML generation is not
// by all platforms (like the Android implementation) // supported by all platforms (like the Android implementation)
} }
final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); final DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
@ -736,8 +695,8 @@ public final class YoutubeDashManifestCreatorsUtils {
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, ""); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
} catch (final Exception ignored) { } catch (final Exception ignored) {
// Ignore exceptions as setting these attributes to secure XML generation is supported // Ignore exceptions as setting these attributes to secure XML generation is not
// by all platforms (like the Android implementation) // supported by all platforms (like the Android implementation)
} }
final Transformer transformer = transformerFactory.newTransformer(); final Transformer transformer = transformerFactory.newTransformer();
@ -759,16 +718,10 @@ public final class YoutubeDashManifestCreatorsUtils {
* @return the base streaming URL to which the param(s) are appended, depending on the * @return the base streaming URL to which the param(s) are appended, depending on the
* {@link DeliveryType} of the stream * {@link DeliveryType} of the stream
*/ */
@SuppressWarnings({"checkstyle:FinalParameters", "checkstyle:FinalLocalVariable"})
@Nonnull @Nonnull
private static String appendRnParamAndSqParamIfNeeded( private static String appendRnSqParamsIfNeeded(@Nonnull final String baseStreamingUrl,
@Nonnull String baseStreamingUrl, @Nonnull final DeliveryType deliveryType) {
@Nonnull final DeliveryType deliveryType) { return baseStreamingUrl + (deliveryType == DeliveryType.PROGRESSIVE ? "" : SQ_0) + RN_0;
if (deliveryType != DeliveryType.PROGRESSIVE) {
baseStreamingUrl += SQ_0;
}
return baseStreamingUrl + RN_0;
} }
/** /**

View file

@ -1140,17 +1140,11 @@ public class YoutubeStreamExtractor extends StreamExtractor {
return videoSecondaryInfoRenderer; return videoSecondaryInfoRenderer;
} }
@FunctionalInterface
private interface StreamBuilderHelper<T extends Stream> {
@Nonnull
T buildStream(ItagInfo itagInfo);
}
@Nonnull @Nonnull
private <T extends Stream> List<T> getItags( private <T extends Stream> List<T> getItags(
final String streamingDataKey, final String streamingDataKey,
final ItagItem.ItagType itagTypeWanted, final ItagItem.ItagType itagTypeWanted,
final StreamBuilderHelper<T> streamBuilderHelper, final java.util.function.Function<ItagInfo, T> streamBuilderHelper,
final String streamTypeExceptionMessage) throws ParsingException { final String streamTypeExceptionMessage) throws ParsingException {
try { try {
final List<ItagInfo> itagInfos = new ArrayList<>(); final List<ItagInfo> itagInfos = new ArrayList<>();
@ -1176,7 +1170,7 @@ public class YoutubeStreamExtractor extends StreamExtractor {
final List<T> streamList = new ArrayList<>(); final List<T> streamList = new ArrayList<>();
for (final ItagInfo itagInfo : itagInfos) { for (final ItagInfo itagInfo : itagInfos) {
final T stream = streamBuilderHelper.buildStream(itagInfo); final T stream = streamBuilderHelper.apply(itagInfo);
if (!Stream.containSimilarStream(stream, streamList)) { if (!Stream.containSimilarStream(stream, streamList)) {
streamList.add(stream); streamList.add(stream);
} }
@ -1190,8 +1184,8 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} }
/** /**
* Get the {@link StreamBuilderHelper} which will be used to build {@link AudioStream}s in * Get the stream builder helper which will be used to build {@link AudioStream}s in
* {@link #getItags(String, ItagItem.ItagType, StreamBuilderHelper, String)} * {@link #getItags(String, ItagItem.ItagType, java.util.function.Function, String)}
* *
* <p> * <p>
* The {@code StreamBuilderHelper} will set the following attributes in the * The {@code StreamBuilderHelper} will set the following attributes in the
@ -1213,38 +1207,34 @@ public class YoutubeStreamExtractor extends StreamExtractor {
* Note that the {@link ItagItem} comes from an {@link ItagInfo} instance. * Note that the {@link ItagItem} comes from an {@link ItagInfo} instance.
* </p> * </p>
* *
* @return a {@link StreamBuilderHelper} to build {@link AudioStream}s * @return a stream builder helper to build {@link AudioStream}s
*/ */
@Nonnull @Nonnull
private StreamBuilderHelper<AudioStream> getAudioStreamBuilderHelper() { private java.util.function.Function<ItagInfo, AudioStream> getAudioStreamBuilderHelper() {
return new StreamBuilderHelper<AudioStream>() { return (itagInfo) -> {
@Nonnull final ItagItem itagItem = itagInfo.getItagItem();
@Override final AudioStream.Builder builder = new AudioStream.Builder()
public AudioStream buildStream(@Nonnull final ItagInfo itagInfo) { .setId(String.valueOf(itagItem.id))
final ItagItem itagItem = itagInfo.getItagItem(); .setContent(itagInfo.getContent(), itagInfo.getIsUrl())
final AudioStream.Builder builder = new AudioStream.Builder() .setMediaFormat(itagItem.getMediaFormat())
.setId(String.valueOf(itagItem.id)) .setAverageBitrate(itagItem.getAverageBitrate())
.setContent(itagInfo.getContent(), itagInfo.getIsUrl()) .setItagItem(itagItem);
.setMediaFormat(itagItem.getMediaFormat())
.setAverageBitrate(itagItem.getAverageBitrate())
.setItagItem(itagItem);
if (streamType == StreamType.LIVE_STREAM if (streamType == StreamType.LIVE_STREAM
|| streamType == StreamType.POST_LIVE_STREAM || streamType == StreamType.POST_LIVE_STREAM
|| !itagInfo.getIsUrl()) { || !itagInfo.getIsUrl()) {
// For YouTube videos on OTF streams and for all streams of post-live streams // For YouTube videos on OTF streams and for all streams of post-live streams
// and live streams, only the DASH delivery method can be used. // and live streams, only the DASH delivery method can be used.
builder.setDeliveryMethod(DeliveryMethod.DASH); builder.setDeliveryMethod(DeliveryMethod.DASH);
}
return builder.build();
} }
return builder.build();
}; };
} }
/** /**
* Get the {@link StreamBuilderHelper} which will be used to build {@link VideoStream}s in * Get the stream builder helper which will be used to build {@link VideoStream}s in
* {@link #getItags(String, ItagItem.ItagType, StreamBuilderHelper, String)} * {@link #getItags(String, ItagItem.ItagType, java.util.function.Function, String)}
* *
* <p> * <p>
* The {@code StreamBuilderHelper} will set the following attributes in the * The {@code StreamBuilderHelper} will set the following attributes in the
@ -1272,37 +1262,33 @@ public class YoutubeStreamExtractor extends StreamExtractor {
* Note that the {@link ItagItem} comes from an {@link ItagInfo} instance. * Note that the {@link ItagItem} comes from an {@link ItagInfo} instance.
* </p> * </p>
* *
* @param areStreamsVideoOnly whether the {@link StreamBuilderHelper} will set the video * @param areStreamsVideoOnly whether the stream builder helper will set the video
* streams as video-only streams * streams as video-only streams
* @return a {@link StreamBuilderHelper} to build {@link VideoStream}s * @return a stream builder helper to build {@link VideoStream}s
*/ */
@Nonnull @Nonnull
private StreamBuilderHelper<VideoStream> getVideoStreamBuilderHelper( private java.util.function.Function<ItagInfo, VideoStream> getVideoStreamBuilderHelper(
final boolean areStreamsVideoOnly) { final boolean areStreamsVideoOnly) {
return new StreamBuilderHelper<VideoStream>() { return (itagInfo) -> {
@Nonnull final ItagItem itagItem = itagInfo.getItagItem();
@Override final VideoStream.Builder builder = new VideoStream.Builder()
public VideoStream buildStream(@Nonnull final ItagInfo itagInfo) { .setId(String.valueOf(itagItem.id))
final ItagItem itagItem = itagInfo.getItagItem(); .setContent(itagInfo.getContent(), itagInfo.getIsUrl())
final VideoStream.Builder builder = new VideoStream.Builder() .setMediaFormat(itagItem.getMediaFormat())
.setId(String.valueOf(itagItem.id)) .setIsVideoOnly(areStreamsVideoOnly)
.setContent(itagInfo.getContent(), itagInfo.getIsUrl()) .setItagItem(itagItem);
.setMediaFormat(itagItem.getMediaFormat())
.setIsVideoOnly(areStreamsVideoOnly)
.setItagItem(itagItem);
final String resolutionString = itagItem.getResolutionString(); final String resolutionString = itagItem.getResolutionString();
builder.setResolution(resolutionString != null ? resolutionString builder.setResolution(resolutionString != null ? resolutionString
: EMPTY_STRING); : EMPTY_STRING);
if (streamType != StreamType.VIDEO_STREAM || !itagInfo.getIsUrl()) { if (streamType != StreamType.VIDEO_STREAM || !itagInfo.getIsUrl()) {
// For YouTube videos on OTF streams and for all streams of post-live streams // For YouTube videos on OTF streams and for all streams of post-live streams
// and live streams, only the DASH delivery method can be used. // and live streams, only the DASH delivery method can be used.
builder.setDeliveryMethod(DeliveryMethod.DASH); builder.setDeliveryMethod(DeliveryMethod.DASH);
}
return builder.build();
} }
return builder.build();
}; };
} }

View file

@ -114,7 +114,7 @@ public class StreamInfo extends Info {
final String name = extractor.getName(); final String name = extractor.getName();
final int ageLimit = extractor.getAgeLimit(); final int ageLimit = extractor.getAgeLimit();
// Suppress always-non-null warning as here we double-check it is really not null // Suppress always-non-null warning as here we double-check it really is not null
//noinspection ConstantConditions //noinspection ConstantConditions
if (streamType == StreamType.NONE if (streamType == StreamType.NONE
|| isNullOrEmpty(url) || isNullOrEmpty(url)