services
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
package video
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getDuration(ctx context.Context, inp string) (res float64, err error) {
|
||||
|
||||
args := []string{"-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", inp}
|
||||
|
||||
cmd := exec.CommandContext(ctx, "ffprobe", args...)
|
||||
|
||||
out, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
_, err = fmt.Fscan(bytes.NewReader(out), &res)
|
||||
return
|
||||
}
|
||||
|
||||
func GetDuration(ctx context.Context, inp string) (res float64, err error) {
|
||||
select {
|
||||
case semaphore <- struct{}{}:
|
||||
ctx, cancel := context.WithTimeout(ctx, ProcessingDeadline)
|
||||
defer func() {
|
||||
cancel()
|
||||
<-semaphore
|
||||
}()
|
||||
return getDuration(ctx, inp)
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
func GenerateVtt(ctx context.Context, inp string, s string) ([]string, error) {
|
||||
duration, err := GetDuration(ctx, inp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lines := strings.Split(s, "\n")
|
||||
vttLines := make([]string, len(lines))
|
||||
delta := duration / float64(len(lines))
|
||||
for i := range vttLines {
|
||||
s1 := generateStamp(float64(i) * delta)
|
||||
s2 := generateStamp(float64(i+1) * delta)
|
||||
vttLines[i] = fmt.Sprintf("%s --> %s\n", s1, s2)
|
||||
vttLines[i] += lines[i] + "\n"
|
||||
}
|
||||
return vttLines, err
|
||||
|
||||
}
|
||||
|
||||
func generateStamp(p float64) string {
|
||||
m := math.Floor(p / 60)
|
||||
s := math.Mod(p, 60.0)
|
||||
return fmt.Sprintf("%02.0f:%06.3f", m, s)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user