- 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
408 lines
15 KiB
PHP
408 lines
15 KiB
PHP
<?php
|
|
/*******************************************************************************************************************
|
|
| Software Name : EasyStream
|
|
| Software Description : High End YouTube Clone Script with Videos, Shorts, Streams, Images, Audio, Documents, Blogs
|
|
| Software Author : (c) Sami Ahmed
|
|
|*******************************************************************************************************************
|
|
|
|
|
|*******************************************************************************************************************
|
|
| This source file is subject to the EasyStream Proprietary License Agreement.
|
|
|
|
|
| By using this software, you acknowledge having read this Agreement and agree to be bound thereby.
|
|
|*******************************************************************************************************************
|
|
| Copyright (c) 2025 Sami Ahmed. All rights reserved.
|
|
|*******************************************************************************************************************/
|
|
|
|
/**
|
|
* Subtitle Management Page
|
|
*
|
|
* Allows users to:
|
|
* - Upload subtitle files (.srt, .vtt) for their videos
|
|
* - Manage multiple language tracks
|
|
* - Set default subtitle language
|
|
* - Delete subtitle tracks
|
|
* - Preview subtitles
|
|
*
|
|
* URL: /f_modules/m_frontend/m_file/manage_subtitles.php?v={file_key}&type={file_type}
|
|
*/
|
|
|
|
define('_ISVALID', true);
|
|
|
|
$main_dir = realpath(dirname(__FILE__) . '/../../../');
|
|
set_include_path($main_dir);
|
|
|
|
include_once 'f_core/config.core.php';
|
|
|
|
// Check if user is logged in
|
|
if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID'] == 0) {
|
|
header('Location: ' . $cfg['main_url'] . '/login.php');
|
|
exit;
|
|
}
|
|
|
|
$error_message = null;
|
|
$notice_message = null;
|
|
|
|
// Get file info from URL
|
|
$file_key = isset($_GET['v']) ? VSecurity::getParam('v', 'string') : '';
|
|
$file_type = isset($_GET['type']) ? VSecurity::getParam('type', 'string') : 'video';
|
|
|
|
// Validate file type
|
|
$allowed_types = ['video', 'short', 'live', 'audio'];
|
|
if (!in_array($file_type, $allowed_types)) {
|
|
$file_type = 'video';
|
|
}
|
|
|
|
// Get file ID from key
|
|
$table_map = [
|
|
'video' => 'db_videofiles',
|
|
'short' => 'db_shortfiles',
|
|
'live' => 'db_livefiles',
|
|
'audio' => 'db_audiofiles'
|
|
];
|
|
|
|
$sql = "SELECT `db_id`, `usr_id`, `file_title` FROM `{$table_map[$file_type]}`
|
|
WHERE `file_key` = '%s' AND `usr_id` = %d LIMIT 1";
|
|
$result = $class_database->doQuery($sql, $file_key, (int) $_SESSION['USER_ID']);
|
|
$file_info = $result->fetch_assoc();
|
|
|
|
if (!$file_info) {
|
|
$error_message = 'File not found or you do not have permission to manage its subtitles.';
|
|
} else {
|
|
$file_id = $file_info['db_id'];
|
|
|
|
// Handle subtitle upload
|
|
if (isset($_POST['upload_subtitle']) && isset($_FILES['subtitle_file'])) {
|
|
$language = VSecurity::postParam('language', 'string');
|
|
$label = VSecurity::postParam('label', 'string');
|
|
$is_default = isset($_POST['is_default']) ? true : false;
|
|
|
|
$result = VSubtitles::uploadSubtitle(
|
|
$file_id,
|
|
$file_type,
|
|
$_FILES['subtitle_file'],
|
|
$language,
|
|
$label,
|
|
$is_default
|
|
);
|
|
|
|
if ($result['success']) {
|
|
$notice_message = $result['message'];
|
|
} else {
|
|
$error_message = $result['message'];
|
|
}
|
|
}
|
|
|
|
// Handle subtitle deletion
|
|
if (isset($_POST['delete_subtitle'])) {
|
|
$sub_id = VSecurity::postParam('sub_id', 'int');
|
|
if (VSubtitles::deleteSubtitle($sub_id)) {
|
|
$notice_message = 'Subtitle deleted successfully';
|
|
} else {
|
|
$error_message = 'Failed to delete subtitle';
|
|
}
|
|
}
|
|
|
|
// Handle set default
|
|
if (isset($_POST['set_default'])) {
|
|
$sub_id = VSecurity::postParam('sub_id', 'int');
|
|
// Implement set default logic
|
|
$sql = "UPDATE `db_subtitles` SET `sub_default` = 0
|
|
WHERE `file_id` = %d AND `file_type` = '%s'";
|
|
$class_database->doQuery($sql, $file_id, $file_type);
|
|
|
|
$sql = "UPDATE `db_subtitles` SET `sub_default` = 1 WHERE `sub_id` = %d";
|
|
$class_database->doQuery($sql, $sub_id);
|
|
|
|
$notice_message = 'Default subtitle updated';
|
|
}
|
|
|
|
// Get existing subtitles
|
|
$subtitles = VSubtitles::getSubtitles($file_id, $file_type, false);
|
|
}
|
|
|
|
// Get configuration
|
|
$cfg = $class_database->getConfigurations('subtitles_enabled,subtitles_max_size,subtitles_allowed_formats,subtitles_max_per_video');
|
|
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Manage Subtitles - <?php echo htmlspecialchars($file_info['file_title'] ?? 'EasyStream'); ?></title>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
|
|
max-width: 900px;
|
|
margin: 40px auto;
|
|
padding: 20px;
|
|
background: #f9f9f9;
|
|
}
|
|
.container {
|
|
background: white;
|
|
border-radius: 8px;
|
|
padding: 30px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
h1 {
|
|
color: #333;
|
|
margin-bottom: 10px;
|
|
}
|
|
.file-title {
|
|
color: #666;
|
|
margin-bottom: 30px;
|
|
font-size: 14px;
|
|
}
|
|
.message {
|
|
padding: 12px 16px;
|
|
border-radius: 4px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.error {
|
|
background: #fee;
|
|
color: #c33;
|
|
border-left: 4px solid #c33;
|
|
}
|
|
.notice {
|
|
background: #efe;
|
|
color: #3c3;
|
|
border-left: 4px solid #3c3;
|
|
}
|
|
.upload-form {
|
|
background: #f5f5f5;
|
|
padding: 20px;
|
|
border-radius: 6px;
|
|
margin-bottom: 30px;
|
|
}
|
|
.form-group {
|
|
margin-bottom: 15px;
|
|
}
|
|
label {
|
|
display: block;
|
|
margin-bottom: 5px;
|
|
font-weight: 500;
|
|
color: #333;
|
|
}
|
|
input[type="text"],
|
|
input[type="file"],
|
|
select {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
font-size: 14px;
|
|
}
|
|
.checkbox-group {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.checkbox-group input {
|
|
width: auto;
|
|
margin-right: 8px;
|
|
}
|
|
button {
|
|
background: #1a73e8;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
button:hover {
|
|
background: #1557b0;
|
|
}
|
|
.subtitle-list {
|
|
margin-top: 20px;
|
|
}
|
|
.subtitle-item {
|
|
background: #fff;
|
|
border: 1px solid #e0e0e0;
|
|
border-radius: 6px;
|
|
padding: 16px;
|
|
margin-bottom: 12px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
.subtitle-info {
|
|
flex: 1;
|
|
}
|
|
.subtitle-label {
|
|
font-weight: 500;
|
|
color: #333;
|
|
margin-bottom: 4px;
|
|
}
|
|
.subtitle-meta {
|
|
font-size: 13px;
|
|
color: #666;
|
|
}
|
|
.subtitle-actions {
|
|
display: flex;
|
|
gap: 8px;
|
|
}
|
|
.btn-small {
|
|
padding: 6px 12px;
|
|
font-size: 13px;
|
|
}
|
|
.btn-danger {
|
|
background: #d93025;
|
|
}
|
|
.btn-danger:hover {
|
|
background: #a71e15;
|
|
}
|
|
.btn-secondary {
|
|
background: #5f6368;
|
|
}
|
|
.btn-secondary:hover {
|
|
background: #3c4043;
|
|
}
|
|
.badge {
|
|
background: #1a73e8;
|
|
color: white;
|
|
padding: 2px 8px;
|
|
border-radius: 12px;
|
|
font-size: 11px;
|
|
margin-left: 8px;
|
|
}
|
|
.badge-success {
|
|
background: #34a853;
|
|
}
|
|
.badge-warning {
|
|
background: #fbbc04;
|
|
color: #333;
|
|
}
|
|
.back-link {
|
|
display: inline-block;
|
|
margin-bottom: 20px;
|
|
color: #1a73e8;
|
|
text-decoration: none;
|
|
}
|
|
.back-link:hover {
|
|
text-decoration: underline;
|
|
}
|
|
.info-box {
|
|
background: #e8f0fe;
|
|
padding: 12px 16px;
|
|
border-radius: 4px;
|
|
margin-bottom: 20px;
|
|
font-size: 14px;
|
|
color: #174ea6;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<a href="<?php echo $cfg['main_url']; ?>/watch?v=<?php echo htmlspecialchars($file_key); ?>" class="back-link">
|
|
← Back to Video
|
|
</a>
|
|
|
|
<h1>Manage Subtitles</h1>
|
|
<?php if (isset($file_info)): ?>
|
|
<div class="file-title">For: <strong><?php echo htmlspecialchars($file_info['file_title']); ?></strong></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($error_message): ?>
|
|
<div class="message error"><?php echo htmlspecialchars($error_message); ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($notice_message): ?>
|
|
<div class="message notice"><?php echo htmlspecialchars($notice_message); ?></div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($cfg['subtitles_enabled'] == 1 && isset($file_info)): ?>
|
|
<div class="info-box">
|
|
📝 Upload subtitle files in .VTT or .SRT format. Maximum file size: <?php echo round($cfg['subtitles_max_size'] / 1048576, 2); ?>MB.
|
|
You can upload up to <?php echo $cfg['subtitles_max_per_video']; ?> subtitle tracks per video.
|
|
</div>
|
|
|
|
<div class="upload-form">
|
|
<h3 style="margin-top: 0;">Upload New Subtitle</h3>
|
|
<form method="POST" enctype="multipart/form-data">
|
|
<div class="form-group">
|
|
<label for="subtitle_file">Subtitle File (.vtt or .srt)</label>
|
|
<input type="file" id="subtitle_file" name="subtitle_file" accept=".vtt,.srt" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="language">Language Code</label>
|
|
<select id="language" name="language" required>
|
|
<option value="en">English (en)</option>
|
|
<option value="es">Spanish (es)</option>
|
|
<option value="fr">French (fr)</option>
|
|
<option value="de">German (de)</option>
|
|
<option value="it">Italian (it)</option>
|
|
<option value="pt">Portuguese (pt)</option>
|
|
<option value="ru">Russian (ru)</option>
|
|
<option value="ja">Japanese (ja)</option>
|
|
<option value="ko">Korean (ko)</option>
|
|
<option value="zh">Chinese (zh)</option>
|
|
<option value="ar">Arabic (ar)</option>
|
|
<option value="hi">Hindi (hi)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="label">Display Label</label>
|
|
<input type="text" id="label" name="label" placeholder="e.g., English, Spanish, etc." required>
|
|
</div>
|
|
|
|
<div class="form-group checkbox-group">
|
|
<input type="checkbox" id="is_default" name="is_default">
|
|
<label for="is_default" style="margin-bottom: 0;">Set as default subtitle</label>
|
|
</div>
|
|
|
|
<button type="submit" name="upload_subtitle">Upload Subtitle</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="subtitle-list">
|
|
<h3>Existing Subtitles</h3>
|
|
<?php if (empty($subtitles)): ?>
|
|
<p style="color: #666; font-style: italic;">No subtitles uploaded yet.</p>
|
|
<?php else: ?>
|
|
<?php foreach ($subtitles as $sub): ?>
|
|
<div class="subtitle-item">
|
|
<div class="subtitle-info">
|
|
<div class="subtitle-label">
|
|
<?php echo htmlspecialchars($sub['sub_label']); ?> (<?php echo htmlspecialchars($sub['sub_language']); ?>)
|
|
<?php if ($sub['sub_default'] == 1): ?>
|
|
<span class="badge badge-success">Default</span>
|
|
<?php endif; ?>
|
|
<?php if ($sub['active'] == 0): ?>
|
|
<span class="badge badge-warning">Pending Approval</span>
|
|
<?php endif; ?>
|
|
<?php if ($sub['sub_auto_generated'] == 1): ?>
|
|
<span class="badge">Auto-generated</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="subtitle-meta">
|
|
Format: <?php echo strtoupper($sub['sub_format']); ?> |
|
|
Size: <?php echo round($sub['sub_filesize'] / 1024, 2); ?> KB |
|
|
Uploaded: <?php echo date('M d, Y', strtotime($sub['upload_date'])); ?>
|
|
</div>
|
|
</div>
|
|
<div class="subtitle-actions">
|
|
<?php if ($sub['sub_default'] != 1): ?>
|
|
<form method="POST" style="display: inline;">
|
|
<input type="hidden" name="sub_id" value="<?php echo $sub['sub_id']; ?>">
|
|
<button type="submit" name="set_default" class="btn-small btn-secondary">Set as Default</button>
|
|
</form>
|
|
<?php endif; ?>
|
|
<form method="POST" style="display: inline;">
|
|
<input type="hidden" name="sub_id" value="<?php echo $sub['sub_id']; ?>">
|
|
<button type="submit" name="delete_subtitle" class="btn-small btn-danger" onclick="return confirm('Are you sure you want to delete this subtitle?')">Delete</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<p style="color: #666;">Subtitles are not enabled on this platform or file not found.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</body>
|
|
</html>
|