feat: Add comprehensive documentation suite and reorganize project structure
- Created complete documentation in docs/ directory - Added PROJECT_OVERVIEW.md with feature highlights and getting started guide - Added ARCHITECTURE.md with system design and technical details - Added SECURITY.md with comprehensive security implementation guide - Added DEVELOPMENT.md with development workflows and best practices - Added DEPLOYMENT.md with production deployment instructions - Added API.md with complete REST API documentation - Added CONTRIBUTING.md with contribution guidelines - Added CHANGELOG.md with version history and migration notes - Reorganized all documentation files into docs/ directory for better organization - Updated README.md with proper documentation links and quick navigation - Enhanced project structure with professional documentation standards
This commit is contained in:
304
f_core/f_functions/functions.videoprocessing.php
Normal file
304
f_core/f_functions/functions.videoprocessing.php
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
/*******************************************************************************************************************
|
||||
| Video Processing Helper Functions
|
||||
| Convenience functions for video processing integration
|
||||
|*******************************************************************************************************************/
|
||||
|
||||
defined('_ISVALID') or header('Location: /error');
|
||||
|
||||
/**
|
||||
* Queue video for processing
|
||||
* @param string $videoKey Video key
|
||||
* @param string $inputFile Input file path
|
||||
* @param array $options Processing options
|
||||
* @return string|false Job ID or false on failure
|
||||
*/
|
||||
function queue_video_processing($videoKey, $inputFile, $options = [])
|
||||
{
|
||||
try {
|
||||
$processor = new VVideoProcessor();
|
||||
return $processor->queueVideoProcessing($inputFile, $videoKey, $options);
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Failed to queue video processing', [
|
||||
'video_key' => $videoKey,
|
||||
'input_file' => $inputFile,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process video immediately (synchronous)
|
||||
* @param string $videoKey Video key
|
||||
* @param string $inputFile Input file path
|
||||
* @param array $options Processing options
|
||||
* @return array Processing result
|
||||
*/
|
||||
function process_video_sync($videoKey, $inputFile, $options = [])
|
||||
{
|
||||
try {
|
||||
$processor = new VVideoProcessor();
|
||||
return $processor->processVideo($inputFile, $videoKey, $options);
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Synchronous video processing failed', [
|
||||
'video_key' => $videoKey,
|
||||
'input_file' => $inputFile,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $e->getMessage(),
|
||||
'video_key' => $videoKey
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get video processing status
|
||||
* @param string $videoKey Video key
|
||||
* @return array|false Processing status or false if not found
|
||||
*/
|
||||
function get_video_processing_status($videoKey)
|
||||
{
|
||||
try {
|
||||
$db = VDatabase::getInstance();
|
||||
|
||||
$query = "SELECT processing_status, processed_at, processing_error,
|
||||
available_formats, hls_available, thumbnails_generated
|
||||
FROM db_videofiles WHERE file_key = ?";
|
||||
$result = $db->doQuery($query, [$videoKey]);
|
||||
$row = $db->doFetch($result);
|
||||
|
||||
if ($row) {
|
||||
return [
|
||||
'status' => $row['processing_status'],
|
||||
'processed_at' => $row['processed_at'],
|
||||
'error' => $row['processing_error'],
|
||||
'available_formats' => json_decode($row['available_formats'], true) ?: [],
|
||||
'hls_available' => (bool)$row['hls_available'],
|
||||
'thumbnails_generated' => (bool)$row['thumbnails_generated']
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Failed to get video processing status', [
|
||||
'video_key' => $videoKey,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue thumbnail generation
|
||||
* @param string $fileKey File key
|
||||
* @param string $filePath File path
|
||||
* @param string $fileType File type (video, image)
|
||||
* @param array $sizes Thumbnail sizes
|
||||
* @return string|false Job ID or false on failure
|
||||
*/
|
||||
function queue_thumbnail_generation($fileKey, $filePath, $fileType, $sizes = [])
|
||||
{
|
||||
try {
|
||||
$queue = new VQueue();
|
||||
|
||||
$jobData = [
|
||||
'file_key' => $fileKey,
|
||||
'file_path' => $filePath,
|
||||
'file_type' => $fileType,
|
||||
'sizes' => $sizes ?: [
|
||||
'small' => [160, 120],
|
||||
'medium' => [320, 240],
|
||||
'large' => [640, 480]
|
||||
]
|
||||
];
|
||||
|
||||
return $queue->enqueue('ThumbnailGenerationJob', $jobData, 'thumbnails');
|
||||
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Failed to queue thumbnail generation', [
|
||||
'file_key' => $fileKey,
|
||||
'file_path' => $filePath,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue notification
|
||||
* @param string $type Notification type (email, push, in_app, sms, webhook)
|
||||
* @param string $recipient Recipient (email, user ID, phone, URL)
|
||||
* @param string $subject Subject/title
|
||||
* @param string $message Message content
|
||||
* @param array $templateData Additional template data
|
||||
* @param string $priority Priority (low, normal, high, urgent)
|
||||
* @return string|false Job ID or false on failure
|
||||
*/
|
||||
function queue_notification($type, $recipient, $subject, $message, $templateData = [], $priority = 'normal')
|
||||
{
|
||||
try {
|
||||
$queue = new VQueue();
|
||||
|
||||
$jobData = [
|
||||
'type' => $type,
|
||||
'recipient' => $recipient,
|
||||
'subject' => $subject,
|
||||
'message' => $message,
|
||||
'template_data' => $templateData,
|
||||
'priority' => $priority
|
||||
];
|
||||
|
||||
$queuePriority = $priority === 'urgent' ? 2 : ($priority === 'high' ? 1 : 0);
|
||||
|
||||
return $queue->enqueue('NotificationJob', $jobData, 'notifications', 0, $queuePriority);
|
||||
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Failed to queue notification', [
|
||||
'type' => $type,
|
||||
'recipient' => $recipient,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get queue statistics
|
||||
* @param string $queue Queue name (optional)
|
||||
* @return array Queue statistics
|
||||
*/
|
||||
function get_queue_stats($queue = null)
|
||||
{
|
||||
try {
|
||||
$queueInstance = new VQueue();
|
||||
return $queueInstance->getQueueStats($queue);
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Failed to get queue statistics', [
|
||||
'queue' => $queue,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if video processing is available
|
||||
* @return bool True if FFmpeg is available
|
||||
*/
|
||||
function is_video_processing_available()
|
||||
{
|
||||
static $available = null;
|
||||
|
||||
if ($available === null) {
|
||||
// Check if FFmpeg is available
|
||||
$output = shell_exec('ffmpeg -version 2>&1');
|
||||
$available = $output && strpos($output, 'ffmpeg version') !== false;
|
||||
}
|
||||
|
||||
return $available;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get supported video formats
|
||||
* @return array Supported formats
|
||||
*/
|
||||
function get_supported_video_formats()
|
||||
{
|
||||
return [
|
||||
'mp4' => 'MP4 Video',
|
||||
'avi' => 'AVI Video',
|
||||
'mov' => 'QuickTime Video',
|
||||
'wmv' => 'Windows Media Video',
|
||||
'flv' => 'Flash Video',
|
||||
'webm' => 'WebM Video',
|
||||
'mkv' => 'Matroska Video',
|
||||
'3gp' => '3GP Video'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get video processing formats
|
||||
* @return array Available processing formats
|
||||
*/
|
||||
function get_video_processing_formats()
|
||||
{
|
||||
return [
|
||||
'1080p' => ['width' => 1920, 'height' => 1080, 'bitrate' => '5000k'],
|
||||
'720p' => ['width' => 1280, 'height' => 720, 'bitrate' => '2500k'],
|
||||
'480p' => ['width' => 854, 'height' => 480, 'bitrate' => '1000k'],
|
||||
'360p' => ['width' => 640, 'height' => 360, 'bitrate' => '750k'],
|
||||
'240p' => ['width' => 426, 'height' => 240, 'bitrate' => '400k']
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate video processing time
|
||||
* @param string $inputFile Input file path
|
||||
* @param array $formats Formats to process
|
||||
* @return int Estimated processing time in seconds
|
||||
*/
|
||||
function estimate_video_processing_time($inputFile, $formats = ['720p', '480p', '360p'])
|
||||
{
|
||||
if (!file_exists($inputFile)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$fileSize = filesize($inputFile);
|
||||
$fileSizeMB = $fileSize / (1024 * 1024);
|
||||
|
||||
// Rough estimation: 1MB takes about 2-5 seconds per format
|
||||
$baseTimePerMB = 3; // seconds
|
||||
$timePerFormat = $fileSizeMB * $baseTimePerMB;
|
||||
|
||||
return (int)($timePerFormat * count($formats));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up old processed files
|
||||
* @param int $daysOld Days old threshold
|
||||
* @return int Number of files cleaned
|
||||
*/
|
||||
function cleanup_old_processed_files($daysOld = 30)
|
||||
{
|
||||
try {
|
||||
$processedDir = _FPATH . 'f_data/processed/';
|
||||
$cutoffTime = time() - ($daysOld * 24 * 60 * 60);
|
||||
$cleanedCount = 0;
|
||||
|
||||
if (!is_dir($processedDir)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($processedDir),
|
||||
RecursiveIteratorIterator::CHILD_FIRST
|
||||
);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isFile() && $file->getMTime() < $cutoffTime) {
|
||||
if (unlink($file->getPathname())) {
|
||||
$cleanedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VLogger::getInstance()->info('Cleaned up old processed files', [
|
||||
'days_old' => $daysOld,
|
||||
'files_cleaned' => $cleanedCount
|
||||
]);
|
||||
|
||||
return $cleanedCount;
|
||||
|
||||
} catch (Exception $e) {
|
||||
VLogger::getInstance()->error('Failed to cleanup old processed files', [
|
||||
'days_old' => $daysOld,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user