up
This commit is contained in:
parent
88aad929db
commit
4b5028e9f9
@ -995,6 +995,14 @@ func MediaDetail(db *gorm.DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
partID, _ := strconv.ParseInt(mux.Vars(r)["partID"], 10, 64)
|
||||
|
||||
// 2) Récupérer pathID et sub depuis la query string
|
||||
pathIDStr := r.URL.Query().Get("pathID")
|
||||
sub := r.URL.Query().Get("sub")
|
||||
var pathID int64
|
||||
if pathIDStr != "" {
|
||||
pathID, _ = strconv.ParseInt(pathIDStr, 10, 64)
|
||||
}
|
||||
|
||||
var view mediaDetailView
|
||||
|
||||
if partID > 0 {
|
||||
@ -1061,43 +1069,15 @@ func MediaDetail(db *gorm.DB) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
renderPartial(w, "media_detail", map[string]interface{}{
|
||||
"item": view,
|
||||
})
|
||||
renderPartial(w, "media_detail", map[string]interface{}{
|
||||
"PathID": pathID,
|
||||
"CurrentSub": sub,
|
||||
"item": view,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Stream : transcode à la volée en MP4 progressif et pipe directement dans la réponse
|
||||
func Stream(db *gorm.DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
partID, _ := strconv.ParseInt(mux.Vars(r)["partID"], 10, 64)
|
||||
var part models.MediaPart
|
||||
if err := db.First(&part, partID).Error; err != nil {
|
||||
http.Error(w, "Not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "video/mp4")
|
||||
// ffmpeg en pipe
|
||||
cmd := exec.CommandContext(r.Context(),
|
||||
"ffmpeg",
|
||||
"-i", part.File,
|
||||
"-c:v", "libx264",
|
||||
"-c:a", "aac",
|
||||
"-movflags", "frag_keyframe+empty_moov+faststart",
|
||||
"-f", "mp4",
|
||||
"pipe:1",
|
||||
)
|
||||
cmd.Stdout = w
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Println("ffmpeg:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// renders/media.go (ajoutez cette fonction)
|
||||
// rend le HLS pour BDD (partID>0) et FS-only (partID==0)
|
||||
func HLSStream(db *gorm.DB) http.HandlerFunc {
|
||||
|
||||
@ -1,7 +1,30 @@
|
||||
{{define "media_detail.pages.tmpl"}}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="box">
|
||||
<!-- Fil d’Ariane -->
|
||||
<nav class="breadcrumb mb-4" aria-label="breadcrumbs">
|
||||
<ul>
|
||||
<li>
|
||||
<a
|
||||
hx-get="/api/paths/{{.PathID}}/media"
|
||||
hx-push-url="/api/paths/{{.PathID}}/media"
|
||||
hx-target="#content"
|
||||
hx-swap="innerHTML">
|
||||
Accueil
|
||||
</a>
|
||||
</li>
|
||||
{{if .CurrentSub}}
|
||||
<li>
|
||||
<a>{{.CurrentSub}}</a>
|
||||
</li>
|
||||
{{end}}
|
||||
<li class="is-active">
|
||||
<a aria-current="page">{{.item.Title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="box">
|
||||
<!-- Bloc détail -->
|
||||
<div id="detail-block">
|
||||
<div class="columns is-vcentered">
|
||||
@ -34,43 +57,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
document.body.addEventListener('click', function(e) {
|
||||
// Play
|
||||
const playBtn = e.target.closest('.js-play-btn');
|
||||
if (playBtn) {
|
||||
const detailBlock = document.getElementById('detail-block');
|
||||
const playerBlock = document.querySelector('.js-player-block');
|
||||
const video = document.getElementById('hls-video');
|
||||
const url = playBtn.dataset.hlsurl;
|
||||
|
||||
detailBlock.style.display = 'none';
|
||||
playerBlock.style.display = 'block';
|
||||
|
||||
if (Hls.isSupported()) {
|
||||
const hls = new Hls();
|
||||
hls.loadSource(url);
|
||||
hls.attachMedia(video);
|
||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
video.src = url;
|
||||
} else {
|
||||
console.error('HLS non supporté');
|
||||
// Gestion des boutons Play et Fermer
|
||||
document.body.addEventListener('click', function(e) {
|
||||
const playBtn = e.target.closest('.js-play-btn');
|
||||
if (playBtn) {
|
||||
document.getElementById('detail-block').style.display = 'none';
|
||||
document.querySelector('.js-player-block').style.display = 'block';
|
||||
const video = document.getElementById('hls-video');
|
||||
const url = playBtn.dataset.hlsurl;
|
||||
if (Hls.isSupported()) {
|
||||
const hls = new Hls(); hls.loadSource(url); hls.attachMedia(video);
|
||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
video.src = url;
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fermer
|
||||
const closeBtn = e.target.closest('.js-close-btn');
|
||||
if (closeBtn) {
|
||||
const detailBlock = document.getElementById('detail-block');
|
||||
const playerBlock = document.querySelector('.js-player-block');
|
||||
const video = document.getElementById('hls-video');
|
||||
|
||||
video.pause();
|
||||
video.src = '';
|
||||
playerBlock.style.display = 'none';
|
||||
detailBlock.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
const closeBtn = e.target.closest('.js-close-btn');
|
||||
if (closeBtn) {
|
||||
const video = document.getElementById('hls-video');
|
||||
video.pause(); video.src = '';
|
||||
document.querySelector('.js-player-block').style.display = 'none';
|
||||
document.getElementById('detail-block').style.display = 'block';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
@ -28,8 +28,12 @@
|
||||
<div class="column is-one-quarter">
|
||||
<div class="card">
|
||||
<div class="card-content has-text-centered">
|
||||
<a hx-get="/api/paths/{{$.PathID}}/media?sub={{.SubPath | urlquery}}"
|
||||
hx-target="#content" hx-swap="innerHTML">
|
||||
<a
|
||||
hx-get="/media/{{.MediaPartID}}?path={{.FilePath | urlquery}}&pathID={{$.PathID}}&sub={{$.CurrentSub}}"
|
||||
hx-push-url="/media/{{.MediaPartID}}?path={{.FilePath | urlquery}}&pathID={{$.PathID}}&sub={{$.CurrentSub}}"
|
||||
hx-target="#content"
|
||||
hx-swap="innerHTML"
|
||||
>
|
||||
<span class="icon is-large">
|
||||
<i class="fas fa-folder fa-2x"></i>
|
||||
</span>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user