up
This commit is contained in:
parent
aa2433bee8
commit
12e9c11536
@ -1057,7 +1057,7 @@ func MediaDetail(db *gorm.DB) http.HandlerFunc {
|
||||
DurationFmt: "", // on ne probe pas ici
|
||||
ThumbURL: "/static/thumbs/" + base + ".jpg",
|
||||
// on passe le path en query pour le streaming
|
||||
HLSURL: fmt.Sprintf("/hls/%d/index.m3u8", partID),
|
||||
HLSURL: "/hls/0/index.m3u8?path=" + url.QueryEscape(path),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,25 +1101,38 @@ func Stream(db *gorm.DB) http.HandlerFunc {
|
||||
// renders/media.go (ajoutez cette fonction)
|
||||
func HLSStream(db *gorm.DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// 1) identifier le média
|
||||
partID, _ := strconv.ParseInt(mux.Vars(r)["partID"], 10, 64)
|
||||
vars := mux.Vars(r)
|
||||
partID, _ := strconv.ParseInt(vars["partID"], 10, 64)
|
||||
|
||||
// Déterminer le fichier source
|
||||
var filePath string
|
||||
if partID > 0 {
|
||||
// cas BDD
|
||||
var part models.MediaPart
|
||||
if err := db.First(&part, partID).Error; err != nil {
|
||||
http.Error(w, "Média introuvable", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
filePath = part.File
|
||||
} else {
|
||||
// cas FS-only
|
||||
filePath = r.URL.Query().Get("path")
|
||||
if filePath == "" {
|
||||
http.Error(w, "Média introuvable", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 2) dossier temporaire / cache
|
||||
// Préparer le dossier de cache HLS
|
||||
tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("hls_%d", partID))
|
||||
os.MkdirAll(tmpDir, 0755)
|
||||
playlist := filepath.Join(tmpDir, "index.m3u8")
|
||||
|
||||
// 3) si besoin, (re)générer l’HLS via ffmpeg
|
||||
// (Re)générer si nécessaire
|
||||
if _, err := os.Stat(playlist); os.IsNotExist(err) {
|
||||
// ffmpeg -i input -c:v copy -c:a copy -f hls -hls_time 4 -hls_list_size 0 tmp/index.m3u8
|
||||
cmd := exec.CommandContext(r.Context(),
|
||||
"ffmpeg",
|
||||
"-i", part.File,
|
||||
"-i", filePath,
|
||||
"-c:v", "copy", "-c:a", "copy",
|
||||
"-f", "hls",
|
||||
"-hls_time", "4",
|
||||
@ -1129,14 +1142,14 @@ func HLSStream(db *gorm.DB) http.HandlerFunc {
|
||||
)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
log.Println("ffmpeg HLS error:", err, string(out))
|
||||
http.Error(w, "Erreur de transcodage", 500)
|
||||
http.Error(w, "Erreur de transcodage", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 4) servir le dossier HLS en statique
|
||||
http.StripPrefix(
|
||||
fmt.Sprintf("/hls/%d/", partID),
|
||||
// Servir le dossier HLS
|
||||
prefix := fmt.Sprintf("/hls/%d/", partID)
|
||||
http.StripPrefix(prefix,
|
||||
http.FileServer(http.Dir(tmpDir)),
|
||||
).ServeHTTP(w, r)
|
||||
}
|
||||
@ -1145,6 +1158,7 @@ func HLSStream(db *gorm.DB) http.HandlerFunc {
|
||||
|
||||
|
||||
|
||||
|
||||
func renderPartial(w http.ResponseWriter, templ string, data map[string]interface{}) {
|
||||
// Exécute directement le define `<templ>.pages.tmpl`
|
||||
if err := templates.ExecuteTemplate(w, templ+".pages.tmpl", data); err != nil {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user