Full m3u8 generation

This commit is contained in:
the-m-monk
2025-12-30 01:55:26 +10:00
parent 60edd082af
commit 5f2a4930dd

View File

@@ -1,5 +1,83 @@
package api
func RegisterHlsEndpoints() {
import (
"bytes"
"fmt"
"math"
"net/http"
"os/exec"
"strconv"
"strings"
)
func RegisterHlsEndpoints() {
http.HandleFunc("/hls/index.m3u8", EndpointHlsM3U8)
}
/*
TODO: endpoint for clients to query a video's:
video tracks,
audio tracks,
captions
Then add support to existing endpoints for specifiying these 3 options
*/
func EndpointHlsM3U8(w http.ResponseWriter, r *http.Request) {
//TODO: clean up this mess
options := strings.Split(strings.Split(strings.Replace(r.URL.String(), "%20", " ", -1), "?")[1], "&")
//TODO: make the order of options not hardcoded
libPathName := strings.TrimPrefix(options[0], "lib=")
var lib Library
for _, l := range Libraries {
if l.PathName == libPathName {
lib = l
break
}
}
filePath := lib.Path + strings.TrimPrefix(options[1], "path=")
ffprobe := exec.Command(
"ffprobe",
"-v", "error",
"-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1",
filePath,
)
var ffprobeStdout bytes.Buffer
ffprobe.Stdout = &ffprobeStdout
err := ffprobe.Run()
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
fileLenStr := strings.TrimSuffix(ffprobeStdout.String(), "\n")
fileLenFloat, err := strconv.ParseFloat(fileLenStr, 64)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
fileLenFloat = math.Ceil(fileLenFloat/6.0) * 6.0
fileLenInt := int(fileLenFloat)
w.Header().Set("Content-Type", "application/vnd.apple.mpegurl")
fmt.Fprintln(w, "#EXTM3U")
fmt.Fprintln(w, "#EXT-X-VERSION:7")
//TODO: make this configurable
fmt.Fprintln(w, "#EXT-X-TARGETDURATION:6")
fmt.Fprintln(w, "#EXT-X-MEDIA-SEQUENCE:0")
for i := 0; i < fileLenInt/6; i++ {
fmt.Fprintln(w, "#EXTINF:6.0,")
fmt.Fprintf(w, "/hls/segment/%d.mp4?lib=%s&path=%s\n", i, lib.PathName, strings.TrimPrefix(options[1], "path="))
}
fmt.Fprintln(w, "#EXT-X-ENDLIST")
}