javascript - MediaDevices.getUserMedia() 对 ios 的支持
问题描述
我试图在 ReactJS 项目中获取浏览器设置详细信息(相机、麦克风权限)。基于此,如果它被阻止,我将在 UI 中显示一些错误消息。我使用以下代码。
useEffect(()=>{
collectUserLogData();
},[]);
const collectUserLogData = () => {
navigator.getMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
navigator.getMedia(
{ video: true },
() => {
setCamera(true);
console.log("Permission_", "camera ON");
},
() => {
console.log("Permission_", "Camera OFF");
}
);
navigator.getMedia(
{ audio: true },
() => {
setMic(true);
console.log("Permission_", "Mic ON");
},
() => {
console.log("Permission_", "Mic OFF");
}
);
navigator.geolocation.getCurrentPosition(
() => {
setLocation(true);
console.log("Permission_", "Geo ON");
},
() => {
console.log("Permission_", "Geo OFF");
}
);
};
这适用于 windows 和 android 浏览器,但不适用于 ios 浏览器。我没有在mac ios中测试它。ios 浏览器中未显示弹出窗口。如何解决这个问题。
解决方案
getUserMedia() 在最新版本的 iOS 上正常工作。一般11.1及以上都可以。
要解决这些问题,您需要将 iOS 设备连接到 Mac 并使用 Safari 远程调试设置。这样你就可以获得一个控制台和 javascript 调试器。
如果您已经使用 getUserMedia() 请求用户允许使用相机和/或麦克风,则 enumerateDevices() 可以工作。如果没有该许可, emumerateDevices() 结果会模糊或丢失。这是为了防止浏览器指纹识别。因为网络蠕虫。
在 getUserMedia 实际工作的 iOS 版本中,您无需在各种命名空间中四处寻找它。navigator.mediaDevices.getUserMedia()
足够了。
这是我用来枚举各种不同浏览器平台(包括)上的媒体源的代码。iOS、Android 和各种桌面。我使用async / await
它是因为它是一种处理 getUserMedia() 返回的 Promise 的简单方法。但是如果你愿意,你可以直接使用 Promise。(请注意,我已编辑此代码以删除特定于应用程序的内容,但我尚未对其进行调试。)
async function enumerateSources() {
if( navigator
&& navigator.mediaDevices
&& typeof navigator.mediaDevices.enumerateDevices === 'function' ) {
try {
/* open a generic stream to get permission to see devices;
* Mobile Safari insists */
const stream = await navigator.mediaDevices.getUserMedia(
{ video: true, audio: true} )
let devices = await navigator.mediaDevices.enumerateDevices()
const cameras = devices.filter( device => {
return device.kind === 'videoinput'
})
if (cameras.length >= 1) console.log ('cameras avail')
const mics = devices.filter( device => {
return device.kind === 'audioinput'
})
if (mics.length >= 1) console.log ('mics avail')
/* release stream */
const tracks = stream.getTracks()
if( tracks ) {
for( let t = 0; t < tracks.length; t++ ) tracks[t].stop()
}
return ({cameras, mics})
} catch(error) {
/* user refused permission, or media busy, or some other problem */
console.error(error.name, error.message)
return {cameras:[], mics:[]})
}
}
else throw ('media device stuff not available in this browser')
}
推荐阅读
- javascript - JavaScript - 我似乎无法工作的简单示例
- jquery - 创建粘性元素
- sql - ms 有条件地在 form.activate 上访问更新字段
- asp.net - 如何使用带有文本框值的选择查询与数据库 DATE 列进行比较
- sql - 如何在 SQL 窗口函数中表示与当前行的属性值相关的窗口框架?
- c - 通过指针更改多个函数内的数组
- angularjs - AngularJS + 时刻 + 时区
- javascript - 用于页面路由器的 vue-spinner
- mysql - mysql 在不同版本的 InnoDB 之间复制文件
- android - 试图将 JSONObject 放在 POST Api 中的 @Field 中但不工作