diff --git a/transcoder/main.go b/transcoder/main.go index 2c3d20db..562bdfa6 100644 --- a/transcoder/main.go +++ b/transcoder/main.go @@ -189,7 +189,7 @@ func (h *Handler) GetInfo(c echo.Context) error { // // Path: /:path/attachment/:name func (h *Handler) GetAttachment(c echo.Context) error { - path, sha, err := GetPath(c) + _, sha, err := GetPath(c) if err != nil { return err } @@ -198,12 +198,6 @@ func (h *Handler) GetAttachment(c echo.Context) error { return err } - wait, err := src.Extract(path, sha) - if err != nil { - return err - } - <-wait - ret := fmt.Sprintf("%s/%s/att/%s", src.Settings.Metadata, sha, name) return c.File(ret) } @@ -214,7 +208,7 @@ func (h *Handler) GetAttachment(c echo.Context) error { // // Path: /:path/subtitle/:name func (h *Handler) GetSubtitle(c echo.Context) error { - path, sha, err := GetPath(c) + _, sha, err := GetPath(c) if err != nil { return err } @@ -223,12 +217,6 @@ func (h *Handler) GetSubtitle(c echo.Context) error { return err } - wait, err := src.Extract(path, sha) - if err != nil { - return err - } - <-wait - ret := fmt.Sprintf("%s/%s/sub/%s", src.Settings.Metadata, sha, name) return c.File(ret) } diff --git a/transcoder/src/extract.go b/transcoder/src/extract.go index 536b1e1d..79bf3603 100644 --- a/transcoder/src/extract.go +++ b/transcoder/src/extract.go @@ -9,60 +9,67 @@ import ( var extracted = NewCMap[string, <-chan struct{}]() -func Extract(path string, sha string) (<-chan struct{}, error) { - ret := make(chan struct{}) - existing, created := extracted.GetOrSet(sha, ret) - if !created { - return existing, nil +const ExtractVersion = 1 + +func (s MetadataService) ExtractSubs(info *MediaInfo) (interface{}, error) { + get_running, set := s.extractLock.Start(info.Sha) + if get_running != nil { + return get_running() } - go func() { - defer printExecTime("Starting extraction of %s", path)() - info, err := GetInfo(path, sha) - 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, 0o755) - os.MkdirAll(subs_path, 0o755) - - // If there is no subtitles, there is nothing to extract (also fonts would be useless). - if len(info.Subtitles) == 0 { - close(ret) - return - } - - cmd := exec.Command( - "ffmpeg", - "-dump_attachment:t", "", - // override old attachments - "-y", - "-i", path, - ) - cmd.Dir = attachment_path - - for _, sub := range info.Subtitles { - if ext := sub.Extension; ext != nil { - cmd.Args = append( - cmd.Args, - "-map", fmt.Sprintf("0:s:%d", sub.Index), - "-c:s", "copy", - fmt.Sprintf("%s/%d.%s", subs_path, sub.Index, *ext), - ) - } - } - log.Printf("Starting extraction with the command: %s", cmd) - cmd.Stdout = nil - err = cmd.Run() - if err != nil { - extracted.Remove(sha) - fmt.Println("Error starting ffmpeg extract:", err) - } - close(ret) - }() - - return ret, nil + err := extractSubs(info) + if err != nil { + return set(nil, err) + } + _, err = s.database.NamedExec( + `update info set ver_extract = :version where sha = :sha`, + map[string]interface{}{ + "sha": info.Sha, + "version": ExtractVersion, + }, + ) + return set(nil, err) +} + +func extractSubs(info *MediaInfo) error { + defer printExecTime("Starting extraction of %s", info.Path)() + + attachment_path := fmt.Sprintf("%s/%s/att", Settings.Metadata, info.Sha) + subs_path := fmt.Sprintf("%s/%s/sub", Settings.Metadata, info.Sha) + + os.MkdirAll(attachment_path, 0o755) + os.MkdirAll(subs_path, 0o755) + + // If there is no subtitles, there is nothing to extract (also fonts would be useless). + if len(info.Subtitles) == 0 { + return nil + } + + cmd := exec.Command( + "ffmpeg", + "-dump_attachment:t", "", + // override old attachments + "-y", + "-i", info.Path, + ) + cmd.Dir = attachment_path + + for _, sub := range info.Subtitles { + if ext := sub.Extension; ext != nil { + cmd.Args = append( + cmd.Args, + "-map", fmt.Sprintf("0:s:%d", sub.Index), + "-c:s", "copy", + fmt.Sprintf("%s/%d.%s", subs_path, sub.Index, *ext), + ) + } + } + log.Printf("Starting extraction with the command: %s", cmd) + cmd.Stdout = nil + err := cmd.Run() + if err != nil { + fmt.Println("Error starting ffmpeg extract:", err) + return err + } + return nil } diff --git a/transcoder/src/metadata.go b/transcoder/src/metadata.go index 77c12687..13cc7063 100644 --- a/transcoder/src/metadata.go +++ b/transcoder/src/metadata.go @@ -8,6 +8,7 @@ type MetadataService struct { database *sqlx.DB lock *RunLock[string, *MediaInfo] thumbLock *RunLock[string, interface{}] + extractLock *RunLock[string, interface{}] } func (s MetadataService) GetMetadata(path string, sha string) (*MediaInfo, error) { @@ -19,6 +20,9 @@ func (s MetadataService) GetMetadata(path string, sha string) (*MediaInfo, error if ret.Versions.Thumbs < ThumbsVersion { go s.ExtractThumbs(path, sha) } + if ret.Versions.Extract < ExtractVersion { + go s.ExtractSubs(ret) + } return ret, nil }