mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Rework keyframes creations to allow fs caching
This commit is contained in:
parent
4810d6cc5c
commit
6a1fff227e
@ -12,8 +12,7 @@ type FileStream struct {
|
||||
err error
|
||||
Path string
|
||||
Out string
|
||||
Keyframes []float64
|
||||
CanTransmux bool
|
||||
Keyframes *Keyframe
|
||||
Info *MediaInfo
|
||||
videos CMap[Quality, *VideoStream]
|
||||
audios CMap[int32, *AudioStream]
|
||||
@ -40,12 +39,7 @@ func NewFileStream(path string, sha string, route string) *FileStream {
|
||||
ret.ready.Add(1)
|
||||
go func() {
|
||||
defer ret.ready.Done()
|
||||
keyframes, can_transmux, err := GetKeyframes(path)
|
||||
ret.Keyframes = keyframes
|
||||
ret.CanTransmux = can_transmux
|
||||
if err != nil {
|
||||
ret.err = err
|
||||
}
|
||||
ret.Keyframes = GetKeyframes(sha, path)
|
||||
}()
|
||||
|
||||
return ret
|
||||
|
@ -210,7 +210,7 @@ func GetInfo(path string, sha string, route string) (*MediaInfo, error) {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func getSavedInfo(save_path string, mi *MediaInfo) error {
|
||||
func getSavedInfo[T any](save_path string, mi *T) error {
|
||||
saved_file, err := os.Open(save_path)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -226,7 +226,7 @@ func getSavedInfo(save_path string, mi *MediaInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveInfo(save_path string, mi *MediaInfo) error {
|
||||
func saveInfo[T any](save_path string, mi *T) error {
|
||||
content, err := json.Marshal(*mi)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -2,13 +2,75 @@ package src
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"math"
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func GetKeyframes(path string) ([]float64, bool, error) {
|
||||
type Keyframe struct {
|
||||
Sha string
|
||||
Keyframes []float64
|
||||
CanTransmux bool
|
||||
IsDone bool
|
||||
mutex sync.RWMutex
|
||||
ready sync.WaitGroup
|
||||
}
|
||||
|
||||
func (kf *Keyframe) Get(idx int32) float64 {
|
||||
kf.mutex.RLock()
|
||||
defer kf.mutex.RUnlock()
|
||||
return kf.Keyframes[idx]
|
||||
}
|
||||
|
||||
func (kf *Keyframe) Slice(start int32, end int32) []float64 {
|
||||
if end <= start {
|
||||
return []float64{}
|
||||
}
|
||||
kf.mutex.RLock()
|
||||
defer kf.mutex.RUnlock()
|
||||
ref := kf.Keyframes[start:end]
|
||||
ret := make([]float64, end-start)
|
||||
copy(ret, ref)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (kf *Keyframe) Length() (int32, bool) {
|
||||
kf.mutex.RLock()
|
||||
defer kf.mutex.RUnlock()
|
||||
return int32(len(kf.Keyframes)), kf.IsDone
|
||||
}
|
||||
|
||||
var keyframes = NewCMap[string, *Keyframe]()
|
||||
|
||||
func GetKeyframes(sha string, path string) *Keyframe {
|
||||
ret, _ := keyframes.GetOrCreate(sha, func() *Keyframe {
|
||||
kf := &Keyframe{
|
||||
Sha: sha,
|
||||
IsDone: false,
|
||||
}
|
||||
kf.ready.Add(1)
|
||||
go func() {
|
||||
save_path := fmt.Sprintf("%s/%s/keyframes.json", Settings.Metadata, sha)
|
||||
if err := getSavedInfo(save_path, kf); err == nil {
|
||||
log.Printf("Using keyframes cache on filesystem for %s", path)
|
||||
return
|
||||
}
|
||||
|
||||
err := getKeyframes(path, kf)
|
||||
if err == nil {
|
||||
saveInfo(save_path, kf)
|
||||
}
|
||||
}()
|
||||
return kf
|
||||
})
|
||||
ret.ready.Wait()
|
||||
return ret
|
||||
}
|
||||
|
||||
func getKeyframes(path string, kf *Keyframe) error {
|
||||
defer printExecTime("ffprobe analysis for %s", path)()
|
||||
// run ffprobe to return all IFrames, IFrames are points where we can split the video in segments.
|
||||
// We ask ffprobe to return the time of each frame and it's flags
|
||||
@ -24,11 +86,11 @@ func GetKeyframes(path string) ([]float64, bool, error) {
|
||||
)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return err
|
||||
}
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return err
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
@ -50,7 +112,7 @@ func GetKeyframes(path string) ([]float64, bool, error) {
|
||||
|
||||
fpts, err := strconv.ParseFloat(pts, 64)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return err
|
||||
}
|
||||
|
||||
// Before, we wanted to only save keyframes with at least 3s betweens
|
||||
@ -70,5 +132,8 @@ func GetKeyframes(path string) ([]float64, bool, error) {
|
||||
}
|
||||
ret = append(ret, fpts)
|
||||
}
|
||||
return ret, can_transmux, nil
|
||||
kf.Keyframes = ret
|
||||
kf.IsDone = true
|
||||
kf.ready.Done()
|
||||
return nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user