[YouTube] Make exception messages smaller

This commit is contained in:
Stypox 2022-05-01 19:30:36 +02:00 committed by TiA4f8R
parent 4da05afe11
commit 00bbe5eb4d
No known key found for this signature in database
GPG Key ID: E6D3E7F5949450DD

View File

@ -52,23 +52,6 @@ import javax.xml.transform.stream.StreamResult;
*/ */
public final class YoutubeDashManifestCreator { public final class YoutubeDashManifestCreator {
/**
* URL parameter of the first sequence for live, post-live-DVR and OTF streams.
*/
private static final String SQ_0 = "&sq=0";
/**
* URL parameter of the first stream request made by official clients.
*/
private static final String RN_0 = "&rn=0";
/**
* URL parameter specific to web clients. When this param is added, if a redirection occurs,
* the server will not redirect clients to the redirect URL. Instead, it will provide this URL
* as the response body.
*/
private static final String ALR_YES = "&alr=yes";
/** /**
* The redirect count limit that this class uses, which is the same limit as OkHttp. * The redirect count limit that this class uses, which is the same limit as OkHttp.
*/ */
@ -92,6 +75,28 @@ public final class YoutubeDashManifestCreator {
private static final ManifestCreatorCache<String, String> PROGRESSIVE_CACHE private static final ManifestCreatorCache<String, String> PROGRESSIVE_CACHE
= new ManifestCreatorCache<>(); = new ManifestCreatorCache<>();
/**
* URL parameter of the first sequence for live, post-live-DVR and OTF streams.
*/
private static final String SQ_0 = "&sq=0";
/**
* URL parameter of the first stream request made by official clients.
*/
private static final String RN_0 = "&rn=0";
/**
* URL parameter specific to web clients. When this param is added, if a redirection occurs,
* the server will not redirect clients to the redirect URL. Instead, it will provide this URL
* as the response body.
*/
private static final String ALR_YES = "&alr=yes";
public static final String SEGMENT_TIMELINE = "SegmentTimeline";
public static final String ADAPTATION_SET = "AdaptationSet";
public static final String REPRESENTATION = "Representation";
/** /**
* Enum of streaming format types used by YouTube in their streams. * Enum of streaming format types used by YouTube in their streams.
*/ */
@ -360,8 +365,7 @@ public final class YoutubeDashManifestCreator {
if (targetDurationSec <= 0) { if (targetDurationSec <= 0) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: the targetDurationSec value is less " "targetDurationSec value is <= 0: " + targetDurationSec);
+ "than or equal to 0 (" + targetDurationSec + ")");
} }
try { try {
@ -374,26 +378,22 @@ public final class YoutubeDashManifestCreator {
final int responseCode = response.responseCode(); final int responseCode = response.responseCode();
if (responseCode != 200) { if (responseCode != 200) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not get the initialization "
"Could not generate the DASH manifest: could not get the initialization " + "segment of the post-live-DVR stream: response code " + responseCode);
+ "segment of the post-live-DVR stream: response code "
+ responseCode);
} }
final Map<String, List<String>> responseHeaders = response.responseHeaders(); final Map<String, List<String>> responseHeaders = response.responseHeaders();
streamDuration = responseHeaders.get("X-Head-Time-Millis").get(0); streamDuration = responseHeaders.get("X-Head-Time-Millis").get(0);
segmentCount = responseHeaders.get("X-Head-Seqnum").get(0); segmentCount = responseHeaders.get("X-Head-Seqnum").get(0);
} catch (final IndexOutOfBoundsException e) { } catch (final IndexOutOfBoundsException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not get the value of the "
"Could not generate the DASH manifest: could not get the value of the " + "X-Head-Time-Millis or the X-Head-Seqnum header of the post-live-DVR"
+ "X-Head-Time-Millis or the X-Head-Seqnum header of the post-live-DVR" + "streaming URL", e);
+ "streaming URL", e);
} }
if (isNullOrEmpty(segmentCount)) { if (isNullOrEmpty(segmentCount)) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not get the number of segments "
"Could not generate the DASH manifest: could not get the number of segments of" + "of the post-live-DVR stream");
+ "the post-live-DVR stream");
} }
final Document document = generateDocumentAndMpdElement(new String[] {streamDuration}, final Document document = generateDocumentAndMpdElement(new String[] {streamDuration},
@ -481,12 +481,6 @@ public final class YoutubeDashManifestCreator {
.getSecond(); .getSecond();
} }
if (durationSecondsFallback <= 0) {
throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: the durationSecondsFallback value is"
+ "less than or equal to 0 (" + durationSecondsFallback + ")");
}
final Document document = generateDocumentAndMpdElement(new String[]{}, final Document document = generateDocumentAndMpdElement(new String[]{},
DeliveryType.PROGRESSIVE, itagItem, durationSecondsFallback); DeliveryType.PROGRESSIVE, itagItem, durationSecondsFallback);
generatePeriodElement(document); generatePeriodElement(document);
@ -555,19 +549,16 @@ public final class YoutubeDashManifestCreator {
final byte[] emptyBody = "".getBytes(StandardCharsets.UTF_8); final byte[] emptyBody = "".getBytes(StandardCharsets.UTF_8);
return downloader.post(baseStreamingUrl, headers, emptyBody); return downloader.post(baseStreamingUrl, headers, emptyBody);
} catch (final IOException | ExtractionException e) { } catch (final IOException | ExtractionException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not get the "
"Could not generate the DASH manifest: error when trying to get the " + (isAnIosStreamingUrl ? "ANDROID" : "IOS") + " streaming URL response", e);
+ (isAnIosStreamingUrl ? "ANDROID" : "IOS")
+ " streaming URL response", e);
} }
} }
try { try {
return downloader.get(baseStreamingUrl); return downloader.get(baseStreamingUrl);
} catch (final IOException | ExtractionException e) { } catch (final IOException | ExtractionException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not get the streaming URL "
"Could not generate the DASH manifest: error when trying to get the streaming " + "response", e);
+ "URL response", e);
} }
} }
@ -640,33 +631,15 @@ public final class YoutubeDashManifestCreator {
final int responseCode = response.responseCode(); final int responseCode = response.responseCode();
if (responseCode != 200) { if (responseCode != 200) {
if (deliveryType == DeliveryType.LIVE) { throw new YoutubeDashManifestCreationException("Could not get the "
throw new YoutubeDashManifestCreationException( + "initialization URL of the " + deliveryType
"Could not generate the DASH manifest: could not get the " + " stream: response code " + responseCode);
+ "initialization URL of the post-live-DVR stream: "
+ "response code " + responseCode);
} else if (deliveryType == DeliveryType.OTF) {
throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: could not get the "
+ "initialization URL of the OTF stream: response code "
+ responseCode);
} else {
throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: could not fetch the URL of "
+ "the progressive stream: response code " + responseCode);
}
} }
// A valid response must include a Content-Type header, so we can require that // A valid response must include a Content-Type header, so we can require that
// the response from video servers has this header. // the response from video servers has this header.
try { responseMimeType = Objects.requireNonNull(response.getHeader("Content-Type"),
responseMimeType = Objects.requireNonNull(response.getHeader( "Could not get the Content-Type header from the streaming URL");
"Content-Type"));
} catch (final NullPointerException e) {
throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: could not get the Content-Type "
+ "header from the streaming URL", e);
}
// The response body is the redirection URL // The response body is the redirection URL
if (responseMimeType.equals("text/plain")) { if (responseMimeType.equals("text/plain")) {
@ -679,19 +652,16 @@ public final class YoutubeDashManifestCreator {
if (redirectsCount >= MAXIMUM_REDIRECT_COUNT) { if (redirectsCount >= MAXIMUM_REDIRECT_COUNT) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: too many redirects when trying to " "Too many redirects when trying to get the WEB streaming URL response");
+ "get the WEB streaming URL response");
} }
// This should never be reached, but is required because we don't want to return null // This should never be reached, but is required because we don't want to return null
// here // here
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: error when trying to get the WEB " "Could not get the WEB streaming URL response: unreachable code reached!");
+ "streaming URL response");
} catch (final IOException | ExtractionException e) { } catch (final IOException | ExtractionException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: error when trying to get the WEB " "Could not get the WEB streaming URL response", e);
+ "streaming URL response", e);
} }
} }
@ -724,8 +694,7 @@ public final class YoutubeDashManifestCreator {
} }
return streamLengthMs; return streamLengthMs;
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Unable to get the length of the stream",
"Could not generate the DASH manifest: unable to get the length of the stream",
e); e);
} }
} }
@ -813,11 +782,9 @@ public final class YoutubeDashManifestCreator {
if (durationSecondsFallback > 0) { if (durationSecondsFallback > 0) {
streamDuration = durationSecondsFallback * 1000; streamDuration = durationSecondsFallback * 1000;
} else { } else {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add MPD element: "
"Could not generate or append the MPD element of the DASH " + "the duration of the stream could not be determined and the "
+ "manifest to the document: the duration of the stream " + "durationSecondsFallback is <= 0");
+ "could not be determined and the "
+ "durationSecondsFallback is less than or equal to 0");
} }
} }
} }
@ -828,9 +795,7 @@ public final class YoutubeDashManifestCreator {
return document; return document;
} catch (final Exception e) { } catch (final Exception e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add MPD element", e);
"Could not generate or append the MPD element of the DASH manifest to the "
+ "document", e);
} }
} }
@ -852,9 +817,7 @@ public final class YoutubeDashManifestCreator {
final Element periodElement = document.createElement("Period"); final Element periodElement = document.createElement("Period");
mpdElement.appendChild(periodElement); mpdElement.appendChild(periodElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Period element", e);
"Could not generate or append the Period element of the DASH manifest to the "
+ "document", e);
} }
} }
@ -876,7 +839,7 @@ public final class YoutubeDashManifestCreator {
try { try {
final Element periodElement = (Element) document.getElementsByTagName("Period") final Element periodElement = (Element) document.getElementsByTagName("Period")
.item(0); .item(0);
final Element adaptationSetElement = document.createElement("AdaptationSet"); final Element adaptationSetElement = document.createElement(ADAPTATION_SET);
final Attr idAttribute = document.createAttribute("id"); final Attr idAttribute = document.createAttribute("id");
idAttribute.setValue("0"); idAttribute.setValue("0");
@ -884,10 +847,8 @@ public final class YoutubeDashManifestCreator {
final MediaFormat mediaFormat = itagItem.getMediaFormat(); final MediaFormat mediaFormat = itagItem.getMediaFormat();
if (mediaFormat == null || isNullOrEmpty(mediaFormat.mimeType)) { if (mediaFormat == null || isNullOrEmpty(mediaFormat.mimeType)) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add AdaptationSet "
"Could not generate the AdaptationSet element of the DASH manifest to the " + "element: the MediaFormat or its mime type are null or empty");
+ "document: the MediaFormat or the mime type of the MediaFormat "
+ "of the ItagItem is null or empty");
} }
final Attr mimeTypeAttribute = document.createAttribute("mimeType"); final Attr mimeTypeAttribute = document.createAttribute("mimeType");
@ -901,9 +862,8 @@ public final class YoutubeDashManifestCreator {
periodElement.appendChild(adaptationSetElement); periodElement.appendChild(adaptationSetElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add AdaptationSet element",
"Could not generate or append the AdaptationSet element of the DASH manifest " e);
+ "to the document", e);
} }
} }
@ -931,7 +891,7 @@ public final class YoutubeDashManifestCreator {
throws YoutubeDashManifestCreationException { throws YoutubeDashManifestCreationException {
try { try {
final Element adaptationSetElement = (Element) document.getElementsByTagName( final Element adaptationSetElement = (Element) document.getElementsByTagName(
"AdaptationSet").item(0); ADAPTATION_SET).item(0);
final Element roleElement = document.createElement("Role"); final Element roleElement = document.createElement("Role");
final Attr schemeIdUriAttribute = document.createAttribute("schemeIdUri"); final Attr schemeIdUriAttribute = document.createAttribute("schemeIdUri");
@ -944,9 +904,7 @@ public final class YoutubeDashManifestCreator {
adaptationSetElement.appendChild(roleElement); adaptationSetElement.appendChild(roleElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Role element", e);
"Could not generate or append the Role element of the DASH manifest to the "
+ "document", e);
} }
} }
@ -968,15 +926,13 @@ public final class YoutubeDashManifestCreator {
throws YoutubeDashManifestCreationException { throws YoutubeDashManifestCreationException {
try { try {
final Element adaptationSetElement = (Element) document.getElementsByTagName( final Element adaptationSetElement = (Element) document.getElementsByTagName(
"AdaptationSet").item(0); ADAPTATION_SET).item(0);
final Element representationElement = document.createElement("Representation"); final Element representationElement = document.createElement(REPRESENTATION);
final int id = itagItem.id; final int id = itagItem.id;
if (id <= 0) { if (id <= 0) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Representation "
"Could not generate the Representation element of the DASH manifest to " + "element: the id of the ItagItem is <= 0");
+ "the document: the id of the ItagItem is less than or equal to "
+ "0");
} }
final Attr idAttribute = document.createAttribute("id"); final Attr idAttribute = document.createAttribute("id");
idAttribute.setValue(String.valueOf(id)); idAttribute.setValue(String.valueOf(id));
@ -984,9 +940,8 @@ public final class YoutubeDashManifestCreator {
final String codec = itagItem.getCodec(); final String codec = itagItem.getCodec();
if (isNullOrEmpty(codec)) { if (isNullOrEmpty(codec)) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add AdaptationSet "
"Could not generate the AdaptationSet element of the DASH manifest to the " + "element: the codec value is null or empty");
+ "document: the codec value is null or empty");
} }
final Attr codecsAttribute = document.createAttribute("codecs"); final Attr codecsAttribute = document.createAttribute("codecs");
codecsAttribute.setValue(codec); codecsAttribute.setValue(codec);
@ -1002,10 +957,8 @@ public final class YoutubeDashManifestCreator {
final int bitrate = itagItem.getBitrate(); final int bitrate = itagItem.getBitrate();
if (bitrate <= 0) { if (bitrate <= 0) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Representation "
"Could not generate the Representation element of the DASH manifest to " + "element: the bitrate of the ItagItem is <= 0");
+ "the document: the bitrate of the ItagItem is less than or "
+ "equal to 0");
} }
final Attr bandwidthAttribute = document.createAttribute("bandwidth"); final Attr bandwidthAttribute = document.createAttribute("bandwidth");
bandwidthAttribute.setValue(String.valueOf(bitrate)); bandwidthAttribute.setValue(String.valueOf(bitrate));
@ -1017,10 +970,8 @@ public final class YoutubeDashManifestCreator {
final int height = itagItem.getHeight(); final int height = itagItem.getHeight();
final int width = itagItem.getWidth(); final int width = itagItem.getWidth();
if (height <= 0 && width <= 0) { if (height <= 0 && width <= 0) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Representation "
"Could not generate the Representation element of the DASH manifest " + "element: both width and height of the ItagItem are <= 0");
+ "to the document: the width and the height of the ItagItem "
+ "are less than or equal to 0");
} }
if (width > 0) { if (width > 0) {
@ -1049,9 +1000,8 @@ public final class YoutubeDashManifestCreator {
adaptationSetElement.appendChild(representationElement); adaptationSetElement.appendChild(representationElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Representation element",
"Could not generate or append the Representation element of the DASH manifest " e);
+ "to the document", e);
} }
} }
@ -1088,7 +1038,7 @@ public final class YoutubeDashManifestCreator {
@Nonnull final ItagItem itagItem) throws YoutubeDashManifestCreationException { @Nonnull final ItagItem itagItem) throws YoutubeDashManifestCreationException {
try { try {
final Element representationElement = (Element) document.getElementsByTagName( final Element representationElement = (Element) document.getElementsByTagName(
"Representation").item(0); REPRESENTATION).item(0);
final Element audioChannelConfigurationElement = document.createElement( final Element audioChannelConfigurationElement = document.createElement(
"AudioChannelConfiguration"); "AudioChannelConfiguration");
@ -1101,8 +1051,7 @@ public final class YoutubeDashManifestCreator {
final int audioChannels = itagItem.getAudioChannels(); final int audioChannels = itagItem.getAudioChannels();
if (audioChannels <= 0) { if (audioChannels <= 0) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: the audioChannels value is less " "audioChannels is <= 0: " + audioChannels);
+ "than or equal to 0 (" + audioChannels + ")");
} }
valueAttribute.setValue(String.valueOf(itagItem.getAudioChannels())); valueAttribute.setValue(String.valueOf(itagItem.getAudioChannels()));
audioChannelConfigurationElement.setAttributeNode(valueAttribute); audioChannelConfigurationElement.setAttributeNode(valueAttribute);
@ -1110,8 +1059,7 @@ public final class YoutubeDashManifestCreator {
representationElement.appendChild(audioChannelConfigurationElement); representationElement.appendChild(audioChannelConfigurationElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException(
"Could not generate or append the AudioChannelConfiguration element of the " "Could not add AudioChannelConfiguration element", e);
+ "DASH manifest to the document", e);
} }
} }
@ -1138,14 +1086,12 @@ public final class YoutubeDashManifestCreator {
throws YoutubeDashManifestCreationException { throws YoutubeDashManifestCreationException {
try { try {
final Element representationElement = (Element) document.getElementsByTagName( final Element representationElement = (Element) document.getElementsByTagName(
"Representation").item(0); REPRESENTATION).item(0);
final Element baseURLElement = document.createElement("BaseURL"); final Element baseURLElement = document.createElement("BaseURL");
baseURLElement.setTextContent(baseUrl); baseURLElement.setTextContent(baseUrl);
representationElement.appendChild(baseURLElement); representationElement.appendChild(baseURLElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add BaseURL element", e);
"Could not generate or append the BaseURL element of the DASH manifest to the "
+ "document", e);
} }
} }
@ -1180,33 +1126,22 @@ public final class YoutubeDashManifestCreator {
throws YoutubeDashManifestCreationException { throws YoutubeDashManifestCreationException {
try { try {
final Element representationElement = (Element) document.getElementsByTagName( final Element representationElement = (Element) document.getElementsByTagName(
"Representation").item(0); REPRESENTATION).item(0);
final Element segmentBaseElement = document.createElement("SegmentBase"); final Element segmentBaseElement = document.createElement("SegmentBase");
final Attr indexRangeAttribute = document.createAttribute("indexRange"); final Attr indexRangeAttribute = document.createAttribute("indexRange");
final int indexStart = itagItem.getIndexStart(); if (itagItem.getIndexStart() < 0 || itagItem.getIndexEnd() < 0) {
if (indexStart < 0) { throw new YoutubeDashManifestCreationException("ItagItem's indexStart or indexEnd "
throw new YoutubeDashManifestCreationException( + "are < 0: " + itagItem.getIndexStart() + "-" + itagItem.getIndexEnd());
"Could not generate the DASH manifest: the indexStart value of the "
+ "ItagItem is less than to 0 (" + indexStart + ")");
}
final int indexEnd = itagItem.getIndexEnd();
if (indexEnd < 0) {
throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: the indexEnd value of the ItagItem "
+ "is less than to 0 (" + indexStart + ")");
} }
indexRangeAttribute.setValue(indexStart + "-" + indexEnd); indexRangeAttribute.setValue(itagItem.getIndexStart() + "-" + itagItem.getIndexEnd());
segmentBaseElement.setAttributeNode(indexRangeAttribute); segmentBaseElement.setAttributeNode(indexRangeAttribute);
representationElement.appendChild(segmentBaseElement); representationElement.appendChild(segmentBaseElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add SegmentBase element", e);
"Could not generate or append the SegmentBase element of the DASH manifest to "
+ "the document", e);
} }
} }
@ -1244,30 +1179,20 @@ public final class YoutubeDashManifestCreator {
"SegmentBase").item(0); "SegmentBase").item(0);
final Element initializationElement = document.createElement("Initialization"); final Element initializationElement = document.createElement("Initialization");
final Attr rangeAttribute = document.createAttribute("range"); final Attr rangeAttribute = document.createAttribute("range");
final int initStart = itagItem.getInitStart(); if (itagItem.getInitStart() < 0 || itagItem.getInitEnd() < 0) {
if (initStart < 0) { throw new YoutubeDashManifestCreationException("ItagItem's initStart or initEnd "
throw new YoutubeDashManifestCreationException( + "are < 0: " + itagItem.getInitStart() + "-" + itagItem.getInitEnd());
"Could not generate the DASH manifest: the initStart value of the "
+ "ItagItem is less than to 0 (" + initStart + ")");
}
final int initEnd = itagItem.getInitEnd();
if (initEnd < 0) {
throw new YoutubeDashManifestCreationException(
"Could not generate the DASH manifest: the initEnd value of the ItagItem "
+ "is less than to 0 (" + initEnd + ")");
} }
rangeAttribute.setValue(initStart + "-" + initEnd); rangeAttribute.setValue(itagItem.getInitStart() + "-" + itagItem.getInitEnd());
initializationElement.setAttributeNode(rangeAttribute); initializationElement.setAttributeNode(rangeAttribute);
segmentBaseElement.appendChild(initializationElement); segmentBaseElement.appendChild(initializationElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add Initialization element",
"Could not generate or append the Initialization element of the DASH manifest " e);
+ "to the document", e);
} }
} }
@ -1308,7 +1233,7 @@ public final class YoutubeDashManifestCreator {
throws YoutubeDashManifestCreationException { throws YoutubeDashManifestCreationException {
try { try {
final Element representationElement = (Element) document.getElementsByTagName( final Element representationElement = (Element) document.getElementsByTagName(
"Representation").item(0); REPRESENTATION).item(0);
final Element segmentTemplateElement = document.createElement("SegmentTemplate"); final Element segmentTemplateElement = document.createElement("SegmentTemplate");
final Attr startNumberAttribute = document.createAttribute("startNumber"); final Attr startNumberAttribute = document.createAttribute("startNumber");
@ -1336,9 +1261,8 @@ public final class YoutubeDashManifestCreator {
representationElement.appendChild(segmentTemplateElement); representationElement.appendChild(segmentTemplateElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add SegmentTemplate element",
"Could not generate or append the SegmentTemplate element of the DASH " e);
+ "manifest to the document", e);
} }
} }
@ -1359,13 +1283,12 @@ public final class YoutubeDashManifestCreator {
try { try {
final Element segmentTemplateElement = (Element) document.getElementsByTagName( final Element segmentTemplateElement = (Element) document.getElementsByTagName(
"SegmentTemplate").item(0); "SegmentTemplate").item(0);
final Element segmentTimelineElement = document.createElement("SegmentTimeline"); final Element segmentTimelineElement = document.createElement(SEGMENT_TIMELINE);
segmentTemplateElement.appendChild(segmentTimelineElement); segmentTemplateElement.appendChild(segmentTimelineElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add SegmentTimeline element",
"Could not generate or append the SegmentTimeline element of the DASH " e);
+ "manifest to the document", e);
} }
} }
@ -1405,7 +1328,7 @@ public final class YoutubeDashManifestCreator {
try { try {
final Element segmentTimelineElement = (Element) document.getElementsByTagName( final Element segmentTimelineElement = (Element) document.getElementsByTagName(
"SegmentTimeline").item(0); SEGMENT_TIMELINE).item(0);
for (final String segmentDuration : segmentDurations) { for (final String segmentDuration : segmentDurations) {
final Element sElement = document.createElement("S"); final Element sElement = document.createElement("S");
@ -1432,9 +1355,7 @@ public final class YoutubeDashManifestCreator {
} catch (final DOMException | IllegalStateException | IndexOutOfBoundsException } catch (final DOMException | IllegalStateException | IndexOutOfBoundsException
| NumberFormatException e) { | NumberFormatException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add segment (S) elements", e);
"Could not generate or append the segment (S) elements of the DASH manifest "
+ "to the document", e);
} }
} }
@ -1462,7 +1383,7 @@ public final class YoutubeDashManifestCreator {
@Nonnull final String segmentCount) throws YoutubeDashManifestCreationException { @Nonnull final String segmentCount) throws YoutubeDashManifestCreationException {
try { try {
final Element segmentTimelineElement = (Element) document.getElementsByTagName( final Element segmentTimelineElement = (Element) document.getElementsByTagName(
"SegmentTimeline").item(0); SEGMENT_TIMELINE).item(0);
final Element sElement = document.createElement("S"); final Element sElement = document.createElement("S");
final Attr dAttribute = document.createAttribute("d"); final Attr dAttribute = document.createAttribute("d");
@ -1475,9 +1396,7 @@ public final class YoutubeDashManifestCreator {
segmentTimelineElement.appendChild(sElement); segmentTimelineElement.appendChild(sElement);
} catch (final DOMException e) { } catch (final DOMException e) {
throw new YoutubeDashManifestCreationException( throw new YoutubeDashManifestCreationException("Could not add segment (S) elements", e);
"Could not generate or append the segment (S) elements of the DASH manifest "
+ "to the document", e);
} }
} }