/** * Handles drop folder file status change to PENDING * 1. set parsed slug and flavor * 2. in case there is no parsed flavor (no related files) - add ContentProcessor job * 3. otherwise * a. verify all required flavors are ready * b. if yes - add content processor * c. else - change files status to WAITING * @param DropFolder $folder * @param DropFolderFile $file */ private function onContentDropFolderFileStatusChangedToPending(DropFolder $folder, DropFolderFile $file) { $updatedFile = $this->setParsedSlugFlavor($folder, $file); if ($updatedFile) { $file = $updatedFile; if (is_null($file->getParsedFlavor())) { KalturaLog::log('Parsed flavor is null, triggering ContentProcessing job for source'); $this->triggerContentDropFolderFileProcessing($folder, $file); } else { $assetParamsList = flavorParamsConversionProfilePeer::retrieveByConversionProfile($folder->getConversionProfileId()); $flavorNameValid = $this->validateFlavorName($file, $assetParamsList); if ($flavorNameValid) { KalturaLog::log('Parsed flavor is set, verifying if all files ready'); $statuses = array(DropFolderFileStatus::PENDING, DropFolderFileStatus::WAITING, DropFolderFileStatus::NO_MATCH); $relatedFiles = DropFolderFilePeer::retrieveByDropFolderIdStatusesAndSlug($folder->getId(), $statuses, $file->getParsedSlug()); $isReady = $this->isAllContentDropFolderIngestedFilesReady($folder, $relatedFiles, $assetParamsList); if ($isReady) { $this->triggerContentDropFolderFileProcessing($folder, $file, $relatedFiles); } else { $file->setStatus(DropFolderFileStatus::WAITING); $file->save(); } } } } else { $this->setFileError($file, DropFolderFileStatus::ERROR_HANDLING, DropFolderFileErrorCode::SLUG_REGEX_NO_MATCH, DropFolderPlugin::SLUG_REGEX_NO_MATCH_MESSAGE); } }
function calculateUrgency(BatchJob $batchJob) { $flavorParamsId = $this->getFlavorParamsOutput()->getFlavorParamsId(); $isBulkupload = $batchJob->getBulkJobId() !== null; $readiness = null; if ($this->priority == 0) { self::calculatePriority($batchJob); } if ($this->priority == self::MIGRATION_FLAVOR_PRIORITY) { return BatchJobUrgencyType::MIGRATION_URGENCY; } // If you have no conversion profile, there is no poinr in this calculation if (is_null($this->conversionProfileId)) { return BatchJobUrgencyType::DEFAULT_URGENCY; } if ($batchJob->getObjectId() && $batchJob->getObjectType()) { $batchJobs = BatchJobPeer::retrieveByJobTypeAndObject($batchJob->getObjectId(), $batchJob->getObjectType(), $batchJob->getJobType(), $batchJob->getJobSubType()); if (count($batchJobs)) { return $batchJobs[0]->getLockInfo()->getUrgency() + 1; } } // a conversion job will be considered as required in one of the following cases: // 1. The flavor is required // 2. There are no required flavors and this is the flavor is optional with the minimal bitrate // 3. all flavors are set as READY_BEHAVIOR_NO_IMPACT. $allFlavorParamsIds = array(); $hasRequired = false; $allNoImpact = true; // Go over all flavors and decide on cases 1-3 $fpcps = flavorParamsConversionProfilePeer::retrieveByConversionProfile($this->conversionProfileId); foreach ($fpcps as $fpcp) { $allFlavorParamsIds[] = $fpcp->getFlavorParamsId(); if ($fpcp->getFlavorParamsId() == $flavorParamsId) { // Case 1 $readiness = $fpcp->getReadyBehavior(); } if ($fpcp->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { // Case 2 $hasRequired = true; } if ($fpcp->getReadyBehavior() != flavorParamsConversionProfile::READY_BEHAVIOR_NO_IMPACT) { // Case 3 $allNoImpact = false; } } // Case 2 if (!$hasRequired && $readiness == flavorParamsConversionProfile::READY_BEHAVIOR_OPTIONAL) { $flvParamsMinBitrate = assetParamsPeer::retrieveMinimalBitrate($allFlavorParamsIds); if (!is_null($flvParamsMinBitrate) && $flvParamsMinBitrate->getId() == $flavorParamsId) { $readiness = flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED; } } // Case 3 if ($allNoImpact) { $readiness = flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED; } // Decide on the urgency by the readiness and the upload method if ($readiness == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { return $isBulkupload ? BatchJobUrgencyType::REQUIRED_BULK_UPLOAD : BatchJobUrgencyType::REQUIRED_REGULAR_UPLOAD; } else { if ($readiness == flavorParamsConversionProfile::READY_BEHAVIOR_OPTIONAL) { return $isBulkupload ? BatchJobUrgencyType::OPTIONAL_BULK_UPLOAD : BatchJobUrgencyType::OPTIONAL_REGULAR_UPLOAD; } else { return BatchJobUrgencyType::DEFAULT_URGENCY; } } }
public static function continueProfileConvert(BatchJob $parentJob) { $convertProfileJob = $parentJob->getRootJob(); if ($convertProfileJob->getJobType() != BatchJobType::CONVERT_PROFILE) { throw new Exception("Root job [" . $convertProfileJob->getId() . "] is not profile conversion"); } KalturaLog::log("Conversion decision layer continued for entry [" . $parentJob->getEntryId() . "]"); $convertProfileData = $convertProfileJob->getData(); $entryId = $convertProfileJob->getEntryId(); $entry = $convertProfileJob->getEntry(); if (!$entry) { throw new APIException(APIErrors::INVALID_ENTRY, $convertProfileJob, $entryId); } $profile = myPartnerUtils::getConversionProfile2ForEntry($entryId); if (!$profile) { $errDescription = "Conversion profile for entryId [{$entryId}] not found"; $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob, entryStatus::ERROR_CONVERTING); KalturaLog::err("No flavors created: {$errDescription}"); throw new Exception($errDescription); } $originalFlavorAsset = flavorAssetPeer::retrieveOriginalByEntryId($entryId); if (is_null($originalFlavorAsset)) { $errDescription = 'Original flavor asset not found'; KalturaLog::err($errDescription); $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob, entryStatus::ERROR_CONVERTING); throw new Exception($errDescription); } // gets the list of flavor params of the conversion profile $list = flavorParamsConversionProfilePeer::retrieveByConversionProfile($profile->getId()); if (!count($list)) { $errDescription = "No flavors match the profile id [{$profile->getId()}]"; KalturaLog::err($errDescription); $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription, BatchJobType::CONVERT_PROFILE); kBatchManager::updateEntry($convertProfileJob, entryStatus::ERROR_CONVERTING); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_DELETED); $originalFlavorAsset->setDeletedAt(time()); $originalFlavorAsset->save(); throw new Exception($errDescription); } // gets the ids of the flavor params $flavorsIds = array(); $conversionProfileFlavorParams = array(); foreach ($list as $flavorParamsConversionProfile) { $flavorsId = $flavorParamsConversionProfile->getFlavorParamsId(); $flavorsIds[] = $flavorsId; $conversionProfileFlavorParams[$flavorsId] = $flavorParamsConversionProfile; } $dynamicFlavorAttributes = $entry->getDynamicFlavorAttributes(); // gets the flavor params by the id $flavors = flavorParamsPeer::retrieveByPKs($flavorsIds); foreach ($flavors as $index => $flavor) { if ($flavor->hasTag(flavorParams::TAG_SOURCE)) { unset($flavors[$index]); continue; } if (isset($dynamicFlavorAttributes[$flavor->getId()])) { foreach ($dynamicFlavorAttributes[$flavor->getId()] as $attributeName => $attributeValue) { $flavor->setDynamicAttribute($attributeName, $attributeValue); } } } KalturaLog::log(count($flavors) . " destination flavors found for this profile[" . $profile->getId() . "]"); if (!count($flavors)) { return false; } $mediaInfo = mediaInfoPeer::retrieveByFlavorAssetId($originalFlavorAsset->getId()); return self::decideProfileFlavorsConvert($parentJob, $convertProfileJob, $flavors, $conversionProfileFlavorParams, $mediaInfo); }
/** * Serve XML rendition of the Kaltura Live Transcoding Profile usable by the Wowza transcoding add-on * * @action serve * @param string $streamName the id of the live entry with it's stream suffix * @param string $hostname the media server host name * @return file * * @throws KalturaErrors::ENTRY_ID_NOT_FOUND * @throws WowzaErrors::INVALID_STREAM_NAME */ public function serveAction($streamName, $hostname = null) { $matches = null; if (!preg_match('/^(\\d_.{8})_(\\d+)$/', $streamName, $matches)) { throw new KalturaAPIException(WowzaErrors::INVALID_STREAM_NAME, $streamName); } $entryId = $matches[1]; $suffix = $matches[2]; $entry = null; if (!kCurrentContext::$ks) { kEntitlementUtils::initEntitlementEnforcement(null, false); $entry = kCurrentContext::initPartnerByEntryId($entryId); if (!$entry || $entry->getStatus() == entryStatus::DELETED) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } // enforce entitlement $this->setPartnerFilters(kCurrentContext::getCurrentPartnerId()); } else { $entry = entryPeer::retrieveByPK($entryId); } if (!$entry || $entry->getType() != KalturaEntryType::LIVE_STREAM || !in_array($entry->getSource(), array(KalturaSourceType::LIVE_STREAM, KalturaSourceType::LIVE_STREAM_ONTEXTDATA_CAPTIONS))) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } $mediaServer = null; if ($hostname) { $mediaServer = MediaServerPeer::retrieveByHostname($hostname); } $conversionProfileId = $entry->getConversionProfileId(); $liveParams = assetParamsPeer::retrieveByProfile($conversionProfileId); $liveParamsInput = null; $disableIngested = true; foreach ($liveParams as $liveParamsItem) { /* @var $liveParamsItem liveParams */ if ($liveParamsItem->getStreamSuffix() == $suffix) { $liveParamsInput = $liveParamsItem; if (!$liveParamsInput->hasTag(assetParams::TAG_SOURCE)) { $liveParams = array($liveParamsInput); $disableIngested = false; } break; } } $ignoreLiveParamsIds = array(); if ($disableIngested) { $conversionProfileAssetParams = flavorParamsConversionProfilePeer::retrieveByConversionProfile($conversionProfileId); foreach ($conversionProfileAssetParams as $conversionProfileAssetParamsItem) { /* @var $conversionProfileAssetParamsItem flavorParamsConversionProfile */ if ($conversionProfileAssetParamsItem->getOrigin() == assetParamsOrigin::INGEST) { $ignoreLiveParamsIds[] = $conversionProfileAssetParamsItem->getFlavorParamsId(); } } } // translate the $liveParams to XML according to doc: http://www.wowza.com/forums/content.php?304#configTemplate $root = new SimpleXMLElement('<Root/>'); $transcode = $root->addChild('Transcode'); $encodes = $transcode->addChild('Encodes'); $groups = array(); foreach ($liveParams as $liveParamsItem) { /* @var $liveParamsItem liveParams */ if (!$liveParamsItem->hasTag(assetParams::TAG_SOURCE) && in_array($liveParamsItem->getId(), $ignoreLiveParamsIds)) { continue; } $this->appendLiveParams($entry, $mediaServer, $encodes, $liveParamsItem); $tags = $liveParamsItem->getTagsArray(); $tags[] = 'all'; foreach ($tags as $tag) { if (!isset($groups[$tag])) { $groups[$tag] = array(); } $systemName = $liveParamsItem->getSystemName() ? $liveParamsItem->getSystemName() : $liveParamsItem->getId(); $groups[$tag][] = $systemName; } } $decode = $transcode->addChild('Decode'); $video = $decode->addChild('Video'); $video->addChild('Deinterlace', 'false'); $streamNameGroups = $transcode->addChild('StreamNameGroups'); foreach ($groups as $groupName => $groupMembers) { $streamNameGroup = $streamNameGroups->addChild('StreamNameGroup'); $streamNameGroup->addChild('Name', $groupName); $streamNameGroup->addChild('StreamName', '${SourceStreamName}_' . $groupName); $members = $streamNameGroup->addChild('Members'); foreach ($groupMembers as $groupMember) { $member = $members->addChild('Member'); $member->addChild('EncodeName', $groupMember); } } $properties = $transcode->addChild('Properties'); $dom = new DOMDocument("1.0"); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($root->asXML()); return new kRendererString($dom->saveXML(), 'text/xml'); }
/** * @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; }
public static function continueProfileConvert(BatchJob $parentJob) { $convertProfileJob = $parentJob->getRootJob(); if ($convertProfileJob->getJobType() != BatchJobType::CONVERT_PROFILE) { throw new Exception("Root job [" . $convertProfileJob->getId() . "] is not profile conversion"); } KalturaLog::log("Conversion decision layer continued for entry [" . $parentJob->getEntryId() . "]"); $convertProfileData = $convertProfileJob->getData(); $entryId = $convertProfileJob->getEntryId(); $entry = $convertProfileJob->getEntry(); if (!$entry) { throw new APIException(APIErrors::INVALID_ENTRY, $convertProfileJob, $entryId); } $profile = myPartnerUtils::getConversionProfile2ForEntry($entryId); if (!$profile) { $errDescription = "Conversion profile for entryId [{$entryId}] not found"; self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $entryId); throw new Exception($errDescription); } $originalFlavorAsset = assetPeer::retrieveOriginalByEntryId($entryId); if (is_null($originalFlavorAsset)) { $errDescription = 'Original flavor asset not found'; self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $entryId); throw new Exception($errDescription); } // gets the list of flavor params of the conversion profile $list = flavorParamsConversionProfilePeer::retrieveByConversionProfile($profile->getId()); if (!count($list)) { $errDescription = "No flavors match the profile id [{$profile->getId()}]"; self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $entryId); $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_DELETED); $originalFlavorAsset->setDeletedAt(time()); $originalFlavorAsset->save(); throw new Exception($errDescription); } // gets the ids of the flavor params $flavorsIds = array(); $conversionProfileFlavorParams = array(); foreach ($list as $flavorParamsConversionProfile) { $flavorsId = $flavorParamsConversionProfile->getFlavorParamsId(); $flavorsIds[] = $flavorsId; $conversionProfileFlavorParams[$flavorsId] = $flavorParamsConversionProfile; } // gets the flavor params by the id $flavors = assetParamsPeer::retrieveFlavorsByPKs($flavorsIds); self::checkConvertProfileParams($flavors, $conversionProfileFlavorParams, $entry); KalturaLog::log(count($flavors) . " destination flavors found for this profile[" . $profile->getId() . "]"); if (!count($flavors)) { return false; } $mediaInfo = mediaInfoPeer::retrieveByFlavorAssetId($originalFlavorAsset->getId()); try { return self::decideProfileFlavorsConvert($parentJob, $convertProfileJob, $flavors, $conversionProfileFlavorParams, $profile->getId(), $mediaInfo); } catch (Exception $e) { KalturaLog::err('decideProfileFlavorsConvert - ' . $e->getMessage()); } }
/** * @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 decideLiveProfile(LiveEntry $entry) { // find all live assets of the entry $c = new Criteria(); $c->add(assetPeer::PARTNER_ID, $entry->getPartnerId()); $c->add(assetPeer::ENTRY_ID, $entry->getId()); $c->add(assetPeer::TYPE, assetType::LIVE); // include deleted assets assetPeer::setUseCriteriaFilter(false); $liveAssets = assetPeer::doSelect($c); assetPeer::setUseCriteriaFilter(true); // build array of all assets with asset params id as key $liveAssetsParams = array(); foreach ($liveAssets as $liveAsset) { /* @var $liveAsset liveAsset */ $flavorParamsId = is_null($liveAsset->getFlavorParamsId()) ? $liveAsset->getId() : $liveAsset->getFlavorParamsId(); $liveAssetsParams[$flavorParamsId] = $liveAsset; } $flavorParamsConversionProfileArray = flavorParamsConversionProfilePeer::retrieveByConversionProfile($entry->getConversionProfileId()); $liveParamIdsArray = array(); foreach ($flavorParamsConversionProfileArray as $flavorParamsConversionProfile) { /* @var $flavorParamsConversionProfile flavorParamsConversionProfile */ $liveParamIdsArray[] = $flavorParamsConversionProfile->getFlavorParamsId(); } asort($liveParamIdsArray); $liveParamIds = implode(",", $liveParamIdsArray); if ($liveParamIds == $entry->getFlavorParamsIds()) { return; } $streamBitrates = array(); $definedRecordingAnchor = false; foreach ($flavorParamsConversionProfileArray as $flavorParamsConversionProfile) { /* @var $flavorParamsConversionProfile flavorParamsConversionProfile */ $liveParams = $flavorParamsConversionProfile->getassetParams(); if ($liveParams instanceof liveParams) { if ($flavorParamsConversionProfile->getOrigin() == assetParamsOrigin::INGEST) { $streamBitrate = array('bitrate' => $liveParams->getVideoBitrate(), 'width' => $liveParams->getWidth(), 'height' => $liveParams->getHeight(), 'tags' => $liveParams->getTags()); $streamBitrates[] = $streamBitrate; } // check if asset already exists if (isset($liveAssetsParams[$liveParams->getId()])) { $liveAsset = $liveAssetsParams[$liveParams->getId()]; $liveAsset->setDeletedAt(null); // remove the asset from the list, the left assets will be deleted later unset($liveAssetsParams[$liveParams->getId()]); } else { // create a new asset $liveAsset = new liveAsset(); $liveAsset->setType(assetType::LIVE); $liveAsset->setPartnerId($entry->getPartnerId()); $liveAsset->setFlavorParamsId($liveParams->getId()); $liveAsset->setFromAssetParams($liveParams); $liveAsset->setEntryId($entry->getId()); if ($entry->getRecordStatus() && !$definedRecordingAnchor) { // We specifically add a flag that does NOT exist on the live asset, since we can't predict which // live params the conversion profile is going to contain. $liveAsset->addTags(array(assetParams::TAG_RECORDING_ANCHOR)); $definedRecordingAnchor = true; } } // set the status according to the entry status if ($entry->getStatus() == entryStatus::READY) { $liveAsset->setStatus(asset::ASSET_STATUS_READY); } else { $liveAsset->setStatus(asset::ASSET_STATUS_IMPORTING); } $liveAsset->save(); } } // delete all left assets foreach ($liveAssetsParams as $liveAsset) { /* @var $liveAsset liveAsset */ $liveAsset->setDeletedAt(time()); $liveAsset->setStatus(asset::ASSET_STATUS_DELETED); $liveAsset->save(); } if (!count($streamBitrates)) { $streamBitrate = array('bitrate' => 900, 'width' => 640, 'height' => 480); $streamBitrates[] = $streamBitrate; } $entry->setStreamBitrates($streamBitrates); $entry->save(); }