|
|
@@ -2870,6 +2870,429 @@ function handleEpisodeContent($originalContent) {
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
+function handleEpisodeContentForAce($originalContent) {
|
|
|
+ if (!$originalContent) return [];
|
|
|
+
|
|
|
+ // 解析剧集内容
|
|
|
+ $result = [
|
|
|
+ 'episode_title' => '',
|
|
|
+ 'intro' => '',
|
|
|
+ 'art_style' => '',
|
|
|
+ 'roles' => [],
|
|
|
+ 'scenes' => [],
|
|
|
+ 'acts' => []
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 提取剧集标题 - 匹配"第xx集:标题"或"第xx集 标题"格式,排除###标记
|
|
|
+ if (preg_match('/第(\d+)集[::\s]+([^#\n]+?)(?=\s*###|\s*$|\n)/u', $originalContent, $titleMatch)) {
|
|
|
+ $result['episode_title'] = '第' . $titleMatch[1] . '集:' . trim($titleMatch[2]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取故事梗概 - 兼容多种格式:###故事梗概、### 故事梗概、### 故事梗概
|
|
|
+ if (preg_match('/###\s*故事梗概\s*\n(.*?)(?=\n\s*###[^#]|\z)/s', $originalContent, $summaryMatch)) {
|
|
|
+ $result['intro'] = trim($summaryMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取美术风格 - 兼容多种格式
|
|
|
+ if (preg_match('/###\s*美术风格\s*\n(.*?)(?=\n\s*###[^#]|\z)/s', $originalContent, $styleMatch)) {
|
|
|
+ $result['art_style'] = trim($styleMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取主体列表 - 兼容多种格式
|
|
|
+ if (preg_match('/###\s*主体列表\s*\n(.*?)(?=\n\s*###[^#]|\z)/s', $originalContent, $charactersMatch)) {
|
|
|
+ $charactersText = trim($charactersMatch[1]);
|
|
|
+ $characterLines = explode("\n", $charactersText);
|
|
|
+
|
|
|
+ foreach ($characterLines as $line) {
|
|
|
+ $line = trim($line);
|
|
|
+ if (empty($line)) continue;
|
|
|
+
|
|
|
+ // 兼容中文冒号:和英文冒号:,同时提取音色信息
|
|
|
+ if (preg_match('/^([^::]+)[::](.+)$/u', $line, $charMatch)) {
|
|
|
+ $role = trim($charMatch[1]);
|
|
|
+ $description = trim($charMatch[2]);
|
|
|
+ $timbreName = null;
|
|
|
+
|
|
|
+ // 检查描述末尾是否有{主体图片提示词}{{音色名}}格式
|
|
|
+ $picPrompt = null;
|
|
|
+ $timbrePrompt = null;
|
|
|
+
|
|
|
+ // 修复正则:使用更精确的匹配,支持花括号嵌套
|
|
|
+ // 格式1: 描述{pic_prompt} {{voice_prompt}}
|
|
|
+ if (preg_match('/^(.*?)\{(.+?)\}\s*\{\{(.+?)\}\}\s*$/u', $description, $fullMatch)) {
|
|
|
+ // 匹配格式:主体描述{主体图片提示词}{{音色名}}
|
|
|
+ $description = trim($fullMatch[1]);
|
|
|
+ $picPrompt = trim($fullMatch[2]);
|
|
|
+ $timbrePrompt = trim($fullMatch[3]);
|
|
|
+ }
|
|
|
+ // 格式2: 描述{{voice_prompt}}(兼容旧格式,只有音色)
|
|
|
+ elseif (preg_match('/^(.*?)\{\{(.+?)\}\}\s*$/u', $description, $timbreMatch)) {
|
|
|
+ // 兼容旧格式:主体描述{{音色名}}
|
|
|
+ $description = trim($timbreMatch[1]);
|
|
|
+ $timbrePrompt = trim($timbreMatch[2]);
|
|
|
+ }
|
|
|
+ // 格式3: 描述{pic_prompt}(只有图片提示词)
|
|
|
+ elseif (preg_match('/^(.*?)\{(.+?)\}\s*$/u', $description, $picMatch)) {
|
|
|
+ $description = trim($picMatch[1]);
|
|
|
+ $picPrompt = trim($picMatch[2]);
|
|
|
+ }
|
|
|
+
|
|
|
+ $roleData = [
|
|
|
+ 'role' => $role,
|
|
|
+ 'description' => $description
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 如果有主体图片提示词,添加到数组中
|
|
|
+ if ($picPrompt) {
|
|
|
+ // 检查是否包含"姿态:"或"姿态:"
|
|
|
+ if (preg_match('/姿态[::]/u', $picPrompt)) {
|
|
|
+ // 如果有姿态描述,统一替换为"姿态:站立"
|
|
|
+ $picPrompt = preg_replace('/姿态[::][^.。\n]+/u', '姿态:站立', $picPrompt);
|
|
|
+ } else {
|
|
|
+ // 如果没有姿态描述,在末尾添加"姿态:站立"
|
|
|
+ $picPrompt = rtrim($picPrompt, '。,, ') . '。姿态:站立。';
|
|
|
+ }
|
|
|
+
|
|
|
+ $roleData['pic_prompt'] = $picPrompt;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($timbrePrompt) $roleData['voice_prompt'] = $timbrePrompt;
|
|
|
+
|
|
|
+ $result['roles'][] = $roleData;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // // 加入旁白角色(如果不存在)
|
|
|
+ // $hasNarrator = false;
|
|
|
+ // foreach ($result['roles'] as $role) {
|
|
|
+ // if (isset($role['role']) && $role['role'] === '旁白') {
|
|
|
+ // $hasNarrator = true;
|
|
|
+ // break;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ // if (!$hasNarrator) {
|
|
|
+ // $result['roles'][] = [
|
|
|
+ // 'role' => '旁白',
|
|
|
+ // 'description' => '负责叙述剧情、补充说明和情感渲染的非视觉角色。',
|
|
|
+ // 'pic_prompt' => '',
|
|
|
+ // 'voice_name' => '旁白',
|
|
|
+ // 'voice_type' => 'zh_male_linjiananhai_moon_bigtts',
|
|
|
+ // 'voice_audio_url' => 'https://zw-audiobook.tos-cn-beijing.volces.com/demonstrate/zh_male_linjiananhai_moon_bigtts.wav'
|
|
|
+ // ];
|
|
|
+ // }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取场景列表 - 兼容多种格式
|
|
|
+ if (preg_match('/###\s*场景列表\s*\n(.*?)(?=\n\s*###[^#]|\z)/s', $originalContent, $scenesMatch)) {
|
|
|
+ $scenesText = trim($scenesMatch[1]);
|
|
|
+ $sceneLines = explode("\n", $scenesText);
|
|
|
+
|
|
|
+ foreach ($sceneLines as $line) {
|
|
|
+ $line = trim($line);
|
|
|
+ if (empty($line)) continue;
|
|
|
+
|
|
|
+ // 兼容中文冒号:和英文冒号:
|
|
|
+ if (preg_match('/^([^::]+)[::](.+)$/u', $line, $sceneMatch)) {
|
|
|
+ $scene = trim($sceneMatch[1]);
|
|
|
+ $description = trim($sceneMatch[2]);
|
|
|
+ $picPrompt = null;
|
|
|
+
|
|
|
+ // 检查描述末尾是否有{场景图片提示词}格式
|
|
|
+ if (preg_match('/^(.*?)\{([^}]+)\}\s*$/u', $description, $promptMatch)) {
|
|
|
+ // 匹配格式:场景描述{场景图片提示词}
|
|
|
+ $description = trim($promptMatch[1]);
|
|
|
+ $picPrompt = trim($promptMatch[2]);
|
|
|
+ }
|
|
|
+
|
|
|
+ $sceneData = [
|
|
|
+ 'scene' => $scene,
|
|
|
+ 'description' => $description
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 如果有场景图片提示词,添加到数组中
|
|
|
+ if ($picPrompt) {
|
|
|
+ $sceneData['pic_prompt'] = $picPrompt;
|
|
|
+ }
|
|
|
+
|
|
|
+ $result['scenes'][] = $sceneData;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取分镜剧本 - 兼容多种格式(旧格式:###分镜剧本,新格式:###分段剧本)
|
|
|
+ $storyboardPattern = '/###\s*(?:分镜剧本|分段剧本)\s*\n(.*?)(?=\n\s*###[^#]|\z)/s';
|
|
|
+ if (preg_match($storyboardPattern, $originalContent, $storyboardMatch)) {
|
|
|
+ $storyboardText = trim($storyboardMatch[1]);
|
|
|
+
|
|
|
+ // 提取旁白音色(新格式独有)
|
|
|
+ $narratorVoice = '';
|
|
|
+ if (preg_match('/旁白音色[::]\s*([^\n]+)/u', $storyboardText, $narratorMatch)) {
|
|
|
+ $narratorVoice = trim($narratorMatch[1]);
|
|
|
+
|
|
|
+ // 将旁白加入到roles数组
|
|
|
+ $hasNarrator = false;
|
|
|
+ foreach ($result['roles'] as $role) {
|
|
|
+ if (isset($role['role']) && $role['role'] === '旁白') {
|
|
|
+ $hasNarrator = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$hasNarrator) {
|
|
|
+ $result['roles'][] = [
|
|
|
+ 'role' => '旁白',
|
|
|
+ 'description' => '负责叙述剧情、补充说明和情感渲染的非视觉角色。',
|
|
|
+ 'pic_prompt' => '',
|
|
|
+ 'voice_prompt' => $narratorVoice
|
|
|
+ ];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按幕/片段分割 - 兼容"第X幕"和"片段X"两种格式
|
|
|
+ $acts = [];
|
|
|
+
|
|
|
+ // 先在开头添加换行符,确保第1幕/片段1也能被正确分割
|
|
|
+ $normalizedText = "\n" . $storyboardText;
|
|
|
+ $parts = preg_split('/\n\s*##/', $normalizedText);
|
|
|
+
|
|
|
+ foreach ($parts as $part) {
|
|
|
+ $part = trim($part);
|
|
|
+ if (empty($part)) continue;
|
|
|
+
|
|
|
+ // 兼容"第X幕"和"片段X"两种格式
|
|
|
+ if (!preg_match('/^(?:第\d+幕|片段\d+)/', $part)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分离标题和内容
|
|
|
+ $lines = explode("\n", $part, 2);
|
|
|
+ $actTitle = trim($lines[0]);
|
|
|
+ $actContent = isset($lines[1]) ? trim($lines[1]) : '';
|
|
|
+
|
|
|
+ // 解析标题,提取序号和详细信息
|
|
|
+ if (preg_match('/^第(\d+)幕[::]?\s*(.*)$/u', $actTitle, $actTitleMatch)) {
|
|
|
+ // 旧格式:第X幕
|
|
|
+ $actNumber = intval($actTitleMatch[1]);
|
|
|
+ $actDetails = trim($actTitleMatch[2]);
|
|
|
+ if (empty($actDetails) || $actDetails === ':' || $actDetails === ':') {
|
|
|
+ $actDetails = $actTitle;
|
|
|
+ }
|
|
|
+ } elseif (preg_match('/^片段(\d+)\s*$/u', $actTitle, $segmentTitleMatch)) {
|
|
|
+ // 新格式:片段X
|
|
|
+ $actNumber = intval($segmentTitleMatch[1]);
|
|
|
+ $actDetails = $actTitle;
|
|
|
+ } else {
|
|
|
+ $actNumber = count($acts) + 1;
|
|
|
+ $actDetails = $actTitle;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取时长(新格式独有,仅保留数字)
|
|
|
+ $actDuration = '';
|
|
|
+ if (preg_match('/时长[::]\s*([^\n]+)/u', $actContent, $actDurationMatch)) {
|
|
|
+ $actDurationStr = trim($actDurationMatch[1]);
|
|
|
+ // 提取数字部分(支持整数和小数)
|
|
|
+ if (preg_match('/([-+]?[0-9]*\.?[0-9]+)/', $actDurationStr, $numMatch)) {
|
|
|
+ $actDuration = $numMatch[1];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析该幕/片段下的分镜
|
|
|
+ $segments = [];
|
|
|
+ $segmentPattern = '/分镜(\d+)\s*\n(.*?)(?=\n+\s*分镜\d+|\z)/s';
|
|
|
+ preg_match_all($segmentPattern, $actContent, $segmentMatches, PREG_SET_ORDER);
|
|
|
+
|
|
|
+ foreach ($segmentMatches as $segmentMatch) {
|
|
|
+ $segmentNumber = intval($segmentMatch[1]);
|
|
|
+ $segmentContent = trim($segmentMatch[2]);
|
|
|
+
|
|
|
+ // 解析分镜详细信息
|
|
|
+ $segmentData = [
|
|
|
+ 'segment_id' => date('YmdHis') . mt_rand(1000, 9999) . str_pad($segmentNumber, 3, "0", STR_PAD_LEFT),
|
|
|
+ 'segment_number' => $segmentNumber,
|
|
|
+ 'segment_content' => $segmentContent,
|
|
|
+ 'description' => '',
|
|
|
+ 'composition' => '',
|
|
|
+ 'camera_movement' => '',
|
|
|
+ 'voice_actor' => '',
|
|
|
+ 'dialogue' => '',
|
|
|
+ 'frame_type' => '',
|
|
|
+ 'scene' => '',
|
|
|
+ 'characters' => '',
|
|
|
+ 'tail_frame' => '',
|
|
|
+ 'emotion' => '中性',
|
|
|
+ 'gender' => '0',
|
|
|
+ 'speed_ratio' => 0,
|
|
|
+ 'loudness_ratio' => 0,
|
|
|
+ 'emotion_scale' => 4,
|
|
|
+ 'pitch' => 0,
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 提取场景
|
|
|
+ if (preg_match('/(?:场景|拍摄场景|背景场景|环境)[::]\s*([^\n]+)/u', $segmentContent, $sceneMatch)) {
|
|
|
+ $segmentData['scene'] = trim($sceneMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取画面描述 - 兼容新格式的方括号标注
|
|
|
+ if (preg_match('/(?:画面|画面描述|镜头描述|场景描述)[::]\s*(\[.*?\])?\s*([^\n]+)/u', $segmentContent, $descMatch)) {
|
|
|
+ $frameTypeInDesc = isset($descMatch[1]) ? trim($descMatch[1], '[]') : '';
|
|
|
+ $description = trim($descMatch[2]);
|
|
|
+
|
|
|
+ if (!empty($frameTypeInDesc)) {
|
|
|
+ $segmentData['frame_type'] = $frameTypeInDesc;
|
|
|
+ }
|
|
|
+ $segmentData['description'] = $description;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取运镜
|
|
|
+ if (preg_match('/(?:运镜|运镜调度|镜头运动|摄影机运动)[::]\s*([^\n]+)/u', $segmentContent, $cameraMatch)) {
|
|
|
+ $segmentData['camera_movement'] = trim($cameraMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取配音台词 - 兼容新格式"中文配音:[角色] 台词"
|
|
|
+ // 修复:排除背景音效等非台词内容
|
|
|
+ if (preg_match('/配音台词[::]\s*(?:中文配音[::]?)?\s*(?:\[([^\]]+)\])?\s*([^\n]*?)(?=\n|$)/u', $segmentContent, $dialogueMatch)) {
|
|
|
+ $voiceActor = isset($dialogueMatch[1]) ? trim($dialogueMatch[1]) : '';
|
|
|
+ $dialogue = isset($dialogueMatch[2]) ? trim($dialogueMatch[2]) : '';
|
|
|
+
|
|
|
+ // 排除非台词内容(如果匹配到的是空或者是其他字段标记)
|
|
|
+ if (!empty($dialogue) && preg_match('/^(?:背景音效|音效|场景|画面|运镜|构图)[::]/u', $dialogue)) {
|
|
|
+ $dialogue = ''; // 如果匹配到的是其他字段,清空
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!empty($voiceActor)) {
|
|
|
+ $segmentData['voice_actor'] = $voiceActor;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($dialogue && $dialogue !== '无') {
|
|
|
+ // 确保台词使用中文左右双引号
|
|
|
+ $dialogue = preg_replace('/^[""]/u', '"', $dialogue);
|
|
|
+ $dialogue = preg_replace('/[""]$/u', '"', $dialogue);
|
|
|
+ if (!preg_match('/^["]/', $dialogue)) {
|
|
|
+ $dialogue = '"' . $dialogue;
|
|
|
+ }
|
|
|
+ if (!preg_match('/["]$/', $dialogue)) {
|
|
|
+ $dialogue .= '"';
|
|
|
+ }
|
|
|
+ $segmentData['dialogue'] = $dialogue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 兼容旧格式的台词字段
|
|
|
+ // 修复:排除背景音效等非台词内容
|
|
|
+ if (empty($segmentData['dialogue']) && preg_match('/(?:台词内容|台词|对白|对话)[::]\s*([^\n]*?)(?=\n|$)/u', $segmentContent, $oldDialogueMatch)) {
|
|
|
+ $dialogue = trim($oldDialogueMatch[1]);
|
|
|
+
|
|
|
+ // 排除非台词内容
|
|
|
+ if (!empty($dialogue) && preg_match('/^(?:背景音效|音效|场景|画面|运镜|构图)[::]/u', $dialogue)) {
|
|
|
+ $dialogue = ''; // 如果匹配到的是其他字段,清空
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($dialogue && $dialogue !== '无') {
|
|
|
+ $dialogue = preg_replace('/^[""]/u', '"', $dialogue);
|
|
|
+ $dialogue = preg_replace('/[""]$/u', '"', $dialogue);
|
|
|
+ if (!preg_match('/^["]/', $dialogue)) {
|
|
|
+ $dialogue = '"' . $dialogue;
|
|
|
+ }
|
|
|
+ if (!preg_match('/["]$/', $dialogue)) {
|
|
|
+ $dialogue .= '"';
|
|
|
+ }
|
|
|
+ $segmentData['dialogue'] = $dialogue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 兼容旧格式的配音角色字段
|
|
|
+ if (empty($segmentData['voice_actor']) && preg_match('/(?:配音角色|配音|角色|声优)[::]\s*([^\n]+)/u', $segmentContent, $voiceMatch)) {
|
|
|
+ $segmentData['voice_actor'] = trim($voiceMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取构图
|
|
|
+ if (preg_match('/(?:构图设计|构图|镜头构图)[::]\s*([^\n]+)/u', $segmentContent, $compMatch)) {
|
|
|
+ $segmentData['composition'] = trim($compMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取画面类型
|
|
|
+ if (empty($segmentData['frame_type']) && preg_match('/(?:画面类型|镜头类型|类型)[::]\s*([^\n]+)/u', $segmentContent, $frameMatch)) {
|
|
|
+ $segmentData['frame_type'] = trim($frameMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取出镜角色
|
|
|
+ if (preg_match('/(?:出镜角色|角色出镜|登场角色|人物)[::]\s*([^\n]+)/u', $segmentContent, $charactersMatch)) {
|
|
|
+ $segmentData['characters'] = trim($charactersMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取尾帧描述
|
|
|
+ if (preg_match('/(?:尾帧描述|尾帧|结束帧|最后一帧|结尾画面|结束画面)[::]\s*([^\n]+)/u', $segmentContent, $tailFrameMatch)) {
|
|
|
+ $segmentData['tail_frame'] = trim($tailFrameMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ $replaceEmptyArr = [];
|
|
|
+
|
|
|
+ // 提取情感
|
|
|
+ if (preg_match('/(?:情感|情绪|感情)[::]\s*([^\n]+)/u', $segmentContent, $emotionMatch)) {
|
|
|
+ $replaceEmptyArr[] = trim($emotionMatch[0]);
|
|
|
+ $segmentData['emotion'] = trim($emotionMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取性别
|
|
|
+ if (preg_match('/(?:性别)[::]\s*([^\n]+)/u', $segmentContent, $genderMatch)) {
|
|
|
+ $replaceEmptyArr[] = trim($genderMatch[0]);
|
|
|
+ $genderStr = trim($genderMatch[1]);
|
|
|
+ if (strpos($genderStr, '男') !== false || $genderStr === '1') {
|
|
|
+ $segmentData['gender'] = '1';
|
|
|
+ } elseif (strpos($genderStr, '女') !== false || $genderStr === '2') {
|
|
|
+ $segmentData['gender'] = '2';
|
|
|
+ } else {
|
|
|
+ $segmentData['gender'] = '0';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取语速
|
|
|
+ if (preg_match('/(?:语速|说话速度)[::]\s*([-+]?[0-9]*\.?[0-9]+)/u', $segmentContent, $speedMatch)) {
|
|
|
+ $replaceEmptyArr[] = trim($speedMatch[0]);
|
|
|
+ $segmentData['speed_ratio'] = (float)trim($speedMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取音量
|
|
|
+ if (preg_match('/(?:音量|声音大小)[::]\s*([-+]?[0-9]*\.?[0-9]+)/u', $segmentContent, $loudnessMatch)) {
|
|
|
+ $replaceEmptyArr[] = trim($loudnessMatch[0]);
|
|
|
+ $segmentData['loudness_ratio'] = (float)trim($loudnessMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取情感强度
|
|
|
+ if (preg_match('/(?:情感强度|情绪强度)[::]\s*([0-9]+)/u', $segmentContent, $scaleMatch)) {
|
|
|
+ $replaceEmptyArr[] = trim($scaleMatch[0]);
|
|
|
+ $segmentData['emotion_scale'] = (int)trim($scaleMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取音调
|
|
|
+ if (preg_match('/(?:音调|音高)[::]\s*([-+]?[0-9]+)/u', $segmentContent, $pitchMatch)) {
|
|
|
+ $replaceEmptyArr[] = trim($pitchMatch[0]);
|
|
|
+ $segmentData['pitch'] = (int)trim($pitchMatch[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ $segmentData['segment_content'] = str_replace($replaceEmptyArr, '', $segmentContent);
|
|
|
+ $segmentData['segment_content'] = preg_replace('/\n{2,}/', "\n", $segmentData['segment_content']);
|
|
|
+ $segmentData['segment_content'] = trim($segmentData['segment_content']);
|
|
|
+
|
|
|
+ $segments[] = $segmentData;
|
|
|
+ }
|
|
|
+
|
|
|
+ $acts[] = [
|
|
|
+ 'act_number' => $actNumber,
|
|
|
+ 'act_title' => $actTitle,
|
|
|
+ 'act_details' => $actDetails,
|
|
|
+ 'act_duration' => $actDuration,
|
|
|
+ 'segments' => $segments
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ $result['acts'] = $acts;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
/**
|
|
|
* 远程图片压缩(尽可能保持原图 fidelity,压缩到不超过 maxBytes 字节)
|