/** * @param EntryDistribution $entryDistribution * @param DistributionProfile $distributionProfile * @param bool $submitWhenReady * @return BatchJob */ public static function submitAddEntryDistribution(EntryDistribution $entryDistribution, DistributionProfile $distributionProfile, $submitWhenReady = true) { if ($distributionProfile->getStatus() != DistributionProfileStatus::ENABLED || $distributionProfile->getSubmitEnabled() == DistributionProfileActionStatus::DISABLED) { KalturaLog::debug("Submission is not enabled"); return null; } $validStatus = array(EntryDistributionStatus::ERROR_DELETING, EntryDistributionStatus::ERROR_SUBMITTING, EntryDistributionStatus::ERROR_UPDATING, EntryDistributionStatus::IMPORT_SUBMITTING, EntryDistributionStatus::PENDING, EntryDistributionStatus::QUEUED, EntryDistributionStatus::READY, EntryDistributionStatus::REMOVED); if (!in_array($entryDistribution->getStatus(), $validStatus)) { KalturaLog::notice("Wrong entry distribution status [" . $entryDistribution->getStatus() . "]"); return null; } $returnValue = false; $validationErrors = $entryDistribution->getValidationErrors(); if (!count($validationErrors)) { KalturaLog::debug("No validation errors found"); $returnValue = true; $sunrise = $entryDistribution->getSunrise(null); if ($sunrise) { KalturaLog::debug("Applying sunrise [{$sunrise}]"); $distributionProvider = $distributionProfile->getProvider(); if (!$distributionProvider->isScheduleUpdateEnabled() && !$distributionProvider->isAvailabilityUpdateEnabled()) { $sunrise -= $distributionProvider->getJobIntervalBeforeSunrise(); if ($sunrise > time()) { KalturaLog::log("Will be sent on exact time [{$sunrise}] for sunrise time [" . $entryDistribution->getSunrise() . "]"); $entryDistribution->setDirtyStatus(EntryDistributionDirtyStatus::SUBMIT_REQUIRED); $entryDistribution->save(); $returnValue = null; } } } if ($returnValue) { $returnValue = self::addSubmitAddJob($entryDistribution, $distributionProfile); } } if (!$returnValue && $submitWhenReady && $entryDistribution->getStatus() != EntryDistributionStatus::QUEUED) { $entryDistribution->setStatus(EntryDistributionStatus::QUEUED); $entryDistribution->save(); KalturaLog::debug("Will be submitted when ready"); } if (!count($validationErrors)) { return $returnValue; } KalturaLog::log("Validation errors found"); $entry = entryPeer::retrieveByPK($entryDistribution->getEntryId()); if (!$entry) { KalturaLog::err("Entry [" . $entryDistribution->getEntryId() . "] not found"); return null; } $autoCreateFlavors = $distributionProfile->getAutoCreateFlavorsArray(); $autoCreateThumbs = $distributionProfile->getAutoCreateThumbArray(); foreach ($validationErrors as $validationError) { if ($validationError->getErrorType() == DistributionErrorType::MISSING_FLAVOR && in_array($validationError->getData(), $autoCreateFlavors)) { $errDescription = null; KalturaLog::log("Adding flavor [" . $validationError->getData() . "] to entry [" . $entryDistribution->getEntryId() . "]"); kBusinessPreConvertDL::decideAddEntryFlavor(null, $entryDistribution->getEntryId(), $validationError->getData(), $errDescription); if ($errDescription) { KalturaLog::log($errDescription); } } if ($validationError->getErrorType() == DistributionErrorType::MISSING_THUMBNAIL && count($autoCreateThumbs)) { list($requiredWidth, $requiredHeight) = explode('x', $validationError->getData()); $foundThumbParams = false; $thumbParamsObjects = assetParamsPeer::retrieveByPKs($autoCreateThumbs); foreach ($thumbParamsObjects as $thumbParams) { /* @var $thumbParams thumbParams */ if ($thumbParams->getWidth() == intval($requiredWidth) && $thumbParams->getHeight() == intval($requiredHeight)) { $foundThumbParams = true; KalturaLog::log("Adding thumbnail [" . $thumbParams->getId() . "] to entry [" . $entryDistribution->getEntryId() . "]"); kBusinessPreConvertDL::decideThumbGenerate($entry, $thumbParams); break; } } if (!$foundThumbParams) { KalturaLog::err("Required thumbnail params not found [" . $validationError->getData() . "]"); } } } return null; }
/** * batch adjustToFramesize - verify that in the given set of target flvors, * there is at least one flavor that matches (or as close as possible) * to the source frame size. If there is no such flavor - set '_create_anyway' for the best matching. * The screencast sources are main cases for such adjustments, but there are other cases as well * * @param mediaInfo $source * @param array $targetFlavorArr is array of flavorOutputParams */ protected static function adjustToFramesize(mediaInfo $source, array $targetFlavorArr) { /* * Evaluate the 'adjusted' source height, to use as a for best matching flavor. */ $srcHgt = 0; if (isset($source)) { $srcHgt = $source->getVideoHeight(); $srcHgt = $srcHgt - $srcHgt % 16; } $matchSourceHeightIdx = null; // index of the smallest flavor that matches the source height $matchSourceOriginalFlavorBR = 0; $targetLargestHeight = 0; // To save the height of the largest target flavor and its key $targetLargestHeightKey = null; // and its key id. foreach ($targetFlavorArr as $key => $target) { /* * Ignore flavors that are smaller than the source - * they are not in the scope of 'adjustToFramesize'. * Track the largest target flavor, required for cases when the source height is larger than ALL flavors */ if ($target->getHeight() < $srcHgt) { KalturaLog::log("Source is larger than the target, skipping - key:{$key}, srcHgt:{$srcHgt}, trgHgt:" . $target->getHeight()); if ($targetLargestHeight < $target->getHeight()) { $targetLargestHeight = $target->getHeight(); $targetLargestHeightKey = $key; } continue; } /* * Stop searching if there is a flavor, in that set, that matches the source frame size - * no need to activate another flavor conversion */ if (!$target->_isNonComply || $target->_force || $target->_create_anyway) { $matchSourceHeightIdx = null; $targetLargestHeightKey = null; KalturaLog::log("Found COMPLY/forced/create_anyway, leaving - key:{$key}, srcHgt:{$srcHgt}, trgHgt:" . $target->getHeight()); break; } /* * If 'matching-target' is unset * - set it to the current target */ if (!isset($matchSourceHeightIdx)) { $matchSourceHeightIdx = $key; $flPrm = assetParamsPeer::retrieveByPKs(array($key)); $matchSourceOriginalFlavorBR = $flPrm[0]->getVideoBitrate(); KalturaLog::log("Set matchSourceHeightIdx:{$key}, matchSourceOriginalFlavorBR:{$matchSourceOriginalFlavorBR}, srcHgt:{$srcHgt}"); continue; } /* * If current target is smaller than 'matching-target' * - set it to the current target */ $flPrm = assetParamsPeer::retrieveByPKs(array($key)); $flPrmBR = $flPrm[0]->getVideoBitrate(); if ($matchSourceOriginalFlavorBR > $flPrmBR) { $matchSourceOriginalFlavorBR = $flPrmBR; $matchSourceHeightIdx = $key; KalturaLog::log("Switch to matchSourceHeightIdx:{$matchSourceHeightIdx}, matchSourceOriginalFlavorBR:{$matchSourceOriginalFlavorBR} srcHgt:{$srcHgt}"); } // if($target->getHeight()<$targetFlavorArr[$matchSourceHeightIdx]->getHeight()){ // } } /* * If no match was found, use the largest target flavor */ if (!isset($matchSourceHeightIdx) && isset($targetLargestHeightKey) && $targetFlavorArr[$targetLargestHeightKey]->getHeight() < $srcHgt) { $matchSourceHeightIdx = $targetLargestHeightKey; } /* * If smallest-source-height-matching is found and it is 'non-compliant' (therefore it will not be generated), * set '_create_anyway' flag for the 'matchSourceHeightIdx' flavor. */ if (isset($matchSourceHeightIdx) && $targetFlavorArr[$matchSourceHeightIdx]->_isNonComply) { $targetFlavorArr[$matchSourceHeightIdx]->_create_anyway = true; KalturaLog::log("Forcing (create anyway) target {$matchSourceHeightIdx}"); /* $first = reset($targetFlavorArr); if($first->_isNonComply) { $first->_force = true; // _create_anyway } */ } }
/** * @param BatchJob $dbBatchJob * @param flavorAsset $currentFlavorAsset * @return BatchJob */ public static function handleConvertFinished(BatchJob $dbBatchJob = null, flavorAsset $currentFlavorAsset) { KalturaLog::debug("entry id [" . $currentFlavorAsset->getEntryId() . "] flavor asset id [" . $currentFlavorAsset->getId() . "]"); $profile = null; try { $profile = myPartnerUtils::getConversionProfile2ForEntry($currentFlavorAsset->getEntryId()); KalturaLog::debug("profile [" . $profile->getId() . "]"); } catch (Exception $e) { KalturaLog::err($e->getMessage()); } $currentReadyBehavior = self::getReadyBehavior($currentFlavorAsset, $profile); KalturaLog::debug("Current ready behavior [{$currentReadyBehavior}]"); if ($currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { return $dbBatchJob; } $rootBatchJob = null; if ($dbBatchJob) { $rootBatchJob = $dbBatchJob->getRootJob(); } if ($rootBatchJob) { KalturaLog::debug("root batch job id [" . $rootBatchJob->getId() . "] type [" . $rootBatchJob->getJobType() . "]"); } // update the root job end exit if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::BULKDOWNLOAD) { $siblingJobs = $rootBatchJob->getChildJobs(); foreach ($siblingJobs as $siblingJob) { // checking only conversion child jobs if ($siblingJob->getJobType() != BatchJobType::CONVERT && $siblingJob->getJobType() != BatchJobType::CONVERT_COLLECTION && $siblingJob->getJobType() != BatchJobType::POSTCONVERT) { continue; } // if not complete leave function if (!in_array($siblingJob->getStatus(), BatchJobPeer::getClosedStatusList())) { KalturaLog::debug("job id [" . $siblingJob->getId() . "] status [" . $siblingJob->getStatus() . "]"); return $dbBatchJob; } } KalturaLog::debug("finish bulk download root job"); // all child jobs completed kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); return $dbBatchJob; } $inheritedFlavorParamsIds = array(); $requiredFlavorParamsIds = array(); $flavorParamsConversionProfileItems = array(); if ($profile) { $flavorParamsConversionProfileItems = flavorParamsConversionProfilePeer::retrieveByConversionProfile($profile->getId()); } foreach ($flavorParamsConversionProfileItems as $flavorParamsConversionProfile) { if ($flavorParamsConversionProfile->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $requiredFlavorParamsIds[$flavorParamsConversionProfile->getFlavorParamsId()] = true; } if ($flavorParamsConversionProfile->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_NO_IMPACT) { $inheritedFlavorParamsIds[] = $flavorParamsConversionProfile->getFlavorParamsId(); } } $flavorParamsItems = assetParamsPeer::retrieveByPKs($inheritedFlavorParamsIds); foreach ($flavorParamsItems as $flavorParams) { if ($flavorParams->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $requiredFlavorParamsIds[$flavorParamsConversionProfile->getFlavorParamsId()] = true; } } KalturaLog::debug("required flavor params ids [" . print_r($requiredFlavorParamsIds, true) . "]"); // go over all the flavor assets of the entry $inCompleteFlavorIds = array(); $origianlAssetFlavorId = null; $siblingFlavorAssets = assetPeer::retrieveFlavorsByEntryId($currentFlavorAsset->getEntryId()); foreach ($siblingFlavorAssets as $siblingFlavorAsset) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] flavor params id [" . $siblingFlavorAsset->getFlavorParamsId() . "]"); // don't mark any incomplete flag if ($siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_READY) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is ready"); if (isset($requiredFlavorParamsIds[$siblingFlavorAsset->getFlavorParamsId()])) { unset($requiredFlavorParamsIds[$siblingFlavorAsset->getFlavorParamsId()]); } continue; } $readyBehavior = self::getReadyBehavior($siblingFlavorAsset, $profile); if ($siblingFlavorAsset->getStatus() == flavorAsset::ASSET_STATUS_EXPORTING) { if ($siblingFlavorAsset->getIsOriginal()) { $origianlAssetFlavorId = $siblingFlavorAsset->getFlavorParamsId(); } else { if ($readyBehavior != flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is incomplete"); $inCompleteFlavorIds[] = $siblingFlavorAsset->getFlavorParamsId(); } } } if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_IGNORE) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is ignored"); continue; } if ($siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_QUEUED || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_IMPORTING || $siblingFlavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_VALIDATING) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is incomplete"); $inCompleteFlavorIds[] = $siblingFlavorAsset->getFlavorParamsId(); } if ($readyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { KalturaLog::debug("sibling flavor asset id [" . $siblingFlavorAsset->getId() . "] is required"); $requiredFlavorParamsIds[$siblingFlavorAsset->getFlavorParamsId()] = true; } } KalturaLog::debug("left required flavor params ids [" . print_r($requiredFlavorParamsIds, true) . "]"); KalturaLog::debug("left incomplete flavor ids [" . print_r($inCompleteFlavorIds, true) . "]"); if (count($requiredFlavorParamsIds)) { $inCompleteRequiredFlavorParamsIds = array_keys($requiredFlavorParamsIds); foreach ($inCompleteRequiredFlavorParamsIds as $inCompleteFlavorId) { $inCompleteFlavorIds[] = $inCompleteFlavorId; } KalturaLog::debug('Convert Finished - has In-Complete Required flavors [[' . print_r($inCompleteRequiredFlavorParamsIds, true) . ']'); } elseif ($currentFlavorAsset->getStatus() == asset::ASSET_STATUS_READY && ($currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_OPTIONAL || $currentReadyBehavior == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED)) { // mark the entry as ready if all required conversions completed or any of the optionals if ($currentFlavorAsset->getentry()->getReplacedEntryId()) { KalturaLog::debug('Entry is temporary replacement and requires all flavors to complete'); } else { KalturaLog::debug('Mark the entry as ready'); kBatchManager::updateEntry($currentFlavorAsset->getEntryId(), entryStatus::READY); } } if ($origianlAssetFlavorId) { $inCompleteFlavorIds = array_diff($inCompleteFlavorIds, array($origianlAssetFlavorId)); } if (!count($inCompleteFlavorIds)) { KalturaLog::debug('Convert Finished'); if ($origianlAssetFlavorId && $rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::CONVERT_PROFILE) { kStorageExporter::exportSourceAssetFromJob($rootBatchJob); } else { // mark the context root job as finished only if all conversion jobs are completed kBatchManager::updateEntry($currentFlavorAsset->getEntryId(), entryStatus::READY); if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::CONVERT_PROFILE) { kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } } return $dbBatchJob; } KalturaLog::debug('Convert Finished - has In-Complete flavors [' . print_r($inCompleteFlavorIds, true) . ']'); if (!$rootBatchJob || $rootBatchJob->getJobType() != BatchJobType::CONVERT_PROFILE) { return $dbBatchJob; } $childJobs = $rootBatchJob->getChildJobs(); KalturaLog::debug('Child jobs found [' . count($childJobs) . ']'); if (count($childJobs) > 1) { $allDone = true; foreach ($childJobs as $childJob) { if ($childJob->getId() != $rootBatchJob->getId() && $childJob->getStatus() != BatchJob::BATCHJOB_STATUS_FINISHED) { KalturaLog::debug('Child job id [' . $childJob->getId() . '] status [' . $childJob->getStatus() . ']'); $allDone = false; } } if ($allDone) { KalturaLog::debug('All child jobs done, closing profile'); kJobsManager::updateBatchJob($rootBatchJob, BatchJob::BATCHJOB_STATUS_FINISHED); } } return $dbBatchJob; }
/** * Authenticate live-stream entry against stream token and partner limitations * * @action authenticate * @param string $entryId Live stream entry id * @param string $token Live stream broadcasting token * @return KalturaLiveStreamEntry The authenticated live stream entry * * @throws KalturaErrors::ENTRY_ID_NOT_FOUND * @throws KalturaErrors::LIVE_STREAM_INVALID_TOKEN */ function authenticateAction($entryId, $token) { $dbEntry = entryPeer::retrieveByPK($entryId); if (!$dbEntry || $dbEntry->getType() != entryType::LIVE_STREAM) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } /* @var $dbEntry LiveStreamEntry */ if ($dbEntry->getStreamPassword() != $token) { throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_INVALID_TOKEN, $entryId); } $mediaServer = $dbEntry->getMediaServer(true); if ($mediaServer) { $url = null; $protocol = null; foreach (array(KalturaPlaybackProtocol::HLS, KalturaPlaybackProtocol::APPLE_HTTP) as $hlsProtocol) { $config = $dbEntry->getLiveStreamConfigurationByProtocol($hlsProtocol, requestUtils::PROTOCOL_HTTP, null, true); if ($config) { $url = $config->getUrl(); $protocol = $hlsProtocol; break; } } if ($url) { KalturaLog::info('Determining status of live stream URL [' . $url . ']'); $dpda = new DeliveryProfileDynamicAttributes(); $dpda->setEntryId($entryId); $dpda->setFormat($protocol); $deliveryProfile = DeliveryProfilePeer::getLiveDeliveryProfileByHostName(parse_url($url, PHP_URL_HOST), $dpda); if ($deliveryProfile && $deliveryProfile->isLive($url)) { throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_ALREADY_BROADCASTING, $entryId, $mediaServer->getHostname()); } } } // fetch current stream live params $liveParamsIds = flavorParamsConversionProfilePeer::getFlavorIdsByProfileId($dbEntry->getConversionProfileId()); $usedLiveParamsIds = array(); foreach ($liveParamsIds as $liveParamsId) { $usedLiveParamsIds[$liveParamsId] = array($entryId); } // fetch all live entries that currently are live $baseCriteria = KalturaCriteria::create(entryPeer::OM_CLASS); $filter = new entryFilter(); $filter->setIsLive(true); $filter->setIdNotIn(array($entryId)); $filter->setPartnerSearchScope(baseObjectFilter::MATCH_KALTURA_NETWORK_AND_PRIVATE); $filter->attachToCriteria($baseCriteria); $entries = entryPeer::doSelect($baseCriteria); $maxInputStreams = $this->getPartner()->getMaxLiveStreamInputs(); if (!$maxInputStreams) { $maxInputStreams = kConf::get('partner_max_live_stream_inputs', 'local', 10); } KalturaLog::debug("Max live stream inputs [{$maxInputStreams}]"); $maxTranscodedStreams = 0; if (PermissionPeer::isValidForPartner(PermissionName::FEATURE_KALTURA_LIVE_STREAM_TRANSCODE, $this->getPartnerId())) { $maxTranscodedStreams = $this->getPartner()->getMaxLiveStreamOutputs(); if (!$maxTranscodedStreams) { $maxTranscodedStreams = kConf::get('partner_max_live_stream_outputs', 'local', 10); } } KalturaLog::debug("Max live stream outputs [{$maxTranscodedStreams}]"); $totalInputStreams = count($entries) + 1; if ($totalInputStreams > $maxInputStreams + $maxTranscodedStreams) { KalturaLog::debug("Live input stream [{$totalInputStreams}]"); throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_PASSTHRU, $entryId); } $entryIds = array($entryId); foreach ($entries as $liveEntry) { /* @var $liveEntry LiveEntry */ $entryIds[] = $liveEntry->getId(); $liveParamsIds = array_map('intval', explode(',', $liveEntry->getFlavorParamsIds())); foreach ($liveParamsIds as $liveParamsId) { if (isset($usedLiveParamsIds[$liveParamsId])) { $usedLiveParamsIds[$liveParamsId][] = $liveEntry->getId(); } else { $usedLiveParamsIds[$liveParamsId] = array($liveEntry->getId()); } } } $liveParams = assetParamsPeer::retrieveByPKs(array_keys($usedLiveParamsIds)); $passthruEntries = null; $transcodedEntries = null; foreach ($liveParams as $liveParamsItem) { /* @var $liveParamsItem LiveParams */ if ($liveParamsItem->hasTag(liveParams::TAG_INGEST)) { $passthruEntries = array_intersect(is_array($passthruEntries) ? $passthruEntries : $entryIds, $usedLiveParamsIds[$liveParamsItem->getId()]); } else { $transcodedEntries = array_intersect(is_array($transcodedEntries) ? $transcodedEntries : $entryIds, $usedLiveParamsIds[$liveParamsItem->getId()]); } } $passthruEntries = array_diff($passthruEntries, $transcodedEntries); $passthruEntriesCount = count($passthruEntries); $transcodedEntriesCount = count($transcodedEntries); KalturaLog::debug("Live transcoded entries [{$transcodedEntriesCount}], max live transcoded streams [{$maxTranscodedStreams}]"); if ($transcodedEntriesCount > $maxTranscodedStreams) { throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_TRANSCODED, $entryId); } $maxInputStreams += $maxTranscodedStreams - $transcodedEntriesCount; KalturaLog::debug("Live params inputs [{$passthruEntriesCount}], max live stream inputs [{$maxInputStreams}]"); if ($passthruEntriesCount > $maxInputStreams) { throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_PASSTHRU, $entryId); } $entry = KalturaEntryFactory::getInstanceByType($dbEntry->getType()); $entry->fromObject($dbEntry, $this->getResponseProfile()); return $entry; }
/** * @param BatchJob $batchJob * @param entry $entry * @param string $flavorAssetId * @param string $inputFileSyncLocalPath * @return BatchJob */ public static function addConvertProfileJob(BatchJob $parentJob = null, entry $entry, $flavorAssetId, $inputFileSyncLocalPath) { KalturaLog::debug("Parent job [" . ($parentJob ? $parentJob->getId() : 'none') . "] entry [" . $entry->getId() . "] flavor asset [{$flavorAssetId}] input file [{$inputFileSyncLocalPath}]"); if ($entry->getConversionQuality() == conversionProfile2::CONVERSION_PROFILE_NONE) { $entry->setStatus(entryStatus::PENDING); $entry->save(); KalturaLog::notice('Entry should not be converted'); return null; } $importingSources = false; // if file size is 0, do not create conversion profile and set entry status as error converting if (!file_exists($inputFileSyncLocalPath) || kFile::fileSize($inputFileSyncLocalPath) == 0) { KalturaLog::debug("Input file [{$inputFileSyncLocalPath}] does not exist"); $partner = $entry->getPartner(); $conversionProfile = myPartnerUtils::getConversionProfile2ForEntry($entry->getId()); // load the asset params to the instance pool $flavorIds = flavorParamsConversionProfilePeer::getFlavorIdsByProfileId($conversionProfile->getId()); assetParamsPeer::retrieveByPKs($flavorIds); $conversionRequired = false; $sourceFileRequiredStorages = array(); $sourceIncludedInProfile = false; $flavorAsset = assetPeer::retrieveById($flavorAssetId); $flavors = flavorParamsConversionProfilePeer::retrieveByConversionProfile($conversionProfile->getId()); KalturaLog::debug("Found flavors [" . count($flavors) . "] in conversion profile [" . $conversionProfile->getId() . "]"); foreach ($flavors as $flavor) { /* @var $flavor flavorParamsConversionProfile */ if ($flavor->getFlavorParamsId() == $flavorAsset->getFlavorParamsId()) { KalturaLog::debug("Flavor [" . $flavor->getFlavorParamsId() . "] is ingested source"); $sourceIncludedInProfile = true; continue; } $flavorParams = assetParamsPeer::retrieveByPK($flavor->getFlavorParamsId()); if ($flavorParams instanceof liveParams || $flavor->getOrigin() == assetParamsOrigin::INGEST) { KalturaLog::debug("Flavor [" . $flavor->getFlavorParamsId() . "] should be ingested"); continue; } if ($flavor->getOrigin() == assetParamsOrigin::CONVERT_WHEN_MISSING) { $siblingFlavorAsset = assetPeer::retrieveByEntryIdAndParams($entry->getId(), $flavor->getFlavorParamsId()); if ($siblingFlavorAsset) { KalturaLog::debug("Flavor [" . $flavor->getFlavorParamsId() . "] already ingested"); continue; } } $sourceFileRequiredStorages[] = $flavorParams->getSourceRemoteStorageProfileId(); $conversionRequired = true; break; } if ($conversionRequired) { foreach ($sourceFileRequiredStorages as $storageId) { if ($storageId == StorageProfile::STORAGE_KALTURA_DC) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); list($syncFile, $local) = kFileSyncUtils::getReadyFileSyncForKey($key, true, false); if ($syncFile && $syncFile->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_URL && $partner && $partner->getImportRemoteSourceForConvert()) { KalturaLog::debug("Creates import job for remote file sync"); $url = $syncFile->getExternalUrl($entry->getId()); kJobsManager::addImportJob($parentJob, $entry->getId(), $partner->getId(), $url, $flavorAsset, null, null, true); $importingSources = true; continue; } } elseif ($flavorAsset->getExternalUrl($storageId)) { continue; } kBatchManager::updateEntry($entry->getId(), entryStatus::ERROR_CONVERTING); $flavorAsset = assetPeer::retrieveById($flavorAssetId); $flavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR); $flavorAsset->setDescription('Entry of size 0 should not be converted'); $flavorAsset->save(); KalturaLog::err('Entry of size 0 should not be converted'); return null; } } else { if ($flavorAsset->getStatus() == asset::FLAVOR_ASSET_STATUS_QUEUED) { if ($sourceIncludedInProfile) { $flavorAsset->setStatusLocalReady(); } else { $flavorAsset->setStatus(asset::FLAVOR_ASSET_STATUS_DELETED); $flavorAsset->setDeletedAt(time()); } $flavorAsset->save(); if ($sourceIncludedInProfile) { kBusinessPostConvertDL::handleConvertFinished(null, $flavorAsset); } } return null; } } if ($entry->getStatus() != entryStatus::READY) { $entry->setStatus(entryStatus::PRECONVERT); } $jobData = new kConvertProfileJobData(); $jobData->setFlavorAssetId($flavorAssetId); $jobData->setInputFileSyncLocalPath($inputFileSyncLocalPath); $jobData->setExtractMedia(true); if ($entry->getType() != entryType::MEDIA_CLIP) { $jobData->setExtractMedia(false); $entry->setCreateThumb(false); } $entry->save(); $batchJob = null; if ($parentJob) { $batchJob = $parentJob->createChild(BatchJobType::CONVERT_PROFILE); } else { $batchJob = new BatchJob(); $batchJob->setEntryId($entry->getId()); $batchJob->setPartnerId($entry->getPartnerId()); $batchJob->setUseNewRoot(true); } $batchJob->setObjectId($entry->getId()); $batchJob->setObjectType(BatchJobObjectType::ENTRY); if ($importingSources) { $batchJob->setStatus(BatchJob::BATCHJOB_STATUS_DONT_PROCESS); } return self::addJob($batchJob, $jobData, BatchJobType::CONVERT_PROFILE); }
public static function filterTagFlavors(array $flavors) { KalturaLog::log("Filter Tag Flavors, " . count($flavors) . " flavors supplied"); // check if there is a complete flavor $hasComplied = false; $hasForced = false; $hasCreateAnyway = false; $originalFlavorParamsIds = array(); foreach ($flavors as $flavorParamsId => $flavor) { $originalFlavorParamsIds[] = $flavor->getFlavorParamsId(); if (!$flavor->_isNonComply) { $hasComplied = true; } if ($flavor->_force) { $hasForced = true; } if ($flavor->_create_anyway) { $hasCreateAnyway = true; } } $originalFlavorParams = array(); $dbOriginalFlavorParams = assetParamsPeer::retrieveByPKs($originalFlavorParamsIds); foreach ($dbOriginalFlavorParams as $dbFlavorParams) { $originalFlavorParams[$dbFlavorParams->getId()] = $dbFlavorParams; } // return only complete flavors if ($hasComplied) { KalturaLog::log("Has complied flavors"); } if ($hasForced) { KalturaLog::log("Has forced flavors"); } if ($hasCreateAnyway) { KalturaLog::log("Has createAnyway flavors"); } if ($hasComplied || $hasForced || $hasCreateAnyway) { return $flavors; } // find the lowest flavor $lowestFlavorParamsId = null; foreach ($flavors as $flavorParamsId => $flavor) { if (!$flavor->IsValid()) { continue; } // is lower than the selected if (!isset($originalFlavorParams[$flavor->getFlavorParamsId()])) { continue; } $currentOriginalFlavor = $originalFlavorParams[$flavor->getFlavorParamsId()]; // is first flavor to check if (is_null($lowestFlavorParamsId)) { $lowestFlavorParamsId = $flavorParamsId; continue; } $lowestOriginalFlavor = $originalFlavorParams[$flavors[$lowestFlavorParamsId]->getFlavorParamsId()]; if (self::isFlavorLower($currentOriginalFlavor, $lowestOriginalFlavor)) { $lowestFlavorParamsId = $flavorParamsId; } } if ($lowestFlavorParamsId) { KalturaLog::log("Lowest flavor selected [{$lowestFlavorParamsId}]"); $flavors[$lowestFlavorParamsId]->_create_anyway = true; } return $flavors; }
/** * Adds the relation of flavorParams <> conversionProfile2 * * @param conversionProfile2 $conversionProfileDb * @param $flavorParamsIds */ protected function addFlavorParamsRelation(conversionProfile2 $conversionProfileDb, $flavorParamsIds) { $existingIds = flavorParamsConversionProfilePeer::getFlavorIdsByProfileId($conversionProfileDb->getId()); $assetParamsObjects = assetParamsPeer::retrieveByPKs($flavorParamsIds); foreach ($assetParamsObjects as $assetParams) { /* @var $assetParams assetParams */ if (in_array($assetParams->getId(), $existingIds)) { continue; } $fpc = new flavorParamsConversionProfile(); $fpc->setConversionProfileId($conversionProfileDb->getId()); $fpc->setFlavorParamsId($assetParams->getId()); $fpc->setReadyBehavior($assetParams->getReadyBehavior()); $fpc->setSystemName($assetParams->getSystemName()); $fpc->setForceNoneComplied(false); if ($assetParams->hasTag(assetParams::TAG_SOURCE)) { $fpc->setOrigin(assetParamsOrigin::INGEST); } else { $fpc->setOrigin(assetParamsOrigin::CONVERT); } $fpc->save(); } }
/** * Retrieve multiple objects by pkey. * * @param array $pks List of primary keys * @param PropelPDO $con the connection to use * @throws PropelException Any exceptions caught during processing will be * rethrown wrapped into a PropelException. */ public static function retrieveByPKs($pks, PropelPDO $con = null) { self::getInstance(); return parent::retrieveByPKs($pks, $con); }
/** * Adds the relation of flavorParams <> conversionProfile2 * * @param conversionProfile2 $conversionProfileDb * @param $flavorParamsIds * * @throws KalturaErrors::ASSET_PARAMS_INVALID_TYPE */ protected function addFlavorParamsRelation(conversionProfile2 $conversionProfileDb, $flavorParamsIds) { $existingIds = flavorParamsConversionProfilePeer::getFlavorIdsByProfileId($conversionProfileDb->getId()); $assetParamsObjects = assetParamsPeer::retrieveByPKs($flavorParamsIds); foreach ($assetParamsObjects as $assetParams) { /* @var $assetParams assetParams */ if (in_array($assetParams->getId(), $existingIds)) { continue; } if ($conversionProfileDb->getType() == ConversionProfileType::LIVE_STREAM && $assetParams->getType() != assetType::LIVE) { throw new KalturaAPIException(KalturaErrors::ASSET_PARAMS_INVALID_TYPE, $assetParams->getId(), $assetParams->getType()); } $fpc = new flavorParamsConversionProfile(); $fpc->setConversionProfileId($conversionProfileDb->getId()); $fpc->setFlavorParamsId($assetParams->getId()); $fpc->setReadyBehavior($assetParams->getReadyBehavior()); $fpc->setSystemName($assetParams->getSystemName()); $fpc->setForceNoneComplied(false); if ($assetParams->hasTag(assetParams::TAG_SOURCE) || $assetParams->hasTag(assetParams::TAG_INGEST)) { $fpc->setOrigin(assetParamsOrigin::INGEST); } else { $fpc->setOrigin(assetParamsOrigin::CONVERT); } $fpc->save(); } }
/** * @return array primary URL and backup URL */ private function getLiveEntryStreamConfig() { $this->initFlavorParamsIds(); $tag = null; $tags = $this->deliveryAttributes->getTags(); if (count($tags) == 1) { $tag = reset($tags); } $protocol = $this->deliveryAttributes->getMediaProtocol(); if (in_array($this->deliveryAttributes->getFormat(), self::$httpFormats) && !in_array($protocol, self::$httpProtocols)) { $protocol = requestUtils::getProtocol(); } // use only cloud transcode flavors if timeAlignedRenditions was set $partnerId = $this->entry->getPartnerId(); $partner = PartnerPeer::retrieveByPK($partnerId); $partnerTimeAligned = $partner->getTimeAlignedRenditions(); if ($partnerTimeAligned && $this->getRequestParameter("playerType") === 'flash') { // check entry's flavors $entryFlavorParams = assetParamsPeer::retrieveByPKs(explode(',', $this->entry->getFlavorParamsIds())); $hasTranscode = false; foreach ($entryFlavorParams as $flavor) { // check if we have any transcode flavor if (!$flavor->hasTag("ingest")) { $hasTranscode = true; } } // if so, use only the transcode if ($hasTranscode) { $tag = 'mbr'; } } $liveStreamConfig = $this->entry->getLiveStreamConfigurationByProtocol($this->deliveryAttributes->getFormat(), $protocol, $tag, false, $this->flavorParamsIds); /* @var $liveStreamConfig kLiveStreamConfiguration */ if ($liveStreamConfig) { return $liveStreamConfig; } switch ($this->deliveryAttributes->getFormat()) { case PlaybackProtocol::RTMP: $baseUrl = $this->entry->getStreamUrl(); $baseUrl = rtrim($baseUrl, '/'); if (strpos($this->deliveryAttributes->getMediaProtocol(), "rtmp") === 0) { $baseUrl = $this->deliveryAttributes->getMediaProtocol() . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } $liveStreamConfig = new kLiveStreamConfiguration(); $liveStreamConfig->setUrl($baseUrl); $liveStreamConfig->setProtocol(PlaybackProtocol::RTMP); return $liveStreamConfig; case PlaybackProtocol::APPLE_HTTP: // TODO pass single tag $liveStreamConfig = new kLiveStreamConfiguration(); $liveStreamConfig->setUrl($this->entry->getHlsStreamUrl()); $liveStreamConfig->setProtocol(PlaybackProtocol::APPLE_HTTP); return $liveStreamConfig; } return null; }
public function validateFlavorParamsIds() { $flavorParamsIds = $this->getFlavorParamsAsArray(); assetParamsPeer::resetInstanceCriteriaFilter(); $flavorParams = assetParamsPeer::retrieveByPKs($flavorParamsIds); $sourceFound = false; $indexedFlavorParams = array(); foreach ($flavorParams as $flavorParamsItem) { if ($flavorParamsItem->hasTag(flavorParams::TAG_SOURCE)) { if ($sourceFound) { throw new KalturaAPIException(KalturaErrors::FLAVOR_PARAMS_SOURCE_DUPLICATE); } $sourceFound = true; } $indexedFlavorParams[$flavorParamsItem->getId()] = $flavorParamsItem; } $foundFlavorParams = array(); foreach ($flavorParamsIds as $id) { if (!isset($indexedFlavorParams[$id])) { throw new KalturaAPIException(KalturaErrors::FLAVOR_PARAMS_ID_NOT_FOUND, $id); } if (in_array($id, $foundFlavorParams)) { throw new KalturaAPIException(KalturaErrors::FLAVOR_PARAMS_DUPLICATE, $id); } $foundFlavorParams[] = $id; } }
<?php if ($argc < 3) { echo "Usage:\n"; echo "\tphp " . __FILE__ . " {conversion profile type - media (1) or live (2)} {comma seperated asset params ids (no spaces)}\n"; exit(-1); } $conversionProfileType = $argv[1]; $additioalFlavorParamsIds = explode(',', $argv[2]); chdir(__DIR__); require_once __DIR__ . '/../bootstrap.php'; $additioalFlavorParamsItems = assetParamsPeer::retrieveByPKs($additioalFlavorParamsIds); if (count($additioalFlavorParamsItems) != count($additioalFlavorParamsIds)) { echo "Not all asset params found\n"; echo "Usage:\n"; echo "\tphp " . __FILE__ . " {conversion profile type - media (1) or live (2)} {comma seperated asset params ids (no spaces)}\n"; exit(-1); } $additioalFlavorParamsObjects = array(); foreach ($additioalFlavorParamsItems as $additioalFlavorParamsItem) { /* @var $additioalFlavorParamsItem liveParams */ $additioalFlavorParamsObjects[$additioalFlavorParamsItem->getId()] = $additioalFlavorParamsItem; } $partnerCriteria = new Criteria(); $partnerCriterion = $partnerCriteria->getNewCriterion(PartnerPeer::PARTNER_PARENT_ID, 0); $partnerCriterion->addOr($partnerCriteria->getNewCriterion(PartnerPeer::PARTNER_PARENT_ID, null, Criteria::ISNULL)); $partnerCriteria->add($partnerCriterion); $partnerCriteria->add(PartnerPeer::PARTNER_GROUP_TYPE, PartnerGroupType::TEMPLATE); $partnerCriteria->add(PartnerPeer::STATUS, Partner::PARTNER_STATUS_ACTIVE); $partners = PartnerPeer::doSelect($partnerCriteria); foreach ($partners as $partner) {