From 226213d727f94020780fc2eb146b89b7ba1542e3 Mon Sep 17 00:00:00 2001 From: Erik Zandvliet Date: Mon, 16 Sep 2024 11:27:50 +0200 Subject: [PATCH] Fixed errors and warnings triggered by issue #707 --- HbbTV_DVB/impl/dvbAudioChecks.php | 10 ++-- HbbTV_DVB/impl/dvbEventChecks.php | 2 +- HbbTV_DVB/impl/dvbMPDValidator.php | 21 +++++---- HbbTV_DVB/impl/dvbMpdAnchorCheck.php | 3 ++ HbbTV_DVB/impl/fallbackOperationChecks.php | 2 +- .../impl/mpdUpdateConstraintsWithinPeriod.php | 4 +- Utils/ArgumentsParser.php | 27 +++++------ Utils/MPDHandler.php | 13 ++++-- Utils/MPDUtility.php | 6 +-- Utils/Process_cli.php | 19 ++++---- .../MPDHandler/computeDynamicIntervals.php | 11 ++++- Utils/impl/MPDHandler/computeTiming.php | 12 ++--- Utils/impl/MPDHandler/computeUrls.php | 8 +++- .../MPDHandler/getDurationsForAllPeriods.php | 17 +++++-- Utils/impl/MPDHandler/getPeriodBaseUrl.php | 20 ++++++-- Utils/impl/MPDHandler/getPeriodTimingInfo.php | 3 -- Utils/impl/MPDHandler/load.php | 8 +++- Utils/impl/MPDHandler/loadSegmentUrls.php | 46 ++++++++++++------- 18 files changed, 146 insertions(+), 86 deletions(-) delete mode 100644 Utils/impl/MPDHandler/getPeriodTimingInfo.php diff --git a/HbbTV_DVB/impl/dvbAudioChecks.php b/HbbTV_DVB/impl/dvbAudioChecks.php index 1d9d6682..062df485 100644 --- a/HbbTV_DVB/impl/dvbAudioChecks.php +++ b/HbbTV_DVB/impl/dvbAudioChecks.php @@ -20,16 +20,16 @@ if ($role->getAttribute('value') == 'main') { $this->mainAudioFound = true; - $this->mainAudios[] = $adaptations; + $this->mainAudios[] = $adaptation; } } } -$accesibilityRoles = array(); -$accesibilities = $adaptation->getElementsByTagName("Accessibility"); -foreach ($accesibilities as $accesibility) { +$accessibilityRoles = array(); +$accessibilities = $adaptation->getElementsByTagName("Accessibility"); +foreach ($accessibilities as $accessibility) { if ($accessibility->getAttribute('schemeIdUri') == 'urn:tva:metadata:cs:AudioPurposeCS:2007') { - $accessibilityRoles[] = $accesibility->getAttribute('value'); + $accessibilityRoles[] = $accessibility->getAttribute('value'); } } diff --git a/HbbTV_DVB/impl/dvbEventChecks.php b/HbbTV_DVB/impl/dvbEventChecks.php index dcaba7d3..8bb86425 100644 --- a/HbbTV_DVB/impl/dvbEventChecks.php +++ b/HbbTV_DVB/impl/dvbEventChecks.php @@ -3,7 +3,7 @@ if ($eventStream->getAttribute('schemeIdUri') != 'urn:dvb:iptv:cpm:2014') { return; } -if ($eventStream->getAttribute('value') = '1') { +if ($eventStream->getAttribute('value') != '1') { return; } diff --git a/HbbTV_DVB/impl/dvbMPDValidator.php b/HbbTV_DVB/impl/dvbMPDValidator.php index 5127421a..bceca4bd 100644 --- a/HbbTV_DVB/impl/dvbMPDValidator.php +++ b/HbbTV_DVB/impl/dvbMPDValidator.php @@ -182,7 +182,7 @@ function ($v, $k) { if ($child->nodeName == 'EventStream') { $this->dvbEventChecks($child); } - if ($child->nodename == 'SegmentTemplate') { + if ($child->nodeName == 'SegmentTemplate') { if (DASHIF\Utility\mpdContainsProfile('urn:dvb:dash:profile:dvb-dash:isoff-ext-on-demand:2014')) { $invalidSegmentTemplateFound = true; } @@ -250,8 +250,8 @@ function ($v, $k) { $adaptationSetProfileExists, "WARN", "Check succeeded", - "Check failed: Contains clause 4.1: " . ($adaptationSetContainsDVBDash ? "Yes" : "No") . - ", contains either 4.2.5 or 4.2.8: " . ($adaptationSetContainsExtension ? "Yes" : "No"), + "Check failed: Contains clause 4.1: " . ($adaptationContainsDVBDash ? "Yes" : "No") . + ", contains either 4.2.5 or 4.2.8: " . ($adaptationContainsExtension ? "Yes" : "No"), ); $representations = $adaptationSet->getElementsByTagName("Representation"); @@ -270,7 +270,7 @@ function ($v, $k) { $videoComponentFound = false; $audioComponentFound = false; - if ($ch) { + if (isset($ch) && $ch) { $contentComponents = $ch->getElementsByTagName("ContentComponent"); foreach ($contentComponents as $component) { $contentType = $component->getAttribute("contentType"); @@ -393,18 +393,18 @@ function ($v, $k) { "$this->adaptationVideoCount adaptations found, none labeled as main for period $this->periodCount" ); - $this->dvbContentProtection($adaptationSet, $representations, $i, $cenc); + $this->dvbContentProtection($adaptationSet, $representations, $i, $cencAttribute); } if ($hasVideoService) { $this->streamBandwidthCheck(); } - if ($audioAdaptations->length > 1) { + if (count($audioAdaptations) > 1) { $this->fallbackOperationChecks($audioAdaptations); } - if ($mainAudioFound && !empty($hoh_subtitle_lang)) { + if ($this->mainAudioFound && !empty($hoh_subtitle_lang)) { $mainLanguage = array(); foreach ($main_audios as $main_audio) { if ($main_audio->getAttribute('lang') != '') { @@ -443,13 +443,14 @@ function ($v, $k) { $this->dvbAssociatedAdaptationSetsCheck(); +$audioCount = count($audioAdaptations); $logger->test( "HbbTV-DVB DASH Validation Requirements", "DVB: Section 6.1.2", "If there is more than one audio Adaptation Set in a DASH Presentation then at least one of them SHALL be " . "tagged with an @value set to \"main\"", - $audioAdaptations->length <= 1 || $this->mainAudioFound, + $audioCount <= 1 || $this->mainAudioFound, "FAIL", - "$audioAdaptations->length adaptation(s) found with main label if needed in Presentation", - "$audioAdaptations->length adaptations found but none of them are labeled as main in Presentation" + "$audioCount adaptation(s) found with main label if needed in Presentation", + "$audioCount adaptations found but none of them are labeled as main in Presentation" ); diff --git a/HbbTV_DVB/impl/dvbMpdAnchorCheck.php b/HbbTV_DVB/impl/dvbMpdAnchorCheck.php index 2905fde8..47c04573 100644 --- a/HbbTV_DVB/impl/dvbMpdAnchorCheck.php +++ b/HbbTV_DVB/impl/dvbMpdAnchorCheck.php @@ -3,6 +3,9 @@ global $mpdHandler, $logger; $allowedKeys = array('t', 'period', 'track', 'group'); +if (!array_key_exists("urlcode", $_POST)) { + return; +} $anchors = explode('#', json_decode($_POST['urlcode'])[0]); if (sizeof($anchors) <= 1) { return; diff --git a/HbbTV_DVB/impl/fallbackOperationChecks.php b/HbbTV_DVB/impl/fallbackOperationChecks.php index 108b3502..b6c72271 100644 --- a/HbbTV_DVB/impl/fallbackOperationChecks.php +++ b/HbbTV_DVB/impl/fallbackOperationChecks.php @@ -1,7 +1,7 @@ getElementsByTagName('SupplementalProperty'); diff --git a/HbbTV_DVB/impl/mpdUpdateConstraintsWithinPeriod.php b/HbbTV_DVB/impl/mpdUpdateConstraintsWithinPeriod.php index 5c048ad2..c5d57129 100644 --- a/HbbTV_DVB/impl/mpdUpdateConstraintsWithinPeriod.php +++ b/HbbTV_DVB/impl/mpdUpdateConstraintsWithinPeriod.php @@ -44,8 +44,8 @@ $spec, $section, "A Role Element " . $shallNotChangeInPeriod, - $mpd->getAdaptationSetAttribute($periodIndex, $origIndex, "Role") == - $nextMpd->getAdaptationSetAttribute($nextPeriodIndex, $nextIndex, "Role"), + $mpd->getAdaptationSetChild($periodIndex, $origIndex, "Role") == + $nextMpd->getAdaptationSetChild($nextPeriodIndex, $nextIndex, "Role"), "FAIL", "Role for AdaptationSet@id $origId within period $periodId identical", "Role for AdaptationSet@id $origId within period $periodId differs" diff --git a/Utils/ArgumentsParser.php b/Utils/ArgumentsParser.php index 5847c76d..de00f8cd 100644 --- a/Utils/ArgumentsParser.php +++ b/Utils/ArgumentsParser.php @@ -21,8 +21,8 @@ public function parseAll() $this->parsedOptions = getopt($this->getShortOpts(), $this->getLongOpts(), $restidx); global $argv; - if ($argv){ - $this->extraArguments = array_slice($argv, $restidx); + if ($argv) { + $this->extraArguments = array_slice($argv, $restidx); } @@ -37,21 +37,22 @@ public function parseAll() public function getOption($name) { - if ($_REQUEST[$name]) { + if (array_key_exists($name, $_REQUEST) && $_REQUEST[$name]) { return true; } - if ($this->parsedOptions){ - foreach ($this->allOptions as $option) { - if ($option->label == $name) { - if ( - array_key_exists($option->short[0], $this->parsedOptions) || - array_key_exists($option->long, $this->parsedOptions) - ) { - return true; + if ($this->parsedOptions) { + foreach ($this->allOptions as $option) { + if ($option->label == $name) { + if ( + (strlen($option->short) > 0 && + array_key_exists($option->short[0], $this->parsedOptions)) || + array_key_exists($option->long, $this->parsedOptions) + ) { + return true; + } } } } - } return false; } @@ -80,7 +81,7 @@ public function addOption($label, $short, $long, $desc) public function getPositionalArgument($argname) { - if ($argname == "url" && $_REQUEST["url"]) { + if ($argname == "url" && array_key_exists("url", $_REQUEST) && $_REQUEST["url"]) { return urldecode($_REQUEST["url"]); } switch ($argname) { diff --git a/Utils/MPDHandler.php b/Utils/MPDHandler.php index 68e4195e..732c2259 100644 --- a/Utils/MPDHandler.php +++ b/Utils/MPDHandler.php @@ -102,6 +102,14 @@ public function getAdaptationSetAttribute($idx, $aIdx, $attr): string | null } return $adaptationSetFeatures[$attr]; } + public function getAdaptationSetChild($idx, $aIdx, $childName) + { + $adaptationSetFeatures = $this->features["Period"][$idx]["AdaptationSet"][$aIdx]; + if (!array_key_exists($childName, $adaptationSetFeatures)) { + return null; + } + return $adaptationSetFeatures[$childName]; + } public function getRepresentationAttribute($idx, $aIdx, $rIdx, $attr): string | null { $representationFeatures = $this->features["Period"][$idx]["AdaptationSet"][$aIdx]['Representation'][$rIdx]; @@ -156,7 +164,7 @@ public function getRepresentationIds($periodId, $adaptationSetId) { return include 'impl/MPDHandler/getRepresentationIds.php'; } - + public function selectPeriod($period) { @@ -229,7 +237,7 @@ private function recursiveExtractFeatures($node) public function getPeriodTimingInfo($periodIndex = null) { - return include 'impl/MPDHandler/getPeriodTimingInfo.php'; + return $this->getPeriodDurationInfo($periodIndex ? $periodIndex : $this->selectedPeriod); } private function getPeriodDurationInfo($period) @@ -321,7 +329,6 @@ public function getMPD() return $this->mpd; } - public function getDom() { return $this->dom; diff --git a/Utils/MPDUtility.php b/Utils/MPDUtility.php index 0f0d63ef..7cc0c945 100644 --- a/Utils/MPDUtility.php +++ b/Utils/MPDUtility.php @@ -21,7 +21,7 @@ function in_array_at_least_one($options, $array) function isAbsoluteURL($URL) { $parsedUrl = parse_url($URL); - return $parsedUrl['scheme'] && $parsedUrl['host']; + return array_key_exists("scheme", $parsedUrl) && array_key_exists("host", $parsedUrl); } function inString($option, $string) @@ -163,9 +163,9 @@ function mergeSegmentAccess($highLevel, $lowLevel) function formSegmentAccess($highLevel, $lowLevel) { foreach ($highLevel as $key => $highValue) { - $lowValue = $lowLevel[$key]; + $lowValue = array_key_exists($key, $lowLevel) ? $lowLevel[$key] : array(); foreach ($highValue as $k => $v) { - if (!$lowValue[$k]) { + if (!array_key_exists($k, $lowValue) || !$lowValue[$k]) { $lowValue[$k] = $v; } elseif (gettype($lowValue[$k]) == 'array') { //$v would also work, but this is more clear in meaning diff --git a/Utils/Process_cli.php b/Utils/Process_cli.php index 352474c6..139a3347 100644 --- a/Utils/Process_cli.php +++ b/Utils/Process_cli.php @@ -15,9 +15,15 @@ */ -if(!defined('STDIN')) define('STDIN', fopen('php://stdin', 'rb')); -if(!defined('STDOUT')) define('STDOUT', fopen('php://stdout', 'wb')); -if(!defined('STDERR')) define('STDERR', fopen('php://stderr', 'wb')); +if (!defined('STDIN')) { + define('STDIN', fopen('php://stdin', 'rb')); +} +if (!defined('STDOUT')) { + define('STDOUT', fopen('php://stdout', 'wb')); +} +if (!defined('STDERR')) { + define('STDERR', fopen('php://stderr', 'wb')); +} ini_set('memory_limit', '-1'); ini_set('display_errors', 'stderr'); @@ -33,9 +39,6 @@ require __DIR__ . '/moduleInterface.php'; include __DIR__ . '/moduleLogger.php'; -include __DIR__ . '/Session.php'; //#Session Functions, No Direct Executable Code -//#Document loading functions, mostly xml. Some assertion options and error initialization -include __DIR__ . '/Load.php'; include __DIR__ . '/FileOperations.php'; //#Filesystem and XML checking functions. No Direct Executable Code. //#Global variables. Direct evaluation of post/session vars to define conditionals, //#conditional extra includes for module initialization @@ -77,13 +80,9 @@ //#Cross repo includes. These should be made optional at the very least. include __DIR__ . '/../DASH/processMPD.php'; -include __DIR__ . '/../DASH/MPDFeatures.php'; -include __DIR__ . '/../DASH/validateMPD.php'; -include __DIR__ . '/../DASH/MPDInfo.php'; include __DIR__ . '/../DASH/SchematronIssuesAnalyzer.php'; include __DIR__ . '/../DASH/cross_validation.php'; include __DIR__ . '/../DASH/Representation.php'; -include __DIR__ . '/../DASH/SegmentURLs.php'; include __DIR__ . '/../HLS/HLSProcessing.php'; include __DIR__ . '/Featurelist.php'; diff --git a/Utils/impl/MPDHandler/computeDynamicIntervals.php b/Utils/impl/MPDHandler/computeDynamicIntervals.php index 5e63ace3..bb0a8bc3 100644 --- a/Utils/impl/MPDHandler/computeDynamicIntervals.php +++ b/Utils/impl/MPDHandler/computeDynamicIntervals.php @@ -7,13 +7,16 @@ DASHIF\Utility\timeParsing($this->features['timeShiftBufferDepth']) : INF; $AST = $this->features['availabilityStartTime']; +$segmentduration = 0; if ($segmentAccess['SegmentTimeline'] != null) { - $segmentduration = ($segmentTimings[$segmentCount - 1] - $segmentTimings[0]) / ((float)($segmentCount - 1)); + if (count($segmentTimings) > 1) { + $segmentduration = ($segmentTimings[$segmentCount - 1] - $segmentTimings[0]) / ((float)($segmentCount - 1)); + } } else { $segmentduration = ($segmentAccess['duration'] != null) ? $segmentAccess['duration'] : 0; } $timescale = ($segmentAccess['timescale'] != null) ? $segmentAccess['timescale'] : 1; -$availabilityTimeOffset = ($segmentAccess['availabilityTimeOffset'] != null && +$availabilityTimeOffset = (array_key_exists("availabilityTimeOffset", $segmentAccess) && $segmentAccess['availabilityTimeOffset'] != 'INF') ? $segmentAccess['availabilityTimeOffset'] : 0; $pto = ($segmentAccess['presentationTimeOffset'] != '') ? @@ -40,6 +43,10 @@ $avgsum = array_sum($avgsum) / sizeof($avgsum); $percent = $avgsum / $sumbandwidth; +if ($segmentduration == 0) { + $segmentduration = 1; +} + $buffercapacity = $bufferduration / $segmentduration; //actual buffer capacity date_default_timezone_set("UTC"); //Set default timezone to UTC diff --git a/Utils/impl/MPDHandler/computeTiming.php b/Utils/impl/MPDHandler/computeTiming.php index c88273d1..496de2a6 100644 --- a/Utils/impl/MPDHandler/computeTiming.php +++ b/Utils/impl/MPDHandler/computeTiming.php @@ -15,22 +15,22 @@ $start = 0; $duration = 0; -if ($segmentAccess['duration'] != null) { +if (array_key_exists("duration", $segmentAccess)) { $duration = $segmentAccess['duration']; } $timescale = 1; -if ($segmentAccess['timescale'] != null) { +if (array_key_exists("timescale", $segmentAccess)) { $timescale = $segmentAccess['timescale']; } $availabilityTimeOffset = 0; -if ($segmentAccess['availabilityTimeOffset'] != null && $segmentAccess['availabilityTimeOffset'] != 'INF') { +if (array_key_exists("availabilityTimeOffset", $segmentAccess) && $segmentAccess['availabilityTimeOffset'] != 'INF') { $availabilityTimeOffset = $segmentAccess['availabilityTimeOffset']; } $presentationTimeOffset = 0; -if ($segmentAccess['presentationTimeOffset'] != '') { +if (array_key_exists("presentationTimeOffset", $segmentAccess) && $segmentAccess['presentationTimeOffset'] != '') { $presentationTimeOffset = (int)($segmentAccess['presentationTimeOffset']) / $timescale; } @@ -69,11 +69,11 @@ foreach ($segmentEntries as $index => $segmentEntry) { $d = $segmentEntry['d']; $r = 0; - if ($segmentEntry['r']) { + if (array_key_exists("r", $segmentEntry)) { $r = $segmentEntry['r']; } $t = 0; - if ($segmentEntry['t']) { + if (array_key_exists("t", $segmentEntry)) { $t = $segmentEntry['t']; } $t -= $timeOffset; diff --git a/Utils/impl/MPDHandler/computeUrls.php b/Utils/impl/MPDHandler/computeUrls.php index 63387177..3bb3baf5 100644 --- a/Utils/impl/MPDHandler/computeUrls.php +++ b/Utils/impl/MPDHandler/computeUrls.php @@ -6,7 +6,7 @@ $id = $representation['id']; $startNumber = 1; -if ($segmentAccess['startNumber'] != null) { +if (array_key_exists("startNumber", $segmentAccess)) { $startNumber = $segmentAccess['startNumber']; } @@ -44,9 +44,13 @@ ///\Todo translate checks below into actual "check" while ($index < $segmentCount) { + $timeReplace = 0; + if (array_key_exists($currentTime, $segmentInfo)) { + $timeReplace = $segmentInfo[$currentTime]; + } $segmentUrl = str_replace( array('$Bandwidth$', '$Number$', '$RepresentationID$', '$Time$'), - array($bandwidth, $index + $startNumber, $id, $segmentInfo[$currentTime]), + array($bandwidth, $index + $startNumber, $id, $timeReplace), $media ); diff --git a/Utils/impl/MPDHandler/getDurationsForAllPeriods.php b/Utils/impl/MPDHandler/getDurationsForAllPeriods.php index 7f9a0320..2d4c4bf5 100644 --- a/Utils/impl/MPDHandler/getDurationsForAllPeriods.php +++ b/Utils/impl/MPDHandler/getDurationsForAllPeriods.php @@ -2,15 +2,26 @@ $periods = $this->features['Period']; -$mediapresentationduration = DASHIF\Utility\timeParsing($this->features['mediaPresentationDuration']); +$mediapresentationduration = 0; +if (array_key_exists("mediaPresentationDuration", $this->features)) { + $mediapresentationduration = DASHIF\Utility\timeParsing( + $this->features['mediaPresentationDuration'] + ); +} $this->periodTimingInformation = array(); for ($i = 0; $i < sizeof($periods); $i++) { $period = $periods[$i]; - $periodStart = $period['start']; - $periodDuration = $period['duration']; + $periodStart = ''; + if (array_key_exists('start', $period)) { + $periodStart = $period['start']; + } + $periodDuration = ''; + if (array_key_exists('duration', $period)) { + $periodDuration = $period['duration']; + } if ($periodStart != '') { $start = DASHIF\Utility\timeParsing($periodStart); diff --git a/Utils/impl/MPDHandler/getPeriodBaseUrl.php b/Utils/impl/MPDHandler/getPeriodBaseUrl.php index b13410f1..9890162d 100644 --- a/Utils/impl/MPDHandler/getPeriodBaseUrl.php +++ b/Utils/impl/MPDHandler/getPeriodBaseUrl.php @@ -5,22 +5,34 @@ $periodIdx = $this->selectedPeriod; } -$mpdBaseUrl = $this->features['BaseURL']; +$mpdBaseUrl = null; +if (array_key_exists("BaseURL", $this->features)) { + $mpdBaseUrl = $this->features['BaseURL']; +} $period = $this->features['Period'][$periodIdx]; -$periodBaseUrl = $period['BaseURL']; +$periodBaseUrl = null; +if (array_key_exists("BaseURL", $period)) { + $periodBaseUrl = $period['BaseURL']; +} $adaptationUrls = array(); $adaptations = $period['AdaptationSet']; foreach ($adaptations as $adaptation) { $representationUrls = array(); - $adaptationBaseUrl = $adaptation['BaseURL']; + $adaptationBaseUrl = null; + if (array_key_exists("BaseURL", $adaptation)) { + $adaptationBaseUrl = $adaptation['BaseURL']; + } $representations = $adaptation['Representation']; foreach ($representations as $representation) { $representationUrl = ''; - $representationBaseUrl = $representation['BaseURL']; + $representationBaseUrl = null; + if (array_key_exists("BaseURL", $representation)) { + $representationBaseUrl = $representation['BaseURL']; + } if ($mpdBaseUrl || $periodBaseUrl || $adaptationBaseUrl || $representationBaseUrl) { $url = ''; diff --git a/Utils/impl/MPDHandler/getPeriodTimingInfo.php b/Utils/impl/MPDHandler/getPeriodTimingInfo.php deleted file mode 100644 index bcde9ea9..00000000 --- a/Utils/impl/MPDHandler/getPeriodTimingInfo.php +++ /dev/null @@ -1,3 +0,0 @@ -getPeriodDurationInfo($period ? $period : $this->selectedPeriod); diff --git a/Utils/impl/MPDHandler/load.php b/Utils/impl/MPDHandler/load.php index e930cb4e..36f68f83 100644 --- a/Utils/impl/MPDHandler/load.php +++ b/Utils/impl/MPDHandler/load.php @@ -12,8 +12,11 @@ if (isset($_FILES['mpd']) && move_uploaded_file($_FILES['mpd']['tmp_name'], $localManifestLocation)) { $this->url = $localManifestLocation; $isLocal = true; - } else { - if ($this->url && $this->url != '') { + } elseif ($this->url && $this->url != '') { + if ($this->url[0] == '/') { + $isLocal = true; + copy($this->url, $localManifestLocation); + } else { //Download with CURL; $this->downloadSegment($localManifestLocation, $this->url); $isLocal = true; @@ -34,5 +37,6 @@ ///\Todo: Check if this works with http basic auth if (!$this->mpd) { + fwrite(STDERR, "NO MPD\n"); return; } diff --git a/Utils/impl/MPDHandler/loadSegmentUrls.php b/Utils/impl/MPDHandler/loadSegmentUrls.php index 09572502..61066f3b 100644 --- a/Utils/impl/MPDHandler/loadSegmentUrls.php +++ b/Utils/impl/MPDHandler/loadSegmentUrls.php @@ -19,33 +19,47 @@ $baseUrls = $this->getPeriodBaseUrl($periodIdx); $periodTimingInfo = $this->getPeriodTimingInfo($periodIdx); - $currentTemplate = $period['SegmentTemplate']; - $currentBase = $period['SegmentBase']; + $currentTemplate = ''; + if (array_key_exists("SegmentTemplate", $period)) { + $period['SegmentTemplate']; + } + $currentBase = ''; + if (array_key_exists("SegmentBase", $period)) { + $currentBase = $period['SegmentBase']; + } $periodUrls = array(); $adaptations = $period['AdaptationSet']; foreach ($adaptations as $adaptationIdx => $adaptation) { - $currentTemplate = DASHIF\Utility\mergeSegmentAccess( - $currentTemplate, - $adaptation['SegmentTemplate'] - ); - $currentBase = DASHIF\Utility\mergeSegmentAccess( - $currentBase, - $adaptation['SegmentBase'] - ); - - $adaptationUrls = array(); - - foreach ($adaptation['Representation'] as $representationIdx => $representation) { + if (array_key_exists("SegmentTemplate", $adaptation)) { $currentTemplate = DASHIF\Utility\mergeSegmentAccess( $currentTemplate, - $representation['SegmentTemplate'] + $adaptation['SegmentTemplate'] ); + } + if (array_key_exists("SegmentBase", $adaptation)) { $currentBase = DASHIF\Utility\mergeSegmentAccess( $currentBase, - $representation['SegmentBase'] + $adaptation['SegmentBase'] ); + } + + $adaptationUrls = array(); + + foreach ($adaptation['Representation'] as $representationIdx => $representation) { + if (array_key_exists("SegmentTemplate", $representation)) { + $currentTemplate = DASHIF\Utility\mergeSegmentAccess( + $currentTemplate, + $representation['SegmentTemplate'] + ); + } + if (array_key_exists("SegmentBase", $representation)) { + $currentBase = DASHIF\Utility\mergeSegmentAccess( + $currentBase, + $representation['SegmentBase'] + ); + } if (!$currentTemplate || !count($currentTemplate)) {