【问题标题】:NotReadableError: Could not start sourceNotReadableError:无法启动源
【发布时间】:2018-02-13 20:33:07
【问题描述】:

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

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。

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

有人遇到过这个问题吗?

【问题讨论】:

  • 是的,我在 ionic 2、cordova 7 上有问题。
  • @hthetiot 你解决了吗?
  • 到目前为止,我刚刚发现 video: true, audio: false 工作,但如果我启用 audio: true,我得到“NotReadableError 无法启动源”
  • 同时确认在模拟器上工作但在设备上不行。
  • 在离子上也有这个问题并正在寻找解决方案

标签: javascript cordova getusermedia


【解决方案1】:

更新 - 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) 时出现此错误。它主要取决于本机应用的用户权限,然后是父应用如何创建 webview,您的应用中打包了哪个版本的 webrtc,以及您如何调用 getUserMedia。

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

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

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

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

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

【讨论】:

  • 我已经为这个错误苦苦挣扎了两天,你的回答很有帮助。这是android设备上的权限问题。谢谢@Marcus
  • 对我来说也一样 - 已经为此苦苦挣扎了好几天。最有帮助的是在应用中呈现任何内容之前请求权限。
【解决方案2】:

我想将解决方案添加到我与这个特定错误作斗争的传奇中。我正在使用 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 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 和本机设备开发都非常初级,所以如果有人有任何启发性的补充,请这样做!谢谢大家!

【讨论】:

  • 这将我推向了正确的方向!只需要为音频和视频添加更多权限,但现在它可以工作了:D 谢谢
  • @Wrong 由于 Cordova 将您的网站打包为应用程序,它在 WKWebView/UIWebView 中提供服务。在 iOS 上,出于安全考虑,Apple 不允许这些视图拥有 getUserMedia。您可以在 Android 上覆盖这些安全权限,但在 iOS 上则不行。如果您要本地构建此应用程序,和/或为 iOS 构建 WebRTC 插件,您可以在捕获摄像头馈送并将其传递到前端时获得相同的最终结果。然而,这是一项重大的任务。
  • 对于 android 它有效。我只需要 myAppName/platforms/android/app/src/main/AndroidManifest.xml 更改。没有必要更改 config.xml
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 2017-02-06
相关资源
最近更新 更多