Salut à tous,
Voilà au moins 2 semaines que je suis sur ce problème tout bête Smiley ohwell
Alors je m'explique je souhaite faire un mini-programme de visio-chat (chat avec caméra).
Le principe est que mon script javascript accède a la caméra, récupère le flux vidéo et l'encode en base64, jusque là c'est parfait, ensuite j'envoie le base64 généré via un post en xmlhttprequest vers une page php qui stocke le tout dans une base de donnée.
Le code :

<!doctype html>
<html>
<head>
<title>CamCam</title>
</head>
<body>
<canvas id="canvas">
</canvas>
<video id="video">
</video>
<input type="button" value="cheese" onclick="prendre()"/>
<script>
function getXMLHttpRequest() {
	var xhr = null;
	
	if (window.XMLHttpRequest || window.ActiveXObject) {
		if (window.ActiveXObject) {
			try {
				xhr = new ActiveXObject('Msxml2.XMLHTTP');
			} catch(e) {
				xhr = new ActiveXObject('Microsoft.XMLHTTP');
			}
		} else {
			xhr = new XMLHttpRequest(); 
		}
	} else {
		alert('Votre navigateur ne supporte pas l\'objet XMLHTTPRequest...');
		return null;
	}
	
	return xhr;
}
var canvas=document.getElementById('canvas');var ctx=canvas.getContext('2d'), streaming=false, width=600, height=450, video=document.getElementById('video');
  function init() {
    navigator.getMedia = ( navigator.getUserMedia ||
                           navigator.webkitGetUserMedia ||
                           navigator.mozGetUserMedia ||
                           navigator.msGetUserMedia);

    navigator.getMedia(
      {
        video: true,
        audio: false
      },
      function(stream) {
        if (navigator.mozGetUserMedia) {
          video.mozSrcObject = stream;
        } else {
          var vendorURL = window.URL || window.webkitURL;
          video.src = vendorURL ? vendorURL.createObjectURL(stream) : stream;
        }
        video.play();
      },
      function(err) {
        console.log("Une erreur est survenue " + err);
      }
    );
  }

  function prendre() {
    var finalheight=video.videoHeight / (video.videoWidth/width);
    ctx.save();
    ctx.translate(width, 0);
    ctx.scale(-1, 1);
    ctx.drawImage(video, 0, 0, width, finalheight);
    ctx.restore();
    ctx.scale(1, 1);
	var xhr=getXMLHttpRequest();
	xhr.onreadystatechange = function() {
		if(xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0))
		{
			
		}
	};
   xhr.open('POST', 'http://192.168.0.131/camcam/traite.php', true);
   xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   xhr.setRequestHeader("Content-length", (canvas.toDataURL()).length);
   xhr.send('flux=' + canvas.toDataURL());
  }
init();
</script>
</body>
</html>

L'autre code (php) :

<?php
try
{
	$bdd = new PDO('mysql:host=localhost;dbname=camcam', 'root', '********');
	$bdd->exec('SET CHARACTER SET utf8');
}
catch(Exception $e)
{
	die('Erreur : '.$e->getMessage());
}
if(isset($_POST['flux']))
{
		$insert=$bdd->prepare('INSERT INTO flux_utilisateur (utilisateur, flux) VALUES(:pseudo, :flux)');
		$insert->execute(array(
			'flux' => $_POST['flux'],
			'pseudo' => '******',
		));
}
else
{
	$cam=$bdd->query('SELECT * FROM flux_utilisateur WHERE pseudo=******');
	$res=$cam->fetch();
	echo '<img src="' . $res['flux'] . '" alt="Erreur lors de la récupération du flux"/>';
}
?>


Voilà, lors de la sortie du code base64 de la base de donnée il devient invalide. Smiley decu

