NotReadableError: Could not start source

NotReadableError: Could not start source

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

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 Could not start source

我已经添加了 cordova-plugin-media-capture 插件以确保我的应用程序将请求适当的权限,但是我不想使用该插件我宁愿使用 getUserMedia API.

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

有人遇到过这个问题吗?

更新 - 2020 年 11 月 19 日

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

更新 - 2020 年 4 月 6 日

专门为 WKWebView 提交了另一个错误票。没有支持。 https://bugs.webkit.org/show_bug.cgi?id=208667

在 iOS 13.4 中更新到独立模式以获得 getUserMedia 访问权限 https://bugs.webkit.org/show_bug.cgi?id=185448#c6

更新 - 2019 年 9 月 14 日

iOS 13 和 Safari 13 上的 Safari 发生了变化:https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes

SFSafariViewController 获得了 getUserMedia 功能(!!!,但是我需要确认这一点,请参阅下面的报告以了解它的工作情况)

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

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

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

iOS 13 和 Safari 13 发行说明:

https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes

更新 - 2018 年 4 月 11 日 - 链接到可用的 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) 时遇到了这个错误。它主要取决于本机应用程序的用户权限,然后是父应用程序如何创建 webviews,您的应用程序中打包了哪个版本的 webrtc,以及您如何调用 getUserMedia。

JavaScript 申请方: 不要自己编写浏览器 shim 代码,而是确保使用 WebRTC 适配器 (link). This removes a lot of common problems. You can see an example here (link). I also recommend looking at the WebRTC Samples here (link)。

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

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

我无法让 Video/Audio 模拟仅在实际设备上的模拟器中运行。在接受权限之前,我也只在 Android 上使用 WebChromeView 遇到了 NotReadableError。最后,Android 的最小 API 版本是 21(Lollipop),因为父应用程序需要通过 WebView onPermissionRequest (link).[=34 允许 run-time 权限=]

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

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

安装 Ionic 的 Android权限插件...

$ 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 检查您的 config.xml。xml 并添加 xmlns:android="http://schemas.android.com/apk/res/android" 到您的小部件标签并添加权限请求。我在尝试将它们包含在先前存在的 标签中时遇到了问题,只需在结束标签下添加这些权限请求(创建我自己的第二组)

<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 的 AndroidManifest.xml 文件。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 对权限越来越严格,你不能随便问他们。根据我一直在阅读的文档,如果您实际上没有使用您调用它的代码中的权限,您的请求将被 OS 丢弃,用户将永远不会看到它。

无论如何,我对所有这些 Ionic 和本机设备开发都很初级,所以如果有人有任何启发性的补充,请添加!谢谢大家!