Add thumbnail cache

This commit is contained in:
Zoe Roux 2024-01-21 23:36:05 +01:00
parent b147ee8850
commit e6a9e2c7da
2 changed files with 63 additions and 5 deletions

View File

@ -264,7 +264,7 @@ func (h *Handler) GetSubtitle(c echo.Context) error {
// Get thumbnail sprite // Get thumbnail sprite
// //
// Get a sprite file containing all the thumbnails of the show // Get a sprite file containing all the thumbnails of the show.
// //
// Path: /:resource/:slug/thumbnails.png // Path: /:resource/:slug/thumbnails.png
func (h *Handler) GetThumbnails(c echo.Context) error { func (h *Handler) GetThumbnails(c echo.Context) error {
@ -276,7 +276,10 @@ func (h *Handler) GetThumbnails(c echo.Context) error {
return err return err
} }
out, err := src.ExtractThumbnail(path) out, err := h.thumbnails.ExtractThumbnail(
path,
fmt.Sprintf("%s/%s/thumbnails.png", resource, slug),
)
if err != nil { if err != nil {
return err return err
} }
@ -299,7 +302,10 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
return err return err
} }
out, err := src.ExtractThumbnail(path) out, err := h.thumbnails.ExtractThumbnail(
path,
fmt.Sprintf("%s/%s/thumbnails.png", resource, slug),
)
if err != nil { if err != nil {
return err return err
} }
@ -310,6 +316,7 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
type Handler struct { type Handler struct {
transcoder *src.Transcoder transcoder *src.Transcoder
extractor *src.Extractor extractor *src.Extractor
thumbnails *src.ThumbnailsCreator
} }
func main() { func main() {
@ -322,7 +329,11 @@ func main() {
e.Logger.Fatal(err) e.Logger.Fatal(err)
return return
} }
h := Handler{transcoder: transcoder, extractor: src.NewExtractor()} h := Handler{
transcoder: transcoder,
extractor: src.NewExtractor(),
thumbnails: src.NewThumbnailsCreator(),
}
e.GET("/:resource/:slug/direct", DirectStream) e.GET("/:resource/:slug/direct", DirectStream)
e.GET("/:resource/:slug/master.m3u8", h.GetMaster) e.GET("/:resource/:slug/master.m3u8", h.GetMaster)

View File

@ -7,6 +7,7 @@ import (
"log" "log"
"math" "math"
"os" "os"
"sync"
"github.com/disintegration/imaging" "github.com/disintegration/imaging"
"gitlab.com/opennota/screengen" "gitlab.com/opennota/screengen"
@ -15,7 +16,53 @@ import (
// We want to have a thumbnail every ${interval} seconds. // We want to have a thumbnail every ${interval} seconds.
var default_interval = 10 var default_interval = 10
func ExtractThumbnail(path string) (string, error) { type ThumbnailsCreator struct {
created map[string]string
running map[string]chan struct{}
lock sync.Mutex
}
func NewThumbnailsCreator() *ThumbnailsCreator {
return &ThumbnailsCreator{
created: make(map[string]string),
running: make(map[string]chan struct{}),
}
}
func (t *ThumbnailsCreator) ExtractThumbnail(path string, name string) (string, error) {
t.lock.Lock()
defer t.lock.Unlock()
out, ok := t.created[path]
if ok {
return out, nil
}
wait, ok := t.running[path]
if ok {
t.lock.Unlock()
<-wait
t.lock.Lock()
out = t.created[path]
return out, nil
}
wait = make(chan struct{})
t.running[path] = wait
t.lock.Unlock()
out, err := extractThumbnail(path, name)
t.lock.Lock()
// this will be unlocked by the defer at the top of the function.
delete(t.running, path)
if err == nil {
t.created[path] = out
}
return out, err
}
func extractThumbnail(path string, name string) (string, error) {
ret, err := GetInfo(path) ret, err := GetInfo(path)
if err != nil { if err != nil {
return "", err return "", err