Merci d'avance pour votre aide @+
Modifié par pinguix40 (12 Jul 2013 - 13:46)
Qu'est ce que tu entends par "il devient invalide" ? Tu ne peux plus le décoder ? Si tu compares la chaîne envoyée avec celle enregistrée dans ta base de données, est-ce qu'elles sont identiques ?
Salut,
En disant qu'il devient invalide c'est que je ne peux plus le décoder. Et très bonne idée pour les vérification je vais m'y mettre maintenant. Smiley cligne
PS : Le rang de la bdd flux a pour type "LONGTEXT" et est capable d’accueillir 5000000 caractère Smiley biggol
Merci @+
Salut,
Alors les chaînes envoyée et stockée dans la bdd sont de longueur égale mais sont différentes, mais je ne vois pas du tout en quelle point Smiley ohwell Smiley bawling
Merci encore @+ Smiley cligne
Tu as posté ici le code qui encode ta vidéo en base64 en javascript, mais pourrais-tu poster le code qui décode ?
ET d'ailleurs, à quel moment décodes-tu ? sur le client en javascript ? sur le serveur en php, ou directement en SQL ?
S'il est présent, mes excuses, mais je ne le vois pas.

Est-ce que tu as comparé que la longueur des chaînes, ou as-tu fait un test d'égalité exact ?

Sais-tu qu'il existe différentes versions de base64 ? JE dis ça parce que je préssens (sans avoir testé) que canvas encode en base64 URL safe, tandis que le décodage côté serveur avec php ou MySQL se fait nécessairement en base64 standard. En plus court et plus clair, essaie de remplacer les - par des 1 et les _ par des / dans la chaîne quand tu passes de js à php, et le contraire dans l'autre sens.
Salut, je pense m'avoir (très) mal expliqué, le base64 ne se fait pas décoder mais plutôt stocker dans la bdd, et, lors de la demande de l'utilisateur, affiché dans l'attribut src d'une balise img, merci quand même pour ta réponse qui m'a fait découvrir quelque chose Smiley biggrin .
Le code php :

<?php
try
{
	$bdd = new PDO('mysql:host=localhost;dbname=camcam', 'root', '********');
	$bdd->exec('SET CHARACTER SET utf8');
}
catch(Exception $e)
{
	die('Erreur : '.$e->getMessage());
}
if(isset($_POST['flux']))
{
		$insert=$bdd->prepare('INSERT INTO flux_utilisateur (utilisateur, flux) VALUES(:pseudo, :flux)');
		$insert->execute(array(
			'flux' => $_POST['flux'],
			'pseudo' => '******',
		));
}
else
{
	$cam=$bdd->query('SELECT * FROM flux_utilisateur WHERE pseudo=******');
	$res=$cam->fetch();
	echo '<img src="' . $res['flux'] . '" alt="Erreur lors de la récupération du flux"/>';
}
?>

Merci encore pour ta réponse @+
Modifié par pinguix40 (09 Jul 2013 - 13:25)
Tu n'aurais pas un petit exemple de ce que pourrait contenir $res['flux'] ? Il suffit que ça ne soit pas strictement conforme aux RFC de data URI et de base64 pour que ça ne fonctionne pas et que tu obtiennes un magnifique message d'erreur très peu explicite du genre "le format n'est pas reconnu". Les navigateurs sont extrêmement chiants et avares de détails dans ce genre de situation...

D'ailleurs, tu n'as pas d'erreur dans les consoles (p.ex. firebug ? ou bien c'est juste une erreur totalement bidon ?

Un autre test qui pourrait être intéressant à faire est le suivant: tu prends une des chaînes stockées dans la base, tu la décodes avec un utilitaire (ça se trouve), tu l'enregistres dans un fichier binaire du bon type et tu essaies de l'ouvrir avec un logiciel de dessin. Ca te donnera peut-être plus d'indications sur ce qui ne va pas, et ça te permettra peut-être de réaliser qu'en fait les données sont dans un autre format que celui qui est indiqué... je ne serais pas surpris que ça arrive et que ça suffise à ne pas faire fonctionner le machin.

Petite note d'accessibilité: la'ttribut alt n'est pas du tout conçu pour recevoir des indications d'erreur comme tu le fais ici; idéalement il faudrait tester si le chargement a réussi autrement, par exemple en javascript.
Salut, pour le petit exemple, $res['flux'] contient le flux de la camera encodé en base64, exemple : "data:image/png;base64,iV...".
J'ai également suivi ton conseil, j'ai enregistré dans un fichier le base64 décodé et une erreur est apparue lors de l'ouverture avec GIMP il m'indique "fichier endommagé ?", dans le terminal celui-ci renvoie une erreur "Not a PNG file". Et la console Web de Firefox ne m'avance pas plus.
Effectivement, l'attribut alt n'est pas conçus pour ça, je l'utilise seulement lors de la partie développement.

