2025-07-11 18:02:44 +08:00
|
|
|
import pyJianYingDraft as draft
|
|
|
|
|
from util import generate_draft_url, hex_to_rgb
|
|
|
|
|
from create_draft import get_or_create_draft
|
|
|
|
|
from pyJianYingDraft.text_segment import TextBubble, TextEffect
|
|
|
|
|
from typing import Optional
|
|
|
|
|
import requests
|
|
|
|
|
|
|
|
|
|
def add_subtitle_impl(
|
|
|
|
|
srt_path: str,
|
|
|
|
|
draft_id: str = None,
|
|
|
|
|
track_name: str = "subtitle",
|
|
|
|
|
time_offset: float = 0,
|
2025-07-13 16:21:17 +08:00
|
|
|
# Font style parameters
|
2025-07-11 18:02:44 +08:00
|
|
|
font_size: float = 8.0,
|
|
|
|
|
bold: bool = False,
|
|
|
|
|
italic: bool = False,
|
|
|
|
|
underline: bool = False,
|
|
|
|
|
font_color: str = "#FFFFFF",
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Border parameters
|
2025-07-11 18:02:44 +08:00
|
|
|
border_alpha: float = 1.0,
|
|
|
|
|
border_color: str = "#000000",
|
2025-07-13 16:21:17 +08:00
|
|
|
border_width: float = 0.0, # Default no border display
|
2025-07-11 18:02:44 +08:00
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Background parameters
|
2025-07-11 18:02:44 +08:00
|
|
|
background_color: str = "#000000",
|
|
|
|
|
background_style: int = 1,
|
2025-07-13 16:21:17 +08:00
|
|
|
background_alpha: float = 0.0, # Default no background display
|
2025-07-11 18:02:44 +08:00
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Bubble effect
|
2025-07-11 18:02:44 +08:00
|
|
|
bubble_effect_id: Optional[str] = None,
|
|
|
|
|
bubble_resource_id: Optional[str] = None,
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Text effect
|
2025-07-11 18:02:44 +08:00
|
|
|
effect_effect_id: Optional[str] = None,
|
2025-07-13 16:21:17 +08:00
|
|
|
# Image adjustment parameters
|
2025-07-11 18:02:44 +08:00
|
|
|
transform_x: float = 0.0,
|
2025-07-13 16:21:17 +08:00
|
|
|
transform_y: float = -0.8, # Default subtitle position at bottom
|
2025-07-11 18:02:44 +08:00
|
|
|
scale_x: float = 1.0,
|
|
|
|
|
scale_y: float = 1.0,
|
|
|
|
|
rotation: float = 0.0,
|
|
|
|
|
style_reference: draft.Text_segment = None,
|
2025-07-13 16:21:17 +08:00
|
|
|
vertical: bool = True, # New parameter: whether to display vertically
|
2025-07-11 18:02:44 +08:00
|
|
|
alpha: float = 0.4,
|
2025-07-13 16:21:17 +08:00
|
|
|
width: int = 1080, # New parameter
|
|
|
|
|
height: int = 1920 # New parameter
|
2025-07-11 18:02:44 +08:00
|
|
|
):
|
|
|
|
|
"""
|
2025-07-13 16:21:17 +08:00
|
|
|
Add subtitles to draft
|
|
|
|
|
:param srt_path: Subtitle file path or URL or SRT text content
|
|
|
|
|
:param draft_id: Draft ID, if None, create a new draft
|
|
|
|
|
:param track_name: Track name, default is "subtitle"
|
|
|
|
|
:param time_offset: Time offset, default is "0"s
|
|
|
|
|
:param text_style: Text style, default is None
|
|
|
|
|
:param clip_settings: Clip settings, default is None
|
|
|
|
|
:param style_reference: Style reference, default is None
|
|
|
|
|
:return: Draft information
|
2025-07-11 18:02:44 +08:00
|
|
|
"""
|
2025-07-13 16:21:17 +08:00
|
|
|
# Get or create draft
|
2025-07-11 18:02:44 +08:00
|
|
|
draft_id, script = get_or_create_draft(
|
|
|
|
|
draft_id=draft_id,
|
|
|
|
|
width=width,
|
|
|
|
|
height=height
|
|
|
|
|
)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Process subtitle content
|
2025-07-11 18:02:44 +08:00
|
|
|
srt_content = None
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Check if it's a URL
|
2025-07-11 18:02:44 +08:00
|
|
|
if srt_path.startswith(('http://', 'https://')):
|
|
|
|
|
try:
|
|
|
|
|
response = requests.get(srt_path)
|
|
|
|
|
response.raise_for_status()
|
|
|
|
|
|
|
|
|
|
response.encoding = 'utf-8'
|
|
|
|
|
srt_content = response.text
|
|
|
|
|
except Exception as e:
|
2025-07-13 16:21:17 +08:00
|
|
|
raise Exception(f"Failed to download subtitle file: {str(e)}")
|
2025-07-11 18:02:44 +08:00
|
|
|
else:
|
2025-07-13 16:21:17 +08:00
|
|
|
# If not a URL, use content directly
|
2025-07-11 18:02:44 +08:00
|
|
|
srt_content = srt_path
|
2025-07-13 16:21:17 +08:00
|
|
|
# Handle possible escape characters
|
2025-07-11 18:02:44 +08:00
|
|
|
srt_content = srt_content.replace('\\n', '\n').replace('/n', '\n')
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Import subtitles
|
|
|
|
|
# Convert hexadecimal color to RGB
|
2025-07-11 18:02:44 +08:00
|
|
|
rgb_color = hex_to_rgb(font_color)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Create text_border
|
2025-07-11 18:02:44 +08:00
|
|
|
text_border = None
|
|
|
|
|
if border_width > 0:
|
|
|
|
|
text_border = draft.Text_border(
|
|
|
|
|
alpha=border_alpha,
|
|
|
|
|
color=hex_to_rgb(border_color),
|
|
|
|
|
width=border_width
|
|
|
|
|
)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Create text_background
|
2025-07-11 18:02:44 +08:00
|
|
|
text_background = None
|
|
|
|
|
if background_alpha > 0:
|
|
|
|
|
text_background = draft.Text_background(
|
|
|
|
|
color=background_color,
|
|
|
|
|
style=background_style,
|
|
|
|
|
alpha=background_alpha
|
|
|
|
|
)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Create text_style
|
2025-07-11 18:02:44 +08:00
|
|
|
text_style = draft.Text_style(
|
|
|
|
|
size=font_size,
|
|
|
|
|
bold=bold,
|
|
|
|
|
italic=italic,
|
|
|
|
|
underline=underline,
|
|
|
|
|
color=rgb_color,
|
2025-07-13 16:21:17 +08:00
|
|
|
align=1, # Keep center alignment
|
|
|
|
|
vertical=vertical, # Use the passed vertical parameter
|
|
|
|
|
alpha=alpha # Use the passed alpha parameter
|
2025-07-11 18:02:44 +08:00
|
|
|
)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Create bubble effect
|
2025-07-11 18:02:44 +08:00
|
|
|
text_bubble = None
|
|
|
|
|
if bubble_effect_id and bubble_resource_id:
|
|
|
|
|
text_bubble = TextBubble(
|
|
|
|
|
effect_id=bubble_effect_id,
|
|
|
|
|
resource_id=bubble_resource_id
|
|
|
|
|
)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Create text effect
|
2025-07-11 18:02:44 +08:00
|
|
|
text_effect = None
|
|
|
|
|
if effect_effect_id:
|
|
|
|
|
text_effect = TextEffect(
|
|
|
|
|
effect_id=effect_effect_id,
|
|
|
|
|
resource_id=effect_effect_id
|
|
|
|
|
)
|
|
|
|
|
|
2025-07-13 16:21:17 +08:00
|
|
|
# Create clip_settings
|
2025-07-11 18:02:44 +08:00
|
|
|
clip_settings = draft.Clip_settings(
|
|
|
|
|
transform_x=transform_x,
|
|
|
|
|
transform_y=transform_y,
|
|
|
|
|
scale_x=scale_x,
|
|
|
|
|
scale_y=scale_y,
|
|
|
|
|
rotation=rotation
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
script.import_srt(
|
|
|
|
|
srt_content,
|
|
|
|
|
track_name=track_name,
|
2025-07-13 16:21:17 +08:00
|
|
|
time_offset=int(time_offset * 1000000), # Convert seconds to microseconds
|
2025-07-11 18:02:44 +08:00
|
|
|
text_style=text_style,
|
|
|
|
|
clip_settings=clip_settings,
|
|
|
|
|
style_reference=style_reference,
|
|
|
|
|
border=text_border,
|
|
|
|
|
background=text_background,
|
|
|
|
|
bubble=text_bubble,
|
|
|
|
|
effect=text_effect
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
"draft_id": draft_id,
|
|
|
|
|
"draft_url": generate_draft_url(draft_id)
|
|
|
|
|
}
|