web-dev-qa-db-fra.com

NotReadableError: impossible de démarrer la source

J'ai ajouté ce morceau de code dans mon projet

if (navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {};
}

if (navigator.mediaDevices.getUserMedia === undefined) {
  navigator.mediaDevices.getUserMedia = function (constraints) {

    var getUserMedia = (
      navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia
    );

    if (!getUserMedia) {
      return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
    }

    return new Promise(function (resolve, reject) {
      getUserMedia.call(navigator, constraints, resolve, reject);
    });

  };
}

Ensuite, j'essaie d'accéder à un flux vidéo en utilisant getUserMedia

navigator.mediaDevices.getUserMedia({
    video: true,
    audio: false
}).then(stream => {
    // do stuff
}).catch(error => {
    console.log(error.name + " " + error.message);
});

Lorsque je teste cela dans mes émulateurs, cela fonctionne sur Android versions 5 et supérieures, mais lorsque je l'exécute sur un appareil réel, j'obtiens cette erreur

NotReadableError Impossible de démarrer la source

J'ai ajouté le cordova-plugin-media-capture plugin pour m'assurer que mon application demandera les autorisations appropriées, mais je ne veux pas utiliser le plugin, je préfère utiliser l'API getUserMedia.

Jusqu'à présent, mes recherches montrent que la raison de cette erreur est qu'une autre application utilise déjà l'appareil photo, mais ce n'est pas le cas.Je suis même allé plus loin et j'ai redémarré l'appareil, puis j'ai ouvert mon application en m'assurant qu'il n'y en avait pas d'autre en cours d'exécution. applications et j'ai toujours l'erreur.

Est-ce que quelqu'un a déjà eu ce problème?

11
php_nub_qq

Mise à jour - 14/09/2019

Il y a des changements dans Safari sur iOS 13 et Safari 13: https://developer.Apple.com/documentation/safari_release_notes/safari_13_release_notes

SFSafariViewController a acquis la fonctionnalité getUserMedia (!!!, cependant je dois le confirmer, veuillez voir ci-dessous pour les rapports de son fonctionnement)

https://bugs.webkit.org/show_bug.cgi?id=183201

Cependant WKWebView ne semble pas gagner la fonctionnalité getUserMedia:

https://bugs.chromium.org/p/chromium/issues/detail?id=752458https://bugs.webkit.org/show_bug.cgi?id=185448

notes de version iOS 13 et Safari 13:

https://developer.Apple.com/documentation/ios_ipados_release_notes/ios_13_release_noteshttps://developer.Apple.com/documentation/safari_release_notes/safari_13_release_notes

Mise à jour - 04/11/2018 - Liens vers les exemples Ionic, Cordova et Native Android exemples avec instructions

Lien GitHub vers l'exemple Cordova fonctionnel

lien GitHub pour travailler Android

Lien GitHub vers un Ionic example

Les étapes pour accéder à getUserMedia sur Android via le framework Cordova sont:

  • Suivez Cordova Android instructions d'installation ( link )
  • Ajouter des autorisations à AndroidManifiest.xml ( link )
  • Enregistrer WebRTC Adapter.js fichier dans ./www/js/adapter.js et inclure dans ./www/index.html
  • Ajouter cordova plugin add cordova-plugin-Android-permissions
  • Ajoutez le code d'autorisation du plugin et le code getUserMedia nécessaire à l'intérieur du ./www/js/index.js fichier. Assurez-vous d'utiliser l'adaptateur getUserMedia. Veuillez voir ce fichier à titre d'exemple ( link ).

Veuillez consulter les instructions complètes ligne par ligne avec une image de réussite et d'erreur dans le projet GitHub.


Je ne sais pas dans quelle mesure cela concerne Cordova ... Cependant, j'ai eu cette erreur lorsque j'ai créé ma propre application de test Android getUserMedia ( link ). dépendant principalement des autorisations utilisateur de l'application native, puis de la façon dont l'application parente crée les vues Web, de la version de webrtc incluse dans votre application et de la façon dont vous appelez getUserMedia.

Côté JavaScript de l'application: Plutôt que de faire du code shim de navigateur vous-même, assurez-vous d'utiliser l'adaptateur WebRTC ( link ). Cela supprime beaucoup de problèmes courants. Vous pouvez voir un exemple ici ( link ). Je recommande également de consulter les exemples WebRTC ici ( link ).

Côté natif de l'application: Vous aurez besoin des autorisations utilisateur Mic et Appareil photo pour la vidéo et l'audio. Ceci est le principal coupable. Vous devez vous assurer qu'ils ont été acceptés avant la création de WebView. Ainsi, toutes les vérifications d'autorisations, les popups, etc., doivent avoir lieu avant la création de WebView. Si des autorisations sont accordées après avoir probablement besoin de redémarrer l'application, etc.

Lorsque vous créez et déployez votre application, accédez aux paramètres de l'application et activez manuellement les autorisations si vous n'y avez pas déjà été invité. Ensuite, cela devrait fonctionner.

