NotReadableError:无法启动源代码

时间:2018-02-13 20:33:07

标签: javascript cordova getusermedia

我在项目中添加了这段代码

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);
    });

  };
}

然后我尝试使用getUserMedia

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

当我在我的模拟器中测试它时,它适用于Android版本5及更高版本,但是当我在实际设备上运行它时会出现此错误

  

NotReadableError无法启动源

我添加了cordova-plugin-media-capture插件,以确保我的应用会请求相应的权限,但我不想使用该插件,而是使用getUserMedia API。

到目前为止,我的研究表明,这个错误的原因是其他一些应用程序已经在使用相机但事实并非如此,我甚至更进一步重新启动设备,然后打开我的应用程序,确保有没有其他运行的应用程序,我仍然得到错误。

有人有这个问题吗?

2 个答案:

答案 0 :(得分:10)

更新 - 04/11/2018 - 使用说明链接工作Ionic,Cordova和Native android示例

GitHub link to working Cordova example

GitHub link to working Android example

GitHub link to a working Ionic example

通过Cordova框架在Android上实现getUserMedia访问的步骤是:

  • 按照Cordova Android安装说明(link
  • 向AndroidManifiest.xml(link
  • 添加权限
  • WebRTC Adapter.js个文件保存到./www/js/adapter.js并加入./www/index.html
  • 添加cordova plugin add cordova-plugin-android-permissions
  • ./www/js/index.js文件中添加插件权限代码和必要的getUserMedia代码。确保使用getUserMedia适配器。请参阅此文件作为示例(link)。

请在GitHub项目中查看完整的逐行说明以及成功和错误图像。

我不确定这与Cordova有多大关系......但是当我制作自己的Android getUserMedia测试应用程序(link)时,我遇到了这个错误。它主要依赖于本机应用程序用户权限,然后父应用程序如何创建Web视图,哪个版本的webrtc打包在您的应用程序中,以及您如何调用getUserMedia。

应用程序的JavaScript方面: 而不是自己做浏览器填充程序代码,请确保使用WebRTC适配器(link)。这消除了许多常见问题。你可以在这里看到一个例子(link)。我还建议您在此处查看WebRTC示例(link)。

应用程序的原生端: 您将需要视频和音频的麦克风和相机用户权限。这是罪魁祸首。您需要确保在创建WebView之前已接受它们。因此,所有权限检查,弹出窗口等都需要在创建WebView之前进行。如果在您很可能需要重新启动应用程序之后授予权限,等等。

构建和部署应用程序时,如果尚未提示您,请转到“应用程序设置”并手动打开权限。然后它应该工作。

我无法仅在实际设备上使用模拟器中的视频/音频仿真工作。在接受权限之前,我也只在使用WebChromeView的Android上遇到了NotReadableError。最后,Android的min API版本为21(Lollipop),因为父应用程序需要通过WebView onPermissionRequest(link)允许运行时权限。

由于众多应用内浏览器(Facebook,Pinterest等)无法通​​过网站处理Android WebRTC上的onPermissionRequest,因此通常无效。在iOS上,保证(截至2018年4月)不起作用,因为Apple仅允许通过Safari访问WebRTC。因此Cordova仅限于Android API 21 ,如果它正确处理权限。

答案 1 :(得分:4)

我想为解决这个特殊错误的传奇添加解决方案。我正在使用Ionic构建一个WebRTC聊天应用程序,并且在我的原生Android构建中遇到此错误。以下是让一切变得与众不同的事情。

安装Ionic的AndroidPermissions插件......

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

不要忘记将其作为提供商添加到 app.module.ts

在您的组件的 .ts 文件中...

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);
            }
        }
    }
...

检查 myAppName / config.xml 上的 config.xml 并添加 xmlns:android =“http://schemas.android.com/apk/ res / android“到你的widget标签并添加权限请求。我尝试将它们包含在以前存在的 标记中时遇到问题,只需在结束标记下添加这些权限请求(创建我自己的第二个集合)

<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

现在,您需要检查 myAppName / platforms / android / app / src / main / AndroidManifest.xml 中的 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" />

在清单中声明这些权限对于不被忽略至关重要。显然,Android 26对权限的要求越来越严格,你不能只是毫不犹豫地问他们。根据我一直在阅读的文档,如果您实际上没有使用您从中调用它的代码中的权限,您的请求将被操作系统删除,用户将永远不会看到它。

无论如何,我对所有这些Ionic和本机设备的开发都很熟悉,所以如果有人有任何启发可以添加,请这样做!谢谢大家!