|
@@ -448,53 +448,19 @@ class AnimeService
|
|
|
Utils::throwError("20003:" . $e->getMessage());
|
|
Utils::throwError("20003:" . $e->getMessage());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $start_count = 0;
|
|
|
|
|
- $img_url = '';
|
|
|
|
|
- while ($start_count <= 30) {
|
|
|
|
|
- sleep(3);
|
|
|
|
|
-
|
|
|
|
|
- $task = MpGeneratePicTask::where('id', $task_id)->first();
|
|
|
|
|
- $statusInfo = $this->aiImageGenerationService->queryTaskStatus($task);
|
|
|
|
|
-
|
|
|
|
|
- if ($statusInfo['status'] === 'success') {
|
|
|
|
|
- $task->updateStatus('success', [
|
|
|
|
|
- 'result_url' => $statusInfo['result_url'],
|
|
|
|
|
- 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
|
|
- ]);
|
|
|
|
|
-
|
|
|
|
|
- // 同步调整分镜图片状态和结果
|
|
|
|
|
- if (getProp($task, 'alias_segment_id')) {
|
|
|
|
|
- DB::table('mp_episode_segments')->where('segment_id', getProp($task, 'alias_segment_id'))->update([
|
|
|
|
|
- 'img_url' => $statusInfo['result_url'][0],
|
|
|
|
|
- 'pic_task_status' => '已完成',
|
|
|
|
|
- ]);
|
|
|
|
|
- }
|
|
|
|
|
- $img_url = $statusInfo['result_url'][0];
|
|
|
|
|
- break;
|
|
|
|
|
- } elseif ($statusInfo['status'] === 'failed') {
|
|
|
|
|
- $task->updateStatus('failed', [
|
|
|
|
|
- 'error_message' => $statusInfo['error_message'],
|
|
|
|
|
- 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
|
|
- ]);
|
|
|
|
|
-
|
|
|
|
|
- if (getProp($task, 'alias_segment_id')) {
|
|
|
|
|
- DB::table('mp_episode_segments')->where('segment_id', getProp($task, 'alias_segment_id'))->update([
|
|
|
|
|
- 'pic_task_status' => '失败',
|
|
|
|
|
- ]);
|
|
|
|
|
- }
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
- $start_count+=3;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ $img_url = $this->loopGetPicTaskResult($task_id);
|
|
|
|
|
|
|
|
if (!$img_url) Utils::throwError('20003:图片生成中,请稍后刷新');
|
|
if (!$img_url) Utils::throwError('20003:图片生成中,请稍后刷新');
|
|
|
return $img_url;
|
|
return $img_url;
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public function batchSetSegmentTasks($data) {
|
|
public function batchSetSegmentTasks($data) {
|
|
|
$anime_id = getProp($data, 'anime_id');
|
|
$anime_id = getProp($data, 'anime_id');
|
|
|
$episode_number = getProp($data, 'episode_number');
|
|
$episode_number = getProp($data, 'episode_number');
|
|
|
|
|
+ $ratio = getProp($data, 'ratio');
|
|
|
|
|
+ if (!in_array($ratio, ['1:1', '4:3', '3:2', '16:9', '21:9'])) {
|
|
|
|
|
+ Utils::throwError('1002:画面比例选择不正确,只支持1:1、4:3、3:2、16:9、21:9');
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (!$anime_id || !$episode_number) {
|
|
if (!$anime_id || !$episode_number) {
|
|
|
Utils::throwError('1002:请选择剧集');
|
|
Utils::throwError('1002:请选择剧集');
|
|
@@ -512,6 +478,33 @@ class AnimeService
|
|
|
Utils::throwError('20003:该剧集不存在');
|
|
Utils::throwError('20003:该剧集不存在');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 根据画面比例给宽高赋值
|
|
|
|
|
+ switch ($ratio) {
|
|
|
|
|
+ case '1:1':
|
|
|
|
|
+ $width = 2048;
|
|
|
|
|
+ $height = 2048;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '4:3':
|
|
|
|
|
+ $width = 2304;
|
|
|
|
|
+ $height = 1728;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '3:2':
|
|
|
|
|
+ $width = 2496;
|
|
|
|
|
+ $height = 1664;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '16:9':
|
|
|
|
|
+ $width = 2560;
|
|
|
|
|
+ $height = 1440;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '21:9':
|
|
|
|
|
+ $width = 3024;
|
|
|
|
|
+ $height = 1296;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ $width = 2048;
|
|
|
|
|
+ $height = 2048;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 获取动漫的角色信息(包含参考图)
|
|
// 获取动漫的角色信息(包含参考图)
|
|
|
$anime = DB::table('mp_animes')
|
|
$anime = DB::table('mp_animes')
|
|
|
->where('id', $anime_id)
|
|
->where('id', $anime_id)
|
|
@@ -626,7 +619,9 @@ class AnimeService
|
|
|
$params = [
|
|
$params = [
|
|
|
'alias_segment_id' => $segment_id,
|
|
'alias_segment_id' => $segment_id,
|
|
|
'prompt' => $prompt,
|
|
'prompt' => $prompt,
|
|
|
- 'ref_img_urls' => $ref_img_urls
|
|
|
|
|
|
|
+ 'ref_img_urls' => $ref_img_urls,
|
|
|
|
|
+ 'width' => $width,
|
|
|
|
|
+ 'height' => $height,
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
// $task_id = mt_rand(100000, 999999);
|
|
// $task_id = mt_rand(100000, 999999);
|
|
@@ -652,7 +647,7 @@ class AnimeService
|
|
|
]);
|
|
]);
|
|
|
|
|
|
|
|
// 如果是第一集的首帧图片,则存入待更新数组
|
|
// 如果是第一集的首帧图片,则存入待更新数组
|
|
|
- if ((int)getProp($segment, 'episode_number') === 1 && (int)getProp($segment, 'segment_number') === 1) {
|
|
|
|
|
|
|
+ if ($update_result && (int)getProp($segment, 'episode_number') === 1 && (int)getProp($segment, 'segment_number') === 1) {
|
|
|
Redis::sadd('anime_first_frame_urls', $segment_id);
|
|
Redis::sadd('anime_first_frame_urls', $segment_id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -699,6 +694,230 @@ class AnimeService
|
|
|
];
|
|
];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ public function reGenerateSegment($data) {
|
|
|
|
|
+ $segment_id = getProp($data, 'segment_id');
|
|
|
|
|
+ $segment = DB::table('mp_episode_segments')->where('segment_id', $segment_id)->first();
|
|
|
|
|
+ $anime_id = getProp($segment, 'anime_id');
|
|
|
|
|
+ $episode_number = getProp($segment, 'episode_number');
|
|
|
|
|
+ $segment_content = getProp($data, 'segment_content');
|
|
|
|
|
+ $ratio = getProp($data, 'ratio');
|
|
|
|
|
+ if (!in_array($ratio, ['1:1', '4:3', '3:2', '16:9', '21:9'])) {
|
|
|
|
|
+ Utils::throwError('1002:画面比例选择不正确,只支持1:1、4:3、3:2、16:9、21:9');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!$anime_id || !$episode_number) {
|
|
|
|
|
+ Utils::throwError('1002:请选择分镜');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 根据画面比例给宽高赋值
|
|
|
|
|
+ switch ($ratio) {
|
|
|
|
|
+ case '1:1':
|
|
|
|
|
+ $width = 2048;
|
|
|
|
|
+ $height = 2048;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '4:3':
|
|
|
|
|
+ $width = 2304;
|
|
|
|
|
+ $height = 1728;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '3:2':
|
|
|
|
|
+ $width = 2496;
|
|
|
|
|
+ $height = 1664;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '16:9':
|
|
|
|
|
+ $width = 2560;
|
|
|
|
|
+ $height = 1440;
|
|
|
|
|
+ break;
|
|
|
|
|
+ case '21:9':
|
|
|
|
|
+ $width = 3024;
|
|
|
|
|
+ $height = 1296;
|
|
|
|
|
+ break;
|
|
|
|
|
+ default:
|
|
|
|
|
+ $width = 2048;
|
|
|
|
|
+ $height = 2048;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取动漫的角色信息(包含参考图)
|
|
|
|
|
+ $anime = DB::table('mp_animes')
|
|
|
|
|
+ ->where('id', $anime_id)
|
|
|
|
|
+ ->select('roles', 'scenes')
|
|
|
|
|
+ ->first();
|
|
|
|
|
+
|
|
|
|
|
+ if (!$anime || !$anime->roles) {
|
|
|
|
|
+ Utils::throwError('20003:未找到角色信息');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $roles = json_decode($anime->roles, true);
|
|
|
|
|
+ if (!$roles) {
|
|
|
|
|
+ Utils::throwError('20003:角色信息格式错误');
|
|
|
|
|
+ }
|
|
|
|
|
+ // 构建角色名称到参考图的映射
|
|
|
|
|
+ $role_map = [];
|
|
|
|
|
+ foreach ($roles as $role) {
|
|
|
|
|
+ $role_name = getProp($role, 'role');
|
|
|
|
|
+ $role_url = getProp($role, 'url');
|
|
|
|
|
+ if (!empty($role_name) && !empty($role_url)) {
|
|
|
|
|
+ $role_map[$role_name] = $role_url;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $scenes = json_decode($anime->scenes, true);
|
|
|
|
|
+ if (!$scenes) {
|
|
|
|
|
+ Utils::throwError('20003:角色信息格式错误');
|
|
|
|
|
+ }
|
|
|
|
|
+ // 构建角色名称到参考图的映射
|
|
|
|
|
+ $scene_map = [];
|
|
|
|
|
+ foreach ($scenes as $scene) {
|
|
|
|
|
+ $scene_name = getProp($scene, 'scene');
|
|
|
|
|
+ $scene_url = getProp($scene, 'url');
|
|
|
|
|
+ if (!empty($scene_name) && !empty($scene_url)) {
|
|
|
|
|
+ $scene_map[$scene_name] = $scene_url;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $segment_id = $segment->segment_id;
|
|
|
|
|
+ $segment_content = $segment->segment_content;
|
|
|
|
|
+
|
|
|
|
|
+ if (empty($segment_content)) {
|
|
|
|
|
+ Utils::throwError('20003:分镜内容不存在,请填写内容后重试');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 分镜剧本数组
|
|
|
|
|
+ $update_data = [
|
|
|
|
|
+ 'segment_content' => $segment_content,
|
|
|
|
|
+ 'pic_task_status' => '生成中',
|
|
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 解析分镜内容,提取画面描述作为主要提示词
|
|
|
|
|
+ $prompt = $segment_content;
|
|
|
|
|
+ $ref_img_urls = [];
|
|
|
|
|
+ // 分镜场景
|
|
|
|
|
+ $scene = getProp($data, 'scene');
|
|
|
|
|
+ if ($scene) {
|
|
|
|
|
+ $matched_scene = '';
|
|
|
|
|
+ if (isset($scene_map[$scene])) {
|
|
|
|
|
+ $img_index = count($ref_img_urls) + 1;
|
|
|
|
|
+ $prompt = "场景:$scene(图$img_index)\n$prompt";
|
|
|
|
|
+ $ref_img_urls[] = $scene_map[$scene];
|
|
|
|
|
+ $matched_scene = $scene;
|
|
|
|
|
+ }
|
|
|
|
|
+ $update_data['scene'] = $scene;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 分镜角色
|
|
|
|
|
+ $characters = getProp($data, 'characters');
|
|
|
|
|
+ if ($characters) {
|
|
|
|
|
+ $update_data['characters'] = $characters;
|
|
|
|
|
+ $characters = str_replace(['、', ',', ';'], ',', $characters);
|
|
|
|
|
+ $characters = explode(',', $characters);
|
|
|
|
|
+
|
|
|
|
|
+ // 从分镜内容中提取涉及的角色
|
|
|
|
|
+ $segment_characters = $this->extractCharactersFromSegment($segment_content, array_keys($role_map), $characters);
|
|
|
|
|
+
|
|
|
|
|
+ // 获取匹配角色的参考图
|
|
|
|
|
+ foreach ($segment_characters as $character) {
|
|
|
|
|
+ if (isset($role_map[$character])) {
|
|
|
|
|
+ // 将$prompt中出现的角色替换成角色(图1、2、3,序号是$ref_img_urls的个数加1)
|
|
|
|
|
+ $img_index = count($ref_img_urls) + 1;
|
|
|
|
|
+ $prompt = str_replace($character, $character . '(图' . $img_index . ')', $prompt);
|
|
|
|
|
+ $ref_img_urls[] = $role_map[$character];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有找到匹配的角色参考图,不使用参考图
|
|
|
|
|
+ if (empty($ref_img_urls)) {
|
|
|
|
|
+ $ref_img_urls = [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 准备生成任务参数
|
|
|
|
|
+ $params = [
|
|
|
|
|
+ 'alias_segment_id' => $segment_id,
|
|
|
|
|
+ 'prompt' => $prompt,
|
|
|
|
|
+ 'ref_img_urls' => $ref_img_urls,
|
|
|
|
|
+ 'width' => $width,
|
|
|
|
|
+ 'height' => $height,
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 调用AI图片生成服务
|
|
|
|
|
+ $task = $this->aiImageGenerationService->createImageGenerationTask($params);
|
|
|
|
|
+ $task_id = $task->id;
|
|
|
|
|
+
|
|
|
|
|
+ if (!$task_id) {
|
|
|
|
|
+ Utils::throwError('20003:创建生成任务失败!');
|
|
|
|
|
+ }
|
|
|
|
|
+ $update_data['pic_task_id'] = $task_id;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ // 更新分镜剧本信息
|
|
|
|
|
+ $this->handleEpisodeContent($update_data);
|
|
|
|
|
+ $boolen = DB::table('mp_episode_segments')
|
|
|
|
|
+ ->where('segment_id', $segment_id)
|
|
|
|
|
+ ->update($update_data);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果是第一集的首帧图片,则存入待更新数组
|
|
|
|
|
+ if ($boolen && (int)getProp($segment, 'episode_number') === 1 && (int)getProp($segment, 'segment_number') === 1) {
|
|
|
|
|
+ Redis::sadd('anime_first_frame_urls', $segment_id);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ $failed_segments[] = [
|
|
|
|
|
+ 'segment_id' => $segment_id,
|
|
|
|
|
+ 'error' => $e->getMessage()
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $img_url = $this->loopGetPicTaskResult($task_id);
|
|
|
|
|
+ if (!$img_url) Utils::throwError('20003:图片生成中,请稍后刷新');
|
|
|
|
|
+ return $img_url;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 轮训获取图片任务结果
|
|
|
|
|
+ private function loopGetPicTaskResult($task_id) {
|
|
|
|
|
+ $start_count = 0;
|
|
|
|
|
+ $img_url = '';
|
|
|
|
|
+ while ($start_count <= 30) {
|
|
|
|
|
+ sleep(3);
|
|
|
|
|
+
|
|
|
|
|
+ $task = MpGeneratePicTask::where('id', $task_id)->first();
|
|
|
|
|
+ $statusInfo = $this->aiImageGenerationService->queryTaskStatus($task);
|
|
|
|
|
+
|
|
|
|
|
+ if ($statusInfo['status'] === 'success') {
|
|
|
|
|
+ $task->updateStatus('success', [
|
|
|
|
|
+ 'result_url' => $statusInfo['result_url'],
|
|
|
|
|
+ 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ // 同步调整分镜图片状态和结果
|
|
|
|
|
+ if (getProp($task, 'alias_segment_id')) {
|
|
|
|
|
+ DB::table('mp_episode_segments')->where('segment_id', getProp($task, 'alias_segment_id'))->update([
|
|
|
|
|
+ 'img_url' => $statusInfo['result_url'][0],
|
|
|
|
|
+ 'pic_task_status' => '已完成',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ $img_url = $statusInfo['result_url'][0];
|
|
|
|
|
+ break;
|
|
|
|
|
+ } elseif ($statusInfo['status'] === 'failed') {
|
|
|
|
|
+ $task->updateStatus('failed', [
|
|
|
|
|
+ 'error_message' => $statusInfo['error_message'],
|
|
|
|
|
+ 'result_json' => $statusInfo['result_json'] ?? []
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ if (getProp($task, 'alias_segment_id')) {
|
|
|
|
|
+ DB::table('mp_episode_segments')->where('segment_id', getProp($task, 'alias_segment_id'))->update([
|
|
|
|
|
+ 'pic_task_status' => '失败',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ $start_count+=3;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $img_url;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 从分镜内容中提取涉及的角色
|
|
* 从分镜内容中提取涉及的角色
|
|
|
*/
|
|
*/
|
|
@@ -723,4 +942,58 @@ class AnimeService
|
|
|
|
|
|
|
|
return array_unique($found_characters);
|
|
return array_unique($found_characters);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 从分镜剧本中提取关键字段
|
|
|
|
|
+ private function handleEpisodeContent(&$data) {
|
|
|
|
|
+ $segmentContent = getProp($data, 'segment_content');
|
|
|
|
|
+ // 解析分镜详细信息
|
|
|
|
|
+ $segmentData = [
|
|
|
|
|
+ 'description' => '',
|
|
|
|
|
+ 'composition' => '',
|
|
|
|
|
+ 'camera_movement' => '',
|
|
|
|
|
+ 'voice_actor' => '',
|
|
|
|
|
+ 'dialogue' => '',
|
|
|
|
|
+ 'frame_type' => '',
|
|
|
|
|
+ 'scene' => '', // 新增:场景
|
|
|
|
|
+ 'characters' => '' // 新增:出镜角色
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ // 提取各个字段 - 兼容中文冒号和英文冒号,支持多种表达方式
|
|
|
|
|
+ if (preg_match('/(?:画面描述|镜头描述|场景描述)[::]\s*([^\n]+)/u', $segmentContent, $descMatch)) {
|
|
|
|
|
+ $segmentData['description'] = trim($descMatch[1]);
|
|
|
|
|
+ $data['description'] = trim($descMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (preg_match('/(?:构图设计|构图|镜头构图)[::]\s*([^\n]+)/u', $segmentContent, $compMatch)) {
|
|
|
|
|
+ $segmentData['composition'] = trim($compMatch[1]);
|
|
|
|
|
+ $data['composition'] = trim($compMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (preg_match('/(?:运镜调度|运镜|镜头运动|摄影机运动)[::]\s*([^\n]+)/u', $segmentContent, $cameraMatch)) {
|
|
|
|
|
+ $segmentData['camera_movement'] = trim($cameraMatch[1]);
|
|
|
|
|
+ $data['camera_movement'] = trim($cameraMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (preg_match('/(?:配音角色|配音|角色|声优)[::]\s*([^\n]+)/u', $segmentContent, $voiceMatch)) {
|
|
|
|
|
+ $segmentData['voice_actor'] = trim($voiceMatch[1]);
|
|
|
|
|
+ $data['voice_actor'] = trim($voiceMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (preg_match('/(?:台词内容|台词|对白|对话)[::]\s*([^\n]+)/u', $segmentContent, $dialogueMatch)) {
|
|
|
|
|
+ $segmentData['dialogue'] = trim($dialogueMatch[1]);
|
|
|
|
|
+ $data['dialogue'] = trim($dialogueMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (preg_match('/(?:画面类型|镜头类型|类型)[::]\s*([^\n]+)/u', $segmentContent, $frameMatch)) {
|
|
|
|
|
+ $segmentData['frame_type'] = trim($frameMatch[1]);
|
|
|
|
|
+ $data['frame_type'] = trim($frameMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 新增:场景字段
|
|
|
|
|
+ if (preg_match('/(?:场景|拍摄场景|背景场景|环境)[::]\s*([^\n]+)/u', $segmentContent, $sceneMatch)) {
|
|
|
|
|
+ $segmentData['scene'] = trim($sceneMatch[1]);
|
|
|
|
|
+ $data['scene'] = trim($sceneMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 新增:出镜角色字段
|
|
|
|
|
+ if (preg_match('/(?:出镜角色|角色出镜|登场角色|人物)[::]\s*([^\n]+)/u', $segmentContent, $charactersMatch)) {
|
|
|
|
|
+ $segmentData['characters'] = trim($charactersMatch[1]);
|
|
|
|
|
+ $data['characters'] = trim($charactersMatch[1]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $segmentData;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|