Merci encore pour ta réponse, @+ Smiley smile
Essaie .bmp, .gif, .jpg, .zip, .gz.... soyons fous, on ne sait jamais.

Et sinon, je crois qu'il va falloir sortir l'éditeur hexadécimal...
Salut, alors, dans mon élan de "folie" tous les formats que je connais sont passés "bmp", "svg", "jpeg", "png", "gif" e.t.c... Rien à faire, toujours la même erreur : "Fichier endommagé".
Après toutes ces tentatives pourvues d'échecs, je me suis résolu à ouvrir le fichier "png" dans un éditeur de texte (nano), pas plus d'informations : uniquement des caractères formant des chaînes incompréhensibles Smiley biggol . (pas d'éditeur hexadécimal disponible ... Smiley decu ).

Merci encore @+
Il faudrait trouver à partir de quel moment précis le fichier devient endommagé pour progresser sur le dossier alors.
1 - A la sortie de javascript; idée p.ex. afficher la chaîne dans un prompt ou dans une div directement et pareil, décoder puis ouvrir le fichier décodé dans ton logiciel de dessin
2 - A l'arrivée en php; idée p.ex. essayer de stocker les données reçues AJAX/POST dans un fichier ou l'afficher directement au lieu de l'envoyer à la DB
3 - Après récupération en DB; là on est cerrtain qu'à ce stade ça ne marche plus, mais voir si en lisant la donnée en DB directement depuis un utilitaire, p.ex. phpmyadmin, ou mieux, mysql en ligne de commande, est-ce que ça change quelque chose.
2.5 - Sniffer la connexion HTTP pour voir si rien ne se passe pendant le transfert; ça c'est en bonus, mais on est jamais assez méfiant pour dépister ce genre d'erreur à la con
Salut,
1-J'ai déjà affiché la chaine en javascript dans un src d'une img, tout fonctionne Smiley smile .
2-Je vais essayer et je te tiens au courant Smiley cligne .
3-En lisant le base64 avec phpmyadmin, même résultat, l'image ne s'affiche pas Smiley decu .
2.5-Oui en effet j'ai aussi suivit le chemin du POST vers le php, tout se déroule très bien, code de retour 200 (OK) Smiley biggrin .
Je te tiens au courant, @+ et merci Smiley cligne
Quand tu fais :


echo '<img src="' . $res['flux'] . '" alt="Erreur lors de la récupération du flux"/>';


Est-ce que tu peux poster le code généré côté navigateur pour une de tes images ?
Salut, alors voilà pour le html généré :
Ici.
Et oui hebergé depuis framapad car refusé par alsacreations "texte trop long" Smiley rolleyes .
Je ne vois vraiment pas ce qu'il cloche Smiley help .
Merci @+
JE vois des / et des espaces dans le code envoyé. Je me demande si ce n'est quand même pas ce que j'évoquais tout au début, mais dans l'autre sens: en passant dans une moulinette AJAX/POST, les + sont convertis en espaces et rendent le code invalide...
Modifié par QuentinC (12 Jul 2013 - 08:11)
Yipiiii, Merci à tous pour votre aide qui m'as été précieuse Smiley sourire (QuentinC et jb_gfx), mon problème est enfin résolus Smiley winner .
Encore merci @+ Smiley smile Smiley smile !!
Modifié par pinguix40 (12 Jul 2013 - 13:45)
Le problème était où finalement ?

Ce serait bien si tu le disais, pour les suivants qui passeraient par ici.
Modifié par QuentinC (12 Jul 2013 - 17:24)
Alors le problème, c'est toi qui as trouvé la solution les + sont remplacée par des espaces, j'ai donc en PHP remplacé les espaces par des +, le base64 redevient alors réutilisable Smiley smile
Merci encore @+
Alors j'ai juste envie de dire MERCI MERCI MERCI !
2 jours que ma chaine base64 me donnait une image endommagee....

Youhouuu !