mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Rework thumbnail cache to use db
This commit is contained in:
parent
3ea2004267
commit
a75bd48ccf
@ -176,13 +176,10 @@ func (h *Handler) GetInfo(c echo.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
ret, err := src.GetInfo(path, sha)
|
||||
ret, err := h.metadata.GetMetadata(path, sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Run extractors to have them in cache
|
||||
src.Extract(ret.Path, sha)
|
||||
go src.ExtractThumbnail(ret.Path, sha)
|
||||
return c.JSON(http.StatusOK, ret)
|
||||
}
|
||||
|
||||
@ -246,13 +243,12 @@ func (h *Handler) GetThumbnails(c echo.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := src.ExtractThumbnail(path, sha)
|
||||
sprite, _, err := h.metadata.GetThumb(path, sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.File(fmt.Sprintf("%s/sprite.png", out))
|
||||
return c.File(sprite)
|
||||
}
|
||||
|
||||
// Get thumbnail vtt
|
||||
@ -266,17 +262,17 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := src.ExtractThumbnail(path, sha)
|
||||
_, vtt, err := h.metadata.GetThumb(path, sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.File(fmt.Sprintf("%s/sprite.vtt", out))
|
||||
return c.File(vtt)
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
transcoder *src.Transcoder
|
||||
metadata src.MetadataService
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -5,11 +5,25 @@ import (
|
||||
)
|
||||
|
||||
type MetadataService struct {
|
||||
database *sqlx.DB
|
||||
lock *RunLock[string, *MediaInfo]
|
||||
database *sqlx.DB
|
||||
lock *RunLock[string, *MediaInfo]
|
||||
thumbLock *RunLock[string, interface{}]
|
||||
}
|
||||
|
||||
func (s MetadataService) GetMetadata(path string, sha string) (*MediaInfo, error) {
|
||||
ret, err := s.getMetadata(path, sha)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ret.Versions.Thumbs < ThumbsVersion {
|
||||
go s.ExtractThumbs(path, sha)
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (s MetadataService) getMetadata(path string, sha string) (*MediaInfo, error) {
|
||||
var ret MediaInfo
|
||||
rows, err := s.database.Queryx(`
|
||||
select * from info as i where i.sha=$1;
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
@ -28,32 +29,60 @@ type Thumbnail struct {
|
||||
|
||||
var thumbnails = NewCMap[string, *Thumbnail]()
|
||||
|
||||
func ExtractThumbnail(path string, sha string) (string, error) {
|
||||
ret, _ := thumbnails.GetOrCreate(sha, func() *Thumbnail {
|
||||
ret := &Thumbnail{
|
||||
path: fmt.Sprintf("%s/%s", Settings.Metadata, sha),
|
||||
}
|
||||
ret.ready.Add(1)
|
||||
go func() {
|
||||
extractThumbnail(path, ret.path)
|
||||
ret.ready.Done()
|
||||
}()
|
||||
return ret
|
||||
})
|
||||
ret.ready.Wait()
|
||||
return ret.path, nil
|
||||
const ThumbsVersion = 1
|
||||
|
||||
func getThumbGlob(sha string) string {
|
||||
return fmt.Sprintf("%s/%s/thumbs-v*.*", Settings.Metadata, sha)
|
||||
}
|
||||
|
||||
func extractThumbnail(path string, out string) error {
|
||||
defer printExecTime("extracting thumbnails for %s", path)()
|
||||
os.MkdirAll(out, 0o755)
|
||||
sprite_path := fmt.Sprintf("%s/sprite.png", out)
|
||||
vtt_path := fmt.Sprintf("%s/sprite.vtt", out)
|
||||
func getThumbPath(sha string) string {
|
||||
return fmt.Sprintf("%s/%s/thumbs-v%d.png", Settings.Metadata, sha, ThumbsVersion)
|
||||
}
|
||||
|
||||
func getThumbVttPath(sha string) string {
|
||||
return fmt.Sprintf("%s/%s/thumbs-v%d.vtt", Settings.Metadata, sha, ThumbsVersion)
|
||||
}
|
||||
|
||||
func (s MetadataService) GetThumb(path string, sha string) (string, string, error) {
|
||||
sprite_path := getThumbPath(sha)
|
||||
vtt_path := getThumbVttPath(sha)
|
||||
|
||||
if _, err := os.Stat(sprite_path); err == nil {
|
||||
return nil
|
||||
return sprite_path, vtt_path, nil
|
||||
}
|
||||
|
||||
_, err := s.ExtractThumbs(path, sha)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return sprite_path, vtt_path, nil
|
||||
}
|
||||
|
||||
func (s MetadataService) ExtractThumbs(path string, sha string) (interface{}, error) {
|
||||
get_running, set := s.thumbLock.Start(sha)
|
||||
if get_running != nil {
|
||||
return get_running()
|
||||
}
|
||||
|
||||
err := extractThumbnail(path, sha)
|
||||
if err != nil {
|
||||
return set(nil, err)
|
||||
}
|
||||
_, err = s.database.NamedExec(
|
||||
`update info set ver_thumbs = :version where sha = :sha`,
|
||||
map[string]interface{}{
|
||||
"sha": sha,
|
||||
"version": ThumbsVersion,
|
||||
},
|
||||
)
|
||||
return set(nil, err)
|
||||
}
|
||||
|
||||
func extractThumbnail(path string, sha string) error {
|
||||
defer printExecTime("extracting thumbnails for %s", path)()
|
||||
|
||||
os.MkdirAll(fmt.Sprintf("%s/%s", Settings.Metadata), 0o755)
|
||||
|
||||
gen, err := screengen.NewGenerator(path)
|
||||
if err != nil {
|
||||
log.Printf("Error reading video file: %v", err)
|
||||
@ -102,7 +131,7 @@ func extractThumbnail(path string, out string) error {
|
||||
tsToVttTime(timestamps),
|
||||
tsToVttTime(ts),
|
||||
Settings.RoutePrefix,
|
||||
base64.StdEncoding.EncodeToString([]byte(path)),
|
||||
base64.RawURLEncoding.EncodeToString([]byte(path)),
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
@ -110,11 +139,20 @@ func extractThumbnail(path string, out string) error {
|
||||
)
|
||||
}
|
||||
|
||||
err = os.WriteFile(vtt_path, []byte(vtt), 0o644)
|
||||
// Cleanup old versions of thumbnails
|
||||
files, err := filepath.Glob(getThumbGlob(sha))
|
||||
if err == nil {
|
||||
for _, f := range files {
|
||||
// ignore errors
|
||||
os.Remove(f)
|
||||
}
|
||||
}
|
||||
|
||||
err = os.WriteFile(getThumbVttPath(sha), []byte(vtt), 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = imaging.Save(sprite, sprite_path)
|
||||
err = imaging.Save(sprite, getThumbPath(sha))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user