package model // Timestamp represents a time in a subtitle file type Timestamp struct { Hours int Minutes int Seconds int Milliseconds int } // Lyrics represents a lyrics file with metadata and content type Lyrics struct { Metadata map[string]string Timeline []Timestamp Content []string } // SRTEntry represents a single entry in an SRT file type SRTEntry struct { Number int StartTime Timestamp EndTime Timestamp Content string } // SubtitleEntry represents a generic subtitle entry in our intermediate representation type SubtitleEntry struct { Index int // Sequential index/number StartTime Timestamp // Start time EndTime Timestamp // End time Text string // The subtitle text content Styles map[string]string // Styling information (e.g., VTT's align, position) Classes []string // CSS classes (for VTT) Metadata map[string]string // Additional metadata FormatData map[string]interface{} // Format-specific data that doesn't fit elsewhere } // Subtitle represents our intermediate subtitle representation used for conversions type Subtitle struct { Title string // Optional title Metadata map[string]string // Global metadata (e.g., LRC's ti, ar, al) Entries []SubtitleEntry // Subtitle entries Format string // Source format Styles map[string]string // Global styles (e.g., VTT STYLE blocks) Comments []string // Comments/notes (for VTT) Regions []SubtitleRegion // Region definitions (for VTT) FormatData map[string]interface{} // Format-specific data that doesn't fit elsewhere } // SubtitleRegion represents a region definition (mainly for VTT) type SubtitleRegion struct { ID string Settings map[string]string } // ASSEvent represents an event entry in an ASS file (dialogue, comment, etc.) type ASSEvent struct { Type string // Dialogue, Comment, etc. Layer int // Layer number (0-based) StartTime Timestamp // Start time EndTime Timestamp // End time Style string // Style name Name string // Character name MarginL int // Left margin override MarginR int // Right margin override MarginV int // Vertical margin override Effect string // Transition effect Text string // The actual text } // ASSStyle represents a style definition in an ASS file type ASSStyle struct { Name string // Style name Properties map[string]string // Font name, size, colors, etc. } // ASSFile represents an Advanced SubStation Alpha (ASS) file type ASSFile struct { ScriptInfo map[string]string // Format, Title, ScriptType, etc. Styles []ASSStyle // Style definitions Events []ASSEvent // Dialogue lines } // Creates a new empty Subtitle func NewSubtitle() Subtitle { return Subtitle{ Metadata: make(map[string]string), Entries: []SubtitleEntry{}, Styles: make(map[string]string), Comments: []string{}, Regions: []SubtitleRegion{}, FormatData: make(map[string]interface{}), } } // Creates a new empty SubtitleEntry func NewSubtitleEntry() SubtitleEntry { return SubtitleEntry{ Styles: make(map[string]string), Classes: []string{}, Metadata: make(map[string]string), FormatData: make(map[string]interface{}), } } // Creates a new SubtitleRegion func NewSubtitleRegion(id string) SubtitleRegion { return SubtitleRegion{ ID: id, Settings: make(map[string]string), } } // NewASSFile creates a new empty ASS file structure with minimal defaults func NewASSFile() ASSFile { // Create minimal defaults for a valid ASS file scriptInfo := map[string]string{ "ScriptType": "v4.00+", "Collisions": "Normal", "PlayResX": "640", "PlayResY": "480", "Timer": "100.0000", } // Create a default style defaultStyle := ASSStyle{ Name: "Default", Properties: map[string]string{ "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,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1", }, } return ASSFile{ ScriptInfo: scriptInfo, Styles: []ASSStyle{defaultStyle}, Events: []ASSEvent{}, } } // NewASSEvent creates a new ASS event with default values func NewASSEvent() ASSEvent { return ASSEvent{ Type: "Dialogue", Layer: 0, Style: "Default", MarginL: 0, MarginR: 0, MarginV: 0, } }