public function Generate(KDLMediaDataSet $mediaSet, KDLProfile $profile, array &$targetList) { if ($mediaSet != null && $mediaSet->IsDataSet()) { $rv = $this->Initialize($mediaSet); if ($rv == false) { /* * fix #9599 - handles rm files that fails to extract media info, but still playable by real player - * simulate video and audio elements, although no source mediainfo is provided */ if ($this->_srcDataSet->_container && $this->_srcDataSet->_container->IsFormatOf(array("realmedia"))) { $rmSrc = $this->_srcDataSet; $rmSrc->_errors = array(); $rmSrc->_video = new KDLVideoData(); $rmSrc->_video->_id = $rmSrc->_video->_format = "realvideo"; $rmSrc->_audio = new KDLAudioData(); $rmSrc->_audio->_id = $rmSrc->_audio->_format = "realaudio"; $rmSrc->_warnings[KDLConstants::ContainerIndex][] = KDLWarnings::ToString(KDLWarnings::RealMediaMissingContent); KalturaLog::log("An invalid source RealMedia file thatfails to provide valid mediaInfodata. Set up a flavor with 'default' params."); } else { return false; } } } if ($profile == null) { return true; } $this->GenerateTargetFlavors($profile, $targetList); if (count($this->_srcDataSet->_errors) > 0) { return false; } return true; }
public function GenerateTarget(KDLMediaDataSet $source) { if ($source == null || !$source->IsDataSet() || $this->_flags & self::ForceCommandLineFlagBit) { KalturaLog::log("FORCE " . $this->_flags); $target = clone $this; if ($target->_video && ($target->_video->_gop === null || $target->_video->_gop == 0)) { $target->_video->_gop = KDLConstants::DefaultGOP; } $target->_warnings[KDLConstants::ContainerIndex][] = KDLWarnings::ToString(KDLWarnings::ForceCommandline); } else { $target = $this->generateTargetFlavor($source); if ($target->_video == "" && $target->_audio == "" && $target->_image == "") { // "Invalid File - No media content"; $target->_errors[KDLConstants::ContainerIndex][] = KDLErrors::ToString(KDLErrors::NoValidMediaStream); } if ($target->validateTranscoders($source, $target->_transcoders) == false) { // "No valid transcoder"; $target->_errors[KDLConstants::ContainerIndex][] = KDLErrors::ToString(KDLErrors::NoValidTranscoders); } //kLog::log("==>\n".print_r($target->_transcoders,true)); } $this->generateCommandLines($target, $target->_transcoders); return $target; }
public function ValidateProduct(KDLMediaDataSet $source, KDLFlavor $product) { KalturaLog::log(".SRC-->" . $source->ToString()); KalturaLog::log(".TRG-->" . $this->ToString()); KalturaLog::log(".PRD-->" . $product->ToString()); $rv = $product->ValidateFlavor(); if ($source) { $srcVid = $source->_video; $srcAud = $source->_audio; $srcCont = $source->_container; } else { $srcVid = null; $srcAud = null; $srcCont = null; } /* * ARF (webex) sources don't have proper mediaInfo - thus can not validate the product, skip it * * - The second portion of the 'if condition' is a workaround to handle invalidly passed inter-src * asset both as a source and as a product. * It is 'strstr' rather than 'strcmp', because call to 'product->ValidateFlavor' might add warnings to the ToString */ // if(isset($srcCont) && $srcCont->GetIdOrFormat()=='arf') { if (isset($srcCont) && $srcCont->GetIdOrFormat() == 'arf' || strstr($product->ToString(), $source->ToString()) != false) { KalturaLog::log("ARF (webex) sources don't have proper mediaInfo - thus can not validate the product"); return true; } /* * WVM (DRM Widevine) sources don't have proper mediaInfo - thus can not validate the product, skip it */ if (isset($this->_container) && $this->_container->GetIdOrFormat() == 'wvm') { KalturaLog::log("WVM (DRM Widevine) sources don't have proper mediaInfo - thus can not validate the product"); return true; } /* * Evaluate source duration, to be used to check the product duration validity */ $plannedDur = 0; if ($this->_clipDur && $this->_clipDur > 0) { $plannedDur = $this->_clipDur; $vDur = $plannedDur; $aDur = $plannedDur; $cDur = $plannedDur; } else { $vDur = isset($srcVid) ? $srcVid->_duration : 0; $aDur = isset($srcAud) ? $srcAud->_duration : 0; $cDur = isset($srcCont) ? $srcCont->_duration : 0; $plannedDur = max(max($aDur, $vDur), $cDur); } /* * Allow conversion and fixing of invalidly muxed WEB-CAM recordecd files - * - FLV/Sorenson/Nellimossr * - very HUGE duration * - very LOW bitrate - about several bits-per-sec. * In such cases the 'duration validation' is un-applicable * if(isset($srcVid) && $srcVid->IsFormatOf(array("h.263","h263","sorenson spark","vp6")) && isset($srcAud) && $srcAud->IsFormatOf(array('nellymoser')) && $cDur>0 && isset($srcCont->_fileSize)){ if($srcCont->_fileSize*8000/$cDur<KDLSanityLimits::MinBitrate) { KalturaLog::log("Invalid WEB-CAM source file. Duration validation is un-applicable"); return true; } } */ if ($this->_video !== null) { if ($product->_video === null) { $product->_errors[KDLConstants::VideoIndex][] = KDLErrors::ToString(KDLErrors::MissingMediaStream); $rv = false; } else { $prdVid = $product->_video; $trgVid = $this->_video; /* * On short durations, the 'granulariity' of a single frame dur might cause invalidation. * Don't check for <2sec */ if ($plannedDur > 2000) { if ($prdVid->_duration < $plannedDur * KDLSanityLimits::MinDurationFactor || $prdVid->_duration > $plannedDur * KDLSanityLimits::MaxDurationFactor) { //This check was added to filter out files that have no duration set on their metadata and are of type ogg or ogv to avoid failure on product validation (SUP 546) if ($aDur == 0 && in_array(strtolower($this->_container->GetIdOrFormat()), array("ogg", "ogv"))) { //Do Nothing } else { $product->_errors[KDLConstants::VideoIndex][] = KDLErrors::ToString(KDLErrors::InvalidDuration, $prdVid->_duration / 1000, $plannedDur / 1000); $rv = false; } } else { if ($prdVid->_duration < $plannedDur * KDLConstants::ProductDurationFactor) { $product->_warnings[KDLConstants::VideoIndex][] = KDLWarnings::ToString(KDLWarnings::ProductShortDuration, $prdVid->_duration, $plannedDur); } } } if (isset($srcVid) && $prdVid->_bitRate < $trgVid->_bitRate * KDLConstants::ProductBitrateFactor) { $product->_warnings[KDLConstants::VideoIndex][] = KDLWarnings::ToString(KDLWarnings::ProductLowBitrate, $prdVid->_bitRate, $srcVid->_bitRate); } } } if ($this->_audio !== null) { if ($product->_audio === null) { $product->_errors[KDLConstants::AudioIndex][] = KDLErrors::ToString(KDLErrors::MissingMediaStream); $rv = false; } else { $prdAud = $product->_audio; $trgAud = $this->_audio; /* * On short durations, the 'granulariity' of a single frame dur might cause invalidation. * Don't check for <2sec */ if ($plannedDur > 2000) { if ($prdAud->_duration < $plannedDur * KDLSanityLimits::MinDurationFactor || $prdAud->_duration > $plannedDur * KDLSanityLimits::MaxDurationFactor) { $product->_errors[KDLConstants::AudioIndex][] = KDLErrors::ToString(KDLErrors::InvalidDuration, $prdAud->_duration / 1000, $plannedDur / 1000); $rv = false; } else { if ($prdAud->_duration < $plannedDur * KDLConstants::ProductDurationFactor) { $product->_warnings[KDLConstants::AudioIndex][] = KDLWarnings::ToString(KDLWarnings::ProductShortDuration, $prdAud->_duration, $plannedDur); } } } if (isset($srcAud) && $prdAud->_bitRate < $trgAud->_bitRate * KDLConstants::ProductBitrateFactor) { $product->_warnings[KDLConstants::AudioIndex][] = KDLWarnings::ToString(KDLWarnings::ProductLowBitrate, $prdAud->_bitRate, $srcAud->_bitRate); } } } if ($product->_video === null && $product->_audio === null) { // "Invalid File - No media content."; $product->_errors[KDLConstants::ContainerIndex][] = KDLErrors::ToString(KDLErrors::NoValidMediaStream); } KalturaLog::log(".PRD-->" . $product->ToString()); return $rv; }
public static function runMediasetTest(KDLMediaDataSet $mediaSet, &$dlPrc, $profile = null) { $inFile = realpath($mediaSet->_container->_fileName); //$mediaSet = 100; //new KDLMediaDataSet(); KalturaLog::log("....S-->" . $mediaSet->ToString()); // unset($targetList); // Remarked by Tan-Tan $targetList doesn't exist $targetList = array(); $errors = array(); $warnings = array(); $dlPrc = new KDLProcessor(); $dlPrc->Generate($mediaSet, $profile, $targetList); $dlPrc->_targets = $targetList; $errors = $errors + $dlPrc->get_errors(); $warnings = $warnings + $dlPrc->get_warnings(); if (count($errors) > 0) { $rv = false; } else { $rv = true; } if ($rv == false) { KalturaLog::log("....E==>"); print_r($errors); KalturaLog::log("\n"); } KalturaLog::log("....W==>"); print_r($warnings); KalturaLog::log("\n"); if ($profile == null) { return; } $xmlStr = KDLProcessor::ProceessFlavorsForCollection($targetList); KalturaLog::log(__METHOD__ . "-->XML-->\n" . print_r($xmlStr, true) . "\n<--"); foreach ($targetList as $target) { $output = array(); $rv = 0; KalturaLog::log("...T-->" . $target->ToString()); $outFile = "aaa1.mp4"; if (file_exists($outFile)) { unlink($outFile); } $cmdLineGenerator = $target->SetTranscoderCmdLineGenerator($inFile, $outFile); $cmdLineGenerator->_clipDur = 10000; $exeStr = "FFMpeg " . $cmdLineGenerator->FFMpeg(null); // KalturaLog::log( ".CMD-->".$exeStr); $exeStr = "cli_encode " . $cmdLineGenerator->Generate(new KDLOperationParams(KDLTranscoders::ON2), 1000); kLog::log(".CMD-->" . $exeStr); $exeStr = "mencoder " . $cmdLineGenerator->Generate(new KDLOperationParams(KDLTranscoders::MENCODER), 1000); kLog::log(".CMD-->" . $exeStr); $exeStr = "ffmpeg " . $cmdLineGenerator->Generate(new KDLOperationParams(KDLTranscoders::FFMPEG), 1000); kLog::log(".CMD-->" . $exeStr); exec($exeStr, $output, $rv); kLog::log("..RV-->In" . $inFile . "==>"); if (!file_exists($outFile) || kFile::fileSize($outFile) == 0) { kLog::log("Failed"); } else { kLog::log("Succeeded, Filesize:" . kFile::fileSize($outFile)); $mediaInfoStr = shell_exec(MediaInfoProgram . " " . realpath($outFile)); $medLoader = new KDLMediaInfoLoader($mediaInfoStr); $product = new KDLFlavor(); $medLoader->Load($product); $target->ValidateProduct($mediaSet, $product); kLog::log("\n" . $mediaInfoStr); // kLog::log( ".PRD-->".$product->ToString()); // unlink($outFile); } } }
public function GenerateIntermediateSource(KDLMediaDataSet $mediaSet, KDLProfile $profile = null) { /* * Check minimal source validity, else get out */ if ($mediaSet == null || !$mediaSet->IsDataSet()) { return null; } /* * Source is invalid if Initialize() fails, unless it is an ARF */ if (!(isset($mediaSet->_container) && $mediaSet->_container->_format == "arf" || $mediaSet->Initialize())) { return null; } $interSrcProfile = null; $forceAudioStream = false; /* * For ARF ==> webex plugin */ if (isset($mediaSet->_container) && $mediaSet->_container->IsFormatOf(array("arf"))) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::COPY, KDLVideoTarget::WVC1A, 4000, 1080, KDLAudioTarget::WMA, 128, 0, 1, "webexNbrplayer.WebexNbrplayer"); /* * Following creates 3 retries for Webex conversions. * Required for the sake of 'garbled audio' issue. */ $interSrcFlavor = $interSrcProfile->_flavors[0]; $interSrcFlavor->_transcoders[] = $interSrcFlavor->_transcoders[0]; $interSrcFlavor->_transcoders[] = $interSrcFlavor->_transcoders[0]; } else { if (isset($mediaSet->_video) && $mediaSet->_video->IsFormatOf(array("gotomeeting", "g2m3", "gotomeeting3"))) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::WMV, KDLVideoTarget::WVC1A, 4000, 1080, KDLAudioTarget::WMA, 128, 0, 1, "expressionEncoder.ExpressionEncoder"); } else { if (isset($mediaSet->_video) && ($mediaSet->_container->IsFormatOf(array("qt", "mov")) && $mediaSet->_video->IsFormatOf(array("wmv", "wmv2", "wmv3", "wvc1", "vc1", "vc-1")) && $mediaSet->_audio->IsFormatOf(array("wma", "wma2", "wma3", "windows media audio", "windows media audio 10 professional")))) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::MP4, KDLVideoTarget::H264H, 4000, 1080, KDLAudioTarget::AAC, 128, 0, 1, "quickTimeTools.QuickTimeTools"); } else { if (isset($mediaSet->_video) && $mediaSet->_video->IsFormatOf(array("xdvd", "xdva", "xdvb", "xdvc", "xdve", "xdvf", "xdv4", "hdv2"))) { foreach ($profile->_flavors as $flvr) { foreach ($flvr->_transcoders as $trans) { if ($trans->_id == KDLTranscoders::ON2) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::MP4, KDLVideoTarget::H264H, 4000, 1080, KDLAudioTarget::AAC, 128, 0, 0, KDLTranscoders::FFMPEG); break; } } if (isset($interSrcProfile)) { break; } } } else { if (isset($mediaSet->_video) && !isset($mediaSet->_audio)) { foreach ($profile->_flavors as $flvr) { if (preg_match('/widevine/', strtolower($flvr->_tags), $matches)) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::MP4, KDLVideoTarget::H264H, 4000, 1080, KDLAudioTarget::AAC, 128, 0, 0, KDLTranscoders::FFMPEG); $forceAudioStream = true; break; } } } else { if (isset($mediaSet->_video) && $mediaSet->_video->IsFormatOf(array("wvc1", "wmv3")) && isset($mediaSet->_contentStreams) && isset($mediaSet->_contentStreams->video) && count($mediaSet->_contentStreams->video) > 0 && isset($mediaSet->_contentStreams->video[0]->progressiveSegmented) && $mediaSet->_contentStreams->video[0]->progressiveSegmented == true) { foreach ($profile->_flavors as $flvr) { foreach ($flvr->_transcoders as $trans) { if ($trans->_id == KDLTranscoders::FFMPEG) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::MP4, KDLVideoTarget::H264H, 4000, 1080, KDLAudioTarget::AAC, 128, 0, 0, KDLTranscoders::MENCODER); break; } } if (isset($interSrcProfile)) { break; } } } } } } } } /* else if($mediaSet->_video->IsFormatOf(array("tscc","tsc2"))) { $interSrcProfile = $this->setProfileWithIntermediateSource(KDLContainerTarget::MP4, KDLVideoTarget::H264H, 4000, 1080, KDLAudioTarget::AAC, 128, 0, 0, KDLTranscoders::FFMPEG); } */ /* * If no "inter-src" cases ==> get out */ if (!isset($interSrcProfile)) { return null; } KalturaLog::log("Automatic Intermediate Source will be generated"); $targetList = array(); $this->Generate($mediaSet, $interSrcProfile, $targetList); if (count($targetList) == 0) { return null; } if (!isset($targetList[0]->_video->_width)) { $targetList[0]->_video->_width = 0; } //Add silent track to video if ($forceAudioStream) { //When duration is set on the source we will use it instead of the -shortest to avoid large difference between video and audio difference if ($this->_srcDataSet->_video->_duration) { $useToAddSilence = "-t " . $this->_srcDataSet->_video->_duration / 1000; } else { $useToAddSilence = "-shortest"; } $cmd = $targetList[0]->_transcoders[0]->_cmd; $cmd = str_replace("__inFileName__", "__inFileName__ -ar 44100 -ac 2 -f s16le -i /dev/zero " . $useToAddSilence, $cmd); $cmd = str_replace("-an", "-b:a 64k", $cmd); $targetList[0]->_transcoders[0]->_cmd = $cmd; } return $targetList[0]; }