mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Use concurrent map for subtitles
This commit is contained in:
parent
b687d8ea95
commit
2afed432f7
@ -176,12 +176,16 @@ func (h *Handler) GetInfo(c echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
sha, err := src.GetHash(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ret, err := src.GetInfo(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Run extractors to have them in cache
|
||||
h.extractor.RunExtractor(ret.Path, ret.Sha, &ret.Subtitles)
|
||||
src.Extract(ret.Path, sha)
|
||||
go h.thumbnails.ExtractThumbnail(
|
||||
ret.Path,
|
||||
fmt.Sprintf("%s/thumbnails.png", c.Request().Header.Get("X-Route")),
|
||||
@ -195,46 +199,56 @@ func (h *Handler) GetInfo(c echo.Context) error {
|
||||
//
|
||||
// Path: /attachment/:name
|
||||
func (h *Handler) GetAttachment(c echo.Context) error {
|
||||
path, err := GetPath(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := c.Param("name")
|
||||
|
||||
if err := SanitizePath(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wait, ok := h.extractor.Extract(sha)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Not extracted yet. Call /info to extract.")
|
||||
sha, err := src.GetHash(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wait, err := src.Extract(path, sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
<-wait
|
||||
|
||||
path := fmt.Sprintf("%s/%s/att/%s", src.Settings.Metadata, sha, name)
|
||||
return c.File(path)
|
||||
ret := fmt.Sprintf("%s/%s/att/%s", src.Settings.Metadata, sha, name)
|
||||
return c.File(ret)
|
||||
}
|
||||
|
||||
// Get subtitle
|
||||
//
|
||||
// Get a specific subtitle.
|
||||
//
|
||||
// Path: /:sha/subtitle/:name
|
||||
// Path: /subtitle/:name
|
||||
func (h *Handler) GetSubtitle(c echo.Context) error {
|
||||
sha := c.Param("sha")
|
||||
name := c.Param("name")
|
||||
|
||||
if err := SanitizePath(sha); err != nil {
|
||||
path, err := GetPath(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
name := c.Param("name")
|
||||
if err := SanitizePath(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wait, ok := h.extractor.Extract(sha)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Not extracted yet. Call /info to extract.")
|
||||
sha, err := src.GetHash(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wait, err := src.Extract(path, sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
<-wait
|
||||
|
||||
path := fmt.Sprintf("%s/%s/sub/%s", src.Settings.Metadata, sha, name)
|
||||
return c.File(path)
|
||||
ret := fmt.Sprintf("%s/%s/sub/%s", src.Settings.Metadata, sha, name)
|
||||
return c.File(ret)
|
||||
}
|
||||
|
||||
// Get thumbnail sprite
|
||||
@ -284,7 +298,6 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
|
||||
|
||||
type Handler struct {
|
||||
transcoder *src.Transcoder
|
||||
extractor *src.Extractor
|
||||
thumbnails *src.ThumbnailsCreator
|
||||
}
|
||||
|
||||
@ -300,7 +313,6 @@ func main() {
|
||||
}
|
||||
h := Handler{
|
||||
transcoder: transcoder,
|
||||
extractor: src.NewExtractor(),
|
||||
thumbnails: src.NewThumbnailsCreator(),
|
||||
}
|
||||
|
||||
|
@ -4,36 +4,24 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Extractor struct {
|
||||
extracted map[string]<-chan struct{}
|
||||
lock sync.RWMutex
|
||||
}
|
||||
var extracted = NewCMap[string, <-chan struct{}]()
|
||||
|
||||
func NewExtractor() *Extractor {
|
||||
return &Extractor{
|
||||
extracted: make(map[string]<-chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Extractor) Extract(path string, subs *[]Subtitle) (<-chan struct{}, error) {
|
||||
sha, err := getHash(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
e.lock.Lock()
|
||||
existing, ok := e.extracted[sha]
|
||||
if ok {
|
||||
func Extract(path string, sha string) (<-chan struct{}, error) {
|
||||
ret := make(chan struct{})
|
||||
existing, created := extracted.GetOrSet(sha, ret)
|
||||
if !created {
|
||||
return existing, nil
|
||||
}
|
||||
ret := make(chan struct{})
|
||||
e.extracted[sha] = ret
|
||||
e.lock.Unlock()
|
||||
|
||||
go func() {
|
||||
info, err := GetInfo(path)
|
||||
if err != nil {
|
||||
extracted.Remove(sha)
|
||||
close(ret)
|
||||
return
|
||||
}
|
||||
attachment_path := fmt.Sprintf("%s/%s/att", Settings.Metadata, sha)
|
||||
subs_path := fmt.Sprintf("%s/%s/sub", Settings.Metadata, sha)
|
||||
os.MkdirAll(attachment_path, 0o644)
|
||||
@ -49,7 +37,7 @@ func (e *Extractor) Extract(path string, subs *[]Subtitle) (<-chan struct{}, err
|
||||
)
|
||||
cmd.Dir = attachment_path
|
||||
|
||||
for _, sub := range *subs {
|
||||
for _, sub := range info.Subtitles {
|
||||
if ext := sub.Extension; ext != nil {
|
||||
cmd.Args = append(
|
||||
cmd.Args,
|
||||
@ -61,8 +49,9 @@ func (e *Extractor) Extract(path string, subs *[]Subtitle) (<-chan struct{}, err
|
||||
}
|
||||
fmt.Printf("Starting extraction with the command: %s", cmd)
|
||||
cmd.Stdout = nil
|
||||
err := cmd.Run()
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
extracted.Remove(sha)
|
||||
fmt.Println("Error starting ffmpeg extract:", err)
|
||||
}
|
||||
close(ret)
|
||||
|
@ -68,7 +68,7 @@ func (t *ThumbnailsCreator) ExtractThumbnail(path string, name string) (string,
|
||||
|
||||
func extractThumbnail(path string, name string) (string, error) {
|
||||
defer printExecTime("extracting thumbnails for %s", path)()
|
||||
sha, err := getHash(path)
|
||||
sha, err := GetHash(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func printExecTime(message string, args ...any) func() {
|
||||
}
|
||||
}
|
||||
|
||||
func getHash(path string) (string, error) {
|
||||
func GetHash(path string) (string, error) {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
Loading…
x
Reference in New Issue
Block a user