가사 템플릿 업데이트, 폰트 선택 기능 추가, 주소 injection업데이트

get_video
dhlim 2026-02-04 10:28:47 +00:00
parent 9d92b5d42c
commit 32c6c210a0
3 changed files with 57 additions and 17 deletions

View File

@ -122,7 +122,38 @@ text_template_v_2 = {
} }
] ]
} }
text_template_v_3 = {
"type": "composition",
"track": 3,
"elements": [
{
"type": "text",
"time": 0,
"x": "0%",
"y": "80%",
"width": "100%",
"height": "15%",
"x_anchor": "0%",
"y_anchor": "0%",
"x_alignment": "50%",
"y_alignment": "50%",
"font_family": "Noto Sans",
"font_weight": "700",
"font_size_maximum": "7 vmin",
"fill_color": "#ffffff",
"animations": [
{
"time": 0,
"duration": 1,
"easing": "quadratic-out",
"type": "text-wave",
"split": "line",
"overlap": "50%"
}
]
}
]
}
text_template_h_1 = { text_template_h_1 = {
"type": "composition", "type": "composition",
"track": 3, "track": 3,
@ -408,6 +439,7 @@ class CreatomateService:
image_url_list: list[str], image_url_list: list[str],
lyric: str, lyric: str,
music_url: str, music_url: str,
address: str = None
) -> dict: ) -> dict:
"""템플릿 정보와 이미지/가사/음악 리소스를 매핑합니다. """템플릿 정보와 이미지/가사/음악 리소스를 매핑합니다.
@ -434,9 +466,8 @@ class CreatomateService:
idx % len(image_url_list) idx % len(image_url_list)
] ]
case "text": case "text":
modifications[template_component_name] = lyric_splited[ if "address_input" in template_component_name:
idx % len(lyric_splited) modifications[template_component_name] = address
]
modifications["audio-music"] = music_url modifications["audio-music"] = music_url
@ -448,12 +479,11 @@ class CreatomateService:
image_url_list: list[str], image_url_list: list[str],
lyric: str, lyric: str,
music_url: str, music_url: str,
address: str = None
) -> dict: ) -> dict:
"""elements 정보와 이미지/가사/음악 리소스를 매핑합니다.""" """elements 정보와 이미지/가사/음악 리소스를 매핑합니다."""
template_component_data = self.parse_template_component_name(elements) template_component_data = self.parse_template_component_name(elements)
lyric = lyric.replace("\r", "")
lyric_splited = lyric.split("\n")
modifications = {} modifications = {}
for idx, (template_component_name, template_type) in enumerate( for idx, (template_component_name, template_type) in enumerate(
@ -465,9 +495,8 @@ class CreatomateService:
idx % len(image_url_list) idx % len(image_url_list)
] ]
case "text": case "text":
modifications[template_component_name] = lyric_splited[ if "address_input" in template_component_name:
idx % len(lyric_splited) modifications[template_component_name] = address
]
modifications["audio-music"] = music_url modifications["audio-music"] = music_url
@ -486,7 +515,8 @@ class CreatomateService:
case "video": case "video":
element["source"] = modification[element["name"]] element["source"] = modification[element["name"]]
case "text": case "text":
element["source"] = modification.get(element["name"], "") #element["source"] = modification[element["name"]]
element["text"] = modification.get(element["name"], "")
case "composition": case "composition":
for minor in element["elements"]: for minor in element["elements"]:
recursive_modify(minor) recursive_modify(minor)
@ -704,8 +734,8 @@ class CreatomateService:
def extend_template_duration(self, template: dict, target_duration: float) -> dict: def extend_template_duration(self, template: dict, target_duration: float) -> dict:
"""템플릿의 duration을 target_duration으로 확장합니다.""" """템플릿의 duration을 target_duration으로 확장합니다."""
target_duration += 0.1 # 수동으로 직접 변경 및 테스트 필요 : 파란박스 생기는것 template["duration"] = target_duration + 0.5 # 늘린것보단 짧게
template["duration"] = target_duration target_duration += 1 # 수동으로 직접 변경 및 테스트 필요 : 파란박스 생기는것
total_template_duration = self.calc_scene_duration(template) total_template_duration = self.calc_scene_duration(template)
extend_rate = target_duration / total_template_duration extend_rate = target_duration / total_template_duration
new_template = copy.deepcopy(template) new_template = copy.deepcopy(template)
@ -727,7 +757,7 @@ class CreatomateService:
return new_template return new_template
def lining_lyric(self, text_template: dict, lyric_index: int, lyric_text: str, start_sec: float, end_sec: float) -> dict: def lining_lyric(self, text_template: dict, lyric_index: int, lyric_text: str, start_sec: float, end_sec: float, font_family: str = "Noto Sans") -> dict:
duration = end_sec - start_sec duration = end_sec - start_sec
text_scene = copy.deepcopy(text_template) text_scene = copy.deepcopy(text_template)
text_scene["name"] = f"Caption-{lyric_index}" text_scene["name"] = f"Caption-{lyric_index}"
@ -735,6 +765,7 @@ class CreatomateService:
text_scene["time"] = start_sec text_scene["time"] = start_sec
text_scene["elements"][0]["name"] = f"lyric-{lyric_index}" text_scene["elements"][0]["name"] = f"lyric-{lyric_index}"
text_scene["elements"][0]["text"] = lyric_text text_scene["elements"][0]["text"] = lyric_text
text_scene["elements"][0]["font_family"] = font_family
return text_scene return text_scene
def auto_lyric(self, auto_text_template : dict): def auto_lyric(self, auto_text_template : dict):
@ -744,7 +775,7 @@ class CreatomateService:
def get_text_template(self): def get_text_template(self):
match self.orientation: match self.orientation:
case "vertical": case "vertical":
return text_template_v_2 return text_template_v_3
case "horizontal": case "horizontal":
return text_template_h_1 return text_template_h_1

