mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add extraction cache and wait for extraction to end to return subtitles/attachments
This commit is contained in:
parent
30cb171612
commit
425de0b315
@ -190,10 +190,10 @@ func (h *Handler) GetAudioSegment(c echo.Context) error {
|
||||
|
||||
// Identify
|
||||
//
|
||||
// # Identify metadata about a file
|
||||
// Identify metadata about a file
|
||||
//
|
||||
// Path: /:resource/:slug/info
|
||||
func GetInfo(c echo.Context) error {
|
||||
func (h *Handler) GetInfo(c echo.Context) error {
|
||||
resource := c.Param("resource")
|
||||
slug := c.Param("slug")
|
||||
|
||||
@ -206,6 +206,7 @@ func GetInfo(c echo.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
h.extractor.RunExtractor(ret.Path, ret.Sha, &ret.Subtitles)
|
||||
return c.JSON(http.StatusOK, ret)
|
||||
}
|
||||
|
||||
@ -214,7 +215,7 @@ func GetInfo(c echo.Context) error {
|
||||
// Get a specific attachment
|
||||
//
|
||||
// Path: /:sha/attachment/:name
|
||||
func GetAttachment(c echo.Context) error {
|
||||
func (h *Handler) GetAttachment(c echo.Context) error {
|
||||
sha := c.Param("sha")
|
||||
name := c.Param("name")
|
||||
|
||||
@ -225,6 +226,12 @@ func GetAttachment(c echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
wait, ok := h.extractor.Extract(sha)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Not extracted yet. Call /info to extract.")
|
||||
}
|
||||
<-wait
|
||||
|
||||
path := fmt.Sprintf("%s/%s/att/%s", src.GetMetadataPath(), sha, name)
|
||||
return c.File(path)
|
||||
}
|
||||
@ -233,8 +240,8 @@ func GetAttachment(c echo.Context) error {
|
||||
//
|
||||
// Get a specific subtitle
|
||||
//
|
||||
// Path: /:sha/sub/:name
|
||||
func GetSubtitle(c echo.Context) error {
|
||||
// Path: /:sha/subtitle/:name
|
||||
func (h *Handler) GetSubtitle(c echo.Context) error {
|
||||
sha := c.Param("sha")
|
||||
name := c.Param("name")
|
||||
|
||||
@ -245,12 +252,19 @@ func GetSubtitle(c echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
wait, ok := h.extractor.Extract(sha)
|
||||
if !ok {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, "Not extracted yet. Call /info to extract.")
|
||||
}
|
||||
<-wait
|
||||
|
||||
path := fmt.Sprintf("%s/%s/sub/%s", src.GetMetadataPath(), sha, name)
|
||||
return c.File(path)
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
transcoder *src.Transcoder
|
||||
extractor *src.Extractor
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -263,7 +277,7 @@ func main() {
|
||||
e.Logger.Fatal(err)
|
||||
return
|
||||
}
|
||||
h := Handler{transcoder: transcoder}
|
||||
h := Handler{transcoder: transcoder, extractor: src.NewExtractor()}
|
||||
|
||||
e.GET("/:resource/:slug/direct", DirectStream)
|
||||
e.GET("/:resource/:slug/master.m3u8", h.GetMaster)
|
||||
@ -271,9 +285,9 @@ func main() {
|
||||
e.GET("/:resource/:slug/audio/:audio/index.m3u8", h.GetAudioIndex)
|
||||
e.GET("/:resource/:slug/:quality/:chunk", h.GetVideoSegment)
|
||||
e.GET("/:resource/:slug/audio/:audio/:chunk", h.GetAudioSegment)
|
||||
e.GET("/:resource/:slug/info", GetInfo)
|
||||
e.GET("/:sha/attachment/:name", GetAttachment)
|
||||
e.GET("/:sha/sub/:name", GetSubtitle)
|
||||
e.GET("/:resource/:slug/info", h.GetInfo)
|
||||
e.GET("/:sha/attachment/:name", h.GetAttachment)
|
||||
e.GET("/:sha/subtitle/:name", h.GetSubtitle)
|
||||
|
||||
e.Logger.Fatal(e.Start(":7666"))
|
||||
}
|
||||
|
@ -4,8 +4,14 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Extractor struct {
|
||||
extracted map[string]<-chan struct{}
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
func GetMetadataPath() string {
|
||||
out := os.Getenv("GOCODER_METADATA_ROOT")
|
||||
if out == "" {
|
||||
@ -14,29 +20,66 @@ func GetMetadataPath() string {
|
||||
return out
|
||||
}
|
||||
|
||||
func extract(path string, sha string, subs *[]Subtitle) {
|
||||
fmt.Printf("Extract subs and fonts for %s", path)
|
||||
cmd := exec.Command(
|
||||
"ffmpeg",
|
||||
"-dump_attachment:t", "",
|
||||
"-i", path,
|
||||
)
|
||||
cmd.Dir = fmt.Sprintf("/%s/%s/att/", GetMetadataPath(), sha)
|
||||
|
||||
for _, sub := range *subs {
|
||||
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/%s/sub/%d.%s", GetMetadataPath(), sha, sub.Index, *ext),
|
||||
)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Starting extraction with the command: %s", cmd)
|
||||
cmd.Stdout = nil
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println("Error starting ffmpeg extract:", err)
|
||||
func NewExtractor() *Extractor {
|
||||
return &Extractor{
|
||||
extracted: make(map[string]<-chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Extractor) Extract(sha string) (<-chan struct{}, bool) {
|
||||
e.lock.RLock()
|
||||
existing, ok := e.extracted[sha]
|
||||
e.lock.RUnlock()
|
||||
|
||||
if ok {
|
||||
return existing, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (e *Extractor) RunExtractor(path string, sha string, subs *[]Subtitle) <-chan struct{} {
|
||||
existing, ok := e.Extract(sha)
|
||||
if ok {
|
||||
return existing
|
||||
}
|
||||
|
||||
ret := make(chan struct{})
|
||||
e.lock.Lock()
|
||||
e.extracted[sha] = ret
|
||||
e.lock.Unlock()
|
||||
|
||||
go func() {
|
||||
attachment_path := fmt.Sprintf("%s/%s/att/", GetMetadataPath(), sha)
|
||||
subs_path := fmt.Sprintf("%s/%s/sub/", GetMetadataPath(), sha)
|
||||
os.MkdirAll(attachment_path, 0o644)
|
||||
os.MkdirAll(subs_path, 0o644)
|
||||
|
||||
fmt.Printf("Extract subs and fonts for %s", path)
|
||||
cmd := exec.Command(
|
||||
"ffmpeg",
|
||||
"-dump_attachment:t", "",
|
||||
"-i", path,
|
||||
)
|
||||
cmd.Dir = attachment_path
|
||||
|
||||
for _, sub := range *subs {
|
||||
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),
|
||||
)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Starting extraction with the command: %s", cmd)
|
||||
cmd.Stdout = nil
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println("Error starting ffmpeg extract:", err)
|
||||
}
|
||||
close(ret)
|
||||
}()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
@ -169,8 +169,6 @@ func GetInfo(path string) (*MediaInfo, error) {
|
||||
}
|
||||
defer mi.Close()
|
||||
|
||||
// TODO: extract
|
||||
|
||||
sha := mi.Parameter(mediainfo.StreamGeneral, 0, "UniqueID")
|
||||
// Remove dummy values that some tools use.
|
||||
if len(sha) <= 5 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user