|
|
@@ -53,6 +53,16 @@ class TestCommand extends Command
|
|
|
*/
|
|
|
public function handle()
|
|
|
{
|
|
|
+ // 测试视频超分功能
|
|
|
+ // 使用示例:php artisan test --video_url=https://your-video-url.mp4
|
|
|
+ $videoUrl = 'https://zw-audiobook.tos-cn-beijing.volces.com/video/ai_generation_1785144404_6a672454cabb0.mp4';
|
|
|
+ if ($videoUrl) {
|
|
|
+ $result = $this->testVideoEnhance($videoUrl);
|
|
|
+ dd($result);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ dd('end');
|
|
|
+
|
|
|
$str = "【镜头1】
|
|
|
场景:@{顶层办公室}
|
|
|
画面:[大远景,冷蓝调夜景] 城市夜色如墨,高楼灯火如星点散落。落地窗占据画面主体,窗外城市天际线在夜色中延伸,室内灯光在玻璃上映出暖黄光晕。
|
|
|
@@ -407,6 +417,234 @@ class TestCommand extends Command
|
|
|
// \Log::info('generate_json: '.$generate_json);
|
|
|
}
|
|
|
|
|
|
+ private function testVideoEnhance($video_url) {
|
|
|
+ $startTime = microtime(true); // 开始计时
|
|
|
+
|
|
|
+ $this->info("========== 开始测试视频超分 ==========");
|
|
|
+ $this->info("原始视频URL: {$video_url}");
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 获取API Key
|
|
|
+ $apiKey = env('VOLC_AI_MEDIAKIT_KEY');
|
|
|
+ if (empty($apiKey)) {
|
|
|
+ $this->error('VOLC_AI_MEDIAKIT_KEY 未配置');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 提交超分任务
|
|
|
+ $this->info("\n步骤1: 提交超分任务...");
|
|
|
+ $submitStartTime = microtime(true);
|
|
|
+
|
|
|
+ $client = new Client(['verify' => false, 'timeout' => 120]);
|
|
|
+
|
|
|
+ $requestParams = [
|
|
|
+ 'video_url' => $video_url,
|
|
|
+ 'resolution' => '720p',
|
|
|
+ 'bitrate_level' => 'medium'
|
|
|
+ ];
|
|
|
+
|
|
|
+ $this->info("请求参数: " . json_encode($requestParams, JSON_UNESCAPED_UNICODE));
|
|
|
+
|
|
|
+ $response = $client->post('https://mediakit.cn-beijing.volces.com/api/v1/tools/enhance-video-fast', [
|
|
|
+ 'headers' => [
|
|
|
+ 'Authorization' => 'Bearer ' . $apiKey,
|
|
|
+ 'Content-Type' => 'application/json',
|
|
|
+ ],
|
|
|
+ 'json' => $requestParams
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $responseData = json_decode($response->getBody(), true);
|
|
|
+ $submitEndTime = microtime(true);
|
|
|
+ $submitDuration = round($submitEndTime - $submitStartTime, 2);
|
|
|
+
|
|
|
+ $this->info("提交响应: " . json_encode($responseData, JSON_UNESCAPED_UNICODE));
|
|
|
+ $this->comment("提交耗时: {$submitDuration}秒");
|
|
|
+
|
|
|
+ if (!isset($responseData['success']) || $responseData['success'] !== true) {
|
|
|
+ $errorMsg = isset($responseData['error']) ?
|
|
|
+ ($responseData['error']['message'] ?? json_encode($responseData['error'])) :
|
|
|
+ '未知错误';
|
|
|
+ $this->error("任务提交失败: {$errorMsg}");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $taskId = $responseData['task_id'];
|
|
|
+ $this->info("✓ 任务提交成功,任务ID: {$taskId}");
|
|
|
+
|
|
|
+ // 2. 轮询查询任务状态
|
|
|
+ $this->info("\n步骤2: 开始轮询查询任务状态...");
|
|
|
+ $pollingStartTime = microtime(true);
|
|
|
+ $maxAttempts = 120; // 最多轮询120次(10分钟)
|
|
|
+ $interval = 5; // 每5秒查询一次
|
|
|
+ $attempt = 0;
|
|
|
+
|
|
|
+ while ($attempt < $maxAttempts) {
|
|
|
+ $attempt++;
|
|
|
+ $this->info("\n第 {$attempt} 次查询(间隔{$interval}秒)...");
|
|
|
+
|
|
|
+ sleep($interval);
|
|
|
+
|
|
|
+ try {
|
|
|
+ $queryResponse = $client->get('https://mediakit.cn-beijing.volces.com/api/v1/tasks/' . $taskId, [
|
|
|
+ 'headers' => [
|
|
|
+ 'Authorization' => 'Bearer ' . $apiKey,
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $queryData = json_decode($queryResponse->getBody(), true);
|
|
|
+ $taskStatus = $queryData['status'] ?? 'unknown';
|
|
|
+
|
|
|
+ $this->info("任务状态: {$taskStatus}");
|
|
|
+
|
|
|
+ if ($taskStatus === 'completed') {
|
|
|
+ $pollingEndTime = microtime(true);
|
|
|
+ $pollingDuration = round($pollingEndTime - $pollingStartTime, 2);
|
|
|
+
|
|
|
+ // 任务成功
|
|
|
+ $this->info("\n========== 超分任务完成 ==========");
|
|
|
+ $this->comment("轮询耗时: {$pollingDuration}秒 (查询{$attempt}次)");
|
|
|
+
|
|
|
+ if (isset($queryData['result']['video_url'])) {
|
|
|
+ $enhancedUrl = $queryData['result']['video_url'];
|
|
|
+
|
|
|
+ $this->info("\n✓ 超分成功!API返回的临时URL:");
|
|
|
+ $this->info($enhancedUrl);
|
|
|
+
|
|
|
+ // 3. 上传到TOS
|
|
|
+ $this->info("\n步骤3: 开始上传超分视频到TOS...");
|
|
|
+ $uploadStartTime = microtime(true);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 生成文件名
|
|
|
+ $videoName = 'enhanced_video_' . time() . '_' . uniqid() . '.mp4';
|
|
|
+
|
|
|
+ // 下载并上传到TOS
|
|
|
+ $this->comment("正在下载超分视频...");
|
|
|
+ $videoContent = file_get_contents($enhancedUrl);
|
|
|
+ $videoSize = strlen($videoContent);
|
|
|
+ $this->comment("视频大小: " . round($videoSize / 1024 / 1024, 2) . " MB");
|
|
|
+
|
|
|
+ $this->comment("正在上传到TOS...");
|
|
|
+ $tosUrl = uploadStreamByTos('video', $videoContent, $videoName);
|
|
|
+
|
|
|
+ $uploadEndTime = microtime(true);
|
|
|
+ $uploadDuration = round($uploadEndTime - $uploadStartTime, 2);
|
|
|
+
|
|
|
+ $this->info("✓ 上传成功!耗时: {$uploadDuration}秒");
|
|
|
+ $this->info("TOS地址: {$tosUrl}");
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ $this->error("✗ 上传TOS失败: " . $e->getMessage());
|
|
|
+ $this->warn("将返回原始临时URL");
|
|
|
+ $tosUrl = $enhancedUrl;
|
|
|
+ $uploadDuration = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算总耗时
|
|
|
+ $totalEndTime = microtime(true);
|
|
|
+ $totalDuration = round($totalEndTime - $startTime, 2);
|
|
|
+
|
|
|
+ // 显示详细信息
|
|
|
+ $this->info("\n========== 执行完成 ==========");
|
|
|
+ if (isset($queryData['result']['duration'])) {
|
|
|
+ $this->info("视频时长: " . $queryData['result']['duration'] . "秒");
|
|
|
+ }
|
|
|
+ if (isset($queryData['result']['resolution'])) {
|
|
|
+ $this->info("输出分辨率: " . $queryData['result']['resolution']);
|
|
|
+ }
|
|
|
+ if (isset($queryData['result']['fps'])) {
|
|
|
+ $this->info("输出帧率: " . $queryData['result']['fps'] . " fps");
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->info("\n========== 时间统计 ==========");
|
|
|
+ $this->info("提交任务耗时: {$submitDuration}秒");
|
|
|
+ $this->info("等待处理耗时: {$pollingDuration}秒 (查询{$attempt}次)");
|
|
|
+ $this->info("上传TOS耗时: {$uploadDuration}秒");
|
|
|
+ $this->info("总执行时间: {$totalDuration}秒");
|
|
|
+
|
|
|
+ $this->info("\n========== URL对比 ==========");
|
|
|
+ $this->info("原始视频URL: {$video_url}");
|
|
|
+ $this->info("超分后TOS地址: {$tosUrl}");
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'success' => true,
|
|
|
+ 'original_url' => $video_url,
|
|
|
+ 'enhanced_url' => $enhancedUrl, // API临时URL
|
|
|
+ 'tos_url' => $tosUrl, // TOS永久URL
|
|
|
+ 'task_id' => $taskId,
|
|
|
+ 'result' => $queryData['result'],
|
|
|
+ 'duration' => [
|
|
|
+ 'submit' => $submitDuration,
|
|
|
+ 'polling' => $pollingDuration,
|
|
|
+ 'upload' => $uploadDuration,
|
|
|
+ 'total' => $totalDuration
|
|
|
+ ],
|
|
|
+ 'polling_attempts' => $attempt
|
|
|
+ ];
|
|
|
+ } else {
|
|
|
+ $this->error("✗ 任务完成但未找到视频URL");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ } elseif ($taskStatus === 'failed') {
|
|
|
+ // 任务失败
|
|
|
+ $pollingEndTime = microtime(true);
|
|
|
+ $pollingDuration = round($pollingEndTime - $pollingStartTime, 2);
|
|
|
+ $totalDuration = round($pollingEndTime - $startTime, 2);
|
|
|
+
|
|
|
+ $this->error("\n✗ 超分任务失败");
|
|
|
+ $this->error("完整响应: " . json_encode($queryData, JSON_UNESCAPED_UNICODE));
|
|
|
+ $this->info("\n总执行时间: {$totalDuration}秒 (轮询{$attempt}次,耗时{$pollingDuration}秒)");
|
|
|
+ return;
|
|
|
+
|
|
|
+ } elseif (in_array($taskStatus, ['pending', 'processing', 'queued'])) {
|
|
|
+ // 任务处理中,继续轮询
|
|
|
+ $this->comment(" 任务处理中,继续等待...");
|
|
|
+ continue;
|
|
|
+
|
|
|
+ } else {
|
|
|
+ // 未知状态
|
|
|
+ $this->warn(" 未知的任务状态: {$taskStatus}");
|
|
|
+ $this->info(" 完整响应: " . json_encode($queryData, JSON_UNESCAPED_UNICODE));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ $this->warn(" 查询出错: " . $e->getMessage());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 超时
|
|
|
+ $totalEndTime = microtime(true);
|
|
|
+ $totalDuration = round($totalEndTime - $startTime, 2);
|
|
|
+
|
|
|
+ $this->error("\n✗ 查询超时,已轮询 {$maxAttempts} 次(约 " . ($maxAttempts * $interval / 60) . " 分钟)");
|
|
|
+ $this->info("任务ID: {$taskId}");
|
|
|
+ $this->info("总执行时间: {$totalDuration}秒");
|
|
|
+ $this->info("您可以稍后手动查询任务状态");
|
|
|
+
|
|
|
+ } catch (\GuzzleHttp\Exception\RequestException $e) {
|
|
|
+ $endTime = microtime(true);
|
|
|
+ $duration = round($endTime - $startTime, 2);
|
|
|
+
|
|
|
+ $this->error("\nAPI请求失败(执行时间: {$duration}秒):");
|
|
|
+ if ($e->hasResponse()) {
|
|
|
+ $errorResponse = json_decode($e->getResponse()->getBody()->getContents(), true);
|
|
|
+ $this->error(json_encode($errorResponse, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
|
|
|
+ } else {
|
|
|
+ $this->error($e->getMessage());
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ $endTime = microtime(true);
|
|
|
+ $duration = round($endTime - $startTime, 2);
|
|
|
+
|
|
|
+ $this->error("\n发生错误(执行时间: {$duration}秒): " . $e->getMessage());
|
|
|
+ $this->error("错误堆栈: " . $e->getTraceAsString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 处理历史视频任务 - 压缩视频并更新 compressed_url
|
|
|
*/
|