125 lines
5.2 KiB
PHP
125 lines
5.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/app.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
header('Location: /');
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
app_boot();
|
|
} catch (Throwable $e) {
|
|
notify_redirect('/', 'danger', 'The converter is not ready yet. Please try again in a moment.');
|
|
}
|
|
|
|
if (request_exceeds_upload_limit()) {
|
|
notify_redirect('/', 'warning', 'That upload is larger than the current ' . effective_upload_limit_mb() . ' MB limit. Please choose a smaller file.');
|
|
}
|
|
|
|
$toolKey = trim((string)($_POST['tool_key'] ?? 'webm_mp4'));
|
|
$catalog = tool_catalog();
|
|
if (!isset($catalog[$toolKey])) {
|
|
notify_redirect('/', 'warning', 'Please choose a supported conversion tool.');
|
|
}
|
|
|
|
$tool = $catalog[$toolKey];
|
|
if (!empty($tool['requires_ffmpeg']) && !ffmpeg_is_available()) {
|
|
notify_redirect('/', 'warning', 'FFmpeg is not available on the server yet, so this conversion tool is temporarily offline.');
|
|
}
|
|
|
|
$file = $_FILES['source_file'] ?? $_FILES['video_file'] ?? null;
|
|
if (!is_array($file)) {
|
|
notify_redirect('/', 'warning', 'Please choose a file to convert.');
|
|
}
|
|
|
|
$errorCode = (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE);
|
|
if (in_array($errorCode, [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE], true)) {
|
|
notify_redirect('/', 'warning', 'That upload is larger than the current ' . effective_upload_limit_mb() . ' MB limit. Please choose a smaller file.');
|
|
}
|
|
|
|
if ($errorCode !== UPLOAD_ERR_OK) {
|
|
notify_redirect('/', 'danger', 'Upload failed. Please try another file.');
|
|
}
|
|
|
|
$originalName = (string) ($file['name'] ?? 'upload.bin');
|
|
$safeOriginalName = preg_replace('/[^A-Za-z0-9._-]/', '-', $originalName) ?: 'upload.bin';
|
|
$extension = file_extension($safeOriginalName);
|
|
|
|
if (!in_array($extension, $tool['input_extensions'], true)) {
|
|
notify_redirect('/', 'warning', 'That file type is not supported for ' . $tool['label'] . '.');
|
|
}
|
|
|
|
$size = (int) ($file['size'] ?? 0);
|
|
if ($size < 1) {
|
|
notify_redirect('/', 'warning', 'The selected file looks empty. Please upload a valid file.');
|
|
}
|
|
|
|
if ($size > effective_upload_limit_bytes()) {
|
|
notify_redirect('/', 'warning', 'That upload is larger than the current ' . effective_upload_limit_mb() . ' MB limit. Please choose a smaller file.');
|
|
}
|
|
|
|
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
|
$mime = strtolower((string) $finfo->file((string) $file['tmp_name']));
|
|
$allowedMimes = match ($toolKey) {
|
|
'webm_mp4' => ['video/webm', 'application/octet-stream'],
|
|
'social_mp4' => ['video/webm', 'video/mp4', 'application/mp4', 'video/quicktime', 'application/octet-stream'],
|
|
'subtitle_convert' => ['text/plain', 'text/vtt', 'application/octet-stream', 'application/x-subrip'],
|
|
default => ['application/octet-stream'],
|
|
};
|
|
|
|
if (!in_array($mime, $allowedMimes, true)) {
|
|
notify_redirect('/', 'warning', 'The uploaded file does not match the expected file type for this converter.');
|
|
}
|
|
|
|
$targetFormat = 'mp4';
|
|
$presetKey = null;
|
|
$outputMime = $tool['output_mime'] !== '' ? $tool['output_mime'] : null;
|
|
|
|
if ($toolKey === 'social_mp4') {
|
|
$presetKey = trim((string)($_POST['preset_key'] ?? ''));
|
|
if ($presetKey === '' || preset_option($toolKey, $presetKey) === null) {
|
|
notify_redirect('/', 'warning', 'Please choose a social export preset.');
|
|
}
|
|
}
|
|
|
|
if ($toolKey === 'subtitle_convert') {
|
|
$requestedTarget = strtolower(trim((string)($_POST['subtitle_target'] ?? '')));
|
|
$allowedTargets = array_keys(subtitle_target_options());
|
|
if (!in_array($requestedTarget, $allowedTargets, true)) {
|
|
notify_redirect('/', 'warning', 'Please choose whether to export to SRT or VTT.');
|
|
}
|
|
if ($requestedTarget === $extension) {
|
|
notify_redirect('/', 'warning', 'Please choose the opposite subtitle format so the file is actually converted.');
|
|
}
|
|
$targetFormat = $requestedTarget;
|
|
$outputMime = $targetFormat === 'vtt' ? 'text/vtt' : 'application/x-subrip';
|
|
}
|
|
|
|
$publicId = bin2hex(random_bytes(16));
|
|
$inputPath = APP_UPLOAD_DIR . '/' . $publicId . '.' . $extension;
|
|
$outputPath = APP_OUTPUT_DIR . '/' . $publicId . '.' . $targetFormat;
|
|
|
|
if (!move_uploaded_file((string) $file['tmp_name'], $inputPath)) {
|
|
notify_redirect('/', 'danger', 'We could not save the uploaded file. Please try again.');
|
|
}
|
|
|
|
$downloadName = build_download_name($originalName, $toolKey, $targetFormat, $presetKey);
|
|
$jobId = create_job_record($publicId, $originalName, $inputPath, $size, $toolKey, $extension, $targetFormat, $presetKey, $outputMime, $downloadName);
|
|
|
|
$result = match ($toolKey) {
|
|
'webm_mp4' => convert_media_to_mp4($inputPath, $outputPath),
|
|
'social_mp4' => convert_media_to_mp4($inputPath, $outputPath, (string) preset_option($toolKey, $presetKey)['filter']),
|
|
'subtitle_convert' => convert_subtitle_file($inputPath, $outputPath, $extension, $targetFormat),
|
|
default => ['success' => false, 'message' => 'Unsupported conversion request.'],
|
|
};
|
|
|
|
if (!empty($result['success']) && is_file($outputPath)) {
|
|
mark_job_completed($jobId, $outputPath, (int) filesize($outputPath));
|
|
notify_redirect('/job.php?id=' . urlencode($publicId), 'success', $tool['label'] . ' completed. Your download is ready.');
|
|
}
|
|
|
|
mark_job_failed($jobId, (string) ($result['message'] ?? 'Conversion failed.'));
|
|
notify_redirect('/job.php?id=' . urlencode($publicId), 'danger', $tool['label'] . ' failed. Check the job details for more information.');
|