/** * Will forward to the regular swf player according to the widget_id */ public function execute() { myDbHelper::$use_alternative_con = myDbHelper::DB_HELPER_CONN_PROPEL2; requestUtils::handleConditionalGet(); ignore_user_abort(); $entry_id = $this->getRequestParameter("entry_id"); $widget_id = $this->getRequestParameter("widget_id", 0); $upload_token_id = $this->getRequestParameter("upload_token_id"); $version = $this->getIntRequestParameter("version", null, 0, 10000000); $type = $this->getIntRequestParameter("type", 1, 1, 5); //Hack: if KMS sends thumbnail request containing "!" char, the type should be treated as 5. $width = $this->getRequestParameter("width", -1); $height = $this->getRequestParameter("height", -1); if (strpos($width, "!") || strpos($height, "!")) { $type = 5; } $width = $this->getFloatRequestParameter("width", -1, -1, 10000); $height = $this->getFloatRequestParameter("height", -1, -1, 10000); $crop_provider = $this->getRequestParameter("crop_provider", null); $quality = $this->getIntRequestParameter("quality", 0, 0, 100); $src_x = $this->getFloatRequestParameter("src_x", 0, 0, 10000); $src_y = $this->getFloatRequestParameter("src_y", 0, 0, 10000); $src_w = $this->getFloatRequestParameter("src_w", 0, 0, 10000); $src_h = $this->getFloatRequestParameter("src_h", 0, 0, 10000); $vid_sec = $this->getFloatRequestParameter("vid_sec", -1, -1); $vid_slice = $this->getRequestParameter("vid_slice", -1); $vid_slices = $this->getRequestParameter("vid_slices", -1); $density = $this->getFloatRequestParameter("density", 0, 0); $stripProfiles = $this->getRequestParameter("strip", null); $flavor_id = $this->getRequestParameter("flavor_id", null); $file_name = $this->getRequestParameter("file_name", null); $file_name = basename($file_name); // actual width and height of image from which the src_* values were taken. // these will be used to multiply the src_* parameters to make them relate to the original image size. $rel_width = $this->getFloatRequestParameter("rel_width", -1, -1, 10000); $rel_height = $this->getFloatRequestParameter("rel_height", -1, -1, 10000); if ($width == -1 && $height == -1) { $width = 120; $height = 90; } else { if ($width == -1) { // if only either width or height is missing reset them to zero, and convertImage will handle them $width = 0; } else { if ($height == -1) { $height = 0; } } } $bgcolor = $this->getRequestParameter("bgcolor", "ffffff"); $partner = null; // validating the inputs if (!is_numeric($quality) || $quality < 0 || $quality > 100) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'quality must be between 20 and 100'); } if (!is_numeric($src_x) || $src_x < 0 || $src_x > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_x must be between 0 and 10000'); } if (!is_numeric($src_y) || $src_y < 0 || $src_y > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_y must be between 0 and 10000'); } if (!is_numeric($src_w) || $src_w < 0 || $src_w > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_w must be between 0 and 10000'); } if (!is_numeric($src_h) || $src_h < 0 || $src_h > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_h must be between 0 and 10000'); } if (!is_numeric($width) || $width < 0 || $width > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'width must be between 0 and 10000'); } if (!is_numeric($height) || $height < 0 || $height > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'height must be between 0 and 10000'); } if (!is_numeric($density) || $density < 0) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'density must be positive'); } if (!is_numeric($vid_sec) || $vid_sec < -1) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'vid_sec must be positive'); } if (!preg_match('/^[0-9a-fA-F]{1,6}$/', $bgcolor)) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'bgcolor must be six hexadecimal characters'); } if ($upload_token_id) { $upload_token = UploadTokenPeer::retrieveByPK($upload_token_id); if ($upload_token) { $partnerId = $upload_token->getPartnerId(); $partner = PartnerPeer::retrieveByPK($partnerId); if ($density == 0) { $density = $partner->getDefThumbDensity(); } if (is_null($stripProfiles)) { $stripProfiles = $partner->getStripThumbProfile(); } $thumb_full_path = myContentStorage::getFSCacheRootPath() . myContentStorage::getGeneralEntityPath("uploadtokenthumb", $upload_token->getIntId(), $upload_token->getId(), $upload_token->getId() . ".jpg"); kFile::fullMkdir($thumb_full_path); if (file_exists($upload_token->getUploadTempPath())) { $src_full_path = $upload_token->getUploadTempPath(); $valid_image_types = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_WBMP); $image_type = exif_imagetype($src_full_path); if (!in_array($image_type, $valid_image_types)) { // capture full frame myFileConverter::captureFrame($src_full_path, $thumb_full_path, 1, "image2", -1, -1, 3); if (!file_exists($thumb_full_path)) { myFileConverter::captureFrame($src_full_path, $thumb_full_path, 1, "image2", -1, -1, 0); } $src_full_path = $thumb_full_path; } // and resize it myFileConverter::convertImage($src_full_path, $thumb_full_path, $width, $height, $type, $bgcolor, true, $quality, $src_x, $src_y, $src_w, $src_h, $density, $stripProfiles); kFile::dumpFile($thumb_full_path); } else { KalturaLog::debug("token_id [{$upload_token_id}] not found in DC [" . kDataCenterMgr::getCurrentDcId() . "]. dump url to romote DC"); $remoteUrl = kDataCenterMgr::getRemoteDcExternalUrlByDcId(1 - kDataCenterMgr::getCurrentDcId()) . $_SERVER['REQUEST_URI']; kFile::dumpUrl($remoteUrl); } } } if ($entry_id) { $entry = entryPeer::retrieveByPKNoFilter($entry_id); if (!$entry) { // problem could be due to replication lag kFile::dumpApiRequest(kDataCenterMgr::getRemoteDcExternalUrlByDcId(1 - kDataCenterMgr::getCurrentDcId())); } } else { // get the widget $widget = widgetPeer::retrieveByPK($widget_id); if (!$widget) { KExternalErrors::dieError(KExternalErrors::ENTRY_AND_WIDGET_NOT_FOUND); } // get the kshow $kshow_id = $widget->getKshowId(); $kshow = kshowPeer::retrieveByPK($kshow_id); if ($kshow) { $entry_id = $kshow->getShowEntryId(); } else { $entry_id = $widget->getEntryId(); } $entry = entryPeer::retrieveByPKNoFilter($entry_id); if (!$entry) { KExternalErrors::dieError(KExternalErrors::ENTRY_NOT_FOUND); } } $partner = $entry->getPartner(); if ($density == 0) { $density = $partner->getDefThumbDensity(); } $thumbParams = new kThumbnailParameters(); $thumbParams->setSupportAnimatedThumbnail($partner->getSupportAnimatedThumbnails()); if (is_null($stripProfiles)) { $stripProfiles = $partner->getStripThumbProfile(); } //checks whether the thumbnail display should be restricted by KS $base64Referrer = $this->getRequestParameter("referrer"); $referrer = base64_decode($base64Referrer); if (!is_string($referrer)) { $referrer = ""; } // base64_decode can return binary data if (!$referrer) { $referrer = kApiCache::getHttpReferrer(); } $ksStr = $this->getRequestParameter("ks"); $securyEntryHelper = new KSecureEntryHelper($entry, $ksStr, $referrer, accessControlContextType::THUMBNAIL); $securyEntryHelper->validateForPlay(); // multiply the passed $src_* values so that they will relate to the original image size, according to $src_display_* if ($rel_width != -1) { $widthRatio = $entry->getWidth() / $rel_width; $src_x = $src_x * $widthRatio; $src_w = $src_w * $widthRatio; } if ($rel_height != -1) { $heightRatio = $entry->getHeight() / $rel_height; $src_y = $src_y * $heightRatio; $src_h = $src_h * $heightRatio; } $subType = entry::FILE_SYNC_ENTRY_SUB_TYPE_THUMB; if ($entry->getMediaType() == entry::ENTRY_MEDIA_TYPE_IMAGE) { $subType = entry::FILE_SYNC_ENTRY_SUB_TYPE_DATA; } KalturaLog::debug("get thumbnail filesyncs"); $dataKey = $entry->getSyncKey($subType); list($file_sync, $local) = kFileSyncUtils::getReadyFileSyncForKey($dataKey, true, false); $tempThumbPath = null; $entry_status = $entry->getStatus(); // both 640x480 and 0x0 requests are probably coming from the kdp // 640x480 - old kdp version requesting thumbnail // 0x0 - new kdp version requesting the thumbnail of an unready entry // we need to distinguish between calls from the kdp and calls from a browser: <img src=...> // that can't handle swf input if (($width == 640 && $height == 480 || $width == 0 && $height == 0) && ($entry_status == entryStatus::PRECONVERT || $entry_status == entryStatus::IMPORT || $entry_status == entryStatus::ERROR_CONVERTING || $entry_status == entryStatus::DELETED)) { $contentPath = myContentStorage::getFSContentRootPath(); $msgPath = $contentPath . "content/templates/entry/bigthumbnail/"; if ($entry_status == entryStatus::DELETED) { $msgPath .= $entry->getModerationStatus() == moderation::MODERATION_STATUS_BLOCK ? "entry_blocked.swf" : "entry_deleted.swf"; } else { $msgPath .= $entry_status == entryStatus::ERROR_CONVERTING ? "entry_error.swf" : "entry_converting.swf"; } kFile::dumpFile($msgPath, null, 0); } if (!$file_sync) { $tempThumbPath = $entry->getLocalThumbFilePath($entry, $version, $width, $height, $type, $bgcolor, $crop_provider, $quality, $src_x, $src_y, $src_w, $src_h, $vid_sec, $vid_slice, $vid_slices, $density, $stripProfiles, $flavor_id, $file_name); if (!$tempThumbPath) { KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } } if (!$local && !$tempThumbPath && $file_sync) { if (!in_array($file_sync->getDc(), kDataCenterMgr::getDcIds())) { $remoteUrl = $file_sync->getExternalUrl($entry->getId()); header("Location: {$remoteUrl}"); die; } $remoteUrl = kDataCenterMgr::getRedirectExternalUrl($file_sync, $_SERVER['REQUEST_URI']); kFile::dumpUrl($remoteUrl); } // if we didnt return a template for the player die and dont return the original deleted thumb if ($entry_status == entryStatus::DELETED) { KExternalErrors::dieError(KExternalErrors::ENTRY_DELETED_MODERATED); } if (!$tempThumbPath) { try { $tempThumbPath = myEntryUtils::resizeEntryImage($entry, $version, $width, $height, $type, $bgcolor, $crop_provider, $quality, $src_x, $src_y, $src_w, $src_h, $vid_sec, $vid_slice, $vid_slices, null, $density, $stripProfiles, $thumbParams); } catch (Exception $ex) { if ($ex->getCode() != kFileSyncException::FILE_DOES_NOT_EXIST_ON_CURRENT_DC) { KalturaLog::log("Error - resize image failed"); KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } // get original flavor asset $origFlavorAsset = assetPeer::retrieveOriginalByEntryId($entry_id); if (!$origFlavorAsset) { KalturaLog::log("Error - no original flavor for entry [{$entry_id}]"); KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $syncKey = $origFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $remoteFileSync = kFileSyncUtils::getOriginFileSyncForKey($syncKey, false); if (!$remoteFileSync) { // file does not exist on any DC - die KalturaLog::log("Error - no FileSync for entry [{$entry_id}]"); KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } if ($remoteFileSync->getDc() == kDataCenterMgr::getCurrentDcId()) { KalturaLog::log("ERROR - Trying to redirect to myself - stop here."); KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } if (!in_array($remoteFileSync->getDc(), kDataCenterMgr::getDcIds())) { KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } $remoteUrl = kDataCenterMgr::getRedirectExternalUrl($remoteFileSync); kFile::dumpUrl($remoteUrl); } } $nocache = strpos($tempThumbPath, "_NOCACHE_") !== false; if ($securyEntryHelper->shouldDisableCache() || kApiCache::hasExtraFields() || !$securyEntryHelper->isKsWidget() && $securyEntryHelper->hasRules()) { $nocache = true; } // notify external proxy, so it'll cache this url if (!$nocache && requestUtils::getHost() == kConf::get("apphome_url") && file_exists($tempThumbPath)) { self::notifyProxy($_SERVER["REQUEST_URI"]); } // cache result if (!$nocache) { $requestKey = $_SERVER["REQUEST_URI"]; $cache = new myCache("thumb", 86400 * 30); // 30 days $cache->put($requestKey, $tempThumbPath); } kFile::dumpFile($tempThumbPath, null, $nocache ? 0 : null); // TODO - can delete from disk assuming we caneasily recreate it and it will anyway be cached in the CDN // however dumpfile dies at the end so we cant just write it here (maybe register a shutdown callback) }
/** * Will forward to the regular swf player according to the widget_id */ public function execute() { KExternalErrors::setResponseErrorCode(KExternalErrors::HTTP_STATUS_NOT_FOUND); myDbHelper::$use_alternative_con = myDbHelper::DB_HELPER_CONN_PROPEL2; requestUtils::handleConditionalGet(); ignore_user_abort(); $entry_id = $this->getRequestParameter("entry_id"); $widget_id = $this->getRequestParameter("widget_id", 0); $upload_token_id = $this->getRequestParameter("upload_token_id"); $version = $this->getIntRequestParameter("version", null, 0, 10000000); $type = $this->getIntRequestParameter("type", 1, 1, 5); //Hack: if KMS sends thumbnail request containing "!" char, the type should be treated as 5. $width = $this->getRequestParameter("width", -1); $height = $this->getRequestParameter("height", -1); if (strpos($width, "!") || strpos($height, "!")) { $type = 5; } $width = $this->getFloatRequestParameter("width", -1, -1, 10000); $height = $this->getFloatRequestParameter("height", -1, -1, 10000); $nearest_aspect_ratio = $this->getIntRequestParameter("nearest_aspect_ratio", 0, 0, 1); $imageFilePath = null; $crop_provider = $this->getRequestParameter("crop_provider", null); $quality = $this->getIntRequestParameter("quality", 0, 0, 100); $src_x = $this->getFloatRequestParameter("src_x", 0, 0, 10000); $src_y = $this->getFloatRequestParameter("src_y", 0, 0, 10000); $src_w = $this->getFloatRequestParameter("src_w", 0, 0, 10000); $src_h = $this->getFloatRequestParameter("src_h", 0, 0, 10000); $vid_sec = $this->getFloatRequestParameter("vid_sec", -1, -1); $vid_slice = $this->getRequestParameter("vid_slice", -1); $vid_slices = $this->getRequestParameter("vid_slices", -1); $density = $this->getFloatRequestParameter("density", 0, 0); $stripProfiles = $this->getRequestParameter("strip", null); $flavor_id = $this->getRequestParameter("flavor_id", null); $file_name = $this->getRequestParameter("file_name", null); $file_name = basename($file_name); // actual width and height of image from which the src_* values were taken. // these will be used to multiply the src_* parameters to make them relate to the original image size. $rel_width = $this->getFloatRequestParameter("rel_width", -1, -1, 10000); $rel_height = $this->getFloatRequestParameter("rel_height", -1, -1, 10000); $def_width = $this->getFloatRequestParameter("def_width", -1, -1, 10000); $def_height = $this->getFloatRequestParameter("def_height", -1, -1, 10000); if ($width == -1 && $height == -1) { if ($def_width == -1) { $width = 120; } else { $width = $def_width; } if ($def_height == -1) { $height = 90; } else { $height = $def_height; } } else { if ($width == -1) { $width = 0; } else { if ($height == -1) { $height = 0; } } } $bgcolor = $this->getRequestParameter("bgcolor", "ffffff"); $partner = null; $format = $this->getRequestParameter("format", null); // validating the inputs if (!is_numeric($quality) || $quality < 0 || $quality > 100) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'quality must be between 20 and 100'); } if (!is_numeric($src_x) || $src_x < 0 || $src_x > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_x must be between 0 and 10000'); } if (!is_numeric($src_y) || $src_y < 0 || $src_y > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_y must be between 0 and 10000'); } if (!is_numeric($src_w) || $src_w < 0 || $src_w > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_w must be between 0 and 10000'); } if (!is_numeric($src_h) || $src_h < 0 || $src_h > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'src_h must be between 0 and 10000'); } if (!is_numeric($width) || $width < 0 || $width > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'width must be between 0 and 10000'); } if (!is_numeric($height) || $height < 0 || $height > 10000) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'height must be between 0 and 10000'); } if (!is_numeric($density) || $density < 0) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'density must be positive'); } if (!is_numeric($vid_sec) || $vid_sec < -1) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'vid_sec must be positive'); } if (!preg_match('/^[0-9a-fA-F]{1,6}$/', $bgcolor)) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'bgcolor must be six hexadecimal characters'); } if ($vid_slices != -1 && $vid_slices <= 0 || !is_numeric($vid_slices)) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'vid_slices must be positive'); } if ($upload_token_id) { $upload_token = UploadTokenPeer::retrieveByPK($upload_token_id); if ($upload_token) { $partnerId = $upload_token->getPartnerId(); $partner = PartnerPeer::retrieveByPK($partnerId); if ($partner) { KalturaMonitorClient::initApiMonitor(false, 'extwidget.thumbnail', $partner->getId()); if ($quality == 0) { $quality = $partner->getDefThumbQuality(); } if ($density == 0) { $density = $partner->getDefThumbDensity(); } if (is_null($stripProfiles)) { $stripProfiles = $partner->getStripThumbProfile(); } } $thumb_full_path = myContentStorage::getFSCacheRootPath() . myContentStorage::getGeneralEntityPath("uploadtokenthumb", $upload_token->getIntId(), $upload_token->getId(), $upload_token->getId() . ".jpg"); kFile::fullMkdir($thumb_full_path); if (file_exists($upload_token->getUploadTempPath())) { $src_full_path = $upload_token->getUploadTempPath(); $valid_image_types = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_WBMP); $image_type = exif_imagetype($src_full_path); if (!in_array($image_type, $valid_image_types)) { // capture full frame myFileConverter::captureFrame($src_full_path, $thumb_full_path, 1, "image2", -1, -1, 3); if (!file_exists($thumb_full_path)) { myFileConverter::captureFrame($src_full_path, $thumb_full_path, 1, "image2", -1, -1, 0); } $src_full_path = $thumb_full_path; } // and resize it myFileConverter::convertImage($src_full_path, $thumb_full_path, $width, $height, $type, $bgcolor, true, $quality, $src_x, $src_y, $src_w, $src_h, $density, $stripProfiles, null, $format); kFileUtils::dumpFile($thumb_full_path); } else { KalturaLog::info("token_id [{$upload_token_id}] not found in DC [" . kDataCenterMgr::getCurrentDcId() . "]. dump url to romote DC"); $remoteUrl = kDataCenterMgr::getRemoteDcExternalUrlByDcId(1 - kDataCenterMgr::getCurrentDcId()) . $_SERVER['REQUEST_URI']; kFileUtils::dumpUrl($remoteUrl); } } } if ($entry_id) { $entry = entryPeer::retrieveByPKNoFilter($entry_id); if (!$entry) { // problem could be due to replication lag kFileUtils::dumpApiRequest(kDataCenterMgr::getRemoteDcExternalUrlByDcId(1 - kDataCenterMgr::getCurrentDcId())); } } else { // get the widget $widget = widgetPeer::retrieveByPK($widget_id); if (!$widget) { KExternalErrors::dieError(KExternalErrors::ENTRY_AND_WIDGET_NOT_FOUND); } // get the kshow $kshow_id = $widget->getKshowId(); $kshow = kshowPeer::retrieveByPK($kshow_id); if ($kshow) { $entry_id = $kshow->getShowEntryId(); } else { $entry_id = $widget->getEntryId(); } $entry = entryPeer::retrieveByPKNoFilter($entry_id); if (!$entry) { KExternalErrors::dieError(KExternalErrors::ENTRY_NOT_FOUND); } } KalturaMonitorClient::initApiMonitor(false, 'extwidget.thumbnail', $entry->getPartnerId()); if ($nearest_aspect_ratio) { // Get the entry's default thumbnail path (if any) $defaultThumbnailPath = myEntryUtils::getLocalImageFilePathByEntry($entry, $version); // Get the file path of the thumbnail with the nearest $selectedThumbnailDescriptor = kThumbnailUtils::getNearestAspectRatioThumbnailDescriptorByEntryId($entry_id, $width, $height, $defaultThumbnailPath); if ($selectedThumbnailDescriptor) { $imageFilePath = $selectedThumbnailDescriptor->getImageFilePath(); $thumbWidth = $selectedThumbnailDescriptor->getWidth(); $thumbHeight = $selectedThumbnailDescriptor->getHeight(); // The required width and height will serve as the final crop values $src_w = $width; $src_h = $height; // Base on the thumbnail's dimensions kThumbnailUtils::scaleDimensions($thumbWidth, $thumbHeight, $width, $height, kThumbnailUtils::SCALE_UNIFORM_SMALLER_DIM, $width, $height); // Set crop type $type = KImageMagickCropper::CROP_AFTER_RESIZE; } } $partner = $entry->getPartner(); // not allow capturing frames if the partner has FEATURE_DISALLOW_FRAME_CAPTURE permission if ($vid_sec != -1 || $vid_slice != -1 || $vid_slices != -1) { if ($partner->getEnabledService(PermissionName::FEATURE_BLOCK_THUMBNAIL_CAPTURE)) { KExternalErrors::dieError(KExternalErrors::NOT_ALLOWED_PARAMETER); } } if ($partner) { if ($quality == 0) { $quality = $partner->getDefThumbQuality(); } if ($density == 0) { $density = $partner->getDefThumbDensity(); } } $thumbParams = new kThumbnailParameters(); $thumbParams->setSupportAnimatedThumbnail($partner->getSupportAnimatedThumbnails()); if (is_null($stripProfiles)) { $stripProfiles = $partner->getStripThumbProfile(); } //checks whether the thumbnail display should be restricted by KS $base64Referrer = $this->getRequestParameter("referrer"); $referrer = base64_decode($base64Referrer); if (!is_string($referrer)) { $referrer = ""; } // base64_decode can return binary data if (!$referrer) { $referrer = kApiCache::getHttpReferrer(); } $ksStr = $this->getRequestParameter("ks"); $securyEntryHelper = new KSecureEntryHelper($entry, $ksStr, $referrer, ContextType::THUMBNAIL); $securyEntryHelper->validateForPlay(); // multiply the passed $src_* values so that they will relate to the original image size, according to $src_display_* if ($rel_width != -1 && $rel_width) { $widthRatio = $entry->getWidth() / $rel_width; $src_x = $src_x * $widthRatio; $src_w = $src_w * $widthRatio; } if ($rel_height != -1 && $rel_height) { $heightRatio = $entry->getHeight() / $rel_height; $src_y = $src_y * $heightRatio; $src_h = $src_h * $heightRatio; } $subType = entry::FILE_SYNC_ENTRY_SUB_TYPE_THUMB; if ($entry->getMediaType() == entry::ENTRY_MEDIA_TYPE_IMAGE) { $subType = entry::FILE_SYNC_ENTRY_SUB_TYPE_DATA; } $dataKey = $entry->getSyncKey($subType); list($file_sync, $local) = kFileSyncUtils::getReadyFileSyncForKey($dataKey, true, false); $tempThumbPath = null; $entry_status = $entry->getStatus(); // both 640x480 and 0x0 requests are probably coming from the kdp // 640x480 - old kdp version requesting thumbnail // 0x0 - new kdp version requesting the thumbnail of an unready entry // we need to distinguish between calls from the kdp and calls from a browser: <img src=...> // that can't handle swf input if (($width == 640 && $height == 480 || $width == 0 && $height == 0) && ($entry_status == entryStatus::PRECONVERT || $entry_status == entryStatus::IMPORT || $entry_status == entryStatus::ERROR_CONVERTING || $entry_status == entryStatus::DELETED)) { $contentPath = myContentStorage::getFSContentRootPath(); $msgPath = $contentPath . "content/templates/entry/bigthumbnail/"; if ($entry_status == entryStatus::DELETED) { $msgPath .= $entry->getModerationStatus() == moderation::MODERATION_STATUS_BLOCK ? "entry_blocked.swf" : "entry_deleted.swf"; } else { $msgPath .= $entry_status == entryStatus::ERROR_CONVERTING ? "entry_error.swf" : "entry_converting.swf"; } kFileUtils::dumpFile($msgPath, null, 0); } if (!$file_sync) { $tempThumbPath = $entry->getLocalThumbFilePath($version, $width, $height, $type, $bgcolor, $crop_provider, $quality, $src_x, $src_y, $src_w, $src_h, $vid_sec, $vid_slice, $vid_slices, $density, $stripProfiles, $flavor_id, $file_name); if (!$tempThumbPath) { KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } } if (!$local && !$tempThumbPath && $file_sync) { if (!in_array($file_sync->getDc(), kDataCenterMgr::getDcIds())) { $remoteUrl = $file_sync->getExternalUrl($entry->getId()); header("Location: {$remoteUrl}"); KExternalErrors::dieGracefully(); } $remoteUrl = kDataCenterMgr::getRedirectExternalUrl($file_sync, $_SERVER['REQUEST_URI']); kFileUtils::dumpUrl($remoteUrl); } // if we didnt return a template for the player die and dont return the original deleted thumb if ($entry_status == entryStatus::DELETED) { KExternalErrors::dieError(KExternalErrors::ENTRY_DELETED_MODERATED); } if (!$tempThumbPath) { try { $tempThumbPath = myEntryUtils::resizeEntryImage($entry, $version, $width, $height, $type, $bgcolor, $crop_provider, $quality, $src_x, $src_y, $src_w, $src_h, $vid_sec, $vid_slice, $vid_slices, $imageFilePath, $density, $stripProfiles, $thumbParams, $format); } catch (Exception $ex) { if ($ex->getCode() != kFileSyncException::FILE_DOES_NOT_EXIST_ON_CURRENT_DC) { KalturaLog::err("Resize image failed"); KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } // get original flavor asset $origFlavorAsset = assetPeer::retrieveOriginalByEntryId($entry_id); if (!$origFlavorAsset) { KalturaLog::err("No original flavor for entry [{$entry_id}]"); KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $syncKey = $origFlavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $remoteFileSync = kFileSyncUtils::getOriginFileSyncForKey($syncKey, false); if (!$remoteFileSync) { // file does not exist on any DC - die KalturaLog::log("Error - no FileSync for entry [{$entry_id}]"); KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } if ($remoteFileSync->getDc() == kDataCenterMgr::getCurrentDcId()) { KalturaLog::err("Trying to redirect to myself - stop here."); KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } if (!in_array($remoteFileSync->getDc(), kDataCenterMgr::getDcIds())) { KExternalErrors::dieError(KExternalErrors::MISSING_THUMBNAIL_FILESYNC); } $remoteUrl = kDataCenterMgr::getRedirectExternalUrl($remoteFileSync); kFileUtils::dumpUrl($remoteUrl); } } $nocache = false; if ($securyEntryHelper->shouldDisableCache() || kApiCache::hasExtraFields() || !$securyEntryHelper->isKsWidget() && $securyEntryHelper->hasRules(ContextType::THUMBNAIL)) { $nocache = true; } $cache = null; if (!is_null($entry->getPartner())) { $partnerCacheAge = $entry->getPartner()->getThumbnailCacheAge(); } if ($nocache) { $cacheAge = 0; } else { if ($partnerCacheAge) { $cacheAge = $partnerCacheAge; } else { if (strpos($tempThumbPath, "_NOCACHE_") !== false) { $cacheAge = 60; } else { $cacheAge = 3600; $cache = new myCache("thumb", 2592000); // 30 days, the max memcache allows } } } $lastModified = $entry->getAssetCacheTime(); $renderer = kFileUtils::getDumpFileRenderer($tempThumbPath, null, $cacheAge, 0, $lastModified); $renderer->partnerId = $entry->getPartnerId(); if ($cache) { $invalidationKey = $entry->getCacheInvalidationKeys(); $invalidationKey = kQueryCache::CACHE_PREFIX_INVALIDATION_KEY . $invalidationKey[0]; $cacheTime = time() - kQueryCache::CLOCK_SYNC_TIME_MARGIN_SEC; $cachedResponse = array($renderer, $invalidationKey, $cacheTime); $cache->put($_SERVER["REQUEST_URI"], $cachedResponse); } $renderer->output(); KExternalErrors::dieGracefully(); // TODO - can delete from disk assuming we caneasily recreate it and it will anyway be cached in the CDN // however dumpfile dies at the end so we cant just write it here (maybe register a shutdown callback) }
public function execute() { KExternalErrors::setResponseErrorCode(KExternalErrors::HTTP_STATUS_NOT_FOUND); $this->deliveryAttributes = new DeliveryProfileDynamicAttributes(); // Parse input parameters $this->deliveryAttributes->setSeekFromTime($this->getRequestParameter("seekFrom", -1)); if ($this->deliveryAttributes->getSeekFromTime() <= 0) { $this->deliveryAttributes->setSeekFromTime(-1); } $this->deliveryAttributes->setClipTo($this->getRequestParameter("clipTo", 0)); $this->deliveryAttributes->setPlaybackRate($this->getRequestParameter("playbackRate", 0)); $deliveryCode = $this->getRequestParameter("deliveryCode", null); $playbackContext = $this->getRequestParameter("playbackContext", null); $this->deliveryAttributes->setMediaProtocol($this->getRequestParameter("protocol", null)); if (!$this->deliveryAttributes->getMediaProtocol() || $this->deliveryAttributes->getMediaProtocol() === "null") { $this->deliveryAttributes->setMediaProtocol(PlaybackProtocol::HTTP); } $this->deliveryAttributes->setFormat($this->getRequestParameter("format")); if (!$this->deliveryAttributes->getFormat()) { $this->deliveryAttributes->setFormat(PlaybackProtocol::HTTP); } if ($this->deliveryAttributes->getFormat() == self::HDNETWORKSMIL) { $this->deliveryAttributes->setMediaProtocol(PlaybackProtocol::HTTP); } // Akamai HD doesn't support any other protocol if ($this->deliveryAttributes->getFormat() == PlaybackProtocol::AKAMAI_HDS) { if (strpos($this->deliveryAttributes->getMediaProtocol(), "http") !== 0) { $this->deliveryAttributes->setMediaProtocol(PlaybackProtocol::HTTP); } } $tags = $this->getRequestParameter("tags", null); if (!$tags) { $this->deliveryAttributes->setTags(self::getDefaultTagsByFormat($this->deliveryAttributes->getFormat())); } else { $tagsArray = explode(',', $tags); $tags = array(); foreach ($tagsArray as $tag) { $tags[] = array(trim($tag)); } $this->deliveryAttributes->setTags($tags); } $this->deliveryAttributes->setpreferredBitrate($this->getRequestParameter("preferredBitrate", null)); $this->maxBitrate = $this->getRequestParameter("maxBitrate", null); if ($this->maxBitrate && (!is_numeric($this->maxBitrate) || $this->maxBitrate <= 0)) { KExternalErrors::dieError(KExternalErrors::INVALID_MAX_BITRATE); } $this->deliveryAttributes->setStorageId($this->getRequestParameter("storageId", null)); $this->cdnHost = $this->getRequestParameter("cdnHost", null); $this->deliveryAttributes->setResponseFormat($this->getRequestParameter("responseFormat", null)); // Initialize $this->initEntry(); $this->deliveryAttributes->setEntryId($this->entryId); $this->deliveryAttributes->setUsePlayServer((bool) $this->getRequestParameter("usePlayServer") && PermissionPeer::isValidForPartner(PermissionName::FEATURE_PLAY_SERVER, $this->entry->getPartnerId())); if ($this->deliveryAttributes->getUsePlayServer()) { $this->deliveryAttributes->setPlayerConfig($this->getRequestParameter("playerConfig")); //In case request needs to be redirected to play-server we need to add the ui conf id to the manifest url as well $this->deliveryAttributes->setUiConfId($this->getRequestParameter("uiConfId")); } $this->secureEntryHelper->updateDeliveryAttributes($this->deliveryAttributes); $this->enforceEncryption(); $renderer = null; switch ($this->entry->getType()) { case entryType::MEDIA_CLIP: // VOD $renderer = $this->serveVodEntry(); break; case entryType::LIVE_STREAM: case entryType::LIVE_CHANNEL: // Live stream $renderer = $this->serveLiveEntry(); break; default: KExternalErrors::dieError(KExternalErrors::INVALID_ENTRY_TYPE); } if (!$renderer) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'This format is unsupported'); } $renderer->contributors = array(); $config = new kManifestContributorConfig(); $config->format = $this->deliveryAttributes->getFormat(); $config->deliveryCode = $deliveryCode; $config->storageId = $this->deliveryAttributes->getStorageId(); $config->entryId = $this->entryId; $contributors = KalturaPluginManager::getPluginInstances('IKalturaPlayManifestContributor'); foreach ($contributors as $contributor) { /* @var $contributor IKalturaPlayManifestContributor */ $renderer->contributors = array_merge($renderer->contributors, $contributor->getManifestEditors($config)); } $renderer->entryId = $this->entryId; $renderer->duration = $this->duration; if ($this->deliveryProfile) { $renderer->tokenizer = $this->deliveryProfile->getTokenizer(); } $renderer->defaultDeliveryCode = $this->entry->getPartner()->getDefaultDeliveryCode(); $renderer->lastModified = time(); // Handle caching $canCacheAccessControl = false; if (kConf::hasParam("force_caching_headers") && in_array($this->entry->getPartnerId(), kConf::get("force_caching_headers"))) { $renderer->cachingHeadersAge = 60; $renderer->forceCachingHeaders = true; } if (!$this->secureEntryHelper) { $canCacheAccessControl = true; // TODO: reconsider this if/when expired ktokens will be used } else { if (!$this->secureEntryHelper->shouldDisableCache() && !$this->secureEntryHelper->isKsAdmin() && ($this->secureEntryHelper->isKsWidget() || !$this->secureEntryHelper->hasRules())) { $canCacheAccessControl = true; } } if (!$renderer->tokenizer && $canCacheAccessControl) { // Note: kApiCache::hasExtraFields is checked in kManifestRenderers $renderer->cachingHeadersAge = 60; } if (!$this->secureEntryHelper || !$this->secureEntryHelper->shouldDisableCache()) { $cache = kPlayManifestCacher::getInstance(); $cache->storeRendererToCache($renderer); } // Output the response KExternalErrors::terminateDispatch(); $renderer->output($deliveryCode, $playbackContext); }
public function execute() { $this->seekFrom = $this->getRequestParameter("seekFrom", -1); if ($this->seekFrom <= 0) { $this->seekFrom = -1; } $this->clipTo = $this->getRequestParameter("clipTo", 0); $this->deliveryCode = $this->getRequestParameter("deliveryCode", null); $playbackContext = $this->getRequestParameter("playbackContext", null); $this->protocol = $this->getRequestParameter("protocol", null); if (!$this->protocol || $this->protocol === "null") { $this->protocol = StorageProfile::PLAY_FORMAT_HTTP; } $this->format = $this->getRequestParameter("format"); if (!$this->format) { $this->format = StorageProfile::PLAY_FORMAT_HTTP; } $this->tags = $this->getRequestParameter("tags", null); if (!$this->tags) { switch ($this->format) { case StorageProfile::PLAY_FORMAT_SILVER_LIGHT: $this->tags = array(array(assetParams::TAG_SLWEB)); break; case StorageProfile::PLAY_FORMAT_APPLE_HTTP: case StorageProfile::PLAY_FORMAT_HDS: $this->tags = array(array(assetParams::TAG_APPLEMBR), array('ipadnew', 'iphonenew'), array('ipad', 'iphone')); break; default: $this->tags = array(array(assetParams::TAG_MBR), array(assetParams::TAG_WEB)); } } else { $this->tags = array(array($this->tags)); } $this->cdnHost = $this->getRequestParameter("cdnHost", null); $this->preferredBitrate = $this->getRequestParameter("preferredBitrate", null); $this->maxBitrate = $this->getRequestParameter("maxBitrate", null); if ($this->maxBitrate && (!is_numeric($this->maxBitrate) || $this->maxBitrate <= 0)) { KExternalErrors::dieError(KExternalErrors::INVALID_MAX_BITRATE); } $this->initEntry(); $this->initFlavorIds(); $this->storageId = $this->getRequestParameter("storageId", null); $this->validateStorageId(); $partner = $this->entry->getPartner(); if (!$this->cdnHost || $partner->getForceCdnHost()) { $this->cdnHost = myPartnerUtils::getCdnHost($this->entry->getPartnerId(), $this->protocol); } $playbackParams = array(); if (kConf::hasMap("optimized_playback")) { $partnerId = $this->entry->getPartnerId(); $optimizedPlayback = kConf::getMap("optimized_playback"); if (array_key_exists($partnerId, $optimizedPlayback)) { $playbackParams = $optimizedPlayback[$partnerId]; } } if (array_key_exists('enforce_encryption', $playbackParams) && $playbackParams['enforce_encryption']) { if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') { KExternalErrors::dieError(KExternalErrors::ACCESS_CONTROL_RESTRICTED, 'unencrypted manifest request - forbidden'); } if (strtolower($this->protocol) != 'https') { KExternalErrors::dieError(KExternalErrors::ACCESS_CONTROL_RESTRICTED, 'unencrypted playback protocol - forbidden'); } } $renderer = null; switch ($this->format) { case StorageProfile::PLAY_FORMAT_HTTP: $renderer = $this->serveHttp(); break; case StorageProfile::PLAY_FORMAT_RTMP: $renderer = $this->serveRtmp(); break; case StorageProfile::PLAY_FORMAT_SILVER_LIGHT: $renderer = $this->serveSilverLight(); break; case StorageProfile::PLAY_FORMAT_APPLE_HTTP: $renderer = $this->serveAppleHttp(); break; case StorageProfile::PLAY_FORMAT_HDS: $renderer = $this->serveHds(); break; case "url": $this->format = "http"; // build url for an http delivery $renderer = $this->serveUrl(); break; case "rtsp": $renderer = $this->serveRtsp(); break; case "hdnetworksmil": $renderer = $this->serveHDNetworkSmil(); break; case "hdnetwork": $renderer = $this->serveHDNetwork(); break; case "hdnetworkmanifest": $renderer = $this->serveHDNetworkManifest(); break; } if (!$renderer) { KExternalErrors::dieError(KExternalErrors::BAD_QUERY, 'This format is unsupported'); } $canCacheAccessControl = false; if (!$this->secureEntryHelper) { $canCacheAccessControl = true; // TODO: reconsider this if/when expired ktokens will be used } else { if (!$this->secureEntryHelper->shouldDisableCache() && !$this->secureEntryHelper->isKsAdmin() && ($this->secureEntryHelper->isKsWidget() || !$this->secureEntryHelper->hasRules())) { $canCacheAccessControl = true; } } if (!$renderer->tokenizer && $canCacheAccessControl) { // Note: kApiCache::hasExtraFields is checked in kManifestRenderers $renderer->cachingHeadersAge = 60; } if (!$this->secureEntryHelper || !$this->secureEntryHelper->shouldDisableCache()) { $cache = kPlayManifestCacher::getInstance(); $cache->storeCache($renderer); } $renderer->output($playbackContext); }