/** * Get base entry by ID with no filters. * * @action get * @param string $entryId Entry id * @param int $version Desired version of the data * @return KalturaBaseEntry The requested entry */ function getAction($entryId, $version = -1) { $dbEntries = entryPeer::retrieveByPKsNoFilter(array($entryId)); if (!count($dbEntries)) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } $dbEntry = reset($dbEntries); if (!$dbEntry) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } if ($version !== -1) { $dbEntry->setDesiredVersion($version); } $entry = KalturaEntryFactory::getInstanceByType($dbEntry->getType(), true); $entry->fromObject($dbEntry); return $entry; }
/** * 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; } */ }