View File

@ -15,7 +15,7 @@ class NvMapPwScraper():
_context = None _context = None
_win_width = 1280 _win_width = 1280
_win_height = 720 _win_height = 720
_max_retry = 40 # place id timeout threshold seconds _max_retry = 60 # place id timeout threshold seconds
# instance var # instance var
page = None page = None

View File

@ -201,6 +201,7 @@ async def generate_video(
detail=f"task_id '{task_id}'에 해당하는 Project를 찾을 수 없습니다.", detail=f"task_id '{task_id}'에 해당하는 Project를 찾을 수 없습니다.",
) )
project_id = project.id project_id = project.id
store_address = project.detail_region_info
# ===== 결과 처리: Lyric ===== # ===== 결과 처리: Lyric =====
lyric = lyric_result.scalar_one_or_none() lyric = lyric_result.scalar_one_or_none()
@ -211,6 +212,7 @@ async def generate_video(
detail=f"task_id '{task_id}'에 해당하는 Lyric을 찾을 수 없습니다.", detail=f"task_id '{task_id}'에 해당하는 Lyric을 찾을 수 없습니다.",
) )
lyric_id = lyric.id lyric_id = lyric.id
lyric_language = lyric.language
# ===== 결과 처리: Song ===== # ===== 결과 처리: Song =====
song = song_result.scalar_one_or_none() song = song_result.scalar_one_or_none()
@ -313,6 +315,7 @@ async def generate_video(
image_url_list=image_urls, image_url_list=image_urls,
lyric=lyrics, lyric=lyrics,
music_url=music_url, music_url=music_url,
address=store_address
) )
logger.debug(f"[generate_video] Modifications created - task_id: {task_id}") logger.debug(f"[generate_video] Modifications created - task_id: {task_id}")
@ -333,8 +336,6 @@ async def generate_video(
f"[generate_video] Duration extended to {creatomate_service.target_duration}s - task_id: {task_id}" f"[generate_video] Duration extended to {creatomate_service.target_duration}s - task_id: {task_id}"
) )
# 이런거 추가해야하는데 AI가 자꾸 번호 달면 제가 번호를 다 밀어야 하나요?
song_timestamp_result = await session.execute( song_timestamp_result = await session.execute(
select(SongTimestamp).where( select(SongTimestamp).where(
SongTimestamp.suno_audio_id == song.suno_audio_id SongTimestamp.suno_audio_id == song.suno_audio_id
@ -350,6 +351,13 @@ async def generate_video(
f"[generate_video] timestamp[{i}]: lyric_line={ts.lyric_line}, start_time={ts.start_time}, end_time={ts.end_time}" f"[generate_video] timestamp[{i}]: lyric_line={ts.lyric_line}, start_time={ts.start_time}, end_time={ts.end_time}"
) )
match lyric_language:
case "English" :
lyric_font = "Noto Sans"
# lyric_font = "Pretendard" # 없어요
case _ :
lyric_font = "Noto Sans"
# LYRIC AUTO 결정부 # LYRIC AUTO 결정부
if (creatomate_settings.DEBUG_AUTO_LYRIC): if (creatomate_settings.DEBUG_AUTO_LYRIC):
auto_text_template = creatomate_service.get_auto_text_template() auto_text_template = creatomate_service.get_auto_text_template()
@ -363,6 +371,7 @@ async def generate_video(
aligned.lyric_line, aligned.lyric_line,
aligned.start_time, aligned.start_time,
aligned.end_time, aligned.end_time,
lyric_font
) )
final_template["source"]["elements"].append(caption) final_template["source"]["elements"].append(caption)
# END - LYRIC AUTO 결정부 # END - LYRIC AUTO 결정부