public function validateEntry(entry $dbEntry) { parent::validateEntry($dbEntry); $this->validatePropertyNotNull('entryId'); $srcEntry = entryPeer::retrieveByPK($this->entryId); if (!$srcEntry) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $this->entryId); } if ($srcEntry->getMediaType() == KalturaMediaType::IMAGE) { return parent::validateEntry($dbEntry); } $srcFlavorAsset = null; if (is_null($this->flavorParamsId)) { $srcFlavorAsset = assetPeer::retrieveOriginalByEntryId($this->entryId); if (!$srcFlavorAsset) { throw new KalturaAPIException(KalturaErrors::ORIGINAL_FLAVOR_ASSET_IS_MISSING); } } else { $srcFlavorAsset = assetPeer::retrieveByEntryIdAndParams($this->entryId, $this->flavorParamsId); if (!$srcFlavorAsset) { throw new KalturaAPIException(KalturaErrors::FLAVOR_ASSET_ID_NOT_FOUND, $this->assetId); } } $key = $srcFlavorAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET); $c = FileSyncPeer::getCriteriaForFileSyncKey($key); $c->addAnd(FileSyncPeer::FILE_TYPE, array(FileSync::FILE_SYNC_FILE_TYPE_FILE, FileSync::FILE_SYNC_FILE_TYPE_LINK), Criteria::IN); $fileSyncs = FileSyncPeer::doSelect($c); foreach ($fileSyncs as $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); if ($fileSync->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_FILE) { return; } } throw new KalturaAPIException(KalturaErrors::FILE_DOESNT_EXIST); }
/** * @param FileSync $fileSync * @return string */ protected function doGetFileSyncUrl(FileSync $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); $url = parent::doGetFileSyncUrl($fileSync); $url = ltrim($url, '/'); if ($this->protocol == StorageProfile::PLAY_FORMAT_APPLE_HTTP) { return "/hls-vod/{$url}.m3u8"; } return "/hds-vod/{$url}.f4m"; }
/** * Serves multiple files for synchronization between datacenters */ public function execute() { $fileSyncIds = $this->getRequestParameter("ids"); $hash = $this->getRequestParameter("hash"); // validate hash $currentDc = kDataCenterMgr::getCurrentDc(); $currentDcId = $currentDc["id"]; $expectedHash = md5($currentDc["secret"] . $fileSyncIds); if ($hash !== $expectedHash) { $error = "Invalid hash - ids [{$fileSyncIds}] got [{$hash}] expected [{$expectedHash}]"; KalturaLog::err($error); KExternalErrors::dieError(KExternalErrors::INVALID_TOKEN); } // load file syncs $fileSyncs = FileSyncPeer::retrieveByPks(explode(',', $fileSyncIds)); if ($fileSyncs) { KalturaMonitorClient::initApiMonitor(false, 'extwidget.serveMultiFile', $fileSyncs[0]->getPartnerId()); } // resolve file syncs $filePaths = array(); foreach ($fileSyncs as $fileSync) { if ($fileSync->getDc() != $currentDcId) { $error = "FileSync id [" . $fileSync->getId() . "] does not belong to this DC"; KalturaLog::err($error); KExternalErrors::dieError(KExternalErrors::BAD_QUERY); } // resolve if file_sync is link $fileSyncResolved = kFileSyncUtils::resolve($fileSync); // check if file sync path leads to a file or a directory $resolvedPath = $fileSyncResolved->getFullPath(); if (is_dir($resolvedPath)) { $error = "FileSync id [" . $fileSync->getId() . "] is a directory"; KalturaLog::err($error); KExternalErrors::dieError(KExternalErrors::BAD_QUERY); } if (!file_exists($resolvedPath)) { $error = "Path [{$resolvedPath}] for fileSync id [" . $fileSync->getId() . "] does not exist"; KalturaLog::err($error); continue; } $filePaths[$fileSync->getId()] = $resolvedPath; } $boundary = md5(uniqid('', true)); header('Content-Type: multipart/form-data; boundary=' . $boundary); foreach ($filePaths as $id => $filePath) { echo "--{$boundary}\n"; echo "Content-Type: application/octet-stream\n"; echo "Content-Disposition: form-data; name=\"{$id}\"\n\n"; readfile($filePath); echo "\n"; } echo "--{$boundary}--\n"; KExternalErrors::dieGracefully(); }
/** * Returns the local path with no extension * * @param FileSync $fileSync * @return string */ protected function doGetFileSyncUrl(FileSync $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); $url = $fileSync->getFilePath(); $url = str_replace('\\', '/', $url); if ($this->protocol == StorageProfile::PLAY_FORMAT_RTMP) { $url = preg_replace('/\\.[\\w]+$/', '', $url); } if ($this->protocol == StorageProfile::PLAY_FORMAT_APPLE_HTTP) { return $fileSync->getFilePath() . "/playlist.m3u8"; } return $url; }
/** * @param entry $entry * @param FileSyncKey $key */ protected static function export(entry $entry, StorageProfile $externalStorage, FileSyncKey $key, $force = false) { /* @var $fileSync FileSync */ list($fileSync, $local) = kFileSyncUtils::getReadyFileSyncForKey($key, true, false); if (!$fileSync || $fileSync->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_URL) { KalturaLog::info("no ready fileSync was found for key [{$key}]"); return; } $externalFileSync = kFileSyncUtils::createPendingExternalSyncFileForKey($key, $externalStorage, $fileSync->getIsDir()); $parent_file_sync = kFileSyncUtils::resolve($fileSync); $srcFileSyncPath = $parent_file_sync->getFileRoot() . $parent_file_sync->getFilePath(); kJobsManager::addStorageExportJob(null, $entry->getId(), $entry->getPartnerId(), $externalStorage, $externalFileSync, $srcFileSyncPath, $force, $fileSync->getDc()); return true; }
public function validateForUsage($sourceObject, $propertiesToSkip = array()) { parent::validateForUsage($sourceObject, $propertiesToSkip); $this->validatePropertyNotNull('assetId'); $srcFlavorAsset = assetPeer::retrieveById($this->assetId); if (!$srcFlavorAsset) { throw new KalturaAPIException(KalturaErrors::FLAVOR_ASSET_ID_NOT_FOUND, $resource->assetId); } $key = $srcFlavorAsset->getSyncKey(asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET); $c = FileSyncPeer::getCriteriaForFileSyncKey($key); $c->addAnd(FileSyncPeer::FILE_TYPE, array(FileSync::FILE_SYNC_FILE_TYPE_FILE, FileSync::FILE_SYNC_FILE_TYPE_LINK), Criteria::IN); $fileSyncs = FileSyncPeer::doSelect($c); foreach ($fileSyncs as $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); if ($fileSync->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_FILE) { return; } } throw new KalturaAPIException(KalturaErrors::FILE_DOESNT_EXIST); }
/** * Convert entry * * @param string $entryId Media entry id * @param int $conversionProfileId * @param KalturaConversionAttributeArray $dynamicConversionAttributes * @return int job id * @throws KalturaErrors::ENTRY_ID_NOT_FOUND * @throws KalturaErrors::CONVERSION_PROFILE_ID_NOT_FOUND * @throws KalturaErrors::FLAVOR_PARAMS_NOT_FOUND */ protected function convert($entryId, $conversionProfileId = null, KalturaConversionAttributeArray $dynamicConversionAttributes = null) { $entry = entryPeer::retrieveByPK($entryId); if (!$entry) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } $srcFlavorAsset = flavorAssetPeer::retrieveOriginalByEntryId($entryId); if (!$srcFlavorAsset) { throw new KalturaAPIException(KalturaErrors::ORIGINAL_FLAVOR_ASSET_IS_MISSING); } if (is_null($conversionProfileId) || $conversionProfileId <= 0) { $conversionProfile = myPartnerUtils::getConversionProfile2ForEntry($entryId); if (!$conversionProfile) { throw new KalturaAPIException(KalturaErrors::CONVERSION_PROFILE_ID_NOT_FOUND, $conversionProfileId); } $conversionProfileId = $conversionProfile->getId(); } $srcSyncKey = $srcFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); // if the file sync isn't local (wasn't synced yet) proxy request to other datacenter list($fileSync, $local) = kFileSyncUtils::getReadyFileSyncForKey($srcSyncKey, true, false); if (!$local) { // over come a bug in kFileSyncUtils which return an unready filesync as the filesync of a remote dc $fileSync = kFileSyncUtils::getReadyExternalFileSyncForKey($srcSyncKey, 1 - kDataCenterMgr::getCurrentDcId()); $fileSync = kFileSyncUtils::resolve($fileSync); kFile::dumpApiRequest(kDataCenterMgr::getRemoteDcExternalUrl($fileSync)); } else { if (!$fileSync) { throw new KalturaAPIException(KalturaErrors::FILE_DOESNT_EXIST); } } // even if it null $entry->setConversionQuality($conversionProfileId); $entry->setConversionProfileId($conversionProfileId); $entry->save(); if ($dynamicConversionAttributes) { $flavors = flavorParamsPeer::retrieveByProfile($conversionProfileId); if (!count($flavors)) { throw new KalturaAPIException(KalturaErrors::FLAVOR_PARAMS_NOT_FOUND); } $srcFlavorParamsId = null; $flavorParams = $entry->getDynamicFlavorAttributes(); foreach ($flavors as $flavor) { if ($flavor->hasTag(flavorParams::TAG_SOURCE)) { $srcFlavorParamsId = $flavor->getId(); } $flavorParams[$flavor->getId()] = $flavor; } $dynamicAttributes = array(); foreach ($dynamicConversionAttributes as $dynamicConversionAttribute) { if (is_null($dynamicConversionAttribute->flavorParamsId)) { $dynamicConversionAttribute->flavorParamsId = $srcFlavorParamsId; } if (is_null($dynamicConversionAttribute->flavorParamsId)) { continue; } $dynamicAttributes[$dynamicConversionAttribute->flavorParamsId][trim($dynamicConversionAttribute->name)] = trim($dynamicConversionAttribute->value); } if (count($dynamicAttributes)) { $entry->setDynamicFlavorAttributes($dynamicAttributes); $entry->save(); } } $srcFilePath = kFileSyncUtils::getLocalFilePathForKey($srcSyncKey); $job = kJobsManager::addConvertProfileJob(null, $entry, $srcFlavorAsset->getId(), $srcFilePath); if (!$job) { return null; } return $job->getId(); }
public static function serveFileToRemoteDataCenter($file_sync_id, $file_hash, $file_name) { KalturaLog::log("File sync id [{$file_sync_id}], file_hash [{$file_hash}], file_name [{$file_name}]"); // TODO - verify security $current_dc = self::getCurrentDc(); $current_dc_id = $current_dc["id"]; // retrieve the object $file_sync = FileSyncPeer::retrieveByPk($file_sync_id); if (!$file_sync) { $error = "DC[{$current_dc_id}]: Cannot find FileSync with id [{$file_sync_id}]"; KalturaLog::err($error); throw new Exception($error); } if ($file_sync->getDc() != $current_dc_id) { $error = "DC[{$current_dc_id}]: FileSync with id [{$file_sync_id}] does not belong to this DC"; KalturaLog::err($error); throw new Exception($error); } // resolve if file_sync is link $file_sync_resolved = $file_sync; if ($file_sync->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_LINK) { $file_sync_resolved = kFileSyncUtils::resolve($file_sync); } // check if file sync path leads to a file or a directory $resolvedPath = $file_sync_resolved->getFullPath(); $fileSyncIsDir = is_dir($resolvedPath); if ($fileSyncIsDir && $file_name) { $resolvedPath .= '/' . $file_name; } if (!file_exists($resolvedPath)) { $file_name_msg = $file_name ? "file name [{$file_name}] " : ''; $error = "DC[{$current_dc_id}]: Path for fileSync id [{$file_sync_id}] " . $file_name_msg . "does not exist"; KalturaLog::err($error); throw new Exception($error); } // validate the hash $expected_file_hash = md5($current_dc["secret"] . $file_sync_id); // will be verified on the other side to make sure not some attack or external invalid request if ($file_hash != $expected_file_hash) { $error = "DC[{$current_dc_id}]: FileSync with id [{$file_sync_id}] - invalid hash"; KalturaLog::err($error); throw new Exception($error); } if ($fileSyncIsDir && is_dir($resolvedPath)) { KalturaLog::log("Serving directory content from [" . $resolvedPath . "]"); $contents = kFile::listDir($resolvedPath); sort($contents, SORT_STRING); $contents = serialize($contents); header("file-sync-type: dir"); echo $contents; die; } else { KalturaLog::log("Serving file from [" . $resolvedPath . "]"); kFile::dumpFile($resolvedPath); } }
public function doFromObject($source_object, KalturaDetachedResponseProfile $responseProfile = null) { parent::doFromObject($source_object, $responseProfile); $this->fileUrl = $source_object->getExternalUrl($this->getEntryId($source_object)); $this->isCurrentDc = $source_object->getDc() == kDataCenterMgr::getCurrentDcId(); if ($this->fileType == KalturaFileSyncType::LINK) { $fileSync = kFileSyncUtils::resolve($source_object); $this->fileRoot = $fileSync->getFileRoot(); $this->filePath = $fileSync->getFilePath(); } if ($this->isCurrentDc) { $path = $this->fileRoot . $this->filePath; $this->fileDiscSize = kFile::fileSize($path); $content = file_get_contents($path, false, null, 0, 1024); if (ctype_print($content) || ctype_cntrl($content)) { $this->fileContent = $content; } } }
/** * @param FileSync $fileSync * @return string */ protected function doGetFileSyncUrl(FileSync $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); $storage = StorageProfilePeer::retrieveByPK($fileSync->getDc()); if (!$storage) { return parent::doGetFileSyncUrl($fileSync); } $serverUrl = $storage->getDeliveryIisBaseUrl(); $partnerPath = myPartnerUtils::getUrlForPartner($fileSync->getPartnerId(), $fileSync->getPartnerId() * 100); if ($this->protocol == StorageProfile::PLAY_FORMAT_APPLE_HTTP && isset($this->params["hd_ios"])) { $path = $fileSync->getFilePath(); $urlSuffix = str_replace('\\', '/', $path) . "/index_0_av.m3u8"; $urlPrefix = "http://" . $this->params["hd_ios"] . '/i/'; return $urlPrefix . ltrim($urlSuffix, '/'); } if ($this->protocol == "hdnetworksmil" && isset($this->params["hd_flash"])) { $path = $fileSync->getFilePath(); $urlSuffix = str_replace('\\', '/', $path); $urlPrefix = "http://" . $this->params["hd_flash"]; return $urlPrefix . '/' . ltrim($urlSuffix, '/'); } if ($fileSync->getObjectSubType() != entry::FILE_SYNC_ENTRY_SUB_TYPE_ISM) { return parent::doGetFileSyncUrl($fileSync); } $serverUrl = myPartnerUtils::getIisHost($fileSync->getPartnerId(), "http"); $path = $partnerPath . '/serveIsm/objectId/' . $fileSync->getObjectId() . '_' . $fileSync->getObjectSubType() . '_' . $fileSync->getVersion() . '.' . pathinfo(kFileSyncUtils::resolve($fileSync)->getFilePath(), PATHINFO_EXTENSION) . '/manifest'; $matches = null; if (preg_match('/(https?:\\/\\/[^\\/]+)(.*)/', $serverUrl, $matches)) { $path = $matches[2] . $path; } $path = str_replace('//', '/', $path); return $path; }
public function execute() { //entitlement should be disabled to serveFlavor action as we do not get ks on this action. KalturaCriterion::disableTag(KalturaCriterion::TAG_ENTITLEMENT_CATEGORY); requestUtils::handleConditionalGet(); $flavorId = $this->getRequestParameter("flavorId"); $shouldProxy = $this->getRequestParameter("forceproxy", false); $fileName = $this->getRequestParameter("fileName"); $fileParam = $this->getRequestParameter("file"); $fileParam = basename($fileParam); $pathOnly = $this->getRequestParameter("pathOnly", false); $referrer = base64_decode($this->getRequestParameter("referrer")); if (!is_string($referrer)) { // base64_decode can return binary data $referrer = ''; } $flavorAsset = assetPeer::retrieveById($flavorId); if (is_null($flavorAsset)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $entryId = $this->getRequestParameter("entryId"); if (!is_null($entryId) && $flavorAsset->getEntryId() != $entryId) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if ($fileName) { header("Content-Disposition: attachment; filename=\"{$fileName}\""); header("Content-Type: application/force-download"); header("Content-Description: File Transfer"); } $clipTo = null; $entry = $flavorAsset->getentry(); if (!$entry) { KExternalErrors::dieError(KExternalErrors::ENTRY_NOT_FOUND); } KalturaMonitorClient::initApiMonitor(false, 'extwidget.serveFlavor', $flavorAsset->getPartnerId()); myPartnerUtils::enforceDelivery($entry, $flavorAsset); $version = $this->getRequestParameter("v"); if (!$version) { $version = $flavorAsset->getVersion(); } $syncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET, $version); if ($pathOnly && kIpAddressUtils::isInternalIp($_SERVER['REMOTE_ADDR'])) { $path = null; list($file_sync, $local) = kFileSyncUtils::getReadyFileSyncForKey($syncKey, false, false); if ($file_sync) { $parent_file_sync = kFileSyncUtils::resolve($file_sync); $path = $parent_file_sync->getFullPath(); if ($fileParam && is_dir($path)) { $path .= "/{$fileParam}"; } } $renderer = new kRendererString('{"sequences":[{"clips":[{"type":"source","path":"' . $path . '"}]}]}', 'application/json'); if ($path) { $this->storeCache($renderer, $flavorAsset->getPartnerId()); } $renderer->output(); KExternalErrors::dieGracefully(); } if (kConf::hasParam('serve_flavor_allowed_partners') && !in_array($flavorAsset->getPartnerId(), kConf::get('serve_flavor_allowed_partners'))) { KExternalErrors::dieError(KExternalErrors::ACTION_BLOCKED); } if (!kFileSyncUtils::file_exists($syncKey, false)) { list($fileSync, $local) = kFileSyncUtils::getReadyFileSyncForKey($syncKey, true, false); if (is_null($fileSync)) { KalturaLog::log("Error - no FileSync for flavor [" . $flavorAsset->getId() . "]"); KExternalErrors::dieError(KExternalErrors::FILE_NOT_FOUND); } // always dump remote urls so they will be cached by the cdn transparently $remoteUrl = kDataCenterMgr::getRedirectExternalUrl($fileSync); kFileUtils::dumpUrl($remoteUrl); } $path = kFileSyncUtils::getReadyLocalFilePathForKey($syncKey); $isFlv = false; if (!$shouldProxy) { $flvWrapper = new myFlvHandler($path); $isFlv = $flvWrapper->isFlv(); } $clipFrom = $this->getRequestParameter("clipFrom", 0); // milliseconds if (is_null($clipTo)) { $clipTo = $this->getRequestParameter("clipTo", self::NO_CLIP_TO); } // milliseconds if ($clipTo == 0) { $clipTo = self::NO_CLIP_TO; } if (!is_numeric($clipTo) || $clipTo < 0) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'clipTo must be a positive number'); } $seekFrom = $this->getRequestParameter("seekFrom", -1); if ($seekFrom <= 0) { $seekFrom = -1; } $seekFromBytes = $this->getRequestParameter("seekFromBytes", -1); if ($seekFromBytes <= 0) { $seekFromBytes = -1; } if ($fileParam && is_dir($path)) { $path .= "/{$fileParam}"; kFileUtils::dumpFile($path, null, null); KExternalErrors::dieGracefully(); } else { if (!$isFlv || $clipTo == self::NO_CLIP_TO && $seekFrom < 0 && $seekFromBytes < 0) { $limit_file_size = 0; if ($clipTo != self::NO_CLIP_TO) { if (strtolower($flavorAsset->getFileExt()) == 'mp4' && PermissionPeer::isValidForPartner(PermissionName::FEATURE_ACCURATE_SERVE_CLIPPING, $flavorAsset->getPartnerId())) { $contentPath = myContentStorage::getFSContentRootPath(); $tempClipName = $version . '_' . $clipTo . '.mp4'; $tempClipPath = $contentPath . myContentStorage::getGeneralEntityPath("entry/tempclip", $flavorAsset->getIntId(), $flavorAsset->getId(), $tempClipName); if (!file_exists($tempClipPath)) { kFile::fullMkdir($tempClipPath); $clipToSec = round($clipTo / 1000, 3); $cmdLine = kConf::get("bin_path_ffmpeg") . " -i {$path} -vcodec copy -acodec copy -f mp4 -t {$clipToSec} -y {$tempClipPath} 2>&1"; KalturaLog::log("Executing {$cmdLine}"); $output = array(); $return_value = ""; exec($cmdLine, $output, $return_value); KalturaLog::log("ffmpeg returned {$return_value}, output:" . implode("\n", $output)); } if (file_exists($tempClipPath)) { KalturaLog::log("Dumping {$tempClipPath}"); kFileUtils::dumpFile($tempClipPath); } else { KalturaLog::err('Failed to clip the file using ffmpeg, falling back to rough clipping'); } } $mediaInfo = mediaInfoPeer::retrieveByFlavorAssetId($flavorAsset->getId()); if ($mediaInfo && ($mediaInfo->getVideoDuration() || $mediaInfo->getAudioDuration() || $mediaInfo->getContainerDuration())) { $duration = $mediaInfo->getVideoDuration() ? $mediaInfo->getVideoDuration() : ($mediaInfo->getAudioDuration() ? $mediaInfo->getAudioDuration() : $mediaInfo->getContainerDuration()); $limit_file_size = floor(@kFile::fileSize($path) * ($clipTo / $duration) * 1.2); } } $renderer = kFileUtils::getDumpFileRenderer($path, null, null, $limit_file_size); if (!$fileName) { $this->storeCache($renderer, $flavorAsset->getPartnerId()); } $renderer->output(); KExternalErrors::dieGracefully(); } } $audioOnly = $this->getRequestParameter("audioOnly"); // milliseconds if ($audioOnly === '0') { // audioOnly was explicitly set to 0 - don't attempt to make further automatic investigations } elseif ($flvWrapper->getFirstVideoTimestamp() < 0) { $audioOnly = true; } $bytes = 0; if ($seekFrom !== -1 && $seekFrom !== 0) { list($bytes, $duration, $firstTagByte, $toByte) = $flvWrapper->clip(0, -1, $audioOnly); list($bytes, $duration, $fromByte, $toByte, $seekFromTimestamp) = $flvWrapper->clip($seekFrom, -1, $audioOnly); $seekFromBytes = myFlvHandler::FLV_HEADER_SIZE + $flvWrapper->getMetadataSize($audioOnly) + $fromByte - $firstTagByte; } else { list($bytes, $duration, $fromByte, $toByte, $fromTs, $cuepointPos) = myFlvStaticHandler::clip($path, $clipFrom, $clipTo, $audioOnly); } $metadataSize = $flvWrapper->getMetadataSize($audioOnly); $dataOffset = $metadataSize + myFlvHandler::getHeaderSize(); $totalLength = $dataOffset + $bytes; list($bytes, $duration, $fromByte, $toByte, $fromTs, $cuepointPos) = myFlvStaticHandler::clip($path, $clipFrom, $clipTo, $audioOnly); list($rangeFrom, $rangeTo, $rangeLength) = requestUtils::handleRangeRequest($totalLength); if ($totalLength < 1000) { // (actually $total_length is probably 13 or 143 - header + empty metadata tag) probably a bad flv maybe only the header - dont cache requestUtils::sendCdnHeaders("flv", $rangeLength, 0); } else { requestUtils::sendCdnHeaders("flv", $rangeLength); } // dont inject cuepoint into the stream $cuepointTime = 0; $cuepointPos = 0; try { Propel::close(); } catch (Exception $e) { $this->logMessage("serveFlavor: error closing db {$e}"); } header("Content-Type: video/x-flv"); $flvWrapper->dump(self::CHUNK_SIZE, $fromByte, $toByte, $audioOnly, $seekFromBytes, $rangeFrom, $rangeTo, $cuepointTime, $cuepointPos); KExternalErrors::dieGracefully(); }
/** * @param flavorAsset $flavorAsset * @param FileSyncKey $srcSyncKey */ protected function attachFileSync(flavorAsset $flavorAsset, FileSyncKey $srcSyncKey) { $flavorAsset->incrementVersion(); $flavorAsset->save(); $newSyncKey = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); kFileSyncUtils::createSyncFileLinkForKey($newSyncKey, $srcSyncKey); $fileSync = kFileSyncUtils::getLocalFileSyncForKey($newSyncKey, false); $fileSync = kFileSyncUtils::resolve($fileSync); if (!$flavorAsset->isLocalReadyStatus()) { $flavorAsset->setStatus(flavorAsset::FLAVOR_ASSET_STATUS_QUEUED); } $flavorAsset->setSize($fileSync->getFileSize()); $flavorAsset->save(); }
public function doFromObject($source_object, KalturaDetachedResponseProfile $responseProfile = null) { parent::doFromObject($source_object, $responseProfile); if ($this->shouldGet('fileUrl', $responseProfile)) { $this->fileUrl = $source_object->getExternalUrl($this->getEntryId($source_object)); } if ($this->shouldGet('isCurrentDc', $responseProfile)) { $this->isCurrentDc = $source_object->getDc() == kDataCenterMgr::getCurrentDcId(); } if ($source_object->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_LINK && ($this->shouldGet('fileRoot', $responseProfile) || $this->shouldGet('filePath', $responseProfile))) { $fileSync = kFileSyncUtils::resolve($source_object); $this->fileRoot = $fileSync->getFileRoot(); $this->filePath = $fileSync->getFilePath(); } if ($source_object->getDc() == kDataCenterMgr::getCurrentDcId()) { $path = $source_object->getFullPath(); if ($this->shouldGet('fileDiscSize', $responseProfile)) { $this->fileDiscSize = kFile::fileSize($path); } if ($this->shouldGet('fileContent', $responseProfile)) { $content = file_get_contents($path, false, null, 0, 1024); if (ctype_print($content) || ctype_cntrl($content)) { $this->fileContent = $content; } } } }
private static function saveOriginalSource($mediaInfo) { $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)); $origFileSync = kFileSyncUtils::resolve($origFileSync); $asset->setSize(intval($origFileSync->getFileSize() / 1000)); $asset->save(); }
/** * @param FileAsset $dbFileAsset * @param FileSyncKey $srcSyncKey */ protected function attachFileSync(FileAsset $dbFileAsset, FileSyncKey $srcSyncKey) { $dbFileAsset->incrementVersion(); $dbFileAsset->save(); $newSyncKey = $dbFileAsset->getSyncKey(FileAsset::FILE_SYNC_ASSET); kFileSyncUtils::createSyncFileLinkForKey($newSyncKey, $srcSyncKey); $fileSync = kFileSyncUtils::getLocalFileSyncForKey($newSyncKey, false); $fileSync = kFileSyncUtils::resolve($fileSync); $dbFileAsset->setStatus(FileAssetStatus::READY); $dbFileAsset->setSize($fileSync->getFileSize()); $dbFileAsset->save(); }
public static function serveFileToRemoteDataCenter($file_sync, $file_hash, $file_name) { $file_sync_id = $file_sync->getId(); KalturaLog::log("File sync id [{$file_sync_id}], file_hash [{$file_hash}], file_name [{$file_name}]"); // TODO - verify security $current_dc = self::getCurrentDc(); $current_dc_id = $current_dc["id"]; if ($file_sync->getDc() != $current_dc_id) { $error = "DC[{$current_dc_id}]: FileSync with id [{$file_sync_id}] does not belong to this DC"; KalturaLog::err($error); KExternalErrors::dieError(KExternalErrors::BAD_QUERY); } // resolve if file_sync is link $file_sync_resolved = $file_sync; $file_sync_resolved = kFileSyncUtils::resolve($file_sync); // check if file sync path leads to a file or a directory $resolvedPath = $file_sync_resolved->getFullPath(); $fileSyncIsDir = is_dir($resolvedPath); if ($fileSyncIsDir && $file_name) { $resolvedPath .= '/' . $file_name; } if (!file_exists($resolvedPath)) { $file_name_msg = $file_name ? "file name [{$file_name}] " : ''; $error = "DC[{$current_dc_id}]: Path for fileSync id [{$file_sync_id}] " . $file_name_msg . "does not exist, resolved path [{$resolvedPath}]"; KalturaLog::err($error); KExternalErrors::dieError(KExternalErrors::FILE_NOT_FOUND); } // validate the hash $expected_file_hash = md5($current_dc["secret"] . $file_sync_id); // will be verified on the other side to make sure not some attack or external invalid request if ($file_hash != $expected_file_hash) { $error = "DC[{$current_dc_id}]: FileSync with id [{$file_sync_id}] - invalid hash"; KalturaLog::err($error); KExternalErrors::dieError(KExternalErrors::INVALID_TOKEN); } if ($fileSyncIsDir && is_dir($resolvedPath)) { KalturaLog::log("Serving directory content from [" . $resolvedPath . "]"); $contents = kFile::listDir($resolvedPath); sort($contents, SORT_STRING); $contents = serialize($contents); header("file-sync-type: dir"); echo $contents; KExternalErrors::dieGracefully(); } else { KalturaLog::log("Serving file from [" . $resolvedPath . "]"); kFileUtils::dumpFile($resolvedPath); } }
/** * @param FileSync $fileSync * @param bool $tokenizeUrl * @return string */ public function getFileSyncUrl(FileSync $fileSync, $tokenizeUrl = true) { $fileSync = kFileSyncUtils::resolve($fileSync); $url = $this->doGetFileSyncUrl($fileSync); $url = str_replace('\\', '/', $url); if ($tokenizeUrl) { $tokenizer = $this->getTokenizer(); if ($tokenizer) { $url = $tokenizer->tokenizeSingleUrl($url, $this->getUrlPrefix()); kApiCache::disableCache(); } } return $url; }
/** * @param FileSync $fileSync * @return string */ public function getFileSyncUrl(FileSync $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); if ($fileSync->getObjectSubType() == entry::FILE_SYNC_ENTRY_SUB_TYPE_ISM) { return $fileSync->getSmoothStreamUrl() . "/manifest"; } if ($this->protocol == StorageProfile::PLAY_FORMAT_APPLE_HTTP) { return $fileSync->getFilePath() . "/playlist.m3u8"; } $url = $fileSync->getFilePath(); $url = str_replace('\\', '/', $url); if ($this->protocol == StorageProfile::PLAY_FORMAT_RTMP) { if ($this->extention && strtolower($this->extention) != 'flv' || $this->containerFormat && strtolower($this->containerFormat) != 'flash video') { $url = "mp4:{$url}"; } $url = str_replace('.mp4', '', str_replace('.flv', '', $url)); } return $url; }
public function fromObject($source_object) { parent::fromObject($source_object); $this->fileUrl = $source_object->getExternalUrl(); $this->readyAt = $source_object->getReadyAt(null); $this->isCurrentDc = $source_object->getDc() == kDataCenterMgr::getCurrentDcId(); if ($this->fileType == KalturaFileSyncType::LINK) { $fileSync = kFileSyncUtils::resolve($source_object); $this->fileRoot = $fileSync->getFileRoot(); $this->filePath = $fileSync->getFilePath(); } if ($this->isCurrentDc) { $path = $this->fileRoot . $this->filePath; $this->fileDiscSize = filesize($path); $content = file_get_contents($path, false, null, 0, 1024); if (ctype_print($content) || ctype_cntrl($content)) { $this->fileContent = $content; } } }
/** * @param FileSync $fileSync * @return string */ protected function doGetFileSyncUrl(FileSync $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); if ($fileSync->getObjectSubType() == entry::FILE_SYNC_ENTRY_SUB_TYPE_ISM) { return $fileSync->getSmoothStreamUrl(); } $url = $fileSync->getFilePath(); $url = str_replace('\\', '/', $url); if ($this->protocol == StorageProfile::PLAY_FORMAT_RTMP) { $storageProfile = StorageProfilePeer::retrieveByPK($this->storageProfileId); if ($storageProfile->getRTMPPrefix()) { if (strpos($url, '/') !== 0) { $url = '/' . $url; } $url = $storageProfile->getRTMPPrefix() . $url; } if ($this->extention && strtolower($this->extention) != 'flv' || $this->containerFormat && strtolower($this->containerFormat) != 'flash video') { $url = "mp4:{$url}"; } // when serving files directly via RTMP fms doesnt expect to get the file extension $url = str_replace('.mp4', '', str_replace('.flv', '', $url)); } return $url; }
/** * @param EntryDistribution $entryDistribution * @param DistributionProfile $distributionProfile * @param int $dc * @return bool true if the job could be created */ protected static function prepareDistributionJob(EntryDistribution $entryDistribution, DistributionProfile $distributionProfile, &$dc) { // prepare ids list of all the assets $assetIds = explode(',', implode(',', array($entryDistribution->getThumbAssetIds(), $entryDistribution->getFlavorAssetIds()))); $assets = assetPeer::retrieveByIds($assetIds); $assetObjects = array(); foreach ($assets as $asset) { /* @var $asset asset */ $assetObjects[$asset->getId()] = array('asset' => $asset, 'downloadUrl' => null); } // lists all files from all assets $c = new Criteria(); $c->add(FileSyncPeer::OBJECT_TYPE, FileSyncObjectType::ASSET); $c->add(FileSyncPeer::OBJECT_SUB_TYPE, asset::FILE_SYNC_ASSET_SUB_TYPE_ASSET); $c->add(FileSyncPeer::OBJECT_ID, $assetIds, Criteria::IN); $c->add(FileSyncPeer::PARTNER_ID, $entryDistribution->getPartnerId()); $c->add(FileSyncPeer::STATUS, FileSync::FILE_SYNC_STATUS_READY); $fileSyncs = FileSyncPeer::doSelect($c); $dcs = array(); foreach ($fileSyncs as $fileSync) { /* @var $fileSync FileSync */ $assetId = $fileSync->getObjectId(); if (!isset($assetObjects[$assetId])) { // the object is not in the list of assets continue; } $asset = $assetObjects[$assetId]['asset']; /* @var $asset asset */ if ($asset->getVersion() != $fileSync->getVersion()) { // the file sync is not of the current asset version continue; } $fileSync = kFileSyncUtils::resolve($fileSync); // use the best URL as the source for download in case it will be needed if ($fileSync->getFileType() == FileSync::FILE_SYNC_FILE_TYPE_URL) { if (!is_null($assetObjects[$assetId]['downloadUrl']) && $fileSync->getDc() != $distributionProfile->getRecommendedStorageProfileForDownload()) { continue; } $downloadUrl = $fileSync->getExternalUrl($entryDistribution->getEntryId()); if (!$downloadUrl) { continue; } $assetObjects[$assetId]['downloadUrl'] = $downloadUrl; continue; } // populates the list of files in each dc $fileSyncDc = $fileSync->getDc(); if (!isset($dcs[$fileSyncDc])) { $dcs[$fileSyncDc] = array(); } $dcs[$fileSyncDc][$assetId] = $fileSync->getId(); } if (isset($dcs[$dc]) && count($dcs[$dc]) == count($assets)) { KalturaLog::debug("All files exist in the preferred dc [{$dc}]"); return true; } // check if all files exist on any of the remote dcs $otherDcs = kDataCenterMgr::getAllDcs(true); foreach ($otherDcs as $remoteDc) { $remoteDcId = $remoteDc['id']; if (!isset($dcs[$remoteDcId]) && count($dcs[$remoteDcId]) != count($assets)) { continue; } $dc = $remoteDcId; KalturaLog::debug("All files exist in none-preferred dc [{$dc}]"); return true; } if ($entryDistribution->getStatus() == EntryDistributionStatus::IMPORT_SUBMITTING || $entryDistribution->getStatus() == EntryDistributionStatus::IMPORT_UPDATING) { KalturaLog::debug("Entry distribution already importing"); return false; } // create all needed import jobs $destinationDc = $distributionProfile->getRecommendedDcForDownload(); $dcExistingFiles = $dcs[$destinationDc]; foreach ($assetObjects as $assetId => $assetObject) { if (is_null($assetObject['downloadUrl'])) { KalturaLog::debug("Download URL not found for asset [{$assetId}]"); continue; } $asset = $assetObject['asset']; /* @var $asset asset */ if (isset($dcExistingFiles[$assetId])) { continue; } $jobData = new kImportJobData(); $jobData->setCacheOnly(true); self::addImportJob($destinationDc, $assetObject['downloadUrl'], $asset); } return false; }
/** * @param FileSync $fileSync * @return string */ public function getFileSyncUrl(FileSync $fileSync) { $fileSync = kFileSyncUtils::resolve($fileSync); $storage = StorageProfilePeer::retrieveByPK($fileSync->getDc()); if (!$storage) { return parent::getFileSyncUrl($fileSync); } $serverUrl = $storage->getDeliveryIisBaseUrl(); $partnerPath = myPartnerUtils::getUrlForPartner($fileSync->getPartnerId(), $fileSync->getPartnerId() * 100); if ($this->protocol == StorageProfile::PLAY_FORMAT_APPLE_HTTP) { return $partnerPath . $fileSync->getFilePath() . "/playlist.m3u8"; } if ($fileSync->getObjectSubType() != entry::FILE_SYNC_ENTRY_SUB_TYPE_ISM) { return parent::getFileSyncUrl($fileSync); } $path = $partnerPath . '/serveIsm/objectId/' . $fileSync->getObjectId() . '_' . $fileSync->getObjectSubType() . '_' . $fileSync->getVersion() . '.' . pathinfo(kFileSyncUtils::resolve($fileSync)->getFilePath(), PATHINFO_EXTENSION) . '/manifest'; // $path = $partnerPath.'/serveIsm/objectId/'.pathinfo(kFileSyncUtils::resolve($fileSync)->getFilePath(), PATHINFO_BASENAME).'/manifest'; $matches = null; if (preg_match('/(https?:\\/\\/[^\\/]+)(.*)/', $serverUrl, $matches)) { $serverUrl = $matches[1]; $path = $matches[2] . $path; } $path = str_replace('//', '/', $path); $window = $this->params['smooth_auth_seconds']; $param = $this->params['smooth_auth_param']; $salt = $this->params['smooth_auth_salt']; $authPath = $this->urlauth_gen_url($path, $param, $window, $salt, null, null); return $serverUrl . '/' . $authPath; }