UP
This commit is contained in:
parent
dddf56a2d6
commit
7f332aa88b
@ -980,21 +980,32 @@ func PathMedia(db *gorm.DB) http.HandlerFunc {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
type mediaDetailView struct {
|
||||||
|
Title string
|
||||||
|
Summary string
|
||||||
|
DurationFmt string
|
||||||
|
ThumbURL string
|
||||||
|
StreamURL string
|
||||||
|
}
|
||||||
|
|
||||||
// MediaDetail affiche la page détail + player
|
// MediaDetail affiche la page détail + player
|
||||||
func MediaDetail(db *gorm.DB) http.HandlerFunc {
|
func MediaDetail(db *gorm.DB) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// 1) Extraire le partID
|
||||||
partID, _ := strconv.ParseInt(mux.Vars(r)["partID"], 10, 64)
|
partID, _ := strconv.ParseInt(mux.Vars(r)["partID"], 10, 64)
|
||||||
|
|
||||||
// on récupère 1 metadata + file pour ce media_part
|
var view mediaDetailView
|
||||||
|
|
||||||
|
if partID > 0 {
|
||||||
|
// --- CAS BDD ---
|
||||||
var item struct {
|
var item struct {
|
||||||
models.MetadataItem
|
models.MetadataItem
|
||||||
MediaPartID int64
|
MediaPartID int64
|
||||||
File string
|
File string
|
||||||
|
UserThumbURL string
|
||||||
}
|
}
|
||||||
db.Table("metadata_items").
|
db.Table("metadata_items").
|
||||||
Select("metadata_items.*, media_parts.id AS media_part_id, media_parts.file").
|
Select("metadata_items.*, media_parts.id AS media_part_id, media_parts.file, metadata_items.user_thumb_url").
|
||||||
Joins("JOIN media_items ON media_items.metadata_item_id = metadata_items.id").
|
Joins("JOIN media_items ON media_items.metadata_item_id = metadata_items.id").
|
||||||
Joins("JOIN media_parts ON media_parts.media_item_id = media_items.id").
|
Joins("JOIN media_parts ON media_parts.media_item_id = media_items.id").
|
||||||
Where("media_parts.id = ?", partID).
|
Where("media_parts.id = ?", partID).
|
||||||
@ -1005,8 +1016,54 @@ func MediaDetail(db *gorm.DB) http.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTemplate(w, "media_detail", map[string]interface{}{
|
// formater la durée
|
||||||
"item": item,
|
m := item.Duration / 60
|
||||||
|
s := item.Duration % 60
|
||||||
|
view = mediaDetailView{
|
||||||
|
Title: item.Title,
|
||||||
|
Summary: item.Summary,
|
||||||
|
DurationFmt: strconv.FormatInt(m, 10) + ":" + fmt.Sprintf("%02d", s),
|
||||||
|
ThumbURL: item.UserThumbURL,
|
||||||
|
StreamURL: "/stream/" + strconv.FormatInt(item.MediaPartID, 10),
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// --- CAS FS-ONLY ---
|
||||||
|
path := r.URL.Query().Get("path")
|
||||||
|
if path == "" {
|
||||||
|
http.Error(w, "Média introuvable", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// titre
|
||||||
|
title := filepath.Base(path)
|
||||||
|
|
||||||
|
// génère un thumbnail si besoin
|
||||||
|
ext := filepath.Ext(path)
|
||||||
|
base := strings.TrimSuffix(filepath.Base(path), ext)
|
||||||
|
thumbDir := filepath.Join("static", "thumbs")
|
||||||
|
os.MkdirAll(thumbDir, 0755)
|
||||||
|
thumbPath := filepath.Join(thumbDir, base+".jpg")
|
||||||
|
if _, err := os.Stat(thumbPath); os.IsNotExist(err) {
|
||||||
|
// screenshot au 5s
|
||||||
|
exec.CommandContext(r.Context(),
|
||||||
|
"ffmpeg", "-ss", "5", "-i", path, "-frames:v", "1", thumbPath,
|
||||||
|
).Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
view = mediaDetailView{
|
||||||
|
Title: title,
|
||||||
|
Summary: "", // pas de résumé en FS-only
|
||||||
|
DurationFmt: "", // on ne probe pas ici
|
||||||
|
ThumbURL: "/static/thumbs/" + base + ".jpg",
|
||||||
|
// on passe le path en query pour le streaming
|
||||||
|
StreamURL: "/stream/0?path=" + url.QueryEscape(path),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) Render partial dans #content
|
||||||
|
renderPartial(w, "media_detail", map[string]interface{}{
|
||||||
|
"item": view,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
<div class="detail">
|
<div class="detail p-4">
|
||||||
<img src="{{.item.UserThumbURL}}" alt="{{.item.Title}}" class="cover">
|
<h1 class="text-2xl font-bold mb-4">{{.item.Title}}</h1>
|
||||||
<h1>{{.item.Title}}</h1>
|
{{with .item.Summary}}
|
||||||
{{with .item.Summary}}<p>{{.}}</p>{{end}}
|
<p class="mb-4">{{.}}</p>
|
||||||
<video controls autoplay width="100%" poster="{{.item.UserThumbURL}}">
|
{{end}}
|
||||||
<source src="/stream/{{.item.MediaPartID}}" type="video/mp4">
|
{{with .item.DurationFmt}}
|
||||||
|
<small class="text-gray-500">{{.}}</small>
|
||||||
|
{{end}}
|
||||||
|
<img src="{{.item.ThumbURL}}" alt="{{.item.Title}}" class="cover mb-4 rounded shadow" />
|
||||||
|
<video controls autoplay width="100%" class="rounded shadow">
|
||||||
|
<source src="{{.item.StreamURL}}" type="video/mp4">
|
||||||
Votre navigateur ne supporte pas la vidéo.
|
Votre navigateur ne supporte pas la vidéo.
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user