IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Stream par script PHP plantant avec HTML5 <video> et <audio> [PHP 5.3]


Sujet :

Langage PHP

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Stream par script PHP plantant avec HTML5 <video> et <audio>
    Bonjour,

    Comme l'indique le titre de ce post, le problème est assez complexe...

    Je développe une application Ajax qui, entre autres, gère des documents (une sorte de GED). Dans cette appli, je lis si possible les documents dont je connais le type MIME (donc video, pdf, audio, image, txt...). Pour lire les vidéo et fichiers audio, j'utilise les balises HTML 5 correspondantes.

    Le lien utilisé n'est pas le lien réel (pour des raisons de sécurité), je fais donc un simili streaming du fichier... Ce faux stream est récupéré depuis un autre point d'entrée (donc pas en Ajax) permettant le téléchargement et la lecture du fichier (c'est la même fonction, donc sensiblement les mêmes headers, avec une différence sur le type "application/force-download" qui est changé si je veux faire de la lecture, et le header attachment qui est enlevé si je veux rester en lecture)

    Seulement selon la taille de la vidéo ou du fichier audio, selon l'avancement du streaming ou de la mise en cache, lorsque je rafraichis le div contenant mes balises de lecture audio ou video, parfois la lecture est complètement bloquée, les vidéos suivantes ne se lancent pas, certaines pistes audio ne se lancent plus... Seul un F5 répare la chose... Et c'est relativement aléatoire... De ce que j'ai vu, ça fait un truc du genre :

    - Vidéo de 3mn HD MP4 (~38 Mo) : si pas complètement chargée, elle plante pour le reste de l'appli (entraîne généralement les balises video suivantes complètement bloquées) ; si visionnée jusqu'au bout, on changer le contenu du div autant qu'on veut, elle se relancera (mais il faut toujours la regarder jusqu'au bout)

    - Vidéo de 20s 360P MP4 (1 à 2 Mo): Aucun souci à aucun moment, je peux changer en plein milieu de la lecture, quand je veux, ça plante jamais l'appli

    - Audio (MP3) de moins de 10 Mo : ça plante parfois après cinq changements d'onglets (les onglets sont le basculement entre les "propriétés" du fichier et l'aperçu, donc c'est le fameux rafraichissement de div qui plante ^^), pourquoi cinq aucune idée... Quand ça plante ce n'est pas bloquant sur les autres balise "audio", qui reste généralement utilisable...

    - Audio (MP3) de plus de 10 Mo : ça plante généralement après un seul changement d'onglet, impossible de relancer ce fichier là, là encore normalement pas bloquant...


    A savoir que je n'ai pas ce problème si je mets le lien réel du fichier (sans passer par le fameux fichier php), mais du coup la sécurité en prend un coup, et ce n'est pas acceptable. D'autant qu'à terme de toute manière, ce dossier sera indisponible au public, d'où la nécessité de passer par un fichier qui vérifie les droits d'accès tout ça...

    Pour info, la fonction PHP qui gère le download et donc la lecture aussi c'est ça (elle est dans un namespace tout ça, vous inquiétez pas sur les \Exception ^^) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    public static function download($sFilePath, $sFileName, $nFileSize = 0, $sContentType = 'application/force-download') {
     
    	try {
     
    		// Verification de l'existance du doc dans la BDD
    		if (empty($sFilePath)) 
    			throw new \Exception('Le chemin vers le fichier n\'a pas été spécifié.');
     
    		// Vérification de l'existance du fichier
    		if (!file_exists($sFilePath))
    			throw new \Exception('Le fichier demandé est introuvable sur le serveur de fichiers !!<br/>'.$sFilePath);
     
    		// Calcul de la taille du fichier si non spécifiée
    		$nFileSize = ($nFileSize == 0)? filesize($sFilePath) : $nFileSize; 
     
    		// Entetes HTTP
    		header("Content-Type: {$sContentType}; name=\"{$sFileName}\"");
    		header("Content-Length: ". $nFileSize); 
    		if ($sContentType == 'application/force-download')
    			header("Content-Disposition: attachment; filename=\"{$sFileName}\""); 
    		header("Expires: 0"); 
    		header("Cache-Control: no-cache, must-revalidate"); 
    		header("Pragma: no-cache"); 
     
    		// Récupération du contenu et intégration dans le flux HTTP
    		readfile($sFilePath);
     
    		exit;
    	}
    	catch (\Exception $e) {
     
    		header('Content-type: text/html; charset=UTF-8'); 
     
    		echo '<html><head><style>*{font-size:12pt;font-family:Trebuchet MS;}</style><title>Fichier non téléchargé</title></head><body><center>'. $e->getMessage() .'</center></body></html>';
     
    		die;
    	}
     
    }
    Alors est-ce que ça pourrait venir du cache control, du pragma ? Sachant que ces quelques lignes là je ne sais absolument pas à quoi elles servent (mais n'étant pas seul sur le projet, je pense que si elles y sont elles ont une bonne raison d'y être ^^)

    Merci d'avance pour votre aide

  2. #2
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    enlève les caches, met un Etag à la place

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    J'ai un peu de mal à comprendre comment fonctionne l'etag ? La doc de PHP ne me parle pas des masses, et il n'y a pas masse exemple :/

  4. #4
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par Renkineko Voir le message
    J'ai un peu de mal à comprendre comment fonctionne l'etag ? La doc de PHP ne me parle pas des masses, et il n'y a pas masse exemple :/
    normale c'est pas du PHP mais du HTTP
    mais un header Etag avec le hash (md5 ou sha1) du fichier

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Je demande approbation avant de modifier le code ^^

    Ce serait un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    public static function download($sFilePath, $sFileName, $nFileSize = 0, $sContentType = 'application/force-download') {
     
    	try {
     
    		// Verification de l'existance du doc dans la BDD
    		if (empty($sFilePath)) 
    			throw new \Exception('Le chemin vers le fichier n\'a pas été spécifié.');
     
    		// Vérification de l'existance du fichier
    		if (!file_exists($sFilePath))
    			throw new \Exception('Le fichier demandé est introuvable sur le serveur de fichiers !!<br/>'.$sFilePath);
     
    		// Calcul de la taille du fichier si non spécifiée
    		$nFileSize = ($nFileSize == 0)? filesize($sFilePath) : $nFileSize; 
    		$hMD5 = md5_file($sFilePath);
     
    		// Entetes HTTP
    		header("Content-Type: {$sContentType}; name=\"{$sFileName}\"");
    		header("Content-Length: ". $nFileSize); 
    		if ($sContentType == 'application/force-download')
    			header("Content-Disposition: attachment; filename=\"{$sFileName}\""); 
    		header("Expires: 0"); 
    		header("ETag: {$hMD5}"); 
    		header("Pragma: no-cache"); // A Laisser ici lui ou pas ?
     
    		// Récupération du contenu et intégration dans le flux HTTP
    		readfile($sFilePath);
     
    		exit;
    	}
    	catch (\Exception $e) {
     
    		header('Content-type: text/html; charset=UTF-8'); 
     
    		echo '<html><head><style>*{font-size:12pt;font-family:Trebuchet MS;}</style><title>Fichier non téléchargé</title></head><body><center>'. $e->getMessage() .'</center></body></html>';
    	//	echo STD::trace($e);
     
    		die;
    	}
     
    }
    Comme indiqué dans le code : j'ai viré le cache control pour mettre un header etag, mais j'ai pas vraiment trouvé beaucoup d'explications sur google...

    Donc de là, plusieurs questions : est-ce que j'utilise le etag correctement (bonne syntaxe, tout ça) ? Est-ce que je continue à utiliser la fonction readfile, ou dois-je passer par une autre fonction comme http_send_stream ou http_send_file ? Est-ce que je dois virer le "Pragma" ? Qu'est-ce que c'est d'ailleurs, le Pragma ? (pour cette dernière, j'pense pouvoir trouver la réponse tout seul sur le net, mais j'la met dans la foulée...)

  6. #6
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    enlève Expires et Pragma

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Ok c'est tout bon, donc pour info voilà la version revisitée ^^

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    public static function download($sFilePath, $sFileName, $nFileSize = 0, $sMD5 = '', $sContentType = 'application/force-download') {
    	try {
     
    		// Verification de l'existance du doc dans la BDD
    		if (empty($sFilePath)) 
    			throw new \Exception('Le chemin vers le fichier n\'a pas été spécifié.');
     
    		// Vérification de l'existance du fichier
    		if (!file_exists($sFilePath))
    			throw new \Exception('Le fichier demandé est introuvable sur le serveur de fichiers !!<br/>'.$sFilePath);
     
    		// Calcul de la taille du fichier si non spécifiée
    		$nFileSize = ($nFileSize == 0)? filesize($sFilePath) : $nFileSize; 
    		if (empty($sMD5))
    			$sMD5 = md5_file($sFilePath);
     
    		// Entetes HTTP
    		header("Content-Type: {$sContentType}; name=\"{$sFileName}\""); 
    		header("Content-Length: ". $nFileSize); 
    		if ($sContentType == 'application/force-download')
    			header("Content-Disposition: attachment; filename=\"{$sFileName}\""); 
    		header("ETag: {$sMD5}");
     
    		// Récupération du contenu et intégration dans le flux HTTP
    		readfile($sFilePath);
     
    		exit;
    	}
    	catch (\Exception $e) {
     
    		header('Content-type: text/html; charset=UTF-8'); 
    		echo '<html><head><style>*{font-size:12pt;font-family:Trebuchet MS;}</style><title>Fichier non téléchargé</title></head><body><center>'. $e->getMessage() .'</center></body></html>';
    		die;
    	}
     
    }
    Par contre, une chose me turlupine. Le coup de l'eTag, c'est compatible pour absolument tous les navigateurs tout ça ?

  8. #8
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Oui c'est du standard HTTP

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Insert passe sur Phpmyadmin et plante par script php
    Par Camillo dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 19/07/2014, 00h34
  2. Lancer un script php planifié (avec exec() ) ?
    Par beegees dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 20/12/2010, 09h51
  3. Concaténation de CSS par script PHP
    Par nomasis dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 18/08/2008, 14h15
  4. [Mail] Cherche script PHP mail avec pièce jointe
    Par malabarbe dans le forum Langage
    Réponses: 8
    Dernier message: 17/06/2008, 12h02
  5. [MySQL] Problème de backup par script PHP
    Par bagu dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 30/04/2006, 16h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo