public static function decideProfileFlavorsConvert(BatchJob $parentJob, BatchJob $convertProfileJob, array $flavors, array $conversionProfileFlavorParams, mediaInfo $mediaInfo = null)
 {
     $entryId = $convertProfileJob->getEntryId();
     $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);
         return false;
     }
     $errDescription = null;
     $finalFlavors = self::validateConversionProfile($convertProfileJob->getPartnerId(), $entryId, $mediaInfo, $flavors, $conversionProfileFlavorParams, $errDescription);
     KalturaLog::log(count($finalFlavors) . " flavors returned from the decision layer");
     if (is_null($finalFlavors)) {
         $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription);
         KalturaLog::log("No flavors created");
         throw new Exception($errDescription);
     }
     if (strlen($errDescription)) {
         $err = $convertProfileJob->getDescription() . $errDescription;
         $convertProfileJob->setDescription($err);
         $convertProfileJob->save();
     }
     $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET);
     $conversionsCreated = 0;
     $entry = $convertProfileJob->getEntry();
     if (!$entry) {
         throw new APIException(APIErrors::INVALID_ENTRY, $convertProfileJob, $entryId);
     }
     $flavorsCollections = array();
     // create a convert job per each flavor
     foreach ($finalFlavors as $flavor) {
         $flavorAsset = kBatchManager::createFlavorAsset($flavor, $entry->getPartnerId(), $entry->getId());
         if (!$flavorAsset) {
             KalturaLog::log("Flavor asset could not be created, flavor conversion won't be created");
             continue;
         }
         $collectionTag = $flavor->getCollectionTag();
         if ($collectionTag) {
             $flavorsCollections[$collectionTag][] = $flavor;
             continue;
         }
         KalturaLog::log("Adding flavor conversion with flavor params output id [" . $flavor->getId() . "] and flavor params asset id [" . $flavorAsset->getId() . "]");
         $madiaInfoId = $mediaInfo ? $mediaInfo->getId() : null;
         $createdJob = kJobsManager::addFlavorConvertJob($srcSyncKey, $flavor, $flavorAsset->getId(), $madiaInfoId, $parentJob);
         if ($createdJob) {
             $conversionsCreated++;
         }
     }
     foreach ($flavorsCollections as $tag => $flavors) {
         switch ($tag) {
             case flavorParams::TAG_ISM:
                 $createdJob = kJobsManager::addConvertIsmCollectionJob($tag, $srcSyncKey, $entry, $parentJob, $flavors);
                 if ($createdJob) {
                     $conversionsCreated++;
                 }
                 break;
             default:
                 KalturaLog::log("Error: Invalid collection tag [{$tag}]");
                 break;
         }
     }
     if (!$conversionsCreated) {
         $convertProfileJob = kJobsManager::failBatchJob($convertProfileJob, $errDescription);
         KalturaLog::log("No flavors created: {$errDescription}");
         return false;
     }
     return true;
 }
Beispiel #2
0
 /**
  * @param BatchJob $dbBatchJob
  * @param kConvertJobData $data
  * @param BatchJob $twinJob
  * @return BatchJob
  */
 public static function handleConvertFinished(BatchJob $dbBatchJob, kConvertJobData $data, BatchJob $twinJob = null)
 {
     KalturaLog::debug("Convert finished with destination file: " . $data->getDestFileSyncLocalPath());
     if ($dbBatchJob->getAbort()) {
         return $dbBatchJob;
     }
     // verifies that flavor asset created
     if (!$data->getFlavorAssetId()) {
         throw new APIException(APIErrors::INVALID_FLAVOR_ASSET_ID, $data->getFlavorAssetId());
     }
     $flavorAsset = flavorAssetPeer::retrieveById($data->getFlavorAssetId());
     // verifies that flavor asset exists
     if (!$flavorAsset) {
         throw new APIException(APIErrors::INVALID_FLAVOR_ASSET_ID, $data->getFlavorAssetId());
     }
     $flavorAsset->incrementVersion();
     $flavorAsset->save();
     $syncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET);
     kFileSyncUtils::moveFromFile($data->getDestFileSyncLocalPath(), $syncKey);
     // creats the file sync
     $logSyncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_CONVERT_LOG);
     try {
         kFileSyncUtils::moveFromFile($data->getDestFileSyncLocalPath() . '.log', $logSyncKey);
     } catch (Exception $e) {
         $err = 'Saving conversion log: ' . $e->getMessage();
         KalturaLog::err($err);
         $desc = $dbBatchJob->getDescription() . "\n" . $err;
         $dbBatchJob->getDescription($desc);
     }
     $data->setDestFileSyncLocalPath(kFileSyncUtils::getLocalFilePathForKey($syncKey));
     KalturaLog::debug("Convert archived file to: " . $data->getDestFileSyncLocalPath());
     // save the data changes to the db
     $dbBatchJob->setData($data);
     $dbBatchJob->save();
     $entry = $dbBatchJob->getEntry();
     if (!$entry) {
         throw new APIException(APIErrors::INVALID_ENTRY, $dbBatchJob, $dbBatchJob->getEntryId());
     }
     $entry->addFlavorParamsId($data->getFlavorParamsOutput()->getFlavorParamsId());
     $entry->save();
     $offset = $entry->getThumbOffset();
     // entry getThumbOffset now takes the partner DefThumbOffset into consideration
     $flavorParamsOutput = $data->getFlavorParamsOutput();
     $createThumb = true;
     $extractMedia = true;
     if ($entry->getType() != entryType::MEDIA_CLIP) {
         // e.g. document
         $extractMedia = false;
     }
     $rootBatchJob = $dbBatchJob->getRootJob();
     if (!$rootBatchJob) {
         $createThumb = false;
     } else {
         if ($rootBatchJob->getJobType() != BatchJobType::CONVERT_PROFILE) {
             $createThumb = false;
         } else {
             $rootBatchJobData = $rootBatchJob->getData();
             if ($rootBatchJobData instanceof kConvertProfileJobData) {
                 $createThumb = $rootBatchJobData->getCreateThumb();
                 $extractMedia = $rootBatchJobData->getExtractMedia();
             }
         }
     }
     // For apple http flavors do not attempt to get thumbs and media info,
     // It is up to the operator to provide that kind of data, rather than hardcoded check
     // To-fix
     if ($flavorParamsOutput->getFormat() == assetParams::CONTAINER_FORMAT_APPLEHTTP) {
         $createThumb = false;
         $extractMedia = false;
     }
     if ($createThumb) {
         $videoCodec = $flavorParamsOutput->getVideoCodec();
         if (in_array($videoCodec, self::$thumbUnSupportVideoCodecs)) {
             $createThumb = false;
         }
     }
     $operatorSet = new kOperatorSets();
     $operatorSet->setSerialized(stripslashes($flavorParamsOutput->getOperators()));
     //		KalturaLog::debug("Operators: ".$flavorParamsOutput->getOperators()
     //			."\ngetCurrentOperationSet:".$data->getCurrentOperationSet()
     //			."\ngetCurrentOperationIndex:".$data->getCurrentOperationIndex());
     //		KalturaLog::debug("Operators set: " . print_r($operatorSet, true));
     $nextOperator = $operatorSet->getOperator($data->getCurrentOperationSet(), $data->getCurrentOperationIndex() + 1);
     $nextJob = null;
     if ($nextOperator) {
         //			KalturaLog::debug("Found next operator");
         $nextJob = kJobsManager::addFlavorConvertJob($syncKey, $flavorParamsOutput, $data->getFlavorAssetId(), $data->getMediaInfoId(), $dbBatchJob, $dbBatchJob->getJobSubType());
     }
     if (!$nextJob) {
         if ($createThumb || $extractMedia) {
             $jobSubType = BatchJob::BATCHJOB_SUB_TYPE_POSTCONVERT_FLAVOR;
             if ($flavorAsset->getIsOriginal()) {
                 $jobSubType = BatchJob::BATCHJOB_SUB_TYPE_POSTCONVERT_SOURCE;
             }
             kJobsManager::addPostConvertJob($dbBatchJob, $jobSubType, $data->getDestFileSyncLocalPath(), $data->getFlavorAssetId(), $flavorParamsOutput->getId(), $createThumb, $offset);
         } else {
             $flavorAsset = kBusinessPostConvertDL::handleFlavorReady($dbBatchJob, $data->getFlavorAssetId());
             if ($flavorAsset) {
                 if ($flavorAsset->hasTag(flavorParams::TAG_SOURCE)) {
                     kBusinessPreConvertDL::continueProfileConvert($dbBatchJob);
                 }
                 if ($flavorAsset->getType() == assetType::FLAVOR) {
                     $flavorAsset->setBitrate($flavorParamsOutput->getVideoBitrate());
                     $flavorAsset->setWidth($flavorParamsOutput->getWidth());
                     $flavorAsset->setHeight($flavorParamsOutput->getHeight());
                     $flavorAsset->setFrameRate($flavorParamsOutput->getFrameRate());
                     $flavorAsset->setIsOriginal(0);
                     $flavorAsset->save();
                 }
                 kBusinessPostConvertDL::handleConvertFinished($dbBatchJob, $flavorAsset);
             }
         }
     }
     // this logic decide when a thumbnail should be created
     if ($rootBatchJob && $rootBatchJob->getJobType() == BatchJobType::BULKDOWNLOAD) {
         $localPath = kFileSyncUtils::getLocalFilePathForKey($syncKey);
         $downloadUrl = $flavorAsset->getDownloadUrl();
         $notificationData = array("puserId" => $entry->getPuserId(), "entryId" => $entry->getId(), "entryIntId" => $entry->getIntId(), "entryVersion" => $entry->getVersion(), "fileFormat" => $flavorAsset->getFileExt(), "archivedFile" => $localPath, "downoladPath" => $localPath, "conversionQuality" => $entry->getConversionQuality(), "downloadUrl" => $downloadUrl);
         $extraData = array("data" => json_encode($notificationData), "partner_id" => $entry->getPartnerId(), "puser_id" => $entry->getPuserId(), "entry_id" => $entry->getId(), "entry_int_id" => $entry->getIntId(), "entry_version" => $entry->getVersion(), "file_format" => $flavorAsset->getFileExt(), "archived_file" => $localPath, "downolad_path" => $localPath, "target" => $localPath, "conversion_quality" => $entry->getConversionQuality(), "download_url" => $downloadUrl, "status" => $entry->getStatus(), "abort" => $dbBatchJob->getAbort(), "progress" => $dbBatchJob->getProgress(), "message" => $dbBatchJob->getMessage(), "description" => $dbBatchJob->getDescription(), "updates_count" => $dbBatchJob->getUpdatesCount(), "job_type" => BatchJobType::DOWNLOAD, "status" => BatchJob::BATCHJOB_STATUS_FINISHED, "progress" => 100, "debug" => __LINE__);
         myNotificationMgr::createNotification(kNotificationJobData::NOTIFICATION_TYPE_BATCH_JOB_SUCCEEDED, $dbBatchJob, $dbBatchJob->getPartnerId(), null, null, $extraData, $dbBatchJob->getEntryId());
     }
     return $dbBatchJob;
 }
 private static function decideSourceFlavorConvert($entryId, assetParams $sourceFlavor = null, flavorAsset $originalFlavorAsset, $conversionProfileId, $flavors, mediaInfo $mediaInfo = null, BatchJob $parentJob, BatchJob $convertProfileJob)
 {
     if ($sourceFlavor && ($sourceFlavor->getOperators() || $sourceFlavor->getConversionEngines()) && $originalFlavorAsset->getInterFlowCount() == null) {
         KalturaLog::log("Source flavor asset requires conversion");
         self::adjustAssetParams($entryId, array($sourceFlavor));
         $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET);
         $errDescription = null;
         $sourceFlavorOutput = self::validateFlavorAndMediaInfo($sourceFlavor, $mediaInfo, $errDescription);
         if (!$sourceFlavorOutput) {
             if (!$errDescription) {
                 $errDescription = "Failed to create flavor params output from source flavor";
             }
             $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}");
             $originalFlavorAsset->setStatus(flavorAsset::ASSET_STATUS_ERROR);
             $originalFlavorAsset->save();
             kBatchManager::updateEntry($entryId, entryStatus::ERROR_CONVERTING);
             kJobsManager::updateBatchJob($convertProfileJob, BatchJob::BATCHJOB_STATUS_FAILED);
             return false;
         }
         /*
          * If the conversion profile contains source flavor and the source is tagged with 'save_source' ==> 
          * save the original source asset in another asset, in order 
          * to prevent its liquidated by the inter-source asset.
          */
         if (isset($sourceFlavor) && strstr($sourceFlavor->getTagsArray(), assetParams::TAG_SAVE_SOURCE) !== false) {
             self::saveOriginalSource($mediaInfo);
         }
     } elseif ($mediaInfo) {
         /*
          * Check whether there is a need for an intermediate source pre-processing
          */
         $sourceFlavorOutput = KDLWrap::GenerateIntermediateSource($mediaInfo, $flavors);
         if (!$sourceFlavorOutput) {
             return true;
         }
         $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET);
         $errDescription = null;
         /*
          * Save the original source asset in another asset, in order 
          * to prevent its liquidated by the inter-source asset.
          * But, do it only if the conversion profile contains source flavor
          */
         if (isset($sourceFlavor)) {
             self::saveOriginalSource($mediaInfo);
         }
     }
     /*
      * '_passthrough' controls whether the source is to be 'passthrough' although there 
      * is a source flavor that contains transcoder settings.
      * Looks for a '_passthrough' flag on the source's flavor params output.
      */
     if (!isset($sourceFlavorOutput) || $sourceFlavorOutput->_passthrough == true) {
         return true;
     }
     // save flavor params
     $sourceFlavorOutput->setPartnerId($sourceFlavorOutput->getPartnerId());
     $sourceFlavorOutput->setEntryId($entryId);
     $sourceFlavorOutput->setFlavorAssetId($originalFlavorAsset->getId());
     $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion());
     $sourceFlavorOutput->save();
     if ($errDescription) {
         $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}");
     }
     $errDescription = kBusinessConvertDL::parseFlavorDescription($sourceFlavorOutput);
     if ($errDescription) {
         $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}");
     }
     // decided by the business logic layer
     if ($sourceFlavorOutput->_create_anyway) {
         KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] selected to be created anyway");
     } else {
         if (!$sourceFlavorOutput->IsValid()) {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is invalid");
             $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR);
             $originalFlavorAsset->save();
             $errDescription = "Source flavor could not be converted";
             self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $convertProfileJob->getEntryId());
             return false;
         }
         if ($sourceFlavorOutput->_force) {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is forced");
         } elseif ($sourceFlavorOutput->_isNonComply) {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is none-comply");
         } else {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is valid");
         }
     }
     $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING);
     if (isset($sourceFlavor)) {
         $tagsArr = $sourceFlavor->getTagsArray();
         // No need for 'save_source' tag on the inter-src asset, remove it.
         if (($key = array_search(assetParams::TAG_SAVE_SOURCE, $tagsArr)) !== false) {
             unset($tagsArr[$key]);
         }
         $originalFlavorAsset->addTags($tagsArr);
         $originalFlavorAsset->setFileExt($sourceFlavorOutput->getFileExt());
         $originalFlavorAsset->save();
     }
     // save flavor params
     $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion());
     $sourceFlavorOutput->save();
     $mediaInfoId = null;
     if ($mediaInfo) {
         $mediaInfoId = $mediaInfo->getId();
     }
     kJobsManager::addFlavorConvertJob(array($srcSyncKey), $sourceFlavorOutput, $originalFlavorAsset->getId(), $conversionProfileId, $mediaInfoId, $parentJob);
     return false;
 }
 private static function decideSourceFlavorConvert($entryId, assetParams $sourceFlavor = null, flavorAsset $originalFlavorAsset, $conversionProfileId, $flavors, mediaInfo $mediaInfo = null, BatchJob $parentJob, BatchJob $convertProfileJob)
 {
     if ($sourceFlavor && ($sourceFlavor->getOperators() || $sourceFlavor->getConversionEngines()) && $originalFlavorAsset->getInterFlowCount() == null) {
         KalturaLog::log("Source flavor asset requires conversion");
         self::adjustAssetParams($entryId, array($sourceFlavor));
         $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET);
         $errDescription = null;
         $sourceFlavorOutput = self::validateFlavorAndMediaInfo($sourceFlavor, $mediaInfo, $errDescription);
         if (!$sourceFlavorOutput) {
             if (!$errDescription) {
                 $errDescription = "Failed to create flavor params output from source flavor";
             }
             $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}");
             $originalFlavorAsset->setStatus(flavorAsset::ASSET_STATUS_ERROR);
             $originalFlavorAsset->save();
             kBatchManager::updateEntry($entryId, entryStatus::ERROR_CONVERTING);
             kJobsManager::updateBatchJob($convertProfileJob, BatchJob::BATCHJOB_STATUS_FAILED);
             return false;
         }
     } elseif ($mediaInfo) {
         /*
          * Check whether there is a need for an intermediate source pre-processing
          */
         $sourceFlavorOutput = KDLWrap::GenerateIntermediateSource($mediaInfo, $flavors);
         if (!$sourceFlavorOutput) {
             return true;
         }
         $srcSyncKey = $originalFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET);
         $errDescription = null;
         /*
          * Save the original source asset in another asset, in order 
          * to prevent its liquidated by the inter-source asset.
          * But, do it only if the conversion profile contains source flavor
          */
         if ($sourceFlavor) {
             $sourceAsset = assetPeer::retrieveById($mediaInfo->getFlavorAssetId());
             $copyFlavorParams = assetParamsPeer::retrieveBySystemName(self::SAVE_ORIGINAL_SOURCE_FLAVOR_PARAM_SYS_NAME);
             if (!$copyFlavorParams) {
                 throw new APIException(APIErrors::OBJECT_NOT_FOUND);
             }
             $asset = $sourceAsset->copy();
             $asset->setFlavorParamsId($copyFlavorParams->getId());
             $asset->setFromAssetParams($copyFlavorParams);
             $asset->setStatus(flavorAsset::ASSET_STATUS_READY);
             $asset->setIsOriginal(0);
             $asset->setTags($copyFlavorParams->getTags());
             $asset->incrementVersion();
             $asset->save();
             kFileSyncUtils::createSyncFileLinkForKey($asset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET), $sourceAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET));
             $origFileSync = kFileSyncUtils::getLocalFileSyncForKey($sourceAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET));
             $asset->setSize(intval($origFileSync->getFileSize() / 1000));
             $asset->save();
         }
     }
     /*
      * '_passthrough' controls whether the source is to be 'passthrough' although there 
      * is a source flavor that contains transcoder settings.
      * Looks for a '_passthrough' flag on the source's flavor params output.
      */
     if (!$sourceFlavorOutput || $sourceFlavorOutput->_passthrough == true) {
         return true;
     }
     // save flavor params
     $sourceFlavorOutput->setPartnerId($sourceFlavorOutput->getPartnerId());
     $sourceFlavorOutput->setEntryId($entryId);
     $sourceFlavorOutput->setFlavorAssetId($originalFlavorAsset->getId());
     $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion());
     $sourceFlavorOutput->save();
     if ($errDescription) {
         $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}");
     }
     $errDescription = kBusinessConvertDL::parseFlavorDescription($sourceFlavorOutput);
     if ($errDescription) {
         $originalFlavorAsset->setDescription($originalFlavorAsset->getDescription() . "\n{$errDescription}");
     }
     // decided by the business logic layer
     if ($sourceFlavorOutput->_create_anyway) {
         KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] selected to be created anyway");
     } else {
         if (!$sourceFlavorOutput->IsValid()) {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is invalid");
             $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_ERROR);
             $originalFlavorAsset->save();
             $errDescription = "Source flavor could not be converted";
             self::setError($errDescription, $convertProfileJob, BatchJobType::CONVERT_PROFILE, $convertProfileJob->getEntryId());
             return false;
         }
         if ($sourceFlavorOutput->_force) {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is forced");
         } elseif ($sourceFlavorOutput->_isNonComply) {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is none-comply");
         } else {
             KalturaLog::log("Flavor [" . $sourceFlavorOutput->getFlavorParamsId() . "] is valid");
         }
     }
     $originalFlavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_CONVERTING);
     if (isset($sourceFlavor)) {
         $originalFlavorAsset->addTags($sourceFlavor->getTagsArray());
         $originalFlavorAsset->setFileExt($sourceFlavorOutput->getFileExt());
         $originalFlavorAsset->save();
     }
     // save flavor params
     $sourceFlavorOutput->setFlavorAssetVersion($originalFlavorAsset->getVersion());
     $sourceFlavorOutput->save();
     $mediaInfoId = null;
     if ($mediaInfo) {
         $mediaInfoId = $mediaInfo->getId();
     }
     kJobsManager::addFlavorConvertJob(array($srcSyncKey), $sourceFlavorOutput, $originalFlavorAsset->getId(), $conversionProfileId, $mediaInfoId, $parentJob);
     return false;
 }
Beispiel #5
0
 private static function createNextJob(flavorParamsOutput $flavorParamsOutput, BatchJob $dbBatchJob, kConvertJobData $data, FileSyncKey $syncKey)
 {
     $operatorSet = new kOperatorSets();
     $operatorSet->setSerialized(stripslashes($flavorParamsOutput->getOperators()));
     $nextOperator = $operatorSet->getOperator($data->getCurrentOperationSet(), $data->getCurrentOperationIndex() + 1);
     $nextJob = null;
     if ($nextOperator) {
         //Note: consequent operators doesn't support at the moment conversion based on outputs of multiple sources
         $nextJob = kJobsManager::addFlavorConvertJob(array($syncKey), $flavorParamsOutput, $data->getFlavorAssetId(), null, $data->getMediaInfoId(), $dbBatchJob, $dbBatchJob->getJobSubType());
     }
     return $nextJob;
 }