javascript NotReadableError:无法启动源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/48775154/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NotReadableError: Could not start source
提问by php_nub_qq
I have added this piece of code in my project
我在我的项目中添加了这段代码
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);
});
};
}
Then I'm trying to access a video stream using getUserMedia
然后我尝试使用访问视频流 getUserMedia
navigator.mediaDevices.getUserMedia({
video: true,
audio: false
}).then(stream => {
// do stuff
}).catch(error => {
console.log(error.name + " " + error.message);
});
When I test this in my emulators it works on android versions 5 and up, however when I run it on an actual device I get this error
当我在模拟器中测试它时,它适用于 android 版本 5 及更高版本,但是当我在实际设备上运行它时,我收到此错误
NotReadableError Could not start source
NotReadableError 无法启动源
I have added the cordova-plugin-media-captureplugin to make sure my app will request the appropriate permissions, however I don't want to use the plugin I'd rather use the getUserMediaAPI.
我添加了cordova-plugin-media-capture插件以确保我的应用程序将请求适当的权限,但是我不想使用插件我宁愿使用getUserMediaAPI。
So far my researches show that the reason for this error is that some other app is already using the camera but that's not the case, I even went a step further and restarted the device, then opened my app, making sure there are no other running apps and I still got the error.
到目前为止我的研究表明这个错误的原因是其他一些应用程序已经在使用相机但事实并非如此,我什至更进一步并重新启动设备,然后打开我的应用程序,确保没有其他应用程序正在运行应用程序,我仍然遇到错误。
Has anyone had this issue?
有没有人遇到过这个问题?
回答by Marcus
Update - 14/09/2019
更新 - 14/09/2019
There are changes to Safari on iOS 13 & Safari 13: https://developer.apple.com/documentation/safari_release_notes/safari_13_release_notes
iOS 13 和 Safari 13 上的 Safari 有变化:https: //developer.apple.com/documentation/safari_release_notes/safari_13_release_notes
SFSafariViewController has gained getUserMedia functionality (!!!, however I need to confirm this, please see below for reports of it working)
SFSafariViewController 已获得 getUserMedia 功能(!!!,但是我需要确认这一点,请参阅下面的报告以了解它的工作情况)
https://bugs.webkit.org/show_bug.cgi?id=183201
https://bugs.webkit.org/show_bug.cgi?id=183201
However WKWebView does not seem to gain getUserMedia functionality:
但是 WKWebView 似乎没有获得 getUserMedia 功能:
https://bugs.chromium.org/p/chromium/issues/detail?id=752458https://bugs.webkit.org/show_bug.cgi?id=185448
https://bugs.chromium.org/p/chromium/issues/detail?id=752458 https://bugs.webkit.org/show_bug.cgi?id=185448
iOS 13 and Safari 13 release notes:
iOS 13 和 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
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
Update - 04/11/2018 - Links to working Ionic, Cordova and Native android examples with instructions
更新 - 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
Steps to achieve getUserMedia access on Android via the Cordova framework are:
通过 Cordova 框架在 Android 上实现 getUserMedia 访问的步骤是:
- Follow Cordova Android install instructions (link)
- Add Permissions to AndroidManifiest.xml (link)
- Save WebRTC Adapter.jsfile to
./www/js/adapter.jsand include in./www/index.html - Add
cordova plugin add cordova-plugin-android-permissions - Add plugin permission code, and the necessary getUserMedia code inside of the
./www/js/index.jsfile. Make sure you use getUserMedia adapter. Please see this file as an example (link).
- 遵循 Cordova Android 安装说明(链接)
- 向 AndroidManifyingt.xml 添加权限(链接)
- 将WebRTC Adapter.js文件保存到
./www/js/adapter.js并包含在./www/index.html - 添加
cordova plugin add cordova-plugin-android-permissions - 在
./www/js/index.js文件中添加插件权限代码和必要的 getUserMedia 代码。确保使用 getUserMedia 适配器。请以该文件为例(链接)。
Please see the full line by line instructions with a success and error image inside the GitHub project.
请在 GitHub 项目中查看包含成功和错误图像的完整逐行说明。
I am not sure how much of this relates to Cordova... However I had this error when I made my own Android getUserMedia test app (link). It is dependant mainly on the native app user permissions, then how the parent app creates the webviews, which version of webrtc is packaged within your app, and how you call getUserMedia.
我不确定这有多少与 Cordova 相关……但是,当我制作自己的 Android getUserMedia 测试应用程序(链接)时遇到了这个错误。它主要依赖于原生应用的用户权限,然后是父应用如何创建webviews,你的应用中打包了哪个版本的webrtc,以及你如何调用getUserMedia。
JavaScript side of the application:Rather than doing browser shim code yourself make sure you use the WebRTC adapter (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).
应用程序的 JavaScript 端:与其自己编写浏览器填充代码,不如确保使用 WebRTC 适配器(链接)。这消除了许多常见问题。您可以在此处查看示例(链接)。我还建议在此处查看 WebRTC 示例(链接)。
Native side of the application:You will need Mic and Camera user permissions for Video and Audio. This is the main culprit. You need to make sure they have been accepted before the creation of the WebView. Thus all permission checking, popups, etc, need to happen before the creation of the WebView. If permissions are granted after you most likely need to reboot the App, etc.
应用程序的本机端:您将需要视频和音频的麦克风和相机用户权限。这是罪魁祸首。在创建 WebView 之前,您需要确保它们已被接受。因此,所有权限检查、弹出窗口等都需要在创建 WebView 之前发生。如果在您很可能需要重新启动应用程序后授予权限,等等。
When you build and deploy your application go to App Settings and manually turn on the permissions if you haven't been prompted already. Then it should work.
当您构建和部署您的应用程序时,如果您尚未收到提示,请转到“应用程序设置”并手动打开权限。那么它应该工作。
I wasn't able to get Video/Audio emulation working in the emulator only on the actual device. I also only encountered the NotReadableError on Android utilising a WebChromeView before permissions have been accepted. Lastly The min API version for Android is 21 (Lollipop) for this functionality as the parent application needs to allow run-time permissions via WebView onPermissionRequest (link).
我无法仅在实际设备上的模拟器中进行视频/音频模拟。在接受权限之前,我也只在 Android 上使用 WebChromeView 遇到了 NotReadableError。最后,对于此功能,Android 的最小 API 版本是 21(Lollipop),因为父应用程序需要通过 WebView onPermissionRequest(链接)允许运行时权限。
As numerous in-app browsers (Facebook, Pinterest, etc) do not handle onPermissionRequest on Android WebRTC via a website typically doesn't work. On iOS it is guaranteed (as of April 2018) not to work as Apple have only allowed WebRTC access through the Safari only. Thus Cordova is limited to Android API 21 ifit handles the permissions correctly.
由于许多应用内浏览器(Facebook、Pinterest 等)不通过网站处理 Android WebRTC 上的 onPermissionRequest 通常不起作用。在 iOS 上,它保证(截至 2018 年 4 月)不起作用,因为 Apple 仅允许通过 Safari 访问 WebRTC。因此,如果 Cordova正确处理权限,则它仅限于 Android API 21 。
回答by Shane McCurdy
I wanted to add the solution to my saga of fighting this particular error. I am using Ionic to build a WebRTC chat app, and have got this error with my native Android build. Here are the things that made all the difference.
我想将解决方案添加到我与这个特定错误作斗争的传奇中。我正在使用 Ionic 构建一个 WebRTC 聊天应用程序,并且在我的原生 Android 构建中遇到了这个错误。以下是让一切变得不同的事情。
Install Ionic's AndroidPermissions plugin...
安装 Ionic 的 AndroidPermissions 插件...
$ ionic cordova plugin add cordova-plugin-android-permissions
$ npm install --save @ionic-native/android-permissions
Don't forget to add it to app.module.tsas a provider
不要忘记将它作为提供者添加到app.module.ts
In your component's .tsfile...
在您组件的.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);
}
}
}
...
Inspect your config.xmlat myAppName/config.xmland add xmlns:android="http://schemas.android.com/apk/res/android"to your widget tag and add the permissions request. I had issues trying to include them in the previously existing tags, and just add these permissions requests right under the closing tags (creating my own second set)
在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
Now, you need to inspect your AndroidManifest.xmlfile at myAppName/platforms/android/app/src/main/AndroidManifest.xmland look for these permissions. If they are not there, add them
现在,你需要检查你的AndroidManifest.xml文件在myAppName /平台/安卓/应用/ src目录/主/ 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" />
Having these permissions declared in the manifest is critical to not being ignored. Apparently Android 26 is getting strict on permissions, and you can't just ask willy-nilly for them. According to the documentation I've been reading, if you are not actually using the permission from within the code you are calling it from, your request will be dropped by the OS and the user will never see it.
在清单中声明这些权限对于不被忽略至关重要。显然,Android 26 对权限的要求越来越严格,你不能随意要求它们。根据我一直在阅读的文档,如果您实际上没有在从中调用它的代码中使用该权限,则操作系统将删除您的请求,并且用户将永远不会看到它。
Anyway, I'm very junior to all this Ionic and native device development, so if anyone has anything enlightening to add, please do so! Thanks everyone!
无论如何,我对所有这些 Ionic 和本机设备开发都很初级,所以如果有人要添加任何启发性的东西,请添加!感谢大家!

