119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package srt
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
astisub "github.com/asticode/go-astisub"
|
|
)
|
|
|
|
// Load loads an SRT file from the given path
|
|
func Load(path string) (*Transcript, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to open file: %w", err)
|
|
}
|
|
defer f.Close()
|
|
|
|
subs, err := astisub.ReadFromSRT(f)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse SRT file: %w", err)
|
|
}
|
|
|
|
transcript := &Transcript{
|
|
FilePath: path,
|
|
IsTemp: strings.HasSuffix(path, ".tmp"),
|
|
Cues: make([]Cue, len(subs.Items)),
|
|
}
|
|
|
|
lineNum := 1 // SRT files are 1-indexed
|
|
for i, item := range subs.Items {
|
|
var textParts []string
|
|
for _, line := range item.Lines {
|
|
var lineParts []string
|
|
for _, lineItem := range line.Items {
|
|
lineParts = append(lineParts, lineItem.Text)
|
|
}
|
|
textParts = append(textParts, strings.Join(lineParts, ""))
|
|
}
|
|
|
|
text := strings.Join(textParts, "\n")
|
|
transcript.Cues[i] = Cue{
|
|
Index: i + 1,
|
|
Start: item.StartAt,
|
|
End: item.EndAt,
|
|
Text: text,
|
|
LineNumber: lineNum,
|
|
}
|
|
|
|
// Calculate lines used by this cue:
|
|
// 1 (index) + 1 (timestamp) + text lines + 1 (blank line)
|
|
textLines := 1
|
|
if text != "" {
|
|
textLines = strings.Count(text, "\n") + 1
|
|
}
|
|
lineNum += 2 + textLines + 1 // index + timestamp + text + blank
|
|
}
|
|
|
|
return transcript, nil
|
|
}
|
|
|
|
// FindTranscript looks for an SRT file next to the audio file
|
|
func FindTranscript(audioPath string) string {
|
|
ext := filepath.Ext(audioPath)
|
|
basePath := strings.TrimSuffix(audioPath, ext)
|
|
|
|
// Try common SRT naming patterns
|
|
patterns := []string{
|
|
basePath + ".srt",
|
|
basePath + ".en.srt",
|
|
audioPath + ".srt",
|
|
}
|
|
|
|
for _, pattern := range patterns {
|
|
if _, err := os.Stat(pattern); err == nil {
|
|
return pattern
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// CreateTempTranscript creates a temporary SRT file with placeholder content
|
|
func CreateTempTranscript(audioPath string) (string, error) {
|
|
basename := filepath.Base(audioPath)
|
|
ext := filepath.Ext(basename)
|
|
nameOnly := strings.TrimSuffix(basename, ext)
|
|
|
|
tempPath := filepath.Join(os.TempDir(), nameOnly+".srt.tmp")
|
|
|
|
content := fmt.Sprintf(`1
|
|
00:00:00,000 --> 00:00:05,000
|
|
[No transcript found for: %s]
|
|
|
|
2
|
|
00:00:05,000 --> 00:00:15,000
|
|
This is a temporary transcript file.
|
|
You can edit it using vim-style commands.
|
|
Press 'i' to enter edit mode, 'esc' to exit.
|
|
|
|
3
|
|
00:00:15,000 --> 00:00:25,000
|
|
To generate a transcript automatically, try:
|
|
https://git.beitzah.net/ysandler/transcribe
|
|
|
|
4
|
|
00:00:25,000 --> 00:00:35,000
|
|
Or launch with an existing transcript:
|
|
playback %s -t /path/to/transcript.srt
|
|
`, basename, basename)
|
|
|
|
if err := os.WriteFile(tempPath, []byte(content), 0644); err != nil {
|
|
return "", fmt.Errorf("failed to create temp transcript: %w", err)
|
|
}
|
|
|
|
return tempPath, nil
|
|
}
|