web-dev-qa-db-fra.com

Comment résoudre le problème de «contrainte non valide» de getUserMedia sur iOS 11 Safari

J'essaie d'exécuter le code suivant dans Safari dans iOS 11. Il devrait inviter l'utilisateur à donner accès à la caméra de son appareil, puis l'afficher dans mon élément <video autoplay id="video"></video>. Cependant, lors de l'exécution dans iOS 11, il en résulte un OverconstrainedError à lancer:

{message: "Invalid constraint", constraint: ""}
  • Le code fonctionne correctement dans Android et ouvre correctement la caméra.
  • J'ai tenté plusieurs configurations valides sans succès.

Je sais que iOS 11 vient de sortir, donc c'est peut-être un bug, mais des pensées? Quelqu'un d'autre a-t-il rencontré cela?

Code:

var video = document.getElementById('video');
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
     navigator.mediaDevices.getUserMedia({video: true})
         .then(function(stream) {
             video.src = window.URL.createObjectURL(stream);
             video.play();
         })
         .catch(function(err) {
             console.log(err);
         });
}

Modifier 1

J'ai exécuté navigator.mediaDevices.getSupportedConstraints() et il retourne ce qui suit:

{
    aspectRatio: true,
    deviceid: true,
    echoCancellation: false,
    facingMode: true,
    frameRate: true,
    groupId: true,
    height: true,
    sampleRate: false,
    sampleSize: false,
    volume: true,
    width: true
}

J'ai essayé des configurations en omettant la propriété video, mais je n'ai pas eu de chance.

13
mb-ca

Il semble que ce soit un bug qui a été corrigé, car je viens de le réessayer et le message d'erreur n'apparaît plus.

Notez que même si le message d'erreur a disparu, j'ai dû apporter une autre modification pour qu'il fonctionne, qui ajoutait video.srcObject = stream; dans le rappel then.

3
mb-ca

L'erreur de contrainte non valide dans Safari est due au fait que le navigateur s'attend à ce que vous passiez une largeur correcte, l'une des suivantes:

  • 320
  • 640
  • 1280

la hauteur est calculée automatiquement dans un rapport d'aspect de 4: 3 pour 320 ou 640, et 16: 9 pour 1280, puis si vous passez une largeur de 320, votre flux vidéo est défini dans:

  • 320x240

si vous définissez une largeur de 640, votre flux vidéo est défini dans:

  • 640x480

Et si vous définissez une largeur de 1280, votre flux vidéo est défini dans:

  • 1280x720

Dans tous les autres cas, vous obtenez une erreur "InvalidConstrain" pour la valeur de largeur.

Vous pouvez également utiliser des contraintes min, max, exactes ou idéales pour la largeur, veuillez vérifier documentation MDN

Voici un exemple dans ce codepen

var config = { video: { width: 320/*320-640-1280*/ } };
var start = () => navigator.mediaDevices.getUserMedia(config)
  .then(stream => v.srcObject = stream)
  .then(() => new Promise(resolve => v.onloadedmetadata = resolve))
  .then(() => log("Success: " + v.videoWidth + "x" + v.videoHeight))
  .catch(log);

var log = msg => div.innerHTML += "<p>" + msg + "</p>";

PD: Dans chrome vous pouvez définir une largeur de hauteur et le flux vidéo est défini dans ces tailles, Firefox fait un distance de remise en forme , et Safari attend une correspondance exacte.

13
kintaro

N'oubliez pas que le simulateur iOS fourni avec Xcode ne prend pas en charge la webcam ou le microphone, c'est pourquoi vous pouvez obtenir l'erreur OverconstrainedError (selon https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia docs, cela signifie qu'aucun appareil ne correspond aux options passées, même si vous ne mettez pas de détails)

2
Tom Roggero