all repos — gopipe @ 5a91c6dec0ac3e5f50ca3c46af1228c0d8120223

Embed YouTube videos on Telegram, Discord and more!

better subtitles
Marco Andronaco andronacomarco@gmail.com
Fri, 18 Oct 2024 10:00:52 +0200
commit

5a91c6dec0ac3e5f50ca3c46af1228c0d8120223

parent

0271132d3d1468daee659b494a523291666713d6

4 files changed, 39 insertions(+), 20 deletions(-)

jump to
M src/app/handlers.gosrc/app/handlers.go

@@ -49,7 +49,7 @@

func indexHandler(w http.ResponseWriter, r *http.Request) { err := g.XT.ExecuteTemplate(w, "index.tmpl", nil) if err != nil { - log.Println("indexHandler ERROR: ", err) + log.Println("indexHandler ERROR:", err) http.Error(w, err500, http.StatusInternalServerError) return }

@@ -66,7 +66,7 @@ }

} if !videoRegex.MatchString(videoID) { - log.Println("Invalid video ID: ", videoID) + log.Println("Invalid video ID:", videoID) http.Error(w, err404, http.StatusNotFound) return }

@@ -108,7 +108,7 @@ }

err = g.XT.ExecuteTemplate(w, "video.tmpl", data) if err != nil { - log.Println("indexHandler ERROR: ", err) + log.Println("indexHandler ERROR:", err) http.Error(w, err500, http.StatusInternalServerError) return }

@@ -134,7 +134,7 @@

data := map[string]interface{}{"Videos": videos} err := g.XT.ExecuteTemplate(w, "cache.tmpl", data) if err != nil { - log.Println("cacheHandler ERROR: ", err) + log.Println("cacheHandler ERROR:", err) http.Error(w, err500, http.StatusInternalServerError) return }
M src/app/proxy.gosrc/app/proxy.go

@@ -88,7 +88,8 @@ return

} captions := getCaptions(*video) - caption, ok := captions[strings.TrimSuffix(r.PathValue("language"), ".vtt")] + language := strings.TrimSuffix(r.PathValue("language"), ".vtt") + caption, ok := captions[language] if !ok { http.Error(w, err404, http.StatusNotFound) return

@@ -101,9 +102,16 @@ return

} defer res.Body.Close() + buffer, err := subs.Convert(res.Body) + if err != nil { + http.Error(w, err500, http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/vtt") + w.Header().Set("Content-Length", strconv.Itoa(buffer.Len())) - err = subs.Convert(res.Body, w) + _, err = buffer.WriteTo(w) if err != nil { http.Error(w, err500, http.StatusInternalServerError) return
M src/app/video.gosrc/app/video.go

@@ -27,7 +27,7 @@ func parseExpiration(url string) time.Duration {

expireString := expireRegex.FindStringSubmatch(url) expireTimestamp, err := strconv.ParseInt(expireString[1], 10, 64) if err != nil { - log.Println("parseExpiration ERROR: ", err) + log.Println("parseExpiration ERROR:", err) return defaultCacheDuration }

@@ -94,7 +94,7 @@

func getFromYT(videoID string, formatID int) (video *youtube.Video, format *youtube.Format, err error) { url := getURL(videoID) - log.Println("Requesting video ", url) + log.Println("Requesting video", url) video, err = g.YT.GetVideo(url) if err != nil || video == nil { return
M src/subs/subs.gosrc/subs/subs.go

@@ -1,6 +1,7 @@

package subs import ( + "bytes" "encoding/xml" "fmt" "io"

@@ -29,8 +30,8 @@ Text string `xml:",chardata"` // Text inside the <s> tag

Time int `xml:"t,attr"` // Optional start time (not always present) } -func writeVTT(output io.Writer, i, startTime, endTime int, sentence string) { - output.Write( +func writeVTT(output *bytes.Buffer, i, startTime, endTime int, sentence string) (int, error) { + return output.Write( []byte( fmt.Sprintf( "%d\n%s --> %s\n%s\n\n",

@@ -49,28 +50,35 @@ milliseconds := ms % 1000

return fmt.Sprintf("%02d:%02d:%02d.%03d", seconds/3600, (seconds%3600)/60, seconds%60, milliseconds) } -func Convert(reader io.Reader, output io.Writer) error { +func Convert(reader io.Reader) (buffer bytes.Buffer, err error) { content, err := io.ReadAll(reader) if err != nil { - return err + return } var timedText TimedText err = xml.Unmarshal(content, &timedText) if err != nil { log.Println("Error unmarshalling XML:", err) - return err + return } - output.Write([]byte("WEBVTT\n\n")) + n, err := buffer.Write([]byte("WEBVTT\n\n")) + if err != nil { + return + } - var lastEndTime int + l := len(timedText.Body.Paragraphs) - 1 + var m int for i, p := range timedText.Body.Paragraphs { startTimeMS := p.Start endTimeMS := p.Start + p.Length - if startTimeMS < lastEndTime { - startTimeMS = lastEndTime + if i < l { + nextStartTimeMS := timedText.Body.Paragraphs[i+1].Start + if nextStartTimeMS < endTimeMS { + endTimeMS = nextStartTimeMS + } } var sentence string

@@ -87,9 +95,12 @@ if sentence == "" {

continue } - lastEndTime = endTimeMS - writeVTT(output, i+1, startTimeMS, endTimeMS, sentence) + m, err = writeVTT(&buffer, i+1, startTimeMS, endTimeMS, sentence) + n += m + if err != nil { + return + } } - return nil + return }