V0.703 Release Scope — Go Live & Streaming Complet
Statut : En cours
Phase : 7 (Production Readiness — Finale)
Prérequis : v0.702 (taguée)
Date cible : TBD
Estimation : ~3 sprints (15 jours ouvrés)
Précédente : v0.702
1. Objectif
Dernière version de la Phase 7. Complète le module Live Streaming en ajoutant la fonctionnalité Go Live (démarrage de stream), actuellement bloquée par un toast "coming soon" dans la Navbar. Ajoute la gestion de stream keys, les endpoints start/stop/schedule, le chat live connecté WebSocket, et des améliorations player (vitesse de lecture, Media Session API).
2. État actuel (post-v0.702)
Composant
État
Détail
LiveStream model
✅ Livré
live_streams table, GORM model avec StreamKey (json:"-")
GET /live/streams
✅ Livré
Liste publique, filtre ?is_live=true
GET /live/streams/:id
✅ Livré
Détail d'un stream
POST /live/streams
✅ Livré
Création (auth required), mais pas de stream key generation
Stream events handler
✅ Livré
POST /internal/stream-events (stream_started, stream_ended, listener_joined, listener_left)
LiveView (frontend)
✅ Livré
Visualisation de streams (player, info, recommended, chat mock)
Go Live (frontend)
❌ Absent
Navbar "Go Live" → toast "coming soon"
Stream key generation
❌ Absent
StreamKey field exists mais jamais généré ni exposé
GET /live/streams/my/key
❌ Absent
Endpoint pour récupérer sa stream key
PUT /live/streams/:id
❌ Absent
Mise à jour métadonnées pendant le live
Stream scheduling
❌ Absent
Pas de scheduled_at pour planifier un stream
Live chat WebSocket
❌ Absent
LiveViewChat utilise des données mock statiques
VOD (replays)
❌ Absent
Streams terminés non consultables
Playback speed
❌ Absent
Pas de contrôle 0.5x–2x
Media Session API
❌ Absent
Pas de contrôles OS (notification area)
3. Lots
Lot GL1 — Go Live Backend
Objectif : Compléter l'API live streaming avec stream key, mise à jour, scheduling et VOD.
#
Tâche
Fichiers impactés
Effort
GL1-01
Migration 117_live_streams_go_live.sql — ajout colonnes scheduled_at, stream_url, is_vod ; update stream_key NOT NULL avec default UUID
migrations/117_live_streams_go_live.sql
S
GL1-02
Mise à jour modèle LiveStream — ajout champs ScheduledAt, StreamURL, IsVOD
internal/models/live_stream.go
S
GL1-03
GenerateStreamKey dans service — génère un UUID v4 unique pour stream_key lors du Create
internal/services/live_stream_service.go
S
GL1-04
GET /live/streams/me — liste les streams de l'utilisateur authentifié (incluant stream_key)
internal/handlers/live_stream_handler.go, routes
M
GL1-05
GET /live/streams/me/key — retourne la stream key de l'utilisateur (crée un stream draft si nécessaire)
internal/handlers/live_stream_handler.go, routes
S
GL1-06
POST /live/streams/me/key/regenerate — régénère la stream key
internal/handlers/live_stream_handler.go, routes
S
GL1-07
PUT /live/streams/:id — mise à jour titre/description/category/tags pendant ou avant le live
internal/handlers/live_stream_handler.go, routes
S
GL1-08
GET /live/streams?is_vod=true — listing des streams terminés (VOD replays)
func(s*LiveStreamService)Create(ctxcontext.Context,userIDuuid.UUID,stream*models.LiveStream)(*models.LiveStream,error){ifstream.Title==""{returnnil,errors.New("title is required")}stream.UserID=userIDstream.StreamKey=uuid.New().String()ifstream.StreamerName==""{stream.StreamerName="Streamer"}iferr:=s.repo.Create(ctx,stream);err!=nil{returnnil,err}returnstream,nil}
5.4 GET /live/streams/me/key
func(h*LiveStreamHandler)GetMyStreamKey(c*gin.Context){userID,ok:=GetUserIDUUID(c)if!ok{return}streams,err:=h.service.ListByUser(c.Request.Context(),userID)iferr!=nil{RespondWithAppError(c,apperrors.Wrap(apperrors.ErrCodeInternal,"Failed to get streams",err))return}varstreamKeystringiflen(streams)>0{streamKey=streams[0].StreamKey}else{draft:=&models.LiveStream{Title:"My Stream"}created,err:=h.service.Create(c.Request.Context(),userID,draft)iferr!=nil{RespondWithAppError(c,apperrors.Wrap(apperrors.ErrCodeInternal,"Failed to create stream",err))return}streamKey=created.StreamKey}RespondSuccess(c,http.StatusOK,gin.H{"stream_key":streamKey,"rtmp_url":"rtmp://stream.veza.app/live",})}
5.5 VOD — Streams terminés
Quand SetIsLive(false) est appelé (stream_ended event), le stream reste en DB avec ended_at set. On ajoute un filtre is_vod qui retourne les streams avec ended_at IS NOT NULL AND is_live = false.
5.6 Scheduled Streams
Le champ scheduled_at permet de planifier un stream futur. L'endpoint POST /live/streams accepte scheduled_at dans le body. Le frontend affiche les streams planifiés avec un badge "Scheduled" et un countdown.
Connection Info — RTMP URL + stream key, instructions OBS/Streamlabs
Preview — thumbnail upload, scheduled_at picker
Actions — bouton "Go Live Now" ou "Schedule Stream"
6.2 Navbar update
// Avant (toast)
onClick={()=>toast.info('Live streaming feature coming soon')}// Après (navigation)
onClick={()=>{onNavigate('go-live');setShowUserMenu(false);}}
7. Détail technique — Lot GL4
7.1 Playback Speed
constSPEED_OPTIONS=[0.5,0.75,1,1.25,1.5,2];functionPlaybackSpeedButton({currentSpeed,onSpeedChange}:Props){// Cycle through speeds on click, or dropdown on hover
}