Full m3u8 generation
This commit is contained in:
@@ -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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user