|
|
@@ -1402,6 +1402,18 @@ class AnimeController extends BaseController
|
|
|
$episodeId = $data['episode_id'];
|
|
|
|
|
|
try {
|
|
|
+ // 获取动漫信息,判断是否为全能模式
|
|
|
+ $anime = DB::table('mp_animes')
|
|
|
+ ->where('id', $animeId)
|
|
|
+ ->select('ace_mode')
|
|
|
+ ->first();
|
|
|
+
|
|
|
+ if (!$anime) {
|
|
|
+ Utils::throwError('20003:未找到动漫信息');
|
|
|
+ }
|
|
|
+
|
|
|
+ $isAceMode = ($anime->ace_mode == 1);
|
|
|
+
|
|
|
// 获取剧集信息
|
|
|
$episode = DB::table('mp_anime_episodes')
|
|
|
->where('anime_id', $animeId)
|
|
|
@@ -1413,18 +1425,44 @@ class AnimeController extends BaseController
|
|
|
Utils::throwError('20003:未找到剧集信息');
|
|
|
}
|
|
|
|
|
|
- // 获取所有分镜图片和音频
|
|
|
- $segments = DB::table('mp_episode_segments')
|
|
|
- ->where('anime_id', $animeId)
|
|
|
- ->where('episode_id', $episodeId)
|
|
|
- ->whereNotNull('img_url')
|
|
|
- ->where('img_url', '!=', '')
|
|
|
- ->orderBy('segment_number')
|
|
|
- ->select('segment_id', 'segment_number', 'img_url', 'video_url', 'audio_url', 'act_number', 'act_title')
|
|
|
- ->get();
|
|
|
-
|
|
|
- if ($segments->isEmpty()) {
|
|
|
- Utils::throwError('20003:该剧集暂无图片可导出');
|
|
|
+ // 根据模式查询和排序分镜数据
|
|
|
+ if ($isAceMode) {
|
|
|
+ // 全能模式:只查询有视频的分镜,按act_number排序
|
|
|
+ $segments = DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $animeId)
|
|
|
+ ->where('episode_id', $episodeId)
|
|
|
+ ->whereNotNull('video_url')
|
|
|
+ ->where('video_url', '!=', '')
|
|
|
+ ->orderBy('act_number')
|
|
|
+ ->select('id as act_id', 'act_number', 'video_url', 'act_title')
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ if ($segments->isEmpty()) {
|
|
|
+ Utils::throwError('20003:该剧集暂无视频可导出');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 普通模式:查询所有分镜,按segment_number排序
|
|
|
+ $segments = DB::table('mp_episode_segments')
|
|
|
+ ->where('anime_id', $animeId)
|
|
|
+ ->where('episode_id', $episodeId)
|
|
|
+ ->orderBy('segment_number')
|
|
|
+ ->select('segment_id', 'segment_number', 'img_url', 'video_url', 'audio_url')
|
|
|
+ ->get();
|
|
|
+
|
|
|
+ if ($segments->isEmpty()) {
|
|
|
+ Utils::throwError('20003:该剧集暂无分镜数据');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 过滤出有图片或视频的分镜
|
|
|
+ $validSegments = $segments->filter(function($segment) {
|
|
|
+ return (!empty($segment->img_url) || !empty($segment->video_url));
|
|
|
+ });
|
|
|
+
|
|
|
+ if ($validSegments->isEmpty()) {
|
|
|
+ Utils::throwError('20003:该剧集暂无图片或视频可导出');
|
|
|
+ }
|
|
|
+
|
|
|
+ $segments = $validSegments->values();
|
|
|
}
|
|
|
|
|
|
// 创建临时目录
|
|
|
@@ -1433,12 +1471,17 @@ class AnimeController extends BaseController
|
|
|
mkdir($tempDir, 0755, true);
|
|
|
}
|
|
|
|
|
|
- // 下载图片或视频
|
|
|
+ // 下载文件
|
|
|
$downloadedFiles = [];
|
|
|
- foreach ($segments as $segment) {
|
|
|
+ foreach ($segments as $index => $segment) {
|
|
|
try {
|
|
|
- // 优先使用video_url,如果没有则使用img_url
|
|
|
- $mediaUrl = !empty($segment->video_url) ? $segment->video_url : $segment->img_url;
|
|
|
+ if ($isAceMode) {
|
|
|
+ // 全能模式:只下载视频
|
|
|
+ $mediaUrl = $segment->video_url;
|
|
|
+ } else {
|
|
|
+ // 普通模式:优先使用video_url,如果没有则使用img_url
|
|
|
+ $mediaUrl = !empty($segment->video_url) ? $segment->video_url : $segment->img_url;
|
|
|
+ }
|
|
|
|
|
|
if (empty($mediaUrl)) {
|
|
|
continue;
|
|
|
@@ -1451,15 +1494,17 @@ class AnimeController extends BaseController
|
|
|
$extension = !empty($segment->video_url) ? 'mp4' : 'jpg';
|
|
|
}
|
|
|
|
|
|
- // 构建文件名:分镜序号.扩展名
|
|
|
- $fileName = sprintf(
|
|
|
- '%03d.%s',
|
|
|
- $segment->segment_number,
|
|
|
- $extension
|
|
|
- );
|
|
|
+ // 构建文件名
|
|
|
+ if ($isAceMode) {
|
|
|
+ // 全能模式:使用act_number
|
|
|
+ $fileName = sprintf('%03d.%s', $segment->act_number, $extension);
|
|
|
+ } else {
|
|
|
+ // 普通模式:使用segment_number
|
|
|
+ $fileName = sprintf('%03d.%s', $segment->segment_number, $extension);
|
|
|
+ }
|
|
|
$filePath = $tempDir . '/' . $fileName;
|
|
|
|
|
|
- // 下载文件(使用file_get_contents,兼容性更好)
|
|
|
+ // 下载文件
|
|
|
$context = stream_context_create([
|
|
|
'http' => [
|
|
|
'timeout' => 30,
|
|
|
@@ -1479,22 +1524,34 @@ class AnimeController extends BaseController
|
|
|
$downloadedFiles[] = $filePath;
|
|
|
} else {
|
|
|
$logData = [
|
|
|
- 'segment_id' => $segment->segment_id,
|
|
|
'media_url' => $mediaUrl,
|
|
|
- 'type' => !empty($segment->video_url) ? 'video' : 'image'
|
|
|
+ 'type' => $isAceMode ? 'video' : (!empty($segment->video_url) ? 'video' : 'image')
|
|
|
];
|
|
|
- dLog('anime')->warning('文件下载失败', $logData);
|
|
|
+
|
|
|
+ if ($isAceMode) {
|
|
|
+ $logData['act_id'] = $segment->act_id;
|
|
|
+ $logData['act_number'] = $segment->act_number;
|
|
|
+ } else {
|
|
|
+ $logData['segment_id'] = $segment->segment_id;
|
|
|
+ $logData['segment_number'] = $segment->segment_number;
|
|
|
+ }
|
|
|
+
|
|
|
logDB('anime', 'warning', '文件下载失败', $logData);
|
|
|
}
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
$logData = [
|
|
|
- 'segment_id' => $segment->segment_id,
|
|
|
- 'video_url' => $segment->video_url,
|
|
|
- 'img_url' => $segment->img_url,
|
|
|
'error' => $e->getMessage()
|
|
|
];
|
|
|
- dLog('anime')->error('下载文件异常', $logData);
|
|
|
+
|
|
|
+ if ($isAceMode) {
|
|
|
+ $logData['act_id'] = $segment->act_id;
|
|
|
+ $logData['act_number'] = $segment->act_number;
|
|
|
+ } else {
|
|
|
+ $logData['segment_id'] = $segment->segment_id;
|
|
|
+ $logData['segment_number'] = $segment->segment_number;
|
|
|
+ }
|
|
|
+
|
|
|
logDB('anime', 'error', '下载文件异常', $logData);
|
|
|
continue;
|
|
|
}
|
|
|
@@ -1506,163 +1563,187 @@ class AnimeController extends BaseController
|
|
|
array_map('unlink', glob("$tempDir/*"));
|
|
|
rmdir($tempDir);
|
|
|
}
|
|
|
- Utils::throwError('20003:没有成功下载任何图片');
|
|
|
+ Utils::throwError('20003:没有成功下载任何文件');
|
|
|
}
|
|
|
|
|
|
- // 处理音频合成
|
|
|
+ // 处理音频合成(仅普通模式)
|
|
|
$mergedAudioPath = null;
|
|
|
- try {
|
|
|
- // 检查 FFmpeg 是否可用
|
|
|
- exec('which ffmpeg 2>&1', $ffmpegCheck, $ffmpegReturnCode);
|
|
|
- $hasFfmpeg = ($ffmpegReturnCode === 0);
|
|
|
-
|
|
|
- if ($hasFfmpeg) {
|
|
|
- // 下载所有分镜的音频文件
|
|
|
- $audioFiles = [];
|
|
|
- foreach ($segments as $segment) {
|
|
|
- if (!empty($segment->audio_url)) {
|
|
|
- try {
|
|
|
- $context = stream_context_create([
|
|
|
- 'http' => [
|
|
|
- 'timeout' => 30,
|
|
|
- 'follow_location' => 1,
|
|
|
- 'ignore_errors' => true
|
|
|
- ],
|
|
|
- 'ssl' => [
|
|
|
- 'verify_peer' => false,
|
|
|
- 'verify_peer_name' => false
|
|
|
- ]
|
|
|
- ]);
|
|
|
-
|
|
|
- $audioData = @file_get_contents($segment->audio_url, false, $context);
|
|
|
-
|
|
|
- if ($audioData !== false && !empty($audioData)) {
|
|
|
- // 获取音频文件扩展名
|
|
|
- $audioExtension = pathinfo(parse_url($segment->audio_url, PHP_URL_PATH), PATHINFO_EXTENSION);
|
|
|
- if (empty($audioExtension)) {
|
|
|
- $audioExtension = 'wav';
|
|
|
- }
|
|
|
+ if (!$isAceMode) {
|
|
|
+ try {
|
|
|
+ // 检查 FFmpeg 是否可用
|
|
|
+ exec('which ffmpeg 2>&1', $ffmpegCheck, $ffmpegReturnCode);
|
|
|
+ $hasFfmpeg = ($ffmpegReturnCode === 0);
|
|
|
+
|
|
|
+ if ($hasFfmpeg) {
|
|
|
+ // 下载所有分镜的音频文件
|
|
|
+ $audioFiles = [];
|
|
|
+ foreach ($segments as $segment) {
|
|
|
+ if (!empty($segment->audio_url)) {
|
|
|
+ try {
|
|
|
+ $context = stream_context_create([
|
|
|
+ 'http' => [
|
|
|
+ 'timeout' => 30,
|
|
|
+ 'follow_location' => 1,
|
|
|
+ 'ignore_errors' => true
|
|
|
+ ],
|
|
|
+ 'ssl' => [
|
|
|
+ 'verify_peer' => false,
|
|
|
+ 'verify_peer_name' => false
|
|
|
+ ]
|
|
|
+ ]);
|
|
|
|
|
|
- $audioFileName = sprintf('audio_%03d.%s', $segment->segment_number, $audioExtension);
|
|
|
- $audioFilePath = $tempDir . '/' . $audioFileName;
|
|
|
- file_put_contents($audioFilePath, $audioData);
|
|
|
- $audioFiles[] = $audioFilePath;
|
|
|
- } else {
|
|
|
- $logData = [
|
|
|
+ $audioData = @file_get_contents($segment->audio_url, false, $context);
|
|
|
+
|
|
|
+ if ($audioData !== false && !empty($audioData)) {
|
|
|
+ // 获取音频文件扩展名
|
|
|
+ $audioExtension = pathinfo(parse_url($segment->audio_url, PHP_URL_PATH), PATHINFO_EXTENSION);
|
|
|
+ if (empty($audioExtension)) {
|
|
|
+ $audioExtension = 'wav';
|
|
|
+ }
|
|
|
+
|
|
|
+ $audioFileName = sprintf('audio_%03d.%s', $segment->segment_number, $audioExtension);
|
|
|
+ $audioFilePath = $tempDir . '/' . $audioFileName;
|
|
|
+ file_put_contents($audioFilePath, $audioData);
|
|
|
+ $audioFiles[] = $audioFilePath;
|
|
|
+ } else {
|
|
|
+ logDB('anime', 'warning', '音频下载失败', [
|
|
|
+ 'segment_id' => $segment->segment_id,
|
|
|
+ 'audio_url' => $segment->audio_url
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ logDB('anime', 'error', '下载音频异常', [
|
|
|
'segment_id' => $segment->segment_id,
|
|
|
- 'audio_url' => $segment->audio_url
|
|
|
- ];
|
|
|
- dLog('anime')->warning('音频下载失败', $logData);
|
|
|
- logDB('anime', 'warning', '音频下载失败', $logData);
|
|
|
+ 'audio_url' => $segment->audio_url,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
}
|
|
|
- } catch (\Exception $e) {
|
|
|
- $logData = [
|
|
|
- 'segment_id' => $segment->segment_id,
|
|
|
- 'audio_url' => $segment->audio_url,
|
|
|
- 'error' => $e->getMessage()
|
|
|
- ];
|
|
|
- dLog('anime')->error('下载音频异常', $logData);
|
|
|
- logDB('anime', 'error', '下载音频异常', $logData);
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- // 如果有音频文件,则进行合成
|
|
|
- if (!empty($audioFiles)) {
|
|
|
- // 创建 FFmpeg concat 文件列表
|
|
|
- $concatFile = $tempDir . '/concat.txt';
|
|
|
- $concatContent = '';
|
|
|
- foreach ($audioFiles as $audioFile) {
|
|
|
- // 使用相对路径,避免路径中的特殊字符问题
|
|
|
- $concatContent .= "file '" . basename($audioFile) . "'\n";
|
|
|
- }
|
|
|
- file_put_contents($concatFile, $concatContent);
|
|
|
-
|
|
|
- // 合成音频文件
|
|
|
- $mergedAudioPath = $tempDir . '/tts.wav';
|
|
|
-
|
|
|
- // 使用 FFmpeg 合并音频,转换为统一的 WAV 格式
|
|
|
- $ffmpegCommand = sprintf(
|
|
|
- 'cd %s && ffmpeg -f concat -safe 0 -i %s -ar 44100 -ac 2 -y %s 2>&1',
|
|
|
- escapeshellarg($tempDir),
|
|
|
- escapeshellarg(basename($concatFile)),
|
|
|
- escapeshellarg(basename($mergedAudioPath))
|
|
|
- );
|
|
|
-
|
|
|
- exec($ffmpegCommand, $ffmpegOutput, $ffmpegReturnCode);
|
|
|
-
|
|
|
- if ($ffmpegReturnCode !== 0 || !file_exists($mergedAudioPath)) {
|
|
|
- $logData = [
|
|
|
- 'command' => $ffmpegCommand,
|
|
|
- 'output' => implode("\n", $ffmpegOutput),
|
|
|
- 'return_code' => $ffmpegReturnCode
|
|
|
- ];
|
|
|
- dLog('anime')->error('FFmpeg 合成音频失败', $logData);
|
|
|
- logDB('anime', 'error', 'FFmpeg 合成音频失败', $logData);
|
|
|
- $mergedAudioPath = null;
|
|
|
- } else {
|
|
|
- $logData = [
|
|
|
- 'audio_count' => count($audioFiles),
|
|
|
- 'output_file' => $mergedAudioPath,
|
|
|
- 'file_size' => filesize($mergedAudioPath)
|
|
|
- ];
|
|
|
- dLog('anime')->info('音频合成成功', $logData);
|
|
|
- logDB('anime', 'info', '音频合成成功', $logData);
|
|
|
- }
|
|
|
|
|
|
- // 清理临时音频文件和 concat 文件
|
|
|
- foreach ($audioFiles as $audioFile) {
|
|
|
- if (file_exists($audioFile)) {
|
|
|
- @unlink($audioFile);
|
|
|
+ // 如果有音频文件,则进行合成
|
|
|
+ if (!empty($audioFiles)) {
|
|
|
+ // 创建 FFmpeg concat 文件列表
|
|
|
+ $concatFile = $tempDir . '/concat.txt';
|
|
|
+ $concatContent = '';
|
|
|
+ foreach ($audioFiles as $audioFile) {
|
|
|
+ // 使用相对路径,避免路径中的特殊字符问题
|
|
|
+ $concatContent .= "file '" . basename($audioFile) . "'\n";
|
|
|
+ }
|
|
|
+ file_put_contents($concatFile, $concatContent);
|
|
|
+
|
|
|
+ // 合成音频文件
|
|
|
+ $mergedAudioPath = $tempDir . '/tts.wav';
|
|
|
+
|
|
|
+ // 使用 FFmpeg 合并音频,转换为统一的 WAV 格式
|
|
|
+ $ffmpegCommand = sprintf(
|
|
|
+ 'cd %s && ffmpeg -f concat -safe 0 -i %s -ar 44100 -ac 2 -y %s 2>&1',
|
|
|
+ escapeshellarg($tempDir),
|
|
|
+ escapeshellarg(basename($concatFile)),
|
|
|
+ escapeshellarg(basename($mergedAudioPath))
|
|
|
+ );
|
|
|
+
|
|
|
+ exec($ffmpegCommand, $ffmpegOutput, $ffmpegReturnCode);
|
|
|
+
|
|
|
+ if ($ffmpegReturnCode !== 0 || !file_exists($mergedAudioPath)) {
|
|
|
+ logDB('anime', 'error', 'FFmpeg 合成音频失败', [
|
|
|
+ 'command' => $ffmpegCommand,
|
|
|
+ 'output' => implode("\n", $ffmpegOutput),
|
|
|
+ 'return_code' => $ffmpegReturnCode
|
|
|
+ ]);
|
|
|
+ $mergedAudioPath = null;
|
|
|
+ } else {
|
|
|
+ logDB('anime', 'info', '音频合成成功', [
|
|
|
+ 'audio_count' => count($audioFiles),
|
|
|
+ 'output_file' => $mergedAudioPath,
|
|
|
+ 'file_size' => filesize($mergedAudioPath)
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清理临时音频文件和 concat 文件
|
|
|
+ foreach ($audioFiles as $audioFile) {
|
|
|
+ if (file_exists($audioFile)) {
|
|
|
+ @unlink($audioFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (file_exists($concatFile)) {
|
|
|
+ @unlink($concatFile);
|
|
|
}
|
|
|
}
|
|
|
- if (file_exists($concatFile)) {
|
|
|
- @unlink($concatFile);
|
|
|
- }
|
|
|
+ } else {
|
|
|
+ logDB('anime', 'warning', 'FFmpeg 未安装,跳过音频合成', []);
|
|
|
}
|
|
|
- } else {
|
|
|
- dLog('anime')->warning('FFmpeg 未安装,跳过音频合成');
|
|
|
- logDB('anime', 'warning', 'FFmpeg 未安装,跳过音频合成', []);
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ logDB('anime', 'error', '音频合成过程异常', [
|
|
|
+ 'error' => $e->getMessage(),
|
|
|
+ 'trace' => $e->getTraceAsString()
|
|
|
+ ]);
|
|
|
+ // 音频合成失败不影响图片导出
|
|
|
+ $mergedAudioPath = null;
|
|
|
}
|
|
|
- } catch (\Exception $e) {
|
|
|
- $logData = [
|
|
|
- 'error' => $e->getMessage(),
|
|
|
- 'trace' => $e->getTraceAsString()
|
|
|
- ];
|
|
|
- dLog('anime')->error('音频合成过程异常', $logData);
|
|
|
- logDB('anime', 'error', '音频合成过程异常', $logData);
|
|
|
- // 音频合成失败不影响图片导出
|
|
|
- $mergedAudioPath = null;
|
|
|
}
|
|
|
|
|
|
- // 创建zip文件
|
|
|
- $zipFileName = sprintf(
|
|
|
- '%s.zip',
|
|
|
- $episode->title ?: '未命名'
|
|
|
- );
|
|
|
+ // 创建zip文件(使用安全的文件名)
|
|
|
+ $safeTitle = preg_replace('/[^\p{L}\p{N}\s\-_]/u', '', $episode->title ?: '未命名');
|
|
|
+ $safeTitle = trim($safeTitle) ?: '未命名';
|
|
|
+ $zipFileName = sprintf('%s_%s.zip', $safeTitle, time());
|
|
|
$zipFilePath = storage_path('app/temp/' . $zipFileName);
|
|
|
|
|
|
+ // 确保 temp 目录存在
|
|
|
+ $tempZipDir = storage_path('app/temp');
|
|
|
+ if (!file_exists($tempZipDir)) {
|
|
|
+ mkdir($tempZipDir, 0755, true);
|
|
|
+ }
|
|
|
+
|
|
|
$zip = new \ZipArchive();
|
|
|
- if ($zip->open($zipFilePath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
|
|
|
+ $openResult = $zip->open($zipFilePath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
|
|
+
|
|
|
+ if ($openResult !== true) {
|
|
|
// 清理临时文件
|
|
|
array_map('unlink', $downloadedFiles);
|
|
|
+ if ($mergedAudioPath && file_exists($mergedAudioPath)) {
|
|
|
+ @unlink($mergedAudioPath);
|
|
|
+ }
|
|
|
rmdir($tempDir);
|
|
|
+
|
|
|
+ logDB('anime', 'error', '创建ZIP文件失败', [
|
|
|
+ 'zip_path' => $zipFilePath,
|
|
|
+ 'open_result' => $openResult
|
|
|
+ ]);
|
|
|
+
|
|
|
Utils::throwError('20003:创建ZIP文件失败');
|
|
|
}
|
|
|
|
|
|
- // 添加图片文件到zip
|
|
|
+ // 添加文件到zip(使用完整路径确保文件正确添加)
|
|
|
foreach ($downloadedFiles as $file) {
|
|
|
- $zip->addFile($file, basename($file));
|
|
|
+ if (file_exists($file)) {
|
|
|
+ $zip->addFile($file, basename($file));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- // 添加合成的音频文件到zip
|
|
|
- if ($mergedAudioPath && file_exists($mergedAudioPath)) {
|
|
|
+ // 添加合成的音频文件到zip(仅普通模式)
|
|
|
+ if (!$isAceMode && $mergedAudioPath && file_exists($mergedAudioPath)) {
|
|
|
$zip->addFile($mergedAudioPath, 'tts.wav');
|
|
|
}
|
|
|
|
|
|
+ // 关闭 ZIP 文件
|
|
|
$zip->close();
|
|
|
|
|
|
- // 清理临时图片文件
|
|
|
+ // 验证 ZIP 文件是否创建成功
|
|
|
+ if (!file_exists($zipFilePath) || filesize($zipFilePath) == 0) {
|
|
|
+ // 清理临时文件
|
|
|
+ array_map('unlink', $downloadedFiles);
|
|
|
+ if ($mergedAudioPath && file_exists($mergedAudioPath)) {
|
|
|
+ @unlink($mergedAudioPath);
|
|
|
+ }
|
|
|
+ rmdir($tempDir);
|
|
|
+
|
|
|
+ logDB('anime', 'error', 'ZIP文件创建后无效', ['zip_path' => $zipFilePath]);
|
|
|
+
|
|
|
+ Utils::throwError('20003:ZIP文件创建失败或文件为空');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清理临时文件
|
|
|
array_map('unlink', $downloadedFiles);
|
|
|
|
|
|
// 清理合成的音频文件
|
|
|
@@ -1672,17 +1753,20 @@ class AnimeController extends BaseController
|
|
|
|
|
|
rmdir($tempDir);
|
|
|
|
|
|
+ // 清空所有输出缓冲区,避免污染ZIP文件
|
|
|
+ while (ob_get_level() > 0) {
|
|
|
+ ob_end_clean();
|
|
|
+ }
|
|
|
+
|
|
|
// 返回文件下载响应
|
|
|
return response()->download($zipFilePath, $zipFileName)->deleteFileAfterSend(true);
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
- $logData = [
|
|
|
+ logDB('anime', 'error', '导出分集图片失败', [
|
|
|
'anime_id' => $animeId,
|
|
|
'episode_id' => $episodeId,
|
|
|
'error' => $e->getMessage()
|
|
|
- ];
|
|
|
- dLog('anime')->error('导出分集图片失败', $logData);
|
|
|
- logDB('anime', 'error', '导出分集图片失败', $logData);
|
|
|
+ ]);
|
|
|
|
|
|
// 清理可能存在的临时文件
|
|
|
if (isset($tempDir) && file_exists($tempDir)) {
|
|
|
@@ -2744,12 +2828,6 @@ class AnimeController extends BaseController
|
|
|
if (isset($videoParams['tail_frame_url'])) {
|
|
|
$parameters['last_frame_url'] = $videoParams['tail_frame_url'];
|
|
|
}
|
|
|
- } else {
|
|
|
- // 没有图片时,记录错误日志
|
|
|
- logDB('anime', 'error', '智帧20模型缺少首帧图片', [
|
|
|
- 'act_id' => $act->id,
|
|
|
- 'model' => $model
|
|
|
- ]);
|
|
|
}
|
|
|
|
|
|
if ($reference_images) {
|
|
|
@@ -2790,7 +2868,7 @@ class AnimeController extends BaseController
|
|
|
|
|
|
// 更新分镜表的视频任务信息
|
|
|
DB::table('mp_episode_segments')
|
|
|
- ->where('act_id', $act->id)
|
|
|
+ ->where('id', $act->id)
|
|
|
->update([
|
|
|
'video_task_id' => $task->id,
|
|
|
'video_task_status' => '生成中',
|
|
|
@@ -3003,7 +3081,7 @@ class AnimeController extends BaseController
|
|
|
}
|
|
|
|
|
|
$updateResult = DB::table('mp_episode_segments')
|
|
|
- ->where('act_id', $actId)
|
|
|
+ ->where('id', $actId)
|
|
|
->update($actUpdateData);
|
|
|
|
|
|
if ($updateResult) {
|
|
|
@@ -3055,7 +3133,7 @@ class AnimeController extends BaseController
|
|
|
foreach ($actTasks as $actTask) {
|
|
|
if ($actTask['task_id'] == $taskId) {
|
|
|
DB::table('mp_episode_segments')
|
|
|
- ->where('act_id', $actTask['act_id'])
|
|
|
+ ->where('id', $actTask['act_id'])
|
|
|
->update([
|
|
|
'video_task_status' => '失败',
|
|
|
'updated_at' => date('Y-m-d H:i:s')
|