Finish master m3u8 retrival

This commit is contained in:
Zoe Roux 2024-01-13 17:23:48 +01:00
parent 4193b6b391
commit 2d36c6ad6e
5 changed files with 27 additions and 6 deletions

View File

@ -84,7 +84,7 @@ func main() {
e.Use(middleware.Logger())
e.HTTPErrorHandler = ErrorHandler
h := Handler{}
h := Handler{transcoder: src.NewTranscoder()}
e.GET("/:resource/:slug/direct", DirectStream)
e.GET("/:resource/:slug/master.m3u8", h.GetMaster)

View File

@ -2,6 +2,7 @@ package src
import (
"fmt"
"log"
"math"
"os/exec"
"strconv"
@ -49,6 +50,7 @@ func NewFileStream(path string) (*FileStream, error) {
func GetKeyframes(path string) ([]float64, bool, error) {
// run ffprobe to return all IFrames, IFrames are points where we can split the video in segments.
log.Printf("Starting ffprobe for keyframes analysis for %s", path)
out, err := exec.Command(
"ffprobe",
"-loglevel", "error",
@ -57,6 +59,7 @@ func GetKeyframes(path string) ([]float64, bool, error) {
"-of", "csv=print_section=0",
path,
).Output()
log.Printf("%s ffprobe analysis finished", path)
// We ask ffprobe to return the time of each frame and it's flags
// We could ask it to return only i-frames (keyframes) with the -skip_frame nokey but using it is extremly slow
// since ffmpeg parses every frames when this flag is set.
@ -68,6 +71,10 @@ func GetKeyframes(path string) ([]float64, bool, error) {
last := 0.
can_transmux := true
for _, frame := range strings.Split(string(out), "\n") {
if frame == "" {
continue
}
x := strings.Split(frame, ",")
pts, flags := x[0], x[1]

View File

@ -4,6 +4,7 @@ import (
"crypto/sha1"
"encoding/hex"
"fmt"
"log"
"path/filepath"
"strconv"
"strings"
@ -159,6 +160,8 @@ var SubtitleExtensions = map[string]string{
}
func GetInfo(path string) (*MediaInfo, error) {
log.Printf("Running mediainfo for %s", path)
mi, err := mediainfo.Open(path)
if err != nil {
return nil, err

View File

@ -14,7 +14,8 @@ const (
Original Quality = "original"
)
var Qualities = []Quality{P240, P360, P480, P720, P1080, P1440, P4k, P8k, Original}
// Purposfully removing Original from this list (since it require special treatments anyways)
var Qualities = []Quality{P240, P360, P480, P720, P1080, P1440, P4k, P8k}
// I'm not entierly sure about the values for bitrates. Double checking would be nice.
func (v Quality) AverageBitrate() uint32 {

View File

@ -2,6 +2,7 @@ package src
import (
"errors"
"log"
"sync"
)
@ -13,6 +14,13 @@ type Transcoder struct {
mutex sync.RWMutex
}
func NewTranscoder() *Transcoder {
return &Transcoder{
streams: make(map[string]FileStream),
preparing: make(map[string]chan *FileStream),
}
}
func (t *Transcoder) GetMaster(path string, client string) (string, error) {
t.mutex.RLock()
stream, ok := t.streams[path]
@ -32,7 +40,8 @@ func (t *Transcoder) GetMaster(path string, client string) (string, error) {
t.cleanUnused()
t.mutex.Unlock()
stream, err := NewFileStream(path)
newstream, err := NewFileStream(path)
log.Printf("Stream created for %s", path)
if err != nil {
t.mutex.Lock()
delete(t.preparing, path)
@ -43,11 +52,12 @@ func (t *Transcoder) GetMaster(path string, client string) (string, error) {
}
t.mutex.Lock()
t.streams[path] = *stream
t.streams[path] = *newstream
stream = t.streams[path]
delete(t.preparing, path)
t.mutex.Unlock()
channel <- stream
channel <- &stream
}
return stream.GetMaster(), nil