Skip to content

Commit 4da05af

Browse files
StypoxAudricV
authored andcommitted
[YouTube] Inline collectSegmentsData in YoutubeDashManifestCreator
1 parent 3708ab9 commit 4da05af

1 file changed

Lines changed: 42 additions & 91 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreator.java

Lines changed: 42 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
package org.schabi.newpipe.extractor.services.youtube;
22

3+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.addClientInfoHeaders;
4+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getAndroidUserAgent;
5+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getIosUserAgent;
6+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isAndroidStreamingUrl;
7+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isIosStreamingUrl;
8+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isTvHtml5SimplyEmbeddedPlayerStreamingUrl;
9+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
10+
import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING;
11+
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
12+
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
13+
314
import org.schabi.newpipe.extractor.MediaFormat;
415
import org.schabi.newpipe.extractor.NewPipe;
516
import org.schabi.newpipe.extractor.downloader.Downloader;
@@ -12,21 +23,9 @@
1223
import org.w3c.dom.Document;
1324
import org.w3c.dom.Element;
1425

15-
import javax.annotation.Nonnull;
16-
import javax.xml.XMLConstants;
17-
import javax.xml.parsers.DocumentBuilder;
18-
import javax.xml.parsers.DocumentBuilderFactory;
19-
import javax.xml.parsers.ParserConfigurationException;
20-
import javax.xml.transform.OutputKeys;
21-
import javax.xml.transform.Transformer;
22-
import javax.xml.transform.TransformerException;
23-
import javax.xml.transform.TransformerFactory;
24-
import javax.xml.transform.dom.DOMSource;
25-
import javax.xml.transform.stream.StreamResult;
2626
import java.io.IOException;
2727
import java.io.StringWriter;
2828
import java.nio.charset.StandardCharsets;
29-
import java.util.ArrayList;
3029
import java.util.Arrays;
3130
import java.util.Collections;
3231
import java.util.HashMap;
@@ -35,16 +34,17 @@
3534
import java.util.Map;
3635
import java.util.Objects;
3736

38-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.addClientInfoHeaders;
39-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getAndroidUserAgent;
40-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getIosUserAgent;
41-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isAndroidStreamingUrl;
42-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isIosStreamingUrl;
43-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isTvHtml5SimplyEmbeddedPlayerStreamingUrl;
44-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
45-
import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING;
46-
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
47-
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
37+
import javax.annotation.Nonnull;
38+
import javax.xml.XMLConstants;
39+
import javax.xml.parsers.DocumentBuilder;
40+
import javax.xml.parsers.DocumentBuilderFactory;
41+
import javax.xml.parsers.ParserConfigurationException;
42+
import javax.xml.transform.OutputKeys;
43+
import javax.xml.transform.Transformer;
44+
import javax.xml.transform.TransformerException;
45+
import javax.xml.transform.TransformerFactory;
46+
import javax.xml.transform.dom.DOMSource;
47+
import javax.xml.transform.stream.StreamResult;
4848

4949
/**
5050
* Class to generate DASH manifests from YouTube OTF, progressive and ended/post-live-DVR streams.
@@ -74,28 +74,6 @@ public final class YoutubeDashManifestCreator {
7474
*/
7575
private static final int MAXIMUM_REDIRECT_COUNT = 20;
7676

77-
/**
78-
* A list of durations of segments of an OTF stream.
79-
*
80-
* <p>
81-
* This list is automatically cleared in the execution of
82-
* {@link #fromOtfStreamingUrl(String, ItagItem, long)}, before the DASH
83-
* manifest is converted to a string.
84-
* </p>
85-
*/
86-
private static final List<Integer> SEGMENTS_DURATION = new ArrayList<>();
87-
88-
/**
89-
* A list of contiguous repetitions of durations of an OTF stream.
90-
*
91-
* <p>
92-
* This list is automatically cleared in the execution of
93-
* {@link #fromOtfStreamingUrl(String, ItagItem, long)}, before the DASH
94-
* manifest is converted to a string.
95-
* </p>
96-
*/
97-
private static final List<Integer> DURATION_REPETITIONS = new ArrayList<>();
98-
9977
/**
10078
* Cache of DASH manifests generated for OTF streams.
10179
*/
@@ -296,11 +274,7 @@ public static String fromOtfStreamingUrl(
296274
}
297275
generateSegmentTemplateElement(document, realOtfBaseStreamingUrl, DeliveryType.OTF);
298276
generateSegmentTimelineElement(document);
299-
collectSegmentsData(segmentDuration);
300-
generateSegmentElementsForOtfStreams(document);
301-
302-
SEGMENTS_DURATION.clear();
303-
DURATION_REPETITIONS.clear();
277+
generateSegmentElementsForOtfStreams(segmentDuration, document);
304278

305279
return buildAndCacheResult(otfBaseStreamingUrl, document, OTF_CACHE);
306280
}
@@ -721,35 +695,6 @@ private static Response getStreamingWebUrlWithoutRedirects(
721695
}
722696
}
723697

724-
/**
725-
* Collect all segments from an OTF stream, by parsing the string array which contains all the
726-
* sequences.
727-
*
728-
* @param segmentDuration the string array which contains all the sequences extracted with the
729-
* regular expression
730-
*/
731-
private static void collectSegmentsData(@Nonnull final String[] segmentDuration)
732-
throws YoutubeDashManifestCreationException {
733-
try {
734-
for (final String segDuration : segmentDuration) {
735-
final String[] segmentLengthRepeat = segDuration.split("\\(r=");
736-
int segmentRepeatCount = 0;
737-
// There are repetitions of a segment duration in other segments
738-
if (segmentLengthRepeat.length > 1) {
739-
segmentRepeatCount = Integer.parseInt(Utils.removeNonDigitCharacters(
740-
segmentLengthRepeat[1]));
741-
}
742-
final int segmentLength = Integer.parseInt(segmentLengthRepeat[0]);
743-
SEGMENTS_DURATION.add(segmentLength);
744-
DURATION_REPETITIONS.add(segmentRepeatCount);
745-
}
746-
} catch (final NumberFormatException e) {
747-
throw new YoutubeDashManifestCreationException(
748-
"Could not generate the DASH manifest: unable to get the segments of the "
749-
+ "stream", e);
750-
}
751-
}
752-
753698
/**
754699
* Get the duration of an OTF stream.
755700
*
@@ -1429,8 +1374,7 @@ private static void generateSegmentTimelineElement(@Nonnull final Document docum
14291374
*
14301375
* <p>
14311376
* By parsing by the first media sequence, we know how many durations and repetitions there are
1432-
* so we just have to loop into {@link #SEGMENTS_DURATION} and {@link #DURATION_REPETITIONS}
1433-
* to generate the following element for each duration:
1377+
* so we just have to loop into segment durations to generate the following elements for each:
14341378
* </p>
14351379
*
14361380
* <p>
@@ -1451,36 +1395,43 @@ private static void generateSegmentTimelineElement(@Nonnull final Document docum
14511395
* {@link #generateSegmentTimelineElement(Document)}.
14521396
* </p>
14531397
*
1398+
* @param segmentDurations the sequences "length" or "length(r=repeat_count" extracted with the
1399+
* regexes
14541400
* @param document the {@link Document} on which the the {@code <S>} elements will be appended
14551401
*/
1456-
private static void generateSegmentElementsForOtfStreams(@Nonnull final Document document)
1402+
private static void generateSegmentElementsForOtfStreams(final String[] segmentDurations,
1403+
final Document document)
14571404
throws YoutubeDashManifestCreationException {
1405+
14581406
try {
1459-
if (SEGMENTS_DURATION.isEmpty() || DURATION_REPETITIONS.isEmpty()) {
1460-
throw new IllegalStateException(
1461-
"Duration of segments and/or repetition(s) of segments are unknown");
1462-
}
14631407
final Element segmentTimelineElement = (Element) document.getElementsByTagName(
14641408
"SegmentTimeline").item(0);
14651409

1466-
for (int i = 0; i < SEGMENTS_DURATION.size(); i++) {
1410+
for (final String segmentDuration : segmentDurations) {
14671411
final Element sElement = document.createElement("S");
14681412

1469-
final int durationRepetition = DURATION_REPETITIONS.get(i);
1470-
if (durationRepetition != 0) {
1413+
final String[] segmentLengthRepeat = segmentDuration.split("\\(r=");
1414+
// make sure segmentLengthRepeat[0], which is the length, is convertible to int
1415+
Integer.parseInt(segmentLengthRepeat[0]);
1416+
1417+
// There are repetitions of a segment duration in other segments
1418+
if (segmentLengthRepeat.length > 1) {
1419+
final int segmentRepeatCount = Integer.parseInt(
1420+
Utils.removeNonDigitCharacters(segmentLengthRepeat[1]));
14711421
final Attr rAttribute = document.createAttribute("r");
1472-
rAttribute.setValue(String.valueOf(durationRepetition));
1422+
rAttribute.setValue(String.valueOf(segmentRepeatCount));
14731423
sElement.setAttributeNode(rAttribute);
14741424
}
14751425

14761426
final Attr dAttribute = document.createAttribute("d");
1477-
dAttribute.setValue(String.valueOf(SEGMENTS_DURATION.get(i)));
1427+
dAttribute.setValue(segmentLengthRepeat[0]);
14781428
sElement.setAttributeNode(dAttribute);
14791429

14801430
segmentTimelineElement.appendChild(sElement);
14811431
}
14821432

1483-
} catch (final DOMException | IllegalStateException | IndexOutOfBoundsException e) {
1433+
} catch (final DOMException | IllegalStateException | IndexOutOfBoundsException
1434+
| NumberFormatException e) {
14841435
throw new YoutubeDashManifestCreationException(
14851436
"Could not generate or append the segment (S) elements of the DASH manifest "
14861437
+ "to the document", e);

0 commit comments

Comments
 (0)