<?php require_once __DIR__ . '/../bootstrap.php'; if ($argc == 3) { $partner_id = $argv[1]; $path_format = $argv[2]; } else { die('usage: php ' . $_SERVER['SCRIPT_NAME'] . " [partner id] [date format]" . PHP_EOL); } $storages = StorageProfilePeer::retrieveExternalByPartnerId($partner_id); if (!$storages) { die('no such partner.' . PHP_EOL); } foreach ($storages as $storage) { $storage->setPathFormat($path_format); $storage->save(); } echo "Done.";
private function serveRtmp() { switch ($this->entry->getType()) { case entryType::MEDIA_CLIP: $duration = $this->entry->getDurationInt(); $flavorAssets = array(); if ($this->flavorId) { $flavorAsset = flavorAssetPeer::retrieveById($this->flavorId); if (!$flavorAsset->hasTag(flavorParams::TAG_WEB)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if (!$flavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_READY) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $flavorAssets[] = $flavorAsset; } else { $flavorAssets = flavorAssetPeer::retreiveReadyByEntryIdAndTag($this->entryId, flavorParams::TAG_MBR); if (!count($flavorAssets)) { $flavorAssets = flavorAssetPeer::retreiveReadyByEntryIdAndTag($this->entryId, flavorParams::TAG_WEB); } } $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); if (!$this->storageId) { $partner = $this->entry->getPartner(); $finalFlavors = array(); if ($partner->getStorageServePriority() == StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_FIRST) { foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyInternalFileSyncForKey($key); if ($fileSync) { $finalFlavors[] = $flavorAsset; } } } if (!count($finalFlavors) && $partner->getStorageServePriority() && $partner->getStorageServePriority() != StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_ONLY) { $storages = StorageProfilePeer::retrieveExternalByPartnerId($partner->getId()); if (count($storages) == 1) { $this->storageId = $storages[0]->getId(); } elseif (count($storages)) { $storagesFlavors = array(); foreach ($storages as $storage) { $storagesFlavors[$storage->getId()] = array(); foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyExternalFileSyncForKey($key, $storage->getId()); if ($fileSync) { $storagesFlavors[$storage->getId()][] = $flavorAsset; } } } $maxCount = 0; foreach ($storagesFlavors as $storageId => $storageFlavors) { $count = count($storageFlavors); if ($count > $maxCount) { $maxCount = $count; $this->storageId = $storageId; $finalFlavors = $storageFlavors; } } $flavorAssets = $finalFlavors; } else { foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyInternalFileSyncForKey($key); if ($fileSync) { $finalFlavors[] = $flavorAsset; } } } } } foreach ($flavorAssets as $flavorAsset) { $mediaInfo = mediaInfoPeer::retrieveByFlavorAssetId($flavorAsset->getId()); if ($mediaInfo && ($mediaInfo->getVideoDuration() || $mediaInfo->getAudioDuration() || $mediaInfo->getContainerDuration())) { $duration = $mediaInfo->getVideoDuration() ? $mediaInfo->getVideoDuration() : ($mediaInfo->getAudioDuration() ? $mediaInfo->getAudioDuration() : $mediaInfo->getContainerDuration()); $duration /= 1000; break; } } $baseUrl = null; $flavors = array(); if ($this->storageId) { $storage = StorageProfilePeer::retrieveByPK($this->storageId); if (!$storage) { die; } $baseUrl = $storage->getDeliveryRmpBaseUrl(); // get all flavors with external urls foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyExternalFileSyncForKey($key, $this->storageId); if (!$fileSync) { continue; } $urlManager = kUrlManager::getUrlManagerByStorageProfile($fileSync->getDc()); $urlManager->setClipTo($this->clipTo); $urlManager->setFileExtension($flavorAsset->getFileExt()); $urlManager->setProtocol(StorageProfile::PLAY_FORMAT_RTMP); $url = $urlManager->getFileSyncUrl($fileSync); $url = preg_replace('/^\\//', '', $url); $flavors[] = array('url' => $url, 'bitrate' => $flavorAsset->getBitrate(), 'width' => $flavorAsset->getWidth(), 'height' => $flavorAsset->getHeight()); } } else { $partnerId = $this->entry->getPartnerId(); $subpId = $this->entry->getSubpId(); $partnerPath = myPartnerUtils::getUrlForPartner($partnerId, $subpId); $baseUrl = myPartnerUtils::getRtmpUrl($partnerId); $urlManager = kUrlManager::getUrlManagerByCdn($this->cdnHost); // get all flavors with kaltura urls foreach ($flavorAssets as $flavorAsset) { $urlManager->setClipTo($this->clipTo); $urlManager->setFileExtension($flavorAsset->getFileExt()); $urlManager->setProtocol(StorageProfile::PLAY_FORMAT_RTMP); $url = $urlManager->getFlavorAssetUrl($flavorAsset); $url = preg_replace('/^\\//', '', $url); $flavors[] = array('url' => $url, 'bitrate' => $flavorAsset->getBitrate(), 'width' => $flavorAsset->getWidth(), 'height' => $flavorAsset->getHeight()); } } if (!count($flavors)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if (strpos($this->protocol, "rtmp") === 0) { $baseUrl = $this->protocol . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } return $this->buildXml(self::PLAY_STREAM_TYPE_RECORDED, $flavors, 'video/x-flv', $duration, $baseUrl); case entryType::LIVE_STREAM: $streamId = $this->entry->getStreamRemoteId(); $streamUsername = $this->entry->getStreamUsername(); $baseUrl = $this->entry->getStreamUrl(); $baseUrl = rtrim($baseUrl, '/'); $flavors = $this->entry->getStreamBitrates(); if (count($flavors)) { foreach ($flavors as $index => $flavor) { $brIndex = $index + 1; $flavors[$index]['url'] = str_replace('%i', $brIndex, $this->entry->getStreamName()); } } else { $flavors[0]['url'] = str_replace('%i', '1', $this->entry->getStreamName()); } if (strpos($this->protocol, "rtmp") === 0) { $baseUrl = $this->protocol . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } return $this->buildXml(self::PLAY_STREAM_TYPE_LIVE, $flavors, 'video/x-flv', null, $baseUrl); } KExternalErrors::dieError(KExternalErrors::INVALID_ENTRY_TYPE); }
protected function initFlavorAssetArray() { if (!$this->shouldInitFlavorAssetsArray()) { return; } $oneOnly = false; if ($this->deliveryAttributes->getFormat() == PlaybackProtocol::HTTP || $this->deliveryAttributes->getFormat() == "url" || $this->deliveryAttributes->getFormat() == "rtsp") { $oneOnly = true; } // get initial flavor list by input $flavorAssets = array(); if ($this->flavorIds) { $flavorAssets = assetPeer::retrieveReadyByEntryId($this->entryId, $this->flavorIds); $flavorAssets = $this->removeNotAllowedFlavors($flavorAssets); $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); } if (!$flavorAssets || !count($flavorAssets)) { $flavorAssets = assetPeer::retrieveReadyFlavorsByEntryId($this->entryId); $flavorAssets = $this->deliveryAttributes->filterFlavorsByTags($flavorAssets); $flavorAssets = $this->removeNotAllowedFlavors($flavorAssets); $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); } if ($this->deliveryAttributes->getFormat() == PlaybackProtocol::SILVER_LIGHT) { $this->initSilverLightManifest($flavorAssets); return; } if ($this->deliveryAttributes->getFormat() == PlaybackProtocol::HDS || $this->deliveryAttributes->getFormat() == PlaybackProtocol::APPLE_HTTP) { // try to look for a smil manifest, if it was found, we will use it for hds and hls if ($this->initSmilManifest($flavorAssets)) { return; } } // get flavors availability $servePriority = $this->entry->getPartner()->getStorageServePriority(); $localFlavors = array(); $remoteFlavorsByDc = array(); $remoteFileSyncs = array(); foreach ($flavorAssets as $flavorAsset) { $flavorId = $flavorAsset->getId(); $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $c = new Criteria(); $c = FileSyncPeer::getCriteriaForFileSyncKey($key); $c->addAnd(FileSyncPeer::STATUS, FileSync::FILE_SYNC_STATUS_READY); switch ($servePriority) { case StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_ONLY: $c->addAnd(FileSyncPeer::FILE_TYPE, FileSync::FILE_SYNC_FILE_TYPE_URL, Criteria::NOT_EQUAL); break; case StorageProfile::STORAGE_SERVE_PRIORITY_EXTERNAL_ONLY: $c->add(FileSyncPeer::FILE_TYPE, FileSync::FILE_SYNC_FILE_TYPE_URL); break; } if ($this->deliveryAttributes->getStorageId()) { $c->addAnd(FileSyncPeer::DC, $this->deliveryAttributes->getStorageId()); } $fileSyncs = FileSyncPeer::doSelect($c); foreach ($fileSyncs as $fileSync) { if ($fileSync->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_URL) { $dc = $fileSync->getDc(); $remoteFlavorsByDc[$dc][$flavorId] = $flavorAsset; $remoteFileSyncs[$dc][$flavorId] = $fileSync; } else { $localFlavors[$flavorId] = $flavorAsset; } } } // filter out any invalid / disabled storage profiles if ($remoteFileSyncs) { $storageProfileIds = array_keys($remoteFileSyncs); $storageProfiles = StorageProfilePeer::retrieveExternalByPartnerId($this->entry->getPartnerId(), $storageProfileIds); $activeStorageProfileIds = array(); foreach ($storageProfiles as $storageProfile) { $activeStorageProfileIds[] = $storageProfile->getId(); } foreach ($storageProfileIds as $storageProfileId) { if (in_array($storageProfileId, $activeStorageProfileIds)) { continue; } unset($remoteFlavorsByDc[$storageProfileId]); unset($remoteFileSyncs[$storageProfileId]); } } // choose the storage profile with the highest number of flavors $maxDc = null; $maxDcFlavorCount = 0; $remoteFlavors = array(); foreach ($remoteFlavorsByDc as $dc => $curDcFlavors) { $curDcFlavorCount = count($curDcFlavors); if ($curDcFlavorCount <= $maxDcFlavorCount) { continue; } $maxDc = $dc; $maxDcFlavorCount = $curDcFlavorCount; $remoteFlavors = $curDcFlavors; } // choose the flavor set according to the serve priority if ($this->shouldUseLocalFlavors($localFlavors, $remoteFlavors)) { $this->deliveryAttributes->setStorageId(null); $this->deliveryAttributes->setFlavorAssets($localFlavors); } else { if ($maxDc) { $this->deliveryAttributes->setStorageId($maxDc); $this->deliveryAttributes->setFlavorAssets($remoteFlavors); $this->deliveryAttributes->setRemoteFileSyncs($remoteFileSyncs[$maxDc]); } } if (!$this->deliveryAttributes->getFlavorAssets()) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if ($oneOnly) { $flavorAssets = $this->deliveryAttributes->getFlavorAssets(); $this->deliveryAttributes->setFlavorAssets(array(reset($flavorAssets))); } }
/** * (non-PHPdoc) * @see asset::setStatusLocalReady() */ public function setStatusLocalReady() { $newStatus = asset::ASSET_STATUS_READY; $externalStorages = StorageProfilePeer::retrieveExternalByPartnerId($this->getPartnerId()); foreach ($externalStorages as $externalStorage) { if ($this->requiredToExportFlavor($externalStorage)) { KalturaLog::info('Asset id [' . $this->getId() . '] is required to export to profile [' . $externalStorage->getId() . '] - setting status to [EXPORTING]'); $newStatus = asset::ASSET_STATUS_EXPORTING; break; } } KalturaLog::info('Setting status to [' . $newStatus . ']'); $this->setStatus($newStatus); }
/** * (non-PHPdoc) * @see asset::setStatusLocalReady() */ public function setStatusLocalReady() { KalturaLog::debug('Setting local ready status for asset id [' . $this->getId() . ']'); $newStatus = asset::ASSET_STATUS_READY; $externalStorages = StorageProfilePeer::retrieveExternalByPartnerId($this->getPartnerId()); foreach ($externalStorages as $externalStorage) { // check if storage profile should affect the asset ready status if ($externalStorage->getReadyBehavior() != StorageProfileReadyBehavior::REQUIRED) { // current storage profile is not required for asset readiness - skipping continue; } // check if export should happen now or wait for another trigger if (!$externalStorage->triggerFitsReadyAsset($this->getEntryId())) { KalturaLog::debug('Asset id [' . $this->getId() . '] is not ready to export to profile [' . $externalStorage->getId() . ']'); continue; } // check if asset needs to be exported to the remote storage if (!$externalStorage->shouldExportFlavorAsset($this)) { // check if asset is currently being exported to the remote storage if (!$externalStorage->isPendingExport($this)) { KalturaLog::debug('Should not export asset id [' . $this->getId() . '] to profile [' . $externalStorage->getId() . ']'); continue; } else { KalturaLog::debug('Asset id [' . $this->getId() . '] is currently being exported to profile [' . $externalStorage->getId() . ']'); } } KalturaLog::debug('Asset id [' . $this->getId() . '] is required to export to profile [' . $externalStorage->getId() . '] - setting status to [EXPORTING]'); $newStatus = asset::ASSET_STATUS_EXPORTING; break; } KalturaLog::debug('Setting status to [' . $newStatus . ']'); $this->setStatus($newStatus); }
/** * for each storage profile check if it still fulfills the export rules and decide if it should be exported or deleted * * @param entry $entry * */ public static function reExportEntry(entry $entry) { if (!PermissionPeer::isValidForPartner(PermissionName::FEATURE_REMOTE_STORAGE_RULE, $entry->getPartnerId())) { return; } if ($entry->getStatus() == entryStatus::NO_CONTENT) { return; } $storageProfiles = StorageProfilePeer::retrieveExternalByPartnerId($entry->getPartnerId()); foreach ($storageProfiles as $profile) { /* @var $profile StorageProfile */ KalturaLog::debug('Checking entry [' . $entry->getId() . ']re-export to storage [' . $profile->getId() . ']'); $scope = $profile->getScope(); $scope->setEntryId($entry->getId()); if ($profile->triggerFitsReadyAsset($entry->getId()) && $profile->fulfillsRules($scope)) { self::tryExportEntry($entry, $profile); } else { self::deleteExportedEntry($entry, $profile); } } }
/** * @return array */ private function buildRtmpFlavorAssetArray() { // get initial flavor list according to tags / specific flavor request $flavorAssets = array(); if ($this->flavorId) { $flavorAsset = assetPeer::retrieveById($this->flavorId); if (!$this->assetMatchesTags($flavorAsset)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if ($flavorAsset->getStatus() != flavorAsset::FLAVOR_ASSET_STATUS_READY) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $flavorAssets[] = $flavorAsset; } else { $flavorAssets = $this->getReadyFlavorsByTags(); } $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); if ($this->storageId) { // no need to further check the flavors - caller will try this storageId and fall back to local flavors if needed return $flavorAssets; } $partner = $this->entry->getPartner(); // try using local flavors if they have the higher priority if (!$partner->getStorageServePriority() || $partner->getStorageServePriority() == StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_FIRST || $partner->getStorageServePriority() == StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_ONLY) { $localFlavors = $this->getLocalFlavors($flavorAssets); if (count($localFlavors) || !$partner->getStorageServePriority() || $partner->getStorageServePriority() == StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_ONLY) { return $localFlavors; } } // try using remote flavors $storages = StorageProfilePeer::retrieveExternalByPartnerId($partner->getId()); if (count($storages) == 1) { // no need to further check the flavors - caller will try this storageId and fall back to local flavors if needed $this->storageId = $storages[0]->getId(); return $flavorAssets; } if (count($storages)) { // use the storage profile with the highest number of flavors $storagesFlavors = array(); foreach ($storages as $storage) { $storagesFlavors[$storage->getId()] = $this->getRemoteFlavors($flavorAssets, $storage->getId()); } $remoteFlavors = array(); $maxCount = 0; foreach ($storagesFlavors as $storageId => $storageFlavors) { $count = count($storageFlavors); if ($count > $maxCount) { $this->storageId = $storageId; $remoteFlavors = $storageFlavors; $maxCount = $count; } } if (count($remoteFlavors)) { return $remoteFlavors; } } if ($partner->getStorageServePriority() == StorageProfile::STORAGE_SERVE_PRIORITY_EXTERNAL_ONLY) { // could not find any external flavors and the serve priority is external only return array(); } // could not find any external flavors, try local flavors return $this->getLocalFlavors($flavorAssets); }