mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-03 19:17:16 -05:00 
			
		
		
		
	Use cmap for thumbnails
This commit is contained in:
		
							parent
							
								
									acedb77c07
								
							
						
					
					
						commit
						ee3d8916ed
					
				@ -187,9 +187,10 @@ func (h *Handler) GetInfo(c echo.Context) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	// Run extractors to have them in cache
 | 
						// Run extractors to have them in cache
 | 
				
			||||||
	src.Extract(ret.Path, sha, route)
 | 
						src.Extract(ret.Path, sha, route)
 | 
				
			||||||
	go h.thumbnails.ExtractThumbnail(
 | 
						go src.ExtractThumbnail(
 | 
				
			||||||
		ret.Path,
 | 
							ret.Path,
 | 
				
			||||||
		fmt.Sprintf("%s/thumbnails.png", route),
 | 
							route,
 | 
				
			||||||
 | 
							&sha,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	return c.JSON(http.StatusOK, ret)
 | 
						return c.JSON(http.StatusOK, ret)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -265,9 +266,10 @@ func (h *Handler) GetThumbnails(c echo.Context) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	out, err := h.thumbnails.ExtractThumbnail(
 | 
						out, err := src.ExtractThumbnail(
 | 
				
			||||||
		path,
 | 
							path,
 | 
				
			||||||
		fmt.Sprintf("%s/thumbnails.png", GetRoute(c)),
 | 
							GetRoute(c),
 | 
				
			||||||
 | 
							nil,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@ -288,9 +290,10 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	out, err := h.thumbnails.ExtractThumbnail(
 | 
						out, err := src.ExtractThumbnail(
 | 
				
			||||||
		path,
 | 
							path,
 | 
				
			||||||
		fmt.Sprintf("%s/thumbnails.png", GetRoute(c)),
 | 
							GetRoute(c),
 | 
				
			||||||
 | 
							nil,
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@ -301,7 +304,6 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type Handler struct {
 | 
					type Handler struct {
 | 
				
			||||||
	transcoder *src.Transcoder
 | 
						transcoder *src.Transcoder
 | 
				
			||||||
	thumbnails *src.ThumbnailsCreator
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
@ -316,7 +318,6 @@ func main() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	h := Handler{
 | 
						h := Handler{
 | 
				
			||||||
		transcoder: transcoder,
 | 
							transcoder: transcoder,
 | 
				
			||||||
		thumbnails: src.NewThumbnailsCreator(),
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	e.GET("/direct", DirectStream)
 | 
						e.GET("/direct", DirectStream)
 | 
				
			||||||
 | 
				
			|||||||
@ -20,71 +20,47 @@ var default_interval = 10
 | 
				
			|||||||
// Setting this too high allows really long processing times.
 | 
					// Setting this too high allows really long processing times.
 | 
				
			||||||
var max_numcaps = 150
 | 
					var max_numcaps = 150
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ThumbnailsCreator struct {
 | 
					type Thumbnail struct {
 | 
				
			||||||
	created map[string]string
 | 
						ready sync.WaitGroup
 | 
				
			||||||
	running map[string]chan struct{}
 | 
						path  string
 | 
				
			||||||
	lock    sync.Mutex
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewThumbnailsCreator() *ThumbnailsCreator {
 | 
					var thumbnails = NewCMap[string, *Thumbnail]()
 | 
				
			||||||
	return &ThumbnailsCreator{
 | 
					
 | 
				
			||||||
		created: make(map[string]string),
 | 
					func ExtractThumbnail(path string, route string, sha *string) (string, error) {
 | 
				
			||||||
		running: make(map[string]chan struct{}),
 | 
						ret, _ := thumbnails.GetOrCreate(path, func() *Thumbnail {
 | 
				
			||||||
	}
 | 
							if sha == nil {
 | 
				
			||||||
 | 
								nsha, err := GetHash(path)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								sha = &nsha
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ret := &Thumbnail{
 | 
				
			||||||
 | 
								path: fmt.Sprintf("%s/%s", Settings.Metadata, sha),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ret.ready.Add(1)
 | 
				
			||||||
 | 
							go extractThumbnail(path, ret.path, fmt.Sprintf("%s/thumbnails.png", route))
 | 
				
			||||||
 | 
							return ret
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						ret.ready.Wait()
 | 
				
			||||||
 | 
						return ret.path, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (t *ThumbnailsCreator) ExtractThumbnail(path string, name string) (string, error) {
 | 
					func extractThumbnail(path string, out string, name 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) {
 | 
					 | 
				
			||||||
	defer printExecTime("extracting thumbnails for %s", path)()
 | 
						defer printExecTime("extracting thumbnails for %s", path)()
 | 
				
			||||||
	sha, err := GetHash(path)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return "", err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	out := fmt.Sprintf("%s/%s", Settings.Metadata, sha)
 | 
					 | 
				
			||||||
	os.MkdirAll(out, 0o755)
 | 
						os.MkdirAll(out, 0o755)
 | 
				
			||||||
	sprite_path := fmt.Sprintf("%s/sprite.png", out)
 | 
						sprite_path := fmt.Sprintf("%s/sprite.png", out)
 | 
				
			||||||
	vtt_path := fmt.Sprintf("%s/sprite.vtt", out)
 | 
						vtt_path := fmt.Sprintf("%s/sprite.vtt", out)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if _, err := os.Stat(sprite_path); err == nil {
 | 
						if _, err := os.Stat(sprite_path); err == nil {
 | 
				
			||||||
		return out, nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen, err := screengen.NewGenerator(path)
 | 
						gen, err := screengen.NewGenerator(path)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Printf("Error reading video file: %v", err)
 | 
							log.Printf("Error reading video file: %v", err)
 | 
				
			||||||
		return "", err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer gen.Close()
 | 
						defer gen.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,7 +91,7 @@ func extractThumbnail(path string, name string) (string, error) {
 | 
				
			|||||||
		img, err := gen.ImageWxH(int64(ts*1000), width, height)
 | 
							img, err := gen.ImageWxH(int64(ts*1000), width, height)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.Printf("Could not generate screenshot %s", err)
 | 
								log.Printf("Could not generate screenshot %s", err)
 | 
				
			||||||
			return "", err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		x := (i % columns) * width
 | 
							x := (i % columns) * width
 | 
				
			||||||
@ -138,13 +114,13 @@ func extractThumbnail(path string, name string) (string, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	err = os.WriteFile(vtt_path, []byte(vtt), 0o644)
 | 
						err = os.WriteFile(vtt_path, []byte(vtt), 0o644)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = imaging.Save(sprite, sprite_path)
 | 
						err = imaging.Save(sprite, sprite_path)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return out, nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func tsToVttTime(ts int) string {
 | 
					func tsToVttTime(ts int) string {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user