| import os |
| from styles import STYLES |
|
|
| def seconds_to_ass_time(seconds): |
| """Converts seconds (float) to 0:00:00.00 format""" |
| mins, secs = divmod(seconds, 60) |
| hours, mins = divmod(mins, 60) |
| cs = int((secs - int(secs)) * 100) |
| return f"{int(hours)}:{int(mins):02d}:{int(secs):02d}.{cs:02d}" |
|
|
| def generate_ass(transcript, style_name="hormozi", output_file="subs.ass"): |
| """ |
| Generates an .ass file from a transcript list. |
| transcript: [{'text': 'Hello', 'start': 0.0, 'end': 0.5}, ...] |
| """ |
| config = STYLES.get(style_name, STYLES["hormozi"]) |
| |
| header = f"""[Script Info] |
| ScriptType: v4.00+ |
| PlayResX: 1280 |
| PlayResY: 720 |
| |
| [V4+ Styles] |
| Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding |
| Style: Default,{config['Fontname']},{config['Fontsize']},{config['PrimaryColour']},{config['PrimaryColour']},{config['OutlineColour']},{config['BackColour']},{config['Bold']},{config['Italic']},0,0,100,100,0,0,{config['BorderStyle']},{config['Outline']},{config['Shadow']},{config['Alignment']},{config['MarginL']},{config['MarginR']},{config['MarginV']},1 |
| |
| [Events] |
| Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text |
| """ |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| lines = [] |
| current_chunk = [] |
| chunk_start = 0.0 |
| chunk_duration = 0.0 |
| |
| events_str = "" |
| |
| |
| |
| |
| |
| |
| |
| for item in transcript: |
| start = seconds_to_ass_time(item['start']) |
| end = seconds_to_ass_time(item['end']) |
| |
| |
| |
| |
| |
| text = item['text'] |
| style_code = config['active_anim'] |
| |
| |
| line_str = f"Dialogue: 0,{start},{end},Default,,0,0,0,,{style_code}{text}" |
| events_str += line_str + "\n" |
|
|
| with open(output_file, "w", encoding="utf-8") as f: |
| f.write(header + events_str) |
| |
| return output_file |
|
|