Je n'ai pas pu faire fonctionner l'émulation vidéo/audio dans l'émulateur uniquement sur le périphérique réel. Je n'ai également rencontré l'erreur NotReadableError que sur Android utilisant un WebChromeView avant que les autorisations aient été acceptées. Enfin, la version minimale de l'API pour Android est 21 (Lollipop) pour cette fonctionnalité) car l'application parent doit autoriser les autorisations d'exécution via WebView onPermissionRequest ( link ).

Comme de nombreux navigateurs intégrés à l'application (Facebook, Pinterest, etc.) ne gèrent pas onPermissionRequest sur Android WebRTC via un site Web ne fonctionne généralement pas. Sur iOS, il est garanti (à partir d'avril 2018) fonctionner comme Apple ont seulement autorisé l'accès WebRTC via Safari uniquement. Ainsi Cordova est limité à Android API 21 if il gère correctement les autorisations.

11
Marcus

Je voulais ajouter la solution à ma saga de lutter contre cette erreur particulière. J'utilise Ionic pour créer une application de chat WebRTC, et j'ai cette erreur avec ma version native Android build. Voici les choses qui ont fait toute la différence).

Installez le plugin AndroidPermissions d'Ionic ...

$ ionic cordova plugin add cordova-plugin-Android-permissions
$ npm install --save @ionic-native/Android-permissions

N'oubliez pas de l'ajouter à app.module.ts en tant que fournisseur

Dans le fichier . Ts de votre composant ...

import { AndroidPermissions } from '@ionic-native/Android-permissions';

...

iosCordova = false; // I use these for easy if-else logic later
androidCordova = false; // but I want you to see how I handle the logic

constructor(private platform:Platform, private androidPermissions: AndroidPermissions, etc...) {
        navigator.getUserMedia = ((<any>navigator).getUserMedia || (<any>navigator).webkitGetUserMedia || (<any>navigator).mozGetUserMedia || (<any>navigator).msGetUserMedia);
        this.iosCordova = this.platform.is('ios') && typeof cordova !== 'undefined';
        this.androidCordova = this.platform.is('Android') && typeof cordova !== 'undefined';
        platform.ready().then(() => {
            if( this.androidCordova ){ // is Android Native App
                // alert("Android Native")
                androidPermissions.requestPermissions(
                [
                    androidPermissions.PERMISSION.CAMERA, 
                    androidPermissions.PERMISSION.MODIFY_AUDIO_SETTINGS,
                    androidPermissions.PERMISSION.RECORD_AUDIO
                ]
                ).then(()=>{
//getDevices uses Enumerate Devices and initWebRTC starts the chat connections, etc...
                    this.getDevices().then(() => this.initWebRTC())
                })
            }
       }) 
    }


ngOnInit() {
        if( !this.androidCordova ){ // is NOT Android Native App
            // alert("NOT Android Native")
            try {
                this.getDevices().then(() => this.initWebRTC())     
            } catch(e) {
                alert(e);
            }
        }
    }
...

Inspectez votre config.xml à myAppName/config.xml et ajoutez xmlns: Android = "http://schemas.Android.com/apk/res/Android " à votre balise de widget et ajoutez la demande d'autorisations. J'ai eu des problèmes en essayant de les inclure dans les balises existantes, et d'ajouter simplement ces demandes d'autorisations juste sous les balises de fermeture (création de mon deuxième ensemble)

<widget id="your.app" version="1.2.3" xmlns="http://www.w3.org/ns/widgets" xmlns:Android="http://schemas.Android.com/apk/res/Android" xmlns:cdv="http://cordova.Apache.org/ns/1.0">
...
</platform> // previously existing platform name="Android" closing tag
<platform name="Android">
    <custom-config-file parent="/manifest" target="AndroidManifest.xml">
        <uses-permission Android:name="Android.permission.CAMERA" />
        <uses-permission Android:name="Android.permission.MODIFY_AUDIO_SETTINGS" />
        <uses-permission Android:name="Android.permission.RECORD_AUDIO" />
    </custom-config-file>
</platform>
<platform name="ios"> // previously existing platform name="ios" opening tag

Maintenant, vous devez inspecter votre fichier AndroidManifest.xml dans myAppName/plates-formes/Android/app/src/main/AndroidManifest.xml et rechercher ces autorisations. S'ils ne sont pas là, ajoutez-les

<uses-permission Android:name="Android.permission.CAMERA" />
<uses-permission Android:name="Android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission Android:name="Android.permission.RECORD_AUDIO" />

La déclaration de ces autorisations dans le manifeste est essentielle pour ne pas être ignorée. Apparemment Android 26 obtient des autorisations strictes, et vous ne pouvez pas simplement demander bon gré mal gré. Selon la documentation que j'ai lue, si vous n'utilisez pas réellement l'autorisation de dans le code à partir duquel vous l'appelez, votre demande sera abandonnée par le système d'exploitation et l'utilisateur ne la verra jamais.

Quoi qu'il en soit, je suis très junior à tout cela Ionic et développement de périphériques natifs, donc si quelqu'un a quelque chose d'éclairant à ajouter, faites-le! Merci à tous!

5
Shane McCurdy