/** * batch validateConversionProfile validates profile completion rules * * @param mediaInfo $mediaInfo * @param array $flavors is array of flavorParams * @param string $errDescription * @return array of flavorParamsOutput */ protected static function validateConversionProfile($partnerId, $entryId, mediaInfo $mediaInfo = null, array $flavors, array $conversionProfileFlavorParams, &$errDescription) { // if there is no media info, the entire profile returned as is, decision layer ignored if (!$mediaInfo) { KalturaLog::log("Validate Conversion Profile, no media info supplied"); // $ret = array(); // foreach($flavors as $flavor) // { // $outFlavor = new flavorParamsOutputWrap(); // $ret[] = flavorParamsOutputPeer::doCopy($flavor, $outFlavor); // } // return $ret; } else { KalturaLog::log("Validate Conversion Profile, media info [" . $mediaInfo->getId() . "]"); } // call the decision layer KalturaLog::log("Generate Target " . count($flavors) . " Flavors supplied"); $cdl = KDLWrap::CDLGenerateTargetFlavors($mediaInfo, $flavors); KalturaLog::log("Generate Target " . count($cdl->_targetList) . " Flavors returned"); // check for errors $errDescription = ''; if (count($cdl->_errors)) { $errDesc = ''; foreach ($cdl->_errors as $section => $errors) { $errDesc .= "{$section} errors: " . join(";", $errors) . "\n"; } KalturaLog::log("Decision layer input errors: {$errDesc}"); $errDescription .= "\nMedia err: {$errDesc}"; } // check for warnings if (count($cdl->_warnings)) { $errDesc = ''; foreach ($cdl->_warnings as $section => $errors) { $errDesc .= "{$section} warnings: " . join(";", $errors) . "\n"; } KalturaLog::log("Decision layer input warnings: {$errDesc}"); $errDescription .= "\nMedia warn: {$errDesc}"; } // rv - returned value from the decision layer if (!$cdl->_rv) { KalturaLog::log("Decision layer returned false"); return null; } // orgenizing the flavors by the tags $tagedFlavors = array(); $hasInvalidRequired = false; foreach ($cdl->_targetList as $flavor) { // overwrite ready behavior from the conversion profile $flavorParamsConversionProfile = $conversionProfileFlavorParams[$flavor->getFlavorParamsId()]; $flavor->_force = $flavorParamsConversionProfile->getForceNoneComplied(); if ($flavorParamsConversionProfile->getReadyBehavior() != flavorParamsConversionProfile::READY_BEHAVIOR_INHERIT_FLAVOR_PARAMS) { $flavor->setReadyBehavior($flavorParamsConversionProfile->getReadyBehavior()); } if (!$flavor->IsValid()) { KalturaLog::log("Flavor [" . $flavor->getFlavorParamsId() . "] is invalid"); // if required - failing the profile if ($flavor->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $errDescription = "Business decision layer, required flavor not valid: " . $flavor->getId(); $errDescription .= kBusinessConvertDL::parseFlavorDescription($flavor); KalturaLog::log($errDescription); kBatchManager::createErrorFlavorAsset($flavor, $partnerId, $entryId, $errDescription); $hasInvalidRequired = true; continue; } } // if required - failing the profile if ($flavor->_isNonComply) { KalturaLog::log("Flavor [" . $flavor->getFlavorParamsId() . "] is none complied"); if ($flavor->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $errDescription = "Business decision layer, required flavor none complied: id[" . $flavor->getId() . "] flavor params id [" . $flavor->getFlavorParamsId() . "]"; $errDescription .= kBusinessConvertDL::parseFlavorDescription($flavor); KalturaLog::log($errDescription); kBatchManager::createErrorFlavorAsset($flavor, $partnerId, $entryId, $errDescription); $hasInvalidRequired = true; continue; } } foreach ($flavor->getTagsArray() as $tag) { KalturaLog::log("Taged [{$tag}] flavor added [" . $flavor->getFlavorParamsId() . "]"); $tagedFlavors[$tag][$flavor->getFlavorParamsId()] = $flavor; } } if ($hasInvalidRequired) { return null; } // filter out all not forced, none complied, and invalid flavors $finalTagedFlavors = array(); foreach ($tagedFlavors as $tag => $tagedFlavorsArray) { KalturaLog::log("Filtering flavors by tag [{$tag}]"); $finalTagedFlavors[$tag] = kBusinessConvertDL::filterTagFlavors($tagedFlavorsArray); } $finalFlavors = array(); foreach ($finalTagedFlavors as $tag => $tagedFlavorsArray) { foreach ($tagedFlavorsArray as $flavorParamsId => $tagedFlavor) { $finalFlavors[$flavorParamsId] = $tagedFlavor; } } // sort the flavors to decide which one will be performed first usort($finalFlavors, array('kBusinessConvertDL', 'compareFlavors')); KalturaLog::log(count($finalFlavors) . " flavors sorted for execution"); return $finalFlavors; }
/** * batch validateConversionProfile validates profile completion rules * * @param mediaInfo $mediaInfo * @param array $flavors is array of flavorParams * @param string $errDescription * @return array of flavorParamsOutput */ protected static function validateConversionProfile($partnerId, $entryId, mediaInfo $mediaInfo = null, array $flavors, array $conversionProfileFlavorParams, &$errDescription) { // if there is no media info, the entire profile returned as is, decision layer ignored if (!$mediaInfo) { KalturaLog::log("Validate Conversion Profile, no media info supplied"); // $ret = array(); // foreach($flavors as $flavor) // { // $outFlavor = new flavorParamsOutputWrap(); // $ret[] = flavorParamsOutputPeer::doCopy($flavor, $outFlavor); // } // return $ret; } else { KalturaLog::log("Validate Conversion Profile, media info [" . $mediaInfo->getId() . "]"); } self::adjustAssetParams($entryId, $flavors); // call the decision layer KalturaLog::log("Generate Target " . count($flavors) . " Flavors supplied"); $cdl = KDLWrap::CDLGenerateTargetFlavors($mediaInfo, $flavors); KalturaLog::log("Generate Target " . count($cdl->_targetList) . " Flavors returned"); // check for errors $errDescription = ''; if (count($cdl->_errors)) { $errDesc = ''; foreach ($cdl->_errors as $section => $errors) { $errDesc .= "{$section} errors: " . join(";", $errors) . "\n"; foreach ($errors as $error) { if (strpos($error, 'Invalid File - No media content' !== false)) { $errDescription .= "\nMedia err: {$errDesc}"; KalturaLog::err($error); throw new kCoreException($error, KDLErrors::NoValidMediaStream); } if (strpos($error, 'Invalid frame dimensions') !== false) { $errDescription .= "\nMedia err: {$errDesc}"; KalturaLog::err($error); throw new kCoreException($error, KDLErrors::SanityInvalidFrameDim); } } } KalturaLog::log("Decision layer input errors: {$errDesc}"); $errDescription .= "\nMedia err: {$errDesc}"; } // check for warnings if (count($cdl->_warnings)) { $errDesc = ''; foreach ($cdl->_warnings as $section => $errors) { $errDesc .= "{$section} warnings: " . join(";", $errors) . "\n"; } KalturaLog::log("Decision layer input warnings: {$errDesc}"); $errDescription .= "\nMedia warn: {$errDesc}"; } // rv - returned value from the decision layer if (!$cdl->_rv) { KalturaLog::log("Decision layer returned false"); return null; } // orgenizing the flavors by the tags $tagedFlavors = array(); $hasInvalidRequired = false; foreach ($cdl->_targetList as $flavor) { // Get conv.prof data for that flavor $flavorParamsConversionProfile = $conversionProfileFlavorParams[$flavor->getFlavorParamsId()]; // Update force-transcode flag. // This flag might be set by the DL, therefore overide only if it is not set. if (!$flavor->_force) { $flavor->_force = $flavorParamsConversionProfile->getForceNoneComplied(); } $flavor->setReadyBehavior($flavorParamsConversionProfile->getReadyBehavior()); if (!$flavor->IsValid()) { KalturaLog::log("Flavor [" . $flavor->getFlavorParamsId() . "] is invalid"); // if required - failing the profile if ($flavor->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED) { $errDescription = "Business decision layer, required flavor not valid: " . $flavor->getId(); $errDescription .= kBusinessConvertDL::parseFlavorDescription($flavor); KalturaLog::log($errDescription); kBatchManager::createErrorFlavorAsset($flavor, $partnerId, $entryId, $errDescription); $hasInvalidRequired = true; continue; } } // if required - failing the profile if ($flavor->_isNonComply) { KalturaLog::log("Flavor [" . $flavor->getFlavorParamsId() . "] is none complied"); // If the flavor is set to 'force' (generate the asset regardless of any Kaltura optimization), // don't fail it even if it is 'NonComply' if ($flavor->getReadyBehavior() == flavorParamsConversionProfile::READY_BEHAVIOR_REQUIRED && !$flavor->_force) { $errDescription = "Business decision layer, required flavor none complied: id[" . $flavor->getId() . "] flavor params id [" . $flavor->getFlavorParamsId() . "]"; $errDescription .= kBusinessConvertDL::parseFlavorDescription($flavor); KalturaLog::log($errDescription); kBatchManager::createErrorFlavorAsset($flavor, $partnerId, $entryId, $errDescription); $hasInvalidRequired = true; continue; } } foreach ($flavor->getTagsArray() as $tag) { KalturaLog::log("Taged [{$tag}] flavor added [" . $flavor->getFlavorParamsId() . "]"); $tagedFlavors[$tag][$flavor->getFlavorParamsId()] = $flavor; } } if ($hasInvalidRequired) { return null; } /* * For 'playset' collections (MBR & ISM) make sure that the flavor that * matches in the best way the source framee size, will be generated. * Optimally this procedure should be executed for EVERY tag. But this * might cause generation of unrequired flavors that might potentially * harm the entry playback. * Furthermore - we have duplicate iOS tagging (iphonenew and ipadnew), * therefore anyhow at least one ipad flavor will be always generated. * The other tags are less relevant for the framesize adjustment cases. */ if (isset($mediaInfo)) { if (array_key_exists(flavorParams::TAG_MBR, $tagedFlavors)) { self::adjustToFramesize($mediaInfo, $tagedFlavors[flavorParams::TAG_MBR]); } if (array_key_exists(flavorParams::TAG_ISM, $tagedFlavors)) { self::adjustToFramesize($mediaInfo, $tagedFlavors[flavorParams::TAG_ISM]); } } // filter out all not forced, none complied, and invalid flavors $finalTagedFlavors = array(); foreach ($tagedFlavors as $tag => $tagedFlavorsArray) { KalturaLog::log("Filtering flavors by tag [{$tag}]"); /* * Digital-watermark tags should not participate in the 'tagged' flavor activation logic */ if (strstr($tag, "watermark_pair_") == false && strstr($tag, self::TAG_VARIANT_A) == false && strstr($tag, self::TAG_VARIANT_B) == false) { $finalTagedFlavors[$tag] = kBusinessConvertDL::filterTagFlavors($tagedFlavorsArray); } else { $finalTagedFlavors[$tag] = $tagedFlavorsArray; } } $finalFlavors = array(); foreach ($finalTagedFlavors as $tag => $tagedFlavorsArray) { foreach ($tagedFlavorsArray as $flavorParamsId => $tagedFlavor) { $finalFlavors[$flavorParamsId] = $tagedFlavor; } } /* * Digital-watermark flavors go through 'find the matching pair' procedure */ if (array_key_exists(self::TAG_VARIANT_A, $finalTagedFlavors) && array_key_exists(self::TAG_VARIANT_B, $finalTagedFlavors)) { $finalFlavors = self::adjustToPairedDigitalWatermarking(self::TAG_VARIANT_A, $finalTagedFlavors, $finalFlavors); $finalFlavors = self::adjustToPairedDigitalWatermarking(self::TAG_VARIANT_B, $finalTagedFlavors, $finalFlavors); } // sort the flavors to decide which one will be performed first usort($finalFlavors, array('kBusinessConvertDL', 'compareFlavors')); KalturaLog::log(count($finalFlavors) . " flavors sorted for execution"); return $finalFlavors; }