Exigences des En-têtes HTTP pour la Diffusion Vidéo
Problème
Les éléments vidéo HTML5 ne parviennent pas à lire avec une erreur « Impossible de charger la vidéo » même si les requêtes réseau affichent des réponses 200/206 réussies. Le fichier vidéo se télécharge correctement quand testé avec curl, mais les navigateurs refusent de le lire.
Contexte / Conditions de Déclenchement
- L'élément vidéo déclenche l'événement
onerrormalgré le succès réseau - L'onglet Network de DevTools affiche le statut 200 ou 206 pour les requêtes vidéo
curl -O <video-url>télécharge un fichier MP4 valide- La vidéo se lit localement une fois téléchargée
- Le message d'erreur est générique : « Impossible de charger la vidéo » ou code d'erreur média 4
Solution
En-têtes Requis pour la Diffusion Vidéo
-
Accept-Ranges: bytes(CRITIQUE)- Indique au navigateur que les requêtes en plage sont supportées
- Sans cela, les navigateurs peuvent ne pas tenter les requêtes en plage pour la navigation
- Ajouter à TOUTES les réponses vidéo, même les réponses complètes (200)
-
Content-Type: video/mp4(ou type MIME approprié)- Doit correspondre au format vidéo réel
- Le navigateur l'utilise pour sélectionner le décodeur
-
Content-Length(pour les réponses complètes)- Requis pour que le navigateur connaisse la taille du fichier
- Active les indicateurs de progression et les calculs de navigation
- Note : Pour les réponses 206, ce doit être la taille du contenu partiel
-
Pour les Requêtes en Plage (206 Contenu Partiel):
Content-Range: bytes DÉBUT-FIN/TOTAL- Le code de statut DOIT être 206, pas 200
Implémentation Serveur
// Exemple Fastly Compute@Edge
resp.set_header("Accept-Ranges", "bytes");
resp.set_header("Content-Type", "video/mp4");
// Pour les réponses complètes uniquement (pas 206):
if resp.get_status() != StatusCode::PARTIAL_CONTENT {
resp.set_header("Content-Length", file_size.to_string());
}
Considérations CDN
- Les caches edge peuvent retirer ou modifier les en-têtes
- Vérifier que les en-têtes atteignent le client, pas seulement l'origine
- Fastly/CloudFront peuvent servir les requêtes en plage à partir du contenu complet en cache
- Tester avec
curl -I -H "Range: bytes=0-1023"pour vérifier la réponse 206
Vérification
# Vérifier l'en-tête Accept-Ranges
curl -I https://cdn.example.com/video.mp4 | grep -i accept-ranges
# Attendu : accept-ranges: bytes
# Tester le support des requêtes en plage
curl -I -H "Range: bytes=0-1023" https://cdn.example.com/video.mp4
# Attendu : HTTP/2 206 avec en-tête Content-Range
# Vérifier que le téléchargement partiel fonctionne
curl -H "Range: bytes=0-100" https://cdn.example.com/video.mp4 | wc -c
# Attendu : 101 (octets 0-100 inclus)
Exemple
Avant (cassé):
HTTP/2 200
content-type: video/mp4
x-custom-header: value
La vidéo ne se charge pas dans le navigateur.
Après (fonctionnant):
HTTP/2 200
content-type: video/mp4
content-length: 1443199
accept-ranges: bytes
La vidéo se lit correctement avec support de navigation.
Notes
- Même si votre CDN gère automatiquement les requêtes en plage, vous devriez toujours inclure
Accept-Ranges: bytesdans les en-têtes de réponse - Certains navigateurs sont plus tolérants que d'autres ; Safari exige souvent un support correct des plages tandis que Chrome peut fonctionner sans
- Les réponses HTTP/2 peuvent avoir les en-têtes en minuscules (c'est normal)
- Pour la diffusion HLS/DASH, le manifeste et les segments ont tous besoin des en-têtes appropriés
- Les navigateurs mobiles sont particulièrement stricts concernant les en-têtes vidéo