Javascript NotReadableError:无法启动源

Javascript NotReadableError:无法启动源,javascript,cordova,getusermedia,Javascript,Cordova,Getusermedia,我已经在我的项目中添加了这段代码 if (navigator.mediaDevices === undefined) { navigator.mediaDevices = {}; } if (navigator.mediaDevices.getUserMedia === undefined) { navigator.mediaDevices.getUserMedia = function (constraints) { var getUserMedia = ( n

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

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

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


有人遇到过这个问题吗?

更新-2020年11月19日

WKWebView可以在iOS 14.3 beta 1中使用getUserMedia

更新-2020年6月4日

另一个bug通知单专门针对WKWebView提交。没有支持。

iOS 13.4中获得getUserMedia访问权限的独立模式更新

更新-2019年9月14日

iOS 13和Safari 13上的Safari有以下更改:

SFSafariViewController已获得getUserMedia功能(!!),但我需要确认这一点,请参阅下面的工作报告)

但是,WKWebView似乎没有获得getUserMedia功能:

iOS 13和Safari 13发行说明:

更新-2018年11月4日-链接到爱奥尼亚、科尔多瓦和原生安卓系统示例及说明

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

  • 遵循Cordova Android安装说明()
  • 向AndroidManifiest.xml()添加权限
  • 将文件保存到
    /www/js/adapter.js
    并包含在
    /www/index.html
  • 添加
    cordova插件添加cordova插件android权限
  • /www/js/index.js
    文件中添加插件权限代码和必要的getUserMedia代码。确保使用getUserMedia适配器。请以该文件为例()
请在GitHub项目中查看带有成功和错误图像的完整逐行说明


我不知道这和科尔多瓦有多大关系。。。然而,我在制作自己的Android getUserMedia测试应用程序()时遇到了这个错误。这主要取决于本机应用程序用户权限、父应用程序如何创建WebView、应用程序中打包了哪个版本的webrtc以及如何调用getUserMedia

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

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

构建和部署应用程序时,如果尚未收到提示,请转到应用程序设置并手动打开权限。那么它应该会起作用

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


由于许多应用程序内浏览器(Facebook、Pinterest等)无法通过网站处理Android WebRTC上的onPermissionRequest,因此通常无法正常工作。在iOS上,由于苹果只允许通过Safari访问WebRTC,因此保证(截至2018年4月)不起作用。因此,如果Cordova能够正确处理权限,它就只能使用Android API 21。

我想将解决方案添加到我与这个特定错误作斗争的传奇中。我正在使用Ionic构建一个WebRTC聊天应用程序,并且在我的原生Android构建中出现了此错误。以下是造成所有差异的因素

安装爱奥尼亚的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);
            }
        }
    }
...
从'@ionic native/android permissions'导入{AndroidPermissions};
...
iosCordova=false;//我以后使用这些来简化if-else逻辑
androidCordova=false;//但我想让你看看我是如何处理逻辑的
建造商(专用平台:平台、专用androidPermissions:androidPermissions等){
navigator.getUserMedia=((导航器).getUserMedia | | |(导航器).webkitGetUserMedia | | |(导航器).mozGetUserMedia | |(导航器).msGetUserMedia);
this.iosCordova=this.platform.is('ios')&&typeof cordova!=“未定义”;
this.androidCordova=this.platform.is('android')&&typeof cordova!=“未定义”;
platform.ready()。然后(()=>{
如果(this.androidCordova){//是Android本机应用程序
//警报(“Android本机”)
androidPermissions.requestPermissions(
[
androidPermissions.PERMISSION.CAMERA,
androidPermissions.PERMISSION.MODIFY_AUDIO_设置,
androidPermissions.PERMISSION.RECORD_音频
]
).然后(()=>{
//getDevices使用枚举设备,initWebRTC启动
<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
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />