package srt import ( "fmt" "os" "path/filepath" "strings" ) // formatDuration formats a duration as SRT timestamp (HH:MM:SS,mmm) func formatDuration(d int64) string { ms := d % 1000 d /= 1000 s := d % 60 d /= 60 m := d % 60 h := d / 60 return fmt.Sprintf("%02d:%02d:%02d,%03d", h, m, s, ms) } // Save writes the transcript to an SRT file func (t *Transcript) Save() error { return t.SaveTo(t.FilePath) } // SaveTo writes the transcript to the specified path func (t *Transcript) SaveTo(path string) error { var sb strings.Builder for i, cue := range t.Cues { if i > 0 { sb.WriteString("\n") } sb.WriteString(fmt.Sprintf("%d\n", cue.Index)) sb.WriteString(fmt.Sprintf("%s --> %s\n", formatDuration(cue.Start.Milliseconds()), formatDuration(cue.End.Milliseconds()))) sb.WriteString(cue.Text) sb.WriteString("\n") } // Ensure directory exists dir := filepath.Dir(path) if err := os.MkdirAll(dir, 0755); err != nil { return fmt.Errorf("failed to create directory: %w", err) } if err := os.WriteFile(path, []byte(sb.String()), 0644); err != nil { return fmt.Errorf("failed to write file: %w", err) } return nil } // PromoteTempFile saves the transcript to a permanent location func (t *Transcript) PromoteTempFile(audioPath string) (string, error) { if !t.IsTemp { return t.FilePath, nil } // Create permanent path next to audio file ext := filepath.Ext(audioPath) permanentPath := strings.TrimSuffix(audioPath, ext) + ".srt" if err := t.SaveTo(permanentPath); err != nil { return "", err } // Update transcript state t.FilePath = permanentPath t.IsTemp = false // Remove temp file tempPath := filepath.Join(os.TempDir(), filepath.Base(audioPath)) os.Remove(strings.TrimSuffix(tempPath, filepath.Ext(tempPath)) + ".srt.tmp") return permanentPath, nil }