11package 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+
314import org .schabi .newpipe .extractor .MediaFormat ;
415import org .schabi .newpipe .extractor .NewPipe ;
516import org .schabi .newpipe .extractor .downloader .Downloader ;
1223import org .w3c .dom .Document ;
1324import 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 ;
2626import java .io .IOException ;
2727import java .io .StringWriter ;
2828import java .nio .charset .StandardCharsets ;
29- import java .util .ArrayList ;
3029import java .util .Arrays ;
3130import java .util .Collections ;
3231import java .util .HashMap ;
3534import java .util .Map ;
3635import 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