|
@@ -4429,3 +4429,125 @@ function mapErrorMessage($errorMessage)
|
|
|
// 默认返回
|
|
// 默认返回
|
|
|
return '未知异常,请重试';
|
|
return '未知异常,请重试';
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 将480p视频升级到720p
|
|
|
|
|
+ * 使用FFmpeg保持宽高比和画质尽量不丢失
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param string $videoUrl 视频URL地址
|
|
|
|
|
+ * @param string $prefix 上传文件夹前缀(如:'videos')
|
|
|
|
|
+ * @return string 返回升级后的视频URL,失败返回原视频URL
|
|
|
|
|
+ */
|
|
|
|
|
+function upgrade480pTo720p($videoUrl, $prefix = 'videos')
|
|
|
|
|
+{
|
|
|
|
|
+ if (env('APP_ENV') == 'local') return $videoUrl;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 创建临时目录
|
|
|
|
|
+ $tempDir = storage_path('app/temp/videos');
|
|
|
|
|
+ if (!is_dir($tempDir)) {
|
|
|
|
|
+ mkdir($tempDir, 0775, true);
|
|
|
|
|
+ chmod($tempDir, 0775);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 生成唯一文件名
|
|
|
|
|
+ $uniqueId = uniqid('video_upgrade_') . bin2hex(random_bytes(4));
|
|
|
|
|
+ $videoExt = getVideoExtFromUrl($videoUrl);
|
|
|
|
|
+ $inputFile = $tempDir . '/' . $uniqueId . '_input' . $videoExt;
|
|
|
|
|
+ $outputFile = $tempDir . '/' . $uniqueId . '_output.mp4';
|
|
|
|
|
+
|
|
|
|
|
+ // 下载视频到本地
|
|
|
|
|
+ dLog('video_upgrade')->info('开始下载视频进行升级', ['url' => $videoUrl]);
|
|
|
|
|
+ $client = new \GuzzleHttp\Client(['timeout' => 300]);
|
|
|
|
|
+ $response = $client->get($videoUrl);
|
|
|
|
|
+
|
|
|
|
|
+ $fileContent = $response->getBody()->getContents();
|
|
|
|
|
+ if (file_put_contents($inputFile, $fileContent) === false) {
|
|
|
|
|
+ dLog('video_upgrade')->error('视频文件写入失败', [
|
|
|
|
|
+ 'url' => $videoUrl,
|
|
|
|
|
+ 'file' => $inputFile
|
|
|
|
|
+ ]);
|
|
|
|
|
+ return $videoUrl;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ chmod($inputFile, 0664);
|
|
|
|
|
+
|
|
|
|
|
+ if (!file_exists($inputFile)) {
|
|
|
|
|
+ dLog('video_upgrade')->error('视频下载失败', ['url' => $videoUrl]);
|
|
|
|
|
+ return $videoUrl;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $inputFileSize = filesize($inputFile);
|
|
|
|
|
+ dLog('video_upgrade')->info('视频下载成功,准备升级到720p', [
|
|
|
|
|
+ 'url' => $videoUrl,
|
|
|
|
|
+ 'size' => $inputFileSize,
|
|
|
|
|
+ 'size_mb' => round($inputFileSize / 1024 / 1024, 2) . 'MB'
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ // 使用FFmpeg将视频升级到720p
|
|
|
|
|
+ // -vf "scale=-2:720": 保持宽高比,高度设置为720,宽度自动计算(-2确保是偶数)
|
|
|
|
|
+ // -c:v libx264: 使用H.264编码器
|
|
|
|
|
+ // -preset slow: 使用较慢的编码速度以保持更好的画质
|
|
|
|
|
+ // -crf 18: 恒定质量模式,18表示高质量(0-51,数值越小画质越好)
|
|
|
|
|
+ // -c:a copy: 音频直接复制,不重新编码
|
|
|
|
|
+ // -movflags +faststart: 优化网络播放
|
|
|
|
|
+ $ffmpegPath = env('FFMPEG_PATH', 'ffmpeg');
|
|
|
|
|
+ $ffmpegCmd = "$ffmpegPath -i \"$inputFile\" -vf \"scale=-2:720\" -c:v libx264 -preset slow -crf 18 -c:a copy -movflags +faststart -y \"$outputFile\" 2>&1";
|
|
|
|
|
+
|
|
|
|
|
+ dLog('video_upgrade')->info('开始升级视频到720p', ['command' => $ffmpegCmd]);
|
|
|
|
|
+ $output = shell_exec($ffmpegCmd);
|
|
|
|
|
+
|
|
|
|
|
+ if (!file_exists($outputFile)) {
|
|
|
|
|
+ dLog('video_upgrade')->error('视频升级失败', [
|
|
|
|
|
+ 'input' => $inputFile,
|
|
|
|
|
+ 'output' => $output
|
|
|
|
|
+ ]);
|
|
|
|
|
+ @unlink($inputFile);
|
|
|
|
|
+ return $videoUrl;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ chmod($outputFile, 0664);
|
|
|
|
|
+
|
|
|
|
|
+ $outputFileSize = filesize($outputFile);
|
|
|
|
|
+ $sizeRatio = round($outputFileSize / $inputFileSize, 2);
|
|
|
|
|
+
|
|
|
|
|
+ dLog('video_upgrade')->info('视频升级成功', [
|
|
|
|
|
+ 'input_size' => round($inputFileSize / 1024 / 1024, 2) . 'MB',
|
|
|
|
|
+ 'output_size' => round($outputFileSize / 1024 / 1024, 2) . 'MB',
|
|
|
|
|
+ 'size_ratio' => $sizeRatio
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ // 上传到TOS - 使用普通的文件名,不暴露是升级后的视频
|
|
|
|
|
+ $video_name = 'ai_generation_' . time() . '_' . uniqid() . '.mp4';
|
|
|
|
|
+ $uploadedUrl = uploadStreamByTos($prefix, file_get_contents($outputFile), $video_name);
|
|
|
|
|
+
|
|
|
|
|
+ // 清理临时文件
|
|
|
|
|
+ @unlink($inputFile);
|
|
|
|
|
+ @unlink($outputFile);
|
|
|
|
|
+
|
|
|
|
|
+ if (!$uploadedUrl) {
|
|
|
|
|
+ dLog('video_upgrade')->error('升级后的视频上传失败');
|
|
|
|
|
+ return $videoUrl;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ dLog('video_upgrade')->info('升级后的视频上传成功', ['url' => $uploadedUrl]);
|
|
|
|
|
+ return $uploadedUrl;
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ dLog('video_upgrade')->error('视频升级过程出错', [
|
|
|
|
|
+ 'url' => $videoUrl,
|
|
|
|
|
+ 'error' => $e->getMessage()
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ // 清理可能存在的临时文件
|
|
|
|
|
+ if (isset($inputFile) && file_exists($inputFile)) {
|
|
|
|
|
+ @unlink($inputFile);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isset($outputFile) && file_exists($outputFile)) {
|
|
|
|
|
+ @unlink($outputFile);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 出错时返回原视频URL
|
|
|
|
|
+ return $videoUrl;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|