public static function createWidgetImage($partner, $create) { $contentPath = myContentStorage::getFSContentRootPath(); $path = kFile::fixPath($contentPath . $partner->getWidgetImagePath()); // if the create flag is not set and the file doesnt exist exit // e.g. the roughcut name has change, we update the image only if it was already in some widget if (!$create && !file_exists($path)) { return; } $im = imagecreatetruecolor(400, 20); $green = imagecolorallocate($im, 188, 230, 99); $white = imagecolorallocate($im, 255, 255, 255); $font = SF_ROOT_DIR . '/web/ttf/arial.ttf'; $fontSize = 9; $bottom = 15; $pos = imagettftext($im, $fontSize, 0, 10, $bottom, $green, $font, $partner->getPartnerName() . " Collaborative Video"); $pos = imagettftext($im, $fontSize, 0, $pos[2], $bottom, $white, $font, " powered by "); imagettftext($im, $fontSize, 0, $pos[2], $bottom, $green, $font, "Kaltura"); kFile::fullMkdir($path); imagegif($im, $path); imagedestroy($im); }
private static function addKuserPictureFromEntry($contentPath, $im, &$entries, $x, $y, $border = 1, $width = self::DIM_X, $height = self::DIM_Y) { $entry = current($entries); if ($entry == NULL) { // for now - if there are not enough images - stop ! return; // if we reach here - we want to rotate the images we already used reset($entries); $entry = current($entries); } $kuser = $entry->getKuser(); $kuser_image_path = kFile::fixPath($contentPath . $kuser->getPicturePath()); if (file_exists($kuser_image_path)) { list($sourcewidth, $sourceheight, $type, $attr, $kuserIm) = myFileConverter::createImageByFile($kuser_image_path); if ($kuserIm) { $kuserIm_x = imagesx($kuserIm); $kuserIm_y = imagesy($kuserIm); // focus on the ceter of the image - ignore 10% from each side to make the center bigger imagecopyresampled($im, $kuserIm, $width * $x, $height * $y, $kuserIm_x * 0.1, $kuserIm_y * 0.1, $width - $border, $height - $border, $kuserIm_x * 0.9, $kuserIm_y * 0.9); imagedestroy($kuserIm); } } next($entries); }
public static function getVideoDimensions($source_file) { $source_file = kFile::fixPath($source_file); if (realpath($source_file) === FALSE) { throw new Exception("Illegal input was supplied"); } ob_start(); $cmd_line = kConf::get("bin_path_ffmpeg") . " -i \"" . $source_file . "\" 2>&1"; passthru($cmd_line); echo $cmd_line; $size = ob_get_contents(); ob_end_clean(); $width = ""; $height = ""; //extract the video size line (used to suggest 25x25 sise for entry 25x25xqajo) // used to search for , after the {width}x{height} however both of the following lines are valid: // Stream #0.0: Video: h264, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 202 kb/s, 29.92 tbr, 1k tbn, 2k tbc // Stream #0.1(und): Video: h264, yuv420p, 480x270, 59.92 tbr, 29.94 tbn, 59.89 tbc if (preg_match('/Video:.*? (\\d{2,4})x(\\d{2,4})/', $size, $matches)) { $width = $matches[1]; $height = $matches[2]; } $res = array($width, $height); return $res; }
/** * here we'll manipulate the video asset and set the from_byte & to_byte from the milliseconds * */ private static function fixMetadataImpl(&$xml_doc, &$total_duration, $timeline) { self::log(__METHOD__); /* $xml_doc = new DOMDocument(); $xml_doc->loadXML( $content ); */ // $meatadata_elem_list = $xml_doc->getElementsByTagName( "MetaData" ); // if ( $meatadata_elem_list != null && $meatadata_elem_list->length > 0 ) $duration_list = $xml_doc->getElementsByTagName("SeqDuration"); if ($duration_list != null && $duration_list->length > 0) { $total_duration = $duration_list->item(0)->nodeValue; } $xpath = new DOMXPath($xml_doc); $assets = $xpath->query($timeline == "video" ? "//VideoAssets/vidAsset" : ($timeline == "audio" ? "//AudioAssets/AudAsset" : "//VoiceAssets/voiAsset")); $lastTimestamp = 0; $real_start_byte = 0; // the start byte of the current clip in the final merged stream $calculated_total_bytes = 0; // use the entryPool and a 2-pass iteration to reduce the hits to the DB $id_list = array(); $entry_pool = new entryPool(); // first pass - populate the entryPool in a single request to the DB self::log(__METHOD__, "Before assets"); foreach ($assets as $asset) { $type = $asset->getAttribute("type"); if ($type != "VIDEO" && $type != "AUDIO") { continue; } // fetch the file name from the DB $asset_id = $asset->getAttribute("k_id"); $id_list[] = $asset_id; } self::log(__METHOD__, "After assets", count($id_list), $id_list); if ($id_list) { $entry_pool->addEntries(entryPeer::retrieveByPKsNoFilter($id_list)); } // second pass - the entryPool is supposed to already be populated $was_modified = false; foreach ($assets as $asset) { // fix only VIDEO assets $type = $asset->getAttribute("type"); if ($type != "VIDEO" && $type != "AUDIO") { continue; } // fetch the file name from the DB $asset_id = $asset->getAttribute("k_id"); self::log(__METHOD__, "in loop", $asset_id); //$entry = entryPeer::retrieveByPKNoFilter( $asset_id ); $entry = $entry_pool->retrieveByPK($asset_id); // is supposed to exist already in the pool if ($entry == NULL) { // set an error on the asset element $asset->setAttribute("fix_status", "error in k_id [{$asset_id}]"); $was_modified = true; continue; } elseif ($entry->getStatus() == entryStatus::DELETED) { // set an error on the asset element $asset->setAttribute("fix_status", "error in k_id [{$asset_id}] - asset was deleted"); $was_modified = true; continue; } $file_name = null; //TODO: need to work on only an FLV asset $flavor_asset_play = assetPeer::retrieveBestPlayByEntryId($entry->getId()); if (!$flavor_asset_play) { KalturaLog::log(__METHOD__ . ' ' . __LINE__ . ' no play flavor asset for entry ' . $entry->getId()); } else { $file_name = kFileSyncUtils::getReadyLocalFilePathForKey($flavor_asset_play->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET)); } $use_multi_flavor = false; $flv_file_name_edit = false; $flavor_asset_edit = assetPeer::retrieveBestEditByEntryId($entry->getId()); if (!$flavor_asset_edit) { KalturaLog::log(__METHOD__ . ' ' . __LINE__ . ' no edit flavor asset for entry ' . $entry->getId()); } else { $flv_file_name_edit = kFileSyncUtils::getReadyLocalFilePathForKey($flavor_asset_edit->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET)); $use_multi_flavor = $flv_file_name_edit && file_exists($flv_file_name_edit) && $timeline == "video"; } if (!$flv_file_name_edit && !$file_name) { KalturaLog::log(__METHOD__ . ' ' . __LINE__ . ' no edit & play flavor assets for entry ' . $entry->getId()); continue; } $flv_file_name = kFile::fixPath($file_name); $stream_info_list = $asset->getElementsByTagName("StreamInfo"); foreach ($stream_info_list as $stream_info) { $file_name = "?"; try { $stream_info->setAttribute("file_name", kFileSyncUtils::getReadyLocalFilePathForKey($flavor_asset_play->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET))); // replaced__getDataPath $start_byte = $stream_info->getAttribute("start_byte"); $end_byte = $stream_info->getAttribute("end_byte"); $total_bytes = $stream_info->getAttribute("total_bytes"); if ($start_byte == NULL) { $start_byte = self::MISSING_VALUE; } if ($end_byte == NULL) { $end_byte = self::MISSING_VALUE; } if ($total_bytes == NULL) { $total_bytes = self::MISSING_VALUE; } $len_time = floor(1000 * $stream_info->getAttribute("len_time")); if (1 || $start_byte == self::MISSING_VALUE || $end_byte == self::MISSING_VALUE || $total_bytes == self::MISSING_VALUE) { // set the values from start_time & len_time - the original numbers are in seconds (with a decimal point) $start_time = floor(1000 * $stream_info->getAttribute("start_time")); $end_time = $start_time + $len_time; $real_start_byte += $calculated_total_bytes; $calculated_start_byte = 0; $calculated_end_byte = 0; $calculated_total_bytes = 0; $calculated_real_seek_time = 0; $calculated_start_byte_play = 0; $calculated_end_byte_play = 0; $calculated_total_bytes_play = 0; /* $file_name = $stream_info->getAttribute ( "file_name" ); $flv_file_name = kFile::fixPath( myContentStorage::getFSContentRootPath() . $file_name ); $ext = pathinfo ($flv_file_name, PATHINFO_EXTENSION); if ( $ext == NULL ) $flv_file_name .= ".flv"; */ try { self::log(__METHOD__, "before findBytesFromTimestamps", $flv_file_name); //$use_multi_flavor = myFlvStaticHandler::isMultiFlavor ( $flv_file_name ) && $timeline == "video"; $calculated_real_seek_time = $lastTimestamp; $start_time_play = null; if ($use_multi_flavor) { $start_time_play = $start_time; // play // $start_time_play - will be modified according to the first keyframe's time stamp AFTER (not before) the requested timestamp $result = myFlvStaticHandler::findBytesFromTimestamps($flv_file_name, $start_time_play, $end_time, $calculated_start_byte_play, $calculated_end_byte_play, $calculated_total_bytes_play, $lastTimestamp, $timeline != "video", 1); KalturaLog::log(__METHOD__ . ' ' . __LINE__ . " play {$result} = findBytesFromTimestamps({$flv_file_name} , {$start_time_play} , {$end_time} , {$calculated_start_byte_play} , {$calculated_end_byte_play} , {$calculated_total_bytes_play}, {$lastTimestamp}, {$timeline})"); if ($result) { if ($start_time_play != $start_time) { // we need to fill the gap between the user requested keyframe and the one actually found in the play (low res) flavor // edit - more keyfrmaes ! $result = myFlvStaticHandler::findBytesFromTimestamps($flv_file_name_edit, $start_time, $start_time_play, $calculated_start_byte, $calculated_end_byte, $calculated_total_bytes, $lastTimestamp, $timeline != "video", 2); KalturaLog::log(__METHOD__ . ' ' . __LINE__ . " edit {$result} = findBytesFromTimestamps({$flv_file_name} , {$start_time_play} , {$end_time} , {$calculated_start_byte_play} , {$calculated_end_byte_play} , {$calculated_total_bytes_play}, {$lastTimestamp}, {$timeline})"); } } } else { // no reason to have multi-flavor files // either because NOT video or because the edit flavor does not exist $result = myFlvStaticHandler::findBytesFromTimestamps($flv_file_name, $start_time, $end_time, $calculated_start_byte, $calculated_end_byte, $calculated_total_bytes, $lastTimestamp, $timeline != "video", 0); KalturaLog::log(__METHOD__ . ' ' . __LINE__ . " only play {$result} = findBytesFromTimestamps({$flv_file_name} , {$start_time_play} , {$end_time} , {$calculated_start_byte_play} , {$calculated_end_byte_play} , {$calculated_total_bytes_play}, {$lastTimestamp}, {$timeline})"); } self::log(__METHOD__, "after findBytesFromTimestamps", $flv_file_name); } catch (Exception $ex1) { debugUtils::log("Error while converting time2bytes in file [{$file_name}]\n{$ex1}"); echo "Error while converting time2bytes in file [{$file_name}]\n{$ex1}"; } $calculated_total_bytes += $calculated_total_bytes_play; if ($result) { if (1 || $start_byte == self::MISSING_VALUE) { $stream_info->setAttribute("start_byte", $calculated_start_byte); $stream_info->setAttribute("start_byte_play", $calculated_start_byte_play); } if (1 || $end_byte == self::MISSING_VALUE) { $stream_info->setAttribute("end_byte", $calculated_end_byte); $stream_info->setAttribute("end_byte_play", $calculated_end_byte_play); } if (1 || $calculated_total_bytes == self::MISSING_VALUE) { $stream_info->setAttribute("total_bytes", $calculated_total_bytes); $stream_info->setAttribute("real_start_byte", $real_start_byte); $stream_info->setAttribute("real_end_byte", $real_start_byte + $calculated_total_bytes); } if (1 || $calculated_real_seek_time == self::MISSING_VALUE) { // retrun the calculated_real_seek_time in seconds with 2 decimal points $stream_info->setAttribute("real_seek_time", number_format($calculated_real_seek_time / 1000, 3, '.', '')); } if ($asset->hasAttribute("fix_status")) { $asset->removeAttribute("fix_status"); } } elseif (!$result) { // set an error on the asset element $asset->setAttribute("fix_status", "Missing file or invalid FLV structure"); } $was_modified = true; } } catch (Exception $ex2) { echo "Error parsing file [{$file_name}]\n{$ex2}"; } } } return $xml_doc; /* if ( $was_modified ) { return $xml_doc->saveXML(); } else { // nothing was modified - use the original string return $content; } */ }
public static function createWidgetImage($entry, $create) { $contentPath = myContentStorage::getFSContentRootPath(); $path = kFile::fixPath($contentPath . $entry->getWidgetImagePath()); // if the create flag is not set and the file doesnt exist exit // e.g. the roughcut name has change, we update the image only if it was already in some widget if (!$create && !file_exists($path)) { return; } $im = imagecreatetruecolor(400, 30); $color = imagecolorallocate($im, 188, 230, 99); $font = SF_ROOT_DIR . '/web/ttf/arial.ttf'; imagettftext($im, 12, 0, 10, 21, $color, $font, $entry->getName()); myContentStorage::fullMkdir($path); imagegif($im, $path); imagedestroy($im); }
public function __construct($original_flv_file_name) { $original_flv_file_name = kFile::fixPath($original_flv_file_name); $this->file_name = $original_flv_file_name . $this->FILE_SUFFIX; $this->creating = false; // check if the info file exists and is newer than the original if (file_exists($this->file_name)) { $orig_mtime = filemtime($original_flv_file_name); $info_mtime = filemtime($this->file_name); if ($info_mtime < $orig_mtime) { $this->creating = true; } else { // load from disk - replace the dynamic variables } } else { $this->creating = true; // TODO - remove !! $this->sizeList = array(); $this->keyframeTimes = array(); $this->keyframeBytes = array(); } }
public static function getMySpaceLogPath() { $tmp_dir = getenv("TEMP"); if (empty($tmp_dir)) { $tmp_dir = "/tmp"; } $path = kFile::fixPath($tmp_dir . DIRECTORY_SEPARATOR . "kaltura/myspace/logs/"); return $path; }