/** * Append recorded video to live entry * * @action appendRecording * @param string $entryId Live entry id * @param string $assetId Live asset id * @param KalturaMediaServerIndex $mediaServerIndex * @param KalturaDataCenterContentResource $resource * @param float $duration in seconds * @param bool $isLastChunk Is this the last recorded chunk in the current session (i.e. following a stream stop event) * @return KalturaLiveEntry The updated live entry * * @throws KalturaErrors::ENTRY_ID_NOT_FOUND */ function appendRecordingAction($entryId, $assetId, $mediaServerIndex, KalturaDataCenterContentResource $resource, $duration, $isLastChunk = false) { $dbEntry = entryPeer::retrieveByPK($entryId); if (!$dbEntry || !$dbEntry instanceof LiveEntry) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } $dbAsset = assetPeer::retrieveById($assetId); if (!$dbAsset || !$dbAsset instanceof liveAsset) { throw new KalturaAPIException(KalturaErrors::ASSET_ID_NOT_FOUND, $assetId); } $lastDuration = $dbEntry->getLengthInMsecs(); if (!$lastDuration) { $lastDuration = 0; } $liveSegmentDurationInMsec = (int) ($duration * 1000); $currentDuration = $lastDuration + $liveSegmentDurationInMsec; $maxRecordingDuration = (kConf::get('max_live_recording_duration_hours') + 1) * 60 * 60 * 1000; if ($currentDuration > $maxRecordingDuration) { KalturaLog::err("Entry [{$entryId}] duration [" . $dbEntry->getLengthInMsecs() . "] and current duration [{$currentDuration}] is more than max allwoed duration [{$maxRecordingDuration}]"); throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_RECORDED_DURATION, $entryId); } $kResource = $resource->toObject(); $filename = $kResource->getLocalFilePath(); if (!$resource instanceof KalturaServerFileResource) { $filename = kConf::get('uploaded_segment_destination') . basename($kResource->getLocalFilePath()); kFile::moveFile($kResource->getLocalFilePath(), $filename); chgrp($filename, kConf::get('content_group')); chmod($filename, 0640); } if ($dbAsset->hasTag(assetParams::TAG_RECORDING_ANCHOR) && $mediaServerIndex == KalturaMediaServerIndex::PRIMARY) { KalturaLog::debug("Appending assetId {$assetId} to entryId {$entryId}"); $dbEntry->setLengthInMsecs($currentDuration); // Extract the exact video segment duration from the recorded file $mediaInfoParser = new KMediaInfoMediaParser($filename, kConf::get('bin_path_mediainfo')); $recordedSegmentDurationInMsec = $mediaInfoParser->getMediaInfo()->videoDuration; $currentSegmentVodToLiveDeltaTime = $liveSegmentDurationInMsec - $recordedSegmentDurationInMsec; $recordedSegmentsInfo = $dbEntry->getRecordedSegmentsInfo(); $recordedSegmentsInfo->addSegment($lastDuration, $recordedSegmentDurationInMsec, $currentSegmentVodToLiveDeltaTime); $dbEntry->setRecordedSegmentsInfo($recordedSegmentsInfo); if ($isLastChunk) { // Save last elapsed recording time $dbEntry->setLastElapsedRecordingTime($currentDuration); } $dbEntry->save(); } kJobsManager::addConvertLiveSegmentJob(null, $dbAsset, $mediaServerIndex, $filename, $currentDuration); if ($mediaServerIndex == KalturaMediaServerIndex::PRIMARY) { if (!$dbEntry->getRecordedEntryId()) { $this->createRecordedEntry($dbEntry, $mediaServerIndex); } $recordedEntry = entryPeer::retrieveByPK($dbEntry->getRecordedEntryId()); if ($recordedEntry) { $this->ingestAsset($recordedEntry, $dbAsset, $filename); } } $entry = KalturaEntryFactory::getInstanceByType($dbEntry->getType()); $entry->fromObject($dbEntry, $this->getResponseProfile()); return $entry; }
public function crop($quality, $cropType, $width = 0, $height = 0, $cropX = 0, $cropY = 0, $cropWidth = 0, $cropHeight = 0, $scaleWidth = 1, $scaleHeight = 1, $bgcolor = 0xffffff, $density = 0, $forceRotation = null, $strip = false) { if (is_null($quality)) { $quality = 100; } if (is_null($cropType)) { $cropType = 1; } if (is_null($width)) { $width = 0; } if (is_null($height)) { $height = 0; } if (is_null($cropX)) { $cropX = 0; } if (is_null($cropY)) { $cropY = 0; } if (is_null($cropWidth)) { $cropWidth = 0; } if (is_null($cropHeight)) { $cropHeight = 0; } if (is_null($scaleWidth)) { $scaleWidth = 1; } if (is_null($scaleHeight)) { $scaleHeight = 1; } if (is_null($bgcolor)) { $bgcolor = 0; } $cmd = $this->getCommand($quality, $cropType, $width, $height, $cropX, $cropY, $cropWidth, $cropHeight, $scaleWidth, $scaleHeight, $bgcolor, $density, $forceRotation, $strip); if ($cmd) { KalturaLog::info("Executing: {$cmd}"); $returnValue = null; $output = system($cmd, $returnValue); KalturaLog::debug("Returned value: '{$returnValue}'"); if ($returnValue) { return false; } // Support animated gifs - KImageMagick generates multiple images with a postfix of '-<frame num>' if (!kFile::fileSize($this->targetPath)) { $targetFiledir = pathinfo($this->targetPath, PATHINFO_DIRNAME); $targetFilename = pathinfo($this->targetPath, PATHINFO_FILENAME); $targetFileext = pathinfo($this->targetPath, PATHINFO_EXTENSION); $firstFrameTargetFile = "{$targetFiledir}/{$targetFilename}-0.{$targetFileext}"; if (kFile::fileSize($firstFrameTargetFile)) { kFile::moveFile($firstFrameTargetFile, $this->targetPath); } } return true; } KalturaLog::info("No conversion required, copying source[{$this->srcPath}] to target[{$this->targetPath}]"); return copy($this->srcPath, $this->targetPath); }
/** * @param KalturaBatchJob $job * @param KalturaConcatJobData $data * @param string $localTempFilePath * @param string $sharedTempFilePath * @return KalturaBatchJob */ protected function moveFile(KalturaBatchJob $job, KalturaConvertLiveSegmentJobData $data, $localTempFilePath, $sharedTempFilePath) { $this->updateJob($job, "Moving file from [{$localTempFilePath}] to [{$sharedTempFilePath}]", KalturaBatchJobStatus::MOVEFILE); kFile::moveFile($localTempFilePath, $sharedTempFilePath, true); clearstatcache(); $fileSize = kFile::fileSize($sharedTempFilePath); $this->setFilePermissions($sharedTempFilePath); if (!$this->checkFileExists($sharedTempFilePath, $fileSize)) { return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::NFS_FILE_DOESNT_EXIST, 'File not moved correctly', KalturaBatchJobStatus::RETRY); } $data->destFilePath = $sharedTempFilePath; return $this->closeJob($job, null, null, 'Succesfully moved file', KalturaBatchJobStatus::FINISHED, $data); }
public function toObject($object_to_fill = null, $props_to_skip = array()) { if (!$object_to_fill) { $object_to_fill = new kLocalFileResource(); } $ext = pathinfo($this->fileData['name'], PATHINFO_EXTENSION); $uploadPath = $this->fileData['tmp_name']; $tempPath = myContentStorage::getFSUploadsPath() . '/' . uniqid(time()) . '.' . $ext; $moved = kFile::moveFile($uploadPath, $tempPath, true); if (!$moved) { throw new KalturaAPIException(KalturaErrors::UPLOAD_ERROR); } $object_to_fill->setLocalFilePath($tempPath); return $object_to_fill; }
public function execute() { ini_set("memory_limit", "128M"); ini_set("max_execution_time", "240"); $this->forceSystemAuthentication(); $start = microtime(true); $data = $this->getP("data"); $file_path = dirname(__FILE__) . "/../data/viewPartnersData.txt"; if ($data) { $time_str = strftime("-%Y-%d-%m_%H-%M-%S", time()); kFile::moveFile($file_path, $file_path . $time_str); file_put_contents($file_path, $data); // sync - OK } else { $data = file_get_contents($file_path); } $partner_groups = new partnerGroups($file_path); $this->partner_group_list = $partner_groups->partner_group_list; $this->data = $data; }
protected function moveDataFile(KalturaConvertLiveSegmentJobData $data, $localTempAmfFilePath, $sharedTempAmfFilePath) { KalturaLog::debug('moving file from ' . $localTempAmfFilePath . ' to ' . $sharedTempAmfFilePath); kFile::moveFile($localTempAmfFilePath, $sharedTempAmfFilePath, true); clearstatcache(); $fileSize = kFile::fileSize($sharedTempAmfFilePath); $this->setFilePermissions($sharedTempAmfFilePath); if (!$this->checkFileExists($sharedTempAmfFilePath, $fileSize)) { KalturaLog::warning('failed to move file to ' . $sharedTempAmfFilePath); } else { $data->destDataFilePath = $sharedTempAmfFilePath; } }
public static function resizeEntryImage(entry $entry, $version, $width, $height, $type, $bgcolor = "ffffff", $crop_provider = null, $quality = 0, $src_x = 0, $src_y = 0, $src_w = 0, $src_h = 0, $vid_sec = -1, $vid_slice = 0, $vid_slices = -1, $orig_image_path = null, $density = 0, $stripProfiles = false, $thumbParams = null, $format = null) { if (is_null($thumbParams) || !$thumbParams instanceof kThumbnailParameters) { $thumbParams = new kThumbnailParameters(); } $contentPath = myContentStorage::getFSContentRootPath(); $entry_status = $entry->getStatus(); $thumbName = $entry->getId() . "_{$width}_{$height}_{$type}_{$crop_provider}_{$bgcolor}_{$quality}_{$src_x}_{$src_y}_{$src_w}_{$src_h}_{$vid_sec}_{$vid_slice}_{$vid_slices}_{$entry_status}"; if ($orig_image_path) { $thumbName .= '_oip_' . basename($orig_image_path); } if ($density) { $thumbName .= "_dns_{$density}"; } if ($stripProfiles) { $thumbName .= "_stp_{$stripProfiles}"; } $entryThumbFilename = $entry->getThumbnail() ? $entry->getThumbnail() : "0.jpg"; if ($entry->getStatus() != entryStatus::READY || @$entryThumbFilename[0] == '&') { $thumbName .= "_NOCACHE_"; } // we remove the & from the template thumb otherwise getGeneralEntityPath will drop $tempThumbName from the final path $entryThumbFilename = str_replace("&", "", $entryThumbFilename); //create final path for thumbnail created $finalBasePath = myContentStorage::getGeneralEntityPath("entry/tempthumb", $entry->getIntId(), $thumbName, $entryThumbFilename, $version); $finalThumbPath = $contentPath . $finalBasePath; //Add unique id to the proccesing file path to avoid file being overwritten when several identical (with same parameters) calls are made before the final thumbnail is created $thumbName .= "_" . uniqid() . "_"; //create path for processing thumbnail request $processingBasePath = myContentStorage::getGeneralEntityPath("entry/tempthumb", $entry->getIntId(), $thumbName, $entryThumbFilename, $version); $processingThumbPath = $contentPath . $processingBasePath; if (!is_null($format)) { $finalThumbPath = kFile::replaceExt($finalThumbPath, $format); $processingThumbPath = kFile::replaceExt($processingThumbPath, $format); } if (file_exists($finalThumbPath) && @filesize($finalThumbPath)) { header("X-Kaltura:cached-thumb-exists," . md5($finalThumbPath)); return $finalThumbPath; } if ($orig_image_path === null || !file_exists($orig_image_path)) { $orig_image_path = self::getLocalImageFilePathByEntry($entry, $version); } // remark added so ffmpeg will try to load the thumbnail from the original source if ($entry->getMediaType() == entry::ENTRY_MEDIA_TYPE_IMAGE && !file_exists($orig_image_path)) { throw new kFileSyncException('no ready filesync on current DC', kFileSyncException::FILE_DOES_NOT_EXIST_ON_CURRENT_DC); } // check a request for animated thumbs without a concrete vid_slice // in which case we'll create all the frames as one wide image $multi = $vid_slice == -1 && $vid_slices != -1; $count = $multi ? $vid_slices : 1; $im = null; if ($multi) { $vid_slice = 0; } while ($count--) { if ($entry->getMediaType() == entry::ENTRY_MEDIA_TYPE_VIDEO && ($vid_sec != -1 || $vid_slices != -1) || !file_exists($orig_image_path)) { if ($vid_sec != -1) { $calc_vid_sec = min($vid_sec, floor($entry->getLengthInMsecs() / 1000)); } else { if ($vid_slices != -1) { $calc_vid_sec = floor($entry->getLengthInMsecs() / $vid_slices * min($vid_slice, $vid_slices) / 1000); } else { if ($entry->getStatus() != entryStatus::READY && $entry->getLengthInMsecs() == 0) { $calc_vid_sec = $entry->getPartner() && $entry->getPartner()->getDefThumbOffset() ? $entry->getPartner()->getDefThumbOffset() : 3; } else { $calc_vid_sec = $entry->getBestThumbOffset(); } } } $capturedThumbName = $entry->getId() . "_sec_{$calc_vid_sec}"; $capturedThumbPath = $contentPath . myContentStorage::getGeneralEntityPath("entry/tempthumb", $entry->getIntId(), $capturedThumbName, $entry->getThumbnail(), $version); $orig_image_path = $capturedThumbPath . "temp_1.jpg"; // if we already captured the frame at that second, dont recapture, just use the existing file if (!file_exists($orig_image_path)) { // limit creation of more than XX ffmpeg image extraction processes if (kConf::hasParam("resize_thumb_max_processes_ffmpeg") && trim(exec("ps -e -ocmd|awk '{print \$1}'|grep -c " . kConf::get("bin_path_ffmpeg"))) > kConf::get("resize_thumb_max_processes_ffmpeg")) { KExternalErrors::dieError(KExternalErrors::TOO_MANY_PROCESSES); } // creating the thumbnail is a very heavy operation // prevent calling it in parallel for the same thubmnail for 5 minutes $cache = new myCache("thumb-processing", 5 * 60); // 5 minutes $processing = $cache->get($orig_image_path); if ($processing) { KExternalErrors::dieError(KExternalErrors::PROCESSING_CAPTURE_THUMBNAIL); } $cache->put($orig_image_path, true); $flavorAsset = assetPeer::retrieveHighestBitrateByEntryId($entry->getId(), flavorParams::TAG_THUMBSOURCE); if (is_null($flavorAsset)) { $flavorAsset = assetPeer::retrieveOriginalReadyByEntryId($entry->getId()); if ($flavorAsset) { $flavorSyncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); list($fileSync, $local) = kFileSyncUtils::getReadyFileSyncForKey($flavorSyncKey, false, false); if (!$fileSync) { $flavorAsset = null; } } if (is_null($flavorAsset) || !($flavorAsset->hasTag(flavorParams::TAG_MBR) || $flavorAsset->hasTag(flavorParams::TAG_WEB))) { // try the best playable $flavorAsset = assetPeer::retrieveHighestBitrateByEntryId($entry->getId(), null, flavorParams::TAG_SAVE_SOURCE); } if (is_null($flavorAsset)) { // if no READY ORIGINAL entry is available, try to retrieve a non-READY ORIGINAL entry $flavorAsset = assetPeer::retrieveOriginalByEntryId($entry->getId()); } } if (is_null($flavorAsset)) { // if no READY ORIGINAL entry is available, try to retrieve a non-READY ORIGINAL entry $flavorAsset = assetPeer::retrieveOriginalByEntryId($entry->getId()); } if (is_null($flavorAsset)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $flavorSyncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $entry_data_path = kFileSyncUtils::getReadyLocalFilePathForKey($flavorSyncKey); if (!$entry_data_path) { // since this is not really being processed on this server, and will probably cause redirect in thumbnailAction // remove from cache so later requests will still get redirected and will not fail on PROCESSING_CAPTURE_THUMBNAIL $cache->remove($orig_image_path); throw new kFileSyncException('no ready filesync on current DC', kFileSyncException::FILE_DOES_NOT_EXIST_ON_CURRENT_DC); } // close db connections as we won't be requiring the database anymore and capturing a thumbnail may take a long time kFile::closeDbConnections(); myFileConverter::autoCaptureFrame($entry_data_path, $capturedThumbPath . "temp_", $calc_vid_sec, -1, -1); $cache->remove($orig_image_path); } } // close db connections as we won't be requiring the database anymore and image manipulation may take a long time kFile::closeDbConnections(); // limit creation of more than XX Imagemagick processes if (kConf::hasParam("resize_thumb_max_processes_imagemagick") && trim(exec("ps -e -ocmd|awk '{print \$1}'|grep -c " . kConf::get("bin_path_imagemagick"))) > kConf::get("resize_thumb_max_processes_imagemagick")) { KExternalErrors::dieError(KExternalErrors::TOO_MANY_PROCESSES); } // resizing (and editing)) an image file that failes results in a long server waiting time // prevent this waiting time (of future requests) in case the resizeing failes $cache = new myCache("thumb-processing-resize", 5 * 60); // 5 minutes $processing = $cache->get($orig_image_path); if ($processing) { KExternalErrors::dieError(KExternalErrors::PROCESSING_CAPTURE_THUMBNAIL); } kFile::fullMkdir($processingThumbPath); if ($crop_provider) { $convertedImagePath = myFileConverter::convertImageUsingCropProvider($orig_image_path, $processingThumbPath, $width, $height, $type, $crop_provider, $bgcolor, true, $quality, $src_x, $src_y, $src_w, $src_h, $density, $stripProfiles); } else { if (!file_exists($orig_image_path) || !filesize($orig_image_path)) { KExternalErrors::dieError(KExternalErrors::IMAGE_RESIZE_FAILED); } $imageSizeArray = getimagesize($orig_image_path); if ($thumbParams->getSupportAnimatedThumbnail() && is_array($imageSizeArray) && $imageSizeArray[2] === IMAGETYPE_GIF) { $processingThumbPath = kFile::replaceExt($processingThumbPath, "gif"); $finalThumbPath = kFile::replaceExt($finalThumbPath, "gif"); } $convertedImagePath = myFileConverter::convertImage($orig_image_path, $processingThumbPath, $width, $height, $type, $bgcolor, true, $quality, $src_x, $src_y, $src_w, $src_h, $density, $stripProfiles, $thumbParams, $format); } // die if resize operation failed and add failed resizing to cache if ($convertedImagePath === null || !@filesize($convertedImagePath)) { $cache->put($orig_image_path, true); KExternalErrors::dieError(KExternalErrors::IMAGE_RESIZE_FAILED); } // if resizing secceded remove from cache of failed resizing if ($cache->get($orig_image_path)) { $cache->remove($orig_image_path, true); } if ($multi) { list($w, $h, $type, $attr, $srcIm) = myFileConverter::createImageByFile($processingThumbPath); if (!$im) { $im = imagecreatetruecolor($w * $vid_slices, $h); } imagecopy($im, $srcIm, $w * $vid_slice, 0, 0, 0, $w, $h); imagedestroy($srcIm); ++$vid_slice; } } if ($multi) { imagejpeg($im, $processingThumbPath); imagedestroy($im); } kFile::fullMkdir($finalThumbPath); kFile::moveFile($processingThumbPath, $finalThumbPath); return $finalThumbPath; }
private function moveExtraFiles(KalturaConvertJobData &$data, $sharedFile) { $i = 0; foreach ($data->extraDestFileSyncs as $destFileSync) { $i++; clearstatcache(); $directorySync = is_dir($destFileSync->fileSyncLocalPath); if ($directorySync) { $fileSize = KBatchBase::foldersize($destFileSync->fileSyncLocalPath); } else { $fileSize = kFile::fileSize($destFileSync->fileSyncLocalPath); } $ext = pathinfo($destFileSync->fileSyncLocalPath, PATHINFO_EXTENSION); if ($ext) { $newName = $sharedFile . '.' . $ext; } else { $newName = $sharedFile . '.' . $i; } kFile::moveFile($destFileSync->fileSyncLocalPath, $newName); // directory sizes may differ on different devices if (!file_exists($newName) || is_file($newName) && kFile::fileSize($newName) != $fileSize) { KalturaLog::err("Error: moving file failed"); die; } $destFileSync->fileSyncLocalPath = $this->translateLocalPath2Shared($newName); if (self::$taskConfig->params->isRemoteOutput) { $destFileSync->fileSyncRemoteUrl = $this->distributedFileManager->getRemoteUrl($destFileSync->fileSyncLocalPath); } } }
private function moveFile(KalturaBatchJob $job, KalturaConvertJobData $data) { KalturaLog::debug("moveFile({$job->id}, {$data->destFileSyncLocalPath})"); $uniqid = uniqid("convert_{$job->entryId}_"); $sharedFile = "{$this->sharedTempPath}/{$uniqid}"; clearstatcache(); $fileSize = filesize($data->destFileSyncLocalPath); @rename($data->destFileSyncLocalPath . '.log', "{$sharedFile}.log"); kFile::moveFile($data->destFileSyncLocalPath, $sharedFile); if (!file_exists($sharedFile) || filesize($sharedFile) != $fileSize) { KalturaLog::err("Error: moving file failed"); die; } @chmod($sharedFile, 0777); $data->destFileSyncLocalPath = $this->translateLocalPath2Shared($sharedFile); if ($this->taskConfig->params->isRemote) { $data->destFileSyncRemoteUrl = $this->distributedFileManager->getRemoteUrl($data->destFileSyncLocalPath); $job->status = KalturaBatchJobStatus::ALMOST_DONE; $job->message = "File ready for download"; } elseif ($this->checkFileExists($data->destFileSyncLocalPath, $fileSize)) { $job->status = KalturaBatchJobStatus::FINISHED; $job->message = "File moved to shared"; } else { $job->status = KalturaBatchJobStatus::RETRY; $job->message = "File not moved correctly"; } return $this->closeJob($job, null, null, $job->message, $job->status, $data); }
public function operate(kOperator $operator = null, $inFilePath, $configFilePath = null) { KalturaLog::debug("operator==>" . print_r($operator, 1)); $encodingTemplateId = null; $encodingTemplateName = null; $cloneAndUpadate = false; $srcPrefixWindows = null; $srcPrefixLinux = null; $trgPrefixWindows = null; // --------------------------------- // Evaluate and set various Inlet Armada session params if (KBatchBase::$taskConfig->params->InletStorageRootWindows) { $srcPrefixWindows = KBatchBase::$taskConfig->params->InletStorageRootWindows; } if (KBatchBase::$taskConfig->params->InletStorageRootLinux) { $srcPrefixLinux = KBatchBase::$taskConfig->params->InletStorageRootLinux; } if (KBatchBase::$taskConfig->params->InletTmpStorageWindows) { $trgPrefixWindows = KBatchBase::$taskConfig->params->InletTmpStorageWindows; } $url = KBatchBase::$taskConfig->params->InletArmadaUrl; $login = KBatchBase::$taskConfig->params->InletArmadaLogin; $passw = KBatchBase::$taskConfig->params->InletArmadaPassword; if (KBatchBase::$taskConfig->params->InletArmadaPriority) { $priority = KBatchBase::$taskConfig->params->InletArmadaPriority; } else { $priority = 5; } // ---------------------------------- $inlet = new InletAPIWrap($url); KalturaLog::debug(print_r($inlet, 1)); $rvObj = new XmlRpcData(); $rv = $inlet->userLogon($login, $passw, $rvObj); if (!$rv) { throw new KOperationEngineException("Inlet failure: login, rv(" . print_r($rvObj, true) . ")"); } KalturaLog::debug("userLogon - " . print_r($rvObj, 1)); $paramsMap = KDLUtils::parseParamStr2Map($operator->extra); foreach ($paramsMap as $key => $param) { switch ($key) { case 'encodingTemplate': case 'encodingTemplateId': $encodingTemplateId = $param; break; case 'encodingTemplateName': $encodingTemplateId = $this->lookForJobTemplateId($inlet, $param); $encodingTemplateName = $param; break; case 'priority': $priority = $param; break; case 'cloneAndUpadate': $cloneAndUpadate = $param; break; default: break; } } // Adjust linux file path to Inlet Armada Windows path if (isset($srcPrefixWindows) && isset($srcPrefixLinux)) { $srcPrefixLinux = $this->addLastSlashInFolderPath($srcPrefixLinux, "/"); $srcPrefixWindows = $this->addLastSlashInFolderPath($srcPrefixWindows, "\\"); $srcFileWindows = str_replace($srcPrefixLinux, $srcPrefixWindows, $inFilePath); } else { $srcFileWindows = $inFilePath; } if (isset($trgPrefixWindows)) { $trgPrefixLinux = $this->addLastSlashInFolderPath(KBatchBase::$taskConfig->params->localTempPath, "/"); $trgPrefixWindows = $this->addLastSlashInFolderPath($trgPrefixWindows, "\\"); $outFileWindows = str_replace($trgPrefixLinux, $trgPrefixWindows, $this->outFilePath); } else { $outFileWindows = $this->outFilePath; } $rv = $inlet->jobAdd($encodingTemplateId, $srcFileWindows, $outFileWindows, $priority, $srcFileWindows, array(), "", $rvObj); if (!$rv) { throw new KOperationEngineException("Inlet failure: add job, rv(" . print_r($rvObj, 1) . ")"); } KalturaLog::debug("jobAdd - encodingTemplate({$encodingTemplateId}), inFile({$srcFileWindows}), outFile({$outFileWindows}),rv-" . print_r($rvObj, 1)); $jobId = $rvObj->job_id; $attemptCnt = 0; while ($jobId) { sleep(60); $rv = $inlet->jobList(array($jobId), $rvObj); if (!$rv) { throw new KOperationEngineException("Inlet failure: job list, rv(" . print_r($rvObj, 1) . ")"); } switch ($rvObj->job_list[0]->job_state) { case InletArmadaJobStatus::CompletedSuccess: $jobId = null; break; case InletArmadaJobStatus::CompletedUnknown: case InletArmadaJobStatus::CompletedFailure: throw new KOperationEngineException("Inlet failure: job, rv(" . print_r($rvObj, 1) . ")"); break; } if ($attemptCnt % 10 == 0) { KalturaLog::debug("waiting for job completion - " . print_r($rvObj, 1)); } $attemptCnt++; } //KalturaLog::debug("XXX taskConfig=>".print_r(KBatchBase::$taskConfig,1)); KalturaLog::debug("Job completed successfully - " . print_r($rvObj, 1)); if ($trgPrefixWindows) { $trgPrefixLinux = $this->addLastSlashInFolderPath(KBatchBase::$taskConfig->params->sharedTempPath, "/"); $outFileLinux = str_replace($trgPrefixWindows, $trgPrefixLinux, $rvObj->job_list[0]->job_output_file); //KalturaLog::debug("XXX str_replace($trgPrefixWindows, ".$trgPrefixLinux.", ".$rvObj->job_list[0]->job_output_file.")==>$outFileLinux"); } else { $outFileLinux = $rvObj->job_list[0]->job_output_file; } if ($outFileLinux != $this->outFilePath) { KalturaLog::debug("copy({$outFileLinux}, " . $this->outFilePath . ")"); kFile::moveFile($outFileLinux, $this->outFilePath, true); //copy($outFileLinux, $this->outFilePath); } return true; }
public static function moveFromFile($temp_file_path, FileSyncKey $target_key, $strict = true, $copyOnly = false, $cacheOnly = false) { KalturaLog::log(__METHOD__ . " - move file: [{$temp_file_path}] to key [{$target_key}], "); $c = FileSyncPeer::getCriteriaForFileSyncKey($target_key); if ($cacheOnly) { $c->add(FileSyncPeer::FILE_TYPE, FileSync::FILE_SYNC_FILE_TYPE_CACHE); } else { $c->add(FileSyncPeer::FILE_TYPE, array(FileSync::FILE_SYNC_FILE_TYPE_FILE, FileSync::FILE_SYNC_FILE_TYPE_LINK), Criteria::IN); } $existsFileSync = FileSyncPeer::doSelectOne($c); if ($existsFileSync) { KalturaLog::log(__METHOD__ . " - file already exists"); if ($strict) { throw new Exception("key [" . $target_key . "] already exists"); } } $targetFullPath = self::getLocalFilePathForKey($target_key); if (!$targetFullPath) { $targetFullPath = kPathManager::getFilePath($target_key); KalturaLog::log(__METHOD__ . " - Generated new path [{$targetFullPath}]"); } if (!file_exists(dirname($targetFullPath))) { KalturaLog::log(__METHOD__ . " - creating directory for file"); kFile::fullMkdir($targetFullPath); } if (file_exists($temp_file_path)) { KalturaLog::log(__METHOD__ . " - {$temp_file_path} file exists"); } else { KalturaLog::log(__METHOD__ . " - {$temp_file_path} file doesnt exist"); } $wamsSupportedFormats = kWAMS::getSupportedFormats(); $fileExtension = pathinfo($temp_file_path, PATHINFO_EXTENSION); if (in_array($fileExtension, $wamsSupportedFormats)) { $assetName = self::getWamsAssetNameForKey($target_key); if (empty($assetName)) { $assetName = pathinfo($temp_file_path, PATHINFO_BASENAME); } $wamsAssetId = kWAMS::getInstance($target_key->getPartnerId())->publishFileToWAMS($assetName, $temp_file_path); if (!empty($wamsAssetId)) { if (self::checkDeletedEntry($target_key, $wamsAssetId, $temp_file_path)) { return; } self::addFromWAMS($wamsAssetId, $target_key, $strict, $cacheOnly); if (!self::isAttachment($target_key)) { $wamsTempFilePath = kWAMS::getTempFilePathForAssetId($wamsAssetId, pathinfo($targetFullPath, PATHINFO_EXTENSION)); rename($temp_file_path, $wamsTempFilePath); } else { unlink($temp_file_path); } return; } else { KalturaLog::err("File [{$temp_file_path}] not published to WAMS"); } } if ($copyOnly) { $success = copy($temp_file_path, $targetFullPath); } else { $success = kFile::moveFile($temp_file_path, $targetFullPath); } if ($success) { if (!$existsFileSync) { self::createSyncFileForKey($target_key, $strict, false, $cacheOnly); } } else { KalturaLog::log(__METHOD__ . " - could not move file from [{$temp_file_path}] to [{$targetFullPath}]"); throw new Exception("Could not move file from [{$temp_file_path}] to [{$targetFullPath}]"); } }
public static function handleLiveReportExportFinished(BatchJob $dbBatchJob, kLiveReportExportJobData $data) { // Move file from shared temp to it's final location $fileName = basename($data->outputPath); $directory = myContentStorage::getFSContentRootPath() . "/content/reports/live/" . $dbBatchJob->getPartnerId(); $filePath = $directory . DIRECTORY_SEPARATOR . $fileName; $moveFile = kFile::moveFile($data->outputPath, $filePath); if (!$moveFile) { KalturaLog::err("Failed to move report file from: " . $data->outputPath . " to: " . $filePath); return kFlowHelper::handleLiveReportExportFailed($dbBatchJob, $data); } $data->outputPath = $filePath; $dbBatchJob->setData($data); $dbBatchJob->save(); $expiry = kConf::get("live_report_export_expiry", 'local', self::LIVE_REPORT_EXPIRY_TIME); // Create download URL $url = self::createLiveReportExportDownloadUrl($dbBatchJob->getPartnerId(), $fileName, $expiry, $data->applicationUrlTemplate); if (!$url) { KalturaLog::err("Failed to create download URL"); return kFlowHelper::handleLiveReportExportFailed($dbBatchJob, $data); } // Create email params $time = date("m-d-y H:i", $data->timeReference + $data->timeZoneOffset); $email_id = MailType::MAIL_TYPE_LIVE_REPORT_EXPORT_SUCCESS; $validUntil = date("m-d-y H:i", $data->timeReference + $expiry + $data->timeZoneOffset); $expiryInDays = $expiry / 60 / 60 / 24; $params = array($dbBatchJob->getPartner()->getName(), $time, $dbBatchJob->getId(), $url, $expiryInDays, $validUntil); $titleParams = array($time); // Email it all kJobsManager::addMailJob(null, 0, $dbBatchJob->getPartnerId(), $email_id, kMailJobData::MAIL_PRIORITY_NORMAL, kConf::get("live_report_sender_email"), kConf::get("live_report_sender_name"), $data->recipientEmail, $params, $titleParams); return $dbBatchJob; }
/** * Append recorded video to live entry * * @action appendRecording * @param string $entryId Live entry id * @param string $assetId Live asset id * @param KalturaMediaServerIndex $mediaServerIndex * @param KalturaDataCenterContentResource $resource * @param float $duration in seconds * @param bool $isLastChunk Is this the last recorded chunk in the current session (i.e. following a stream stop event) * @return KalturaLiveEntry The updated live entry * * @throws KalturaErrors::ENTRY_ID_NOT_FOUND */ function appendRecordingAction($entryId, $assetId, $mediaServerIndex, KalturaDataCenterContentResource $resource, $duration, $isLastChunk = false) { $dbEntry = entryPeer::retrieveByPK($entryId); if (!$dbEntry || !$dbEntry instanceof LiveEntry) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } $dbAsset = assetPeer::retrieveById($assetId); if (!$dbAsset || !$dbAsset instanceof liveAsset) { throw new KalturaAPIException(KalturaErrors::ASSET_ID_NOT_FOUND, $assetId); } $lastDuration = 0; $recordedEntry = null; if ($dbEntry->getRecordedEntryId()) { $recordedEntry = entryPeer::retrieveByPK($dbEntry->getRecordedEntryId()); if ($recordedEntry) { if ($recordedEntry->getReachedMaxRecordingDuration()) { KalturaLog::err("Entry [{$entryId}] has already reached its maximal recording duration."); throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_RECORDED_DURATION, $entryId); } // if entry is in replacement, the replacement duration is more accurate if ($recordedEntry->getReplacedEntryId()) { $replacementRecordedEntry = entryPeer::retrieveByPK($recordedEntry->getReplacedEntryId()); if ($replacementRecordedEntry) { $lastDuration = $replacementRecordedEntry->getLengthInMsecs(); } } else { $lastDuration = $recordedEntry->getLengthInMsecs(); } } } $liveSegmentDurationInMsec = (int) ($duration * 1000); $currentDuration = $lastDuration + $liveSegmentDurationInMsec; $maxRecordingDuration = (kConf::get('max_live_recording_duration_hours') + 1) * 60 * 60 * 1000; if ($currentDuration > $maxRecordingDuration) { if ($recordedEntry) { $recordedEntry->setReachedMaxRecordingDuration(true); $recordedEntry->save(); } KalturaLog::err("Entry [{$entryId}] duration [" . $lastDuration . "] and current duration [{$currentDuration}] is more than max allwoed duration [{$maxRecordingDuration}]"); throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_RECORDED_DURATION, $entryId); } $kResource = $resource->toObject(); $filename = $kResource->getLocalFilePath(); if (!$resource instanceof KalturaServerFileResource) { $filename = kConf::get('uploaded_segment_destination') . basename($kResource->getLocalFilePath()); kFile::moveFile($kResource->getLocalFilePath(), $filename); chgrp($filename, kConf::get('content_group')); chmod($filename, 0640); } if ($dbAsset->hasTag(assetParams::TAG_RECORDING_ANCHOR) && $mediaServerIndex == KalturaMediaServerIndex::PRIMARY) { $dbEntry->setLengthInMsecs($currentDuration); if ($isLastChunk) { // Save last elapsed recording time $dbEntry->setLastElapsedRecordingTime($currentDuration); } $dbEntry->save(); } kJobsManager::addConvertLiveSegmentJob(null, $dbAsset, $mediaServerIndex, $filename, $currentDuration); if ($mediaServerIndex == KalturaMediaServerIndex::PRIMARY) { if (!$dbEntry->getRecordedEntryId()) { $this->createRecordedEntry($dbEntry, $mediaServerIndex); } $recordedEntry = entryPeer::retrieveByPK($dbEntry->getRecordedEntryId()); if ($recordedEntry) { $this->ingestAsset($recordedEntry, $dbAsset, $filename); } } $entry = KalturaEntryFactory::getInstanceByType($dbEntry->getType()); $entry->fromObject($dbEntry, $this->getResponseProfile()); return $entry; }
public function operate(kOperator $operator = null, $inFilePath, $configFilePath = null) { /* * Creating unique output folder for nbrPlay/Webex sessions. * This is required in order to support concurrent conversion sessions, * because the nbrPlay tool generates temp files with the same name. * Upon completion move the generated file into the 'regular' outFilePath */ $saveOutPath = $this->outFilePath; $path_parts = pathinfo($this->outFilePath); $outDir = realpath($path_parts['dirname']); /* * The temp folder name */ $tempFolder = "{$outDir}/" . $path_parts['basename'] . ".webex_temp_folder"; $tempOutPath = "{$tempFolder}/" . $path_parts['basename']; if (!file_exists($tempFolder)) { $oldUmask = umask(00); $result = @mkdir($tempFolder, 0777, true); umask($oldUmask); } /* * Switch to temp forlder */ $this->outFilePath = $tempOutPath; $rv = parent::operate($operator, $inFilePath, $configFilePath); /* * Restore the original */ if (file_exists($tempOutPath)) { $outFilelist = kFile::dirList($tempFolder); if (isset($outFilelist) && count($outFilelist) > 0) { foreach ($outFilelist as $fileName) { for ($tries = 0; $tries < 5; $tries++) { $toFile = "{$outDir}/" . pathinfo($fileName, PATHINFO_BASENAME); $rv = kFile::moveFile($fileName, $toFile); if (!file_exists($fileName)) { break; } KalturaLog::err("Failed to move ({$fileName}) to ({$toFile})"); Sleep(60); } } Sleep(60); rmdir($tempFolder); } } $this->outFilePath = $saveOutPath; return $rv; }
public static function moveFromFile($temp_file_path, FileSyncKey $target_key, $strict = true, $copyOnly = false) { KalturaLog::log(__METHOD__ . " - move file: [{$temp_file_path}] to key [{$target_key}], "); $c = FileSyncPeer::getCriteriaForFileSyncKey($target_key); $existsFileSync = FileSyncPeer::doSelectOne($c); if ($existsFileSync) { KalturaLog::log(__METHOD__ . " - file already exists"); if ($strict) { throw new Exception("key [" . $target_key . "] already exists"); } } $targetFullPath = self::getLocalFilePathForKey($target_key); if (!$targetFullPath) { $targetFullPath = kPathManager::getFilePath($target_key); KalturaLog::log(__METHOD__ . " - Generated new path [{$targetFullPath}]"); } if (!file_exists(dirname($targetFullPath))) { KalturaLog::log(__METHOD__ . " - creating directory for file"); kFile::fullMkdir($targetFullPath); } if (file_exists($temp_file_path)) { KalturaLog::log(__METHOD__ . " - {$temp_file_path} file exists"); } else { KalturaLog::log(__METHOD__ . " - {$temp_file_path} file doesnt exist"); } if ($copyOnly) { $success = copy($temp_file_path, $targetFullPath); } else { $success = kFile::moveFile($temp_file_path, $targetFullPath); } if ($success) { if (!$existsFileSync) { self::createSyncFileForKey($target_key, $strict); } } else { KalturaLog::log(__METHOD__ . " - could not move file from [{$temp_file_path}] to [{$targetFullPath}]"); throw new Exception("Could not move file from [{$temp_file_path}] to [{$targetFullPath}]"); } }
public static function moveFromFile($temp_file_path, FileSyncKey $target_key, $strict = true, $copyOnly = false, $cacheOnly = false) { KalturaLog::debug("move file: [{$temp_file_path}] to key [{$target_key}], "); $c = FileSyncPeer::getCriteriaForFileSyncKey($target_key); if ($cacheOnly) { $c->add(FileSyncPeer::FILE_TYPE, FileSync::FILE_SYNC_FILE_TYPE_CACHE); } else { $c->add(FileSyncPeer::FILE_TYPE, array(FileSync::FILE_SYNC_FILE_TYPE_FILE, FileSync::FILE_SYNC_FILE_TYPE_LINK), Criteria::IN); } $existsFileSync = FileSyncPeer::doSelectOne($c); if ($existsFileSync) { if ($strict) { throw new Exception("key [" . $target_key . "] already exists"); } else { KalturaLog::err("file already exists"); } } list($rootPath, $filePath) = self::getLocalFilePathArrForKey($target_key); $targetFullPath = $rootPath . $filePath; if (!$targetFullPath) { $targetFullPath = kPathManager::getFilePath($target_key); KalturaLog::info("Generated new path [{$targetFullPath}]"); } $targetFullPath = str_replace(array('/', '\\'), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $targetFullPath); if (!file_exists(dirname($targetFullPath))) { self::fullMkdir($targetFullPath); } if (file_exists($temp_file_path)) { KalturaLog::info("{$temp_file_path} file exists"); } else { KalturaLog::info("{$temp_file_path} file doesnt exist"); } if (file_exists($targetFullPath)) { $time = time(); $targetFullPath .= $time; $filePath .= $time; } if ($copyOnly) { $success = copy($temp_file_path, $targetFullPath); } else { $success = kFile::moveFile($temp_file_path, $targetFullPath); } if ($success) { self::setPermissions($targetFullPath); if (!$existsFileSync) { self::createSyncFileForKey($rootPath, $filePath, $target_key, $strict, false, $cacheOnly); } } else { KalturaLog::err("could not move file from [{$temp_file_path}] to [{$targetFullPath}]"); throw new Exception("Could not move file from [{$temp_file_path}] to [{$targetFullPath}]"); } }
private function moveFile(KalturaBatchJob $job, KalturaConvertJobData $data) { KalturaLog::debug("moveFile({$job->id}, {$data->destFileSyncLocalPath})"); $uniqid = uniqid("convert_{$job->entryId}_"); $sharedFile = "{$this->sharedTempPath}/{$uniqid}"; if (!$data->flavorParamsOutput->sourceRemoteStorageProfileId) { clearstatcache(); $fileSize = kFile::fileSize($data->destFileSyncLocalPath); kFile::moveFile($data->destFileSyncLocalPath, $sharedFile); // directory sizes may differ on different devices if (!file_exists($sharedFile) || is_file($sharedFile) && kFile::fileSize($sharedFile) != $fileSize) { KalturaLog::err("Error: moving file failed"); die; } @chmod($sharedFile, 0777); $data->destFileSyncLocalPath = $this->translateLocalPath2Shared($sharedFile); if ($this->taskConfig->params->isRemoteOutput) { $data->destFileSyncRemoteUrl = $this->distributedFileManager->getRemoteUrl($data->destFileSyncLocalPath); $job->status = KalturaBatchJobStatus::ALMOST_DONE; $job->message = "File ready for download"; } elseif ($this->checkFileExists($data->destFileSyncLocalPath, $fileSize)) { $job->status = KalturaBatchJobStatus::FINISHED; $job->message = "File moved to shared"; } else { $job->status = KalturaBatchJobStatus::RETRY; $job->message = "File not moved correctly"; } } else { $job->status = KalturaBatchJobStatus::FINISHED; $job->message = "File is ready in the remote storage"; } if ($data->logFileSyncLocalPath && file_exists($data->logFileSyncLocalPath)) { kFile::moveFile($data->logFileSyncLocalPath, "{$sharedFile}.log"); @chmod("{$sharedFile}.log", 0777); $data->logFileSyncLocalPath = $this->translateLocalPath2Shared("{$sharedFile}.log"); if ($this->taskConfig->params->isRemoteOutput) { // for remote conversion $data->logFileSyncRemoteUrl = $this->distributedFileManager->getRemoteUrl($data->logFileSyncLocalPath); } } else { $data->logFileSyncLocalPath = ''; } return $this->closeJob($job, null, null, $job->message, $job->status, $data); }
public function crop($quality, $cropType, $width = 0, $height = 0, $cropX = 0, $cropY = 0, $cropWidth = 0, $cropHeight = 0, $scaleWidth = 1, $scaleHeight = 1, $bgcolor = 0xffffff, $density = 0, $forceRotation = null, $strip = false) { if (is_null($quality)) { $quality = 100; } if (is_null($cropType)) { $cropType = 1; } if (is_null($width)) { $width = 0; } if (is_null($height)) { $height = 0; } if (is_null($cropX)) { $cropX = 0; } if (is_null($cropY)) { $cropY = 0; } if (is_null($cropWidth)) { $cropWidth = 0; } if (is_null($cropHeight)) { $cropHeight = 0; } if (is_null($scaleWidth)) { $scaleWidth = 1; } if (is_null($scaleHeight)) { $scaleHeight = 1; } if (is_null($bgcolor)) { $bgcolor = 0; } $cmd = $this->getCommand($quality, $cropType, $width, $height, $cropX, $cropY, $cropWidth, $cropHeight, $scaleWidth, $scaleHeight, $bgcolor, $density, $forceRotation, $strip); if ($cmd) { KalturaLog::info("Executing: {$cmd}"); $returnValue = null; exec($cmd, $output, $returnValue); KalturaLog::debug("Returned value: {$returnValue} Output: " . print_r($output, true)); //Avoid certain images the image magic throws "no pixels defined in cache ... @ cache.c/OpenPixelCache/3789" exception but still generates the cropped image $outputAsString = implode(" ", $output); if ($returnValue && strpos($outputAsString, "no pixels defined in cache") === false && strpos($outputAsString, "cache.c/OpenPixelCache") === false) { return false; } // Support animated gifs - KImageMagick generates multiple images with a postfix of '-<frame num>' if (!file_exists($this->targetPath) || !kFile::fileSize($this->targetPath)) { $targetFiledir = pathinfo($this->targetPath, PATHINFO_DIRNAME); $targetFilename = pathinfo($this->targetPath, PATHINFO_FILENAME); $targetFileext = pathinfo($this->targetPath, PATHINFO_EXTENSION); $firstFrameTargetFile = "{$targetFiledir}/{$targetFilename}-0.{$targetFileext}"; if (file_exists($firstFrameTargetFile) && kFile::fileSize($firstFrameTargetFile)) { kFile::moveFile($firstFrameTargetFile, $this->targetPath); } } return true; } KalturaLog::info("No conversion required, copying source[{$this->srcPath}] to target[{$this->targetPath}]"); return copy($this->srcPath, $this->targetPath); }
/** * Move the uploaded file * @param unknown_type $fileData */ protected function handleMoveFile($fileData) { // get the upload path $extension = strtolower(pathinfo($fileData['name'], PATHINFO_EXTENSION)); // in firefox html5 upload the extension is missing (file name is "blob") so try fetching the extesion from // the original file name that was passed to the uploadToken if ($extension === "" || $extension == "tmp" && $this->_uploadToken->getFileName()) { $extension = strtolower(pathinfo($this->_uploadToken->getFileName(), PATHINFO_EXTENSION)); } $uploadFilePath = $this->getUploadPath($this->_uploadToken->getId(), $extension); $this->_uploadToken->setUploadTempPath($uploadFilePath); kFile::fullMkdir($uploadFilePath, 0700); $moveFileSuccess = kFile::moveFile($fileData['tmp_name'], $uploadFilePath); if (!$moveFileSuccess) { $msg = "Failed to move uploaded file for token id [{$this->_uploadToken->getId()}]"; KalturaLog::log($msg . ' ' . print_r($fileData, true)); throw new kUploadTokenException($msg, kUploadTokenException::UPLOAD_TOKEN_FAILED_TO_MOVE_UPLOADED_FILE); } chmod($uploadFilePath, 0600); }