protected function initPlaylistFlavorAssetArray() { list($entryIds, $durations, $mediaEntry) = myPlaylistUtils::executeStitchedPlaylist($this->entry); if (!$mediaEntry) { KExternalErrors::dieError(KExternalErrors::ENTRY_NOT_FOUND); } $this->duration = array_sum($durations) / 1000; $flavorAssets = array(); if ($this->flavorIds) { $flavorAssets = assetPeer::retrieveReadyByEntryId($mediaEntry->getId(), $this->flavorIds); $flavorAssets = $this->removeNotAllowedFlavors($flavorAssets); $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); } if (!$flavorAssets) { $flavorAssets = assetPeer::retrieveReadyFlavorsByEntryId($mediaEntry->getId()); $flavorAssets = $this->removeNotAllowedFlavors($flavorAssets); $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); $flavorAssets = $this->deliveryAttributes->filterFlavorsByTags($flavorAssets); } $this->deliveryAttributes->setStorageId(null); $this->deliveryAttributes->setFlavorAssets($flavorAssets); }
protected function servePlaylist($entry) { // allow only manual playlist if ($entry->getMediaType() != entry::ENTRY_MEDIA_TYPE_TEXT) { KExternalErrors::dieError(KExternalErrors::INVALID_ENTRY_TYPE); } // get request parameters $flavorParamIds = $this->getRequestParameter("flavorParamIds"); if ($flavorParamIds) { $flavorParamIds = explode(',', $flavorParamIds); } $version = $this->getRequestParameter("v"); // execute the playlist if ($version) { $entry->setDesiredVersion($version); } list($entryIds, $durations, $referenceEntry) = myPlaylistUtils::executeStitchedPlaylist($entry); if (!$referenceEntry) { KExternalErrors::dieError(KExternalErrors::ENTRY_NOT_FOUND); } // load the flavor assets // Note: not filtering by $flavorParamIds here, so that in case some flavor is missing // we can fill in the gap using some other flavor params $c = new Criteria(); $c->add(assetPeer::ENTRY_ID, $entryIds, Criteria::IN); $c->add(assetPeer::STATUS, flavorAsset::FLAVOR_ASSET_STATUS_READY); $flavorTypes = assetPeer::retrieveAllFlavorsTypes(); $c->add(assetPeer::TYPE, $flavorTypes, Criteria::IN); $flavorAssets = assetPeer::doSelect($c); // group the flavors by entry and flavor params $groupedFlavors = array(); foreach ($flavorAssets as $flavor) { if (!isset($groupedFlavors[$flavor->getEntryId()])) { $groupedFlavors[$flavor->getEntryId()] = array(); } $groupedFlavors[$flavor->getEntryId()][$flavor->getFlavorParamsId()] = $flavor; } // remove entries that don't have flavors for ($i = count($entryIds) - 1; $i >= 0; $i--) { $entryId = $entryIds[$i]; if (isset($groupedFlavors[$entryId])) { continue; } unset($entryIds[$i]); unset($durations[$i]); } // get the flavor params of the reference entry that should be returned $referenceEntryFlavorParamsIds = array_keys($groupedFlavors[$referenceEntry->getId()]); if ($flavorParamIds) { $flavorParamIds = array_intersect($referenceEntryFlavorParamsIds, $flavorParamIds); } else { $flavorParamIds = $referenceEntryFlavorParamsIds; } if (!$flavorParamIds) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } // build the sequences $storeCache = true; $sequences = array(); foreach ($flavorParamIds as $flavorParamsId) { $referenceFlavor = $groupedFlavors[$referenceEntry->getId()][$flavorParamsId]; // build the clips of the current sequence $clips = array(); foreach ($entryIds as $entryId) { if (isset($groupedFlavors[$entryId][$flavorParamsId])) { $flavor = $groupedFlavors[$entryId][$flavorParamsId]; } else { // don't have a flavor for this entry in the desired flavor params, // choose the one with the closest bitrate $flavor = null; foreach ($groupedFlavors[$entryId] as $curFlavor) { if (!$flavor || abs($curFlavor->getBitrate() - $referenceFlavor->getBitrate()) < abs($flavor->getBitrate() - $referenceFlavor->getBitrate())) { $flavor = $curFlavor; } } } // get the file path of the flavor $syncKey = $flavor->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); list($fileSync, $local) = kFileSyncUtils::getReadyFileSyncForKey($syncKey, false, false); if ($fileSync) { $resolvedFileSync = kFileSyncUtils::resolve($fileSync); $path = $resolvedFileSync->getFullPath(); } else { error_log('missing file sync for flavor ' . $flavor->getId() . ' version ' . $flavor->getVersion()); $path = ''; $storeCache = false; } $clips[] = array('type' => 'source', 'path' => $path); } $sequences[] = array('clips' => $clips); } // build the json $mediaSet = array('durations' => $durations, 'sequences' => $sequences); $json = json_encode($mediaSet); $renderer = new kRendererString($json, self::JSON_CONTENT_TYPE); if ($storeCache) { $this->storeCache($renderer, $entry->getPartnerId()); } $renderer->output(); KExternalErrors::dieGracefully(); }
private function setContextDataFlavorAssets($flavorTags) { if ($this->entry->getType() == entryType::PLAYLIST && $this->entry->getMediaType() == entry::ENTRY_MEDIA_TYPE_TEXT) { list($entryIds, $durations, $mediaEntry) = myPlaylistUtils::executeStitchedPlaylist($this->entry); if (!$mediaEntry) { return; } $mediaEntryId = $mediaEntry->getId(); $this->msDuration = array_sum($durations); } else { $mediaEntryId = $this->entry->getId(); $this->msDuration = $this->entry->getLengthInMsecs(); } $flavorParamsIds = null; $flavorParamsNotIn = false; if (!$this->isAdmin) { foreach ($this->contextDataResult->getActions() as $action) { if ($action->getType() == RuleActionType::BLOCK) { //in case of block action do not set the list of flavors return; } if ($action->getType() == RuleActionType::LIMIT_FLAVORS) { /* @var $action kAccessControlLimitFlavorsAction */ $flavorParamsIds = explode(',', $action->getFlavorParamsIds()); $flavorParamsNotIn = $action->getIsBlockedList(); } } } $flavorAssets = array(); if (is_null($this->asset)) { if (count($flavorParamsIds)) { $flavorAssets = assetPeer::retrieveReadyByEntryIdAndFlavorParams($mediaEntryId, $flavorParamsIds, $flavorParamsNotIn); } else { $flavorAssets = assetPeer::retrieveFlavorsByEntryIdAndStatus($mediaEntryId, null, array(flavorAsset::ASSET_STATUS_READY)); } if ($mediaEntryId != $this->entry->getId()) { // hack: setting the entry id of the flavors to the original playlist id // since the player uses it in the playManifest url foreach ($flavorAssets as $flavorAsset) { $flavorAsset->setEntryId($this->entry->getId()); } } } else { $flavorAllowed = true; if (count($flavorParamsIds)) { $flavorAllowed = $this->isFlavorAllowed($this->asset->getFlavorParamsId(), $flavorParamsIds, $flavorParamsNotIn); } if ($flavorAllowed) { $flavorAssets[] = $this->asset; } } $this->filterFlavorAssetsByTags($flavorAssets, $flavorTags); }