From 281b8dca237fa5ba2a41b33ceb9977f676a443f4 Mon Sep 17 00:00:00 2001 From: VLEFF Date: Thu, 26 Jul 2018 11:47:09 +0200 Subject: [PATCH] feat: handle subtitles for video streaming (#468) Former-commit-id: 4259259f666304a88a808093afd26967059bd702 [formerly c925c803e33aa5486e920291b97b27e15ee9e2b9] [formerly dfe55f167c82ce734968505765104f855284a095 [formerly eb12bf2c2d962a6749fd199e9bf1d53650d52c59]] Former-commit-id: 96c5284c2a8c00c97dce3965893b4820e7ed4e6e [formerly 84f9ed9f1256e89010c5e813dc0b589af6a32d4a] Former-commit-id: 0c84bae4cefcd2fad3b65f0fbec31e565ca5f27b --- http/http.go | 6 +++- http/subtitle.go | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 http/subtitle.go diff --git a/http/http.go b/http/http.go index 4816660e..a5e93311 100644 --- a/http/http.go +++ b/http/http.go @@ -137,7 +137,7 @@ func apiHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, err } } - if c.Router == "checksum" || c.Router == "download" { + if c.Router == "checksum" || c.Router == "download" || c.Router == "subtitle" || c.Router == "subtitles" { var err error c.File, err = fb.GetInfo(r.URL, c.FileBrowser, c.User) if err != nil { @@ -165,6 +165,10 @@ func apiHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, err code, err = settingsHandler(c, w, r) case "share": code, err = shareHandler(c, w, r) + case "subtitles": + code, err = subtitlesHandler(c, w, r) + case "subtitle": + code, err = subtitleHandler(c, w, r) default: code = http.StatusNotFound } diff --git a/http/subtitle.go b/http/subtitle.go new file mode 100644 index 00000000..be54cd55 --- /dev/null +++ b/http/subtitle.go @@ -0,0 +1,83 @@ +package http + +import ( + "bytes" + fb "github.com/filebrowser/filebrowser" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "regexp" +) + +func subtitlesHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) { + files, err := ReadDir(filepath.Dir(c.File.Path)) + if err != nil { + return http.StatusInternalServerError, err + } + var subtitles = make([]map[string]string, 0) + for _, file := range files { + ext := filepath.Ext(file.Name()) + if ext == ".vtt" || ext == ".srt" { + var sub map[string]string = make(map[string]string) + sub["src"] = filepath.Dir(c.File.Path) + "/" + file.Name() + sub["kind"] = "subtitles" + sub["label"] = file.Name() + subtitles = append(subtitles, sub) + } + } + return renderJSON(w, subtitles) +} + +func subtitleHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) { + str, err := CleanSubtitle(c.File.Path) + if err != nil { + return http.StatusInternalServerError, err + } + + file, err := os.Open(c.File.Path) + defer file.Close() + + if err != nil { + return http.StatusInternalServerError, err + } + + stat, err := file.Stat() + if err != nil { + return http.StatusInternalServerError, err + } + + w.Header().Set("Content-Disposition", "inline") + w.Header().Set("Content-Type", "text/vtt") + http.ServeContent(w, r, stat.Name(), stat.ModTime(), bytes.NewReader([]byte(str))) + + return 0, nil + +} + +func CleanSubtitle(filename string) (string, error) { + b, err := ioutil.ReadFile(filename) + if err != nil { + return "", err + } + str := string(b) // convert content to a 'string' + ext := filepath.Ext(filename) + if ext == ".srt" { + re := regexp.MustCompile("([0-9]{2}:[0-9]{2}:[0-9]{2}),([0-9]{3})") + str = "WEBVTT\n\n" + re.ReplaceAllString(str, "$1.$2") + } + return str, err +} + +func ReadDir(dirname string) ([]os.FileInfo, error) { + f, err := os.Open(dirname) + if err != nil { + return nil, err + } + list, err := f.Readdir(-1) + f.Close() + if err != nil { + return nil, err + } + return list, nil +}