Mac Electron在M1系统下makeCall呼叫白屏?
问题原因
在Mac M1系统下,Electron应用使用摄像头功能时并不会主动申请开启摄像头权限,导致摄像头在没有开启的情况下,Electron底层就采集摄像头数据,导致应用崩溃。
解决方法
在呼叫开始前,先在主进程主动申请摄像头权限,待摄像头开启后,再进入呼叫流程,具体实现步骤如下:
1. 主进程注册申请摄像头权限事件
// 主动申请一次摄像头、麦克风权限
ipcMain.on('check-device-access-privilege', async () => {
// 申请设备权限相关,请看文章结尾备注
await checkDeviceAccessPrivilege();
if (win) {
// 通知Render摄像头已经开启
win.webContents.send("check-device-finished", true);
}
});
2. Render层呼叫时先通知主进程申请摄像头权限
makeCall() {
// 通知主进程
ipcRenderer.send("check-device-access-privilege");
}
3. Render层监听主进程摄像头开启后,开始进入呼叫环节
ipcRenderer.on("check-device-finished", (event, isFinished) => {
if (isFinished) {
this.joinMeeting();
}
});
提示
在开发环境下,有些设备进行上述配置后,可能会导致应用程序退出,主要是因为开发环境是编辑器在申请权限,而编辑器没有摄像头和麦克风权限,因此在程序检查权限时会失败。此种情况需要开发者自己配置电脑允许编辑器有麦克风和摄像头的权限。
备注:checkDeviceAccessPrivilege申请设备权限
import { systemPreferences } from 'electron';
export const checkCameraAccess = async () => {
const cameraPrivilege = systemPreferences.getMediaAccessStatus('camera');
if (cameraPrivilege !== 'granted') {
await systemPreferences.askForMediaAccess('camera');
}
};
export const checkMicrophoneAccess = async () => {
const micPrivilege = systemPreferences.getMediaAccessStatus('microphone');
if (micPrivilege !== 'granted') {
await systemPreferences.askForMediaAccess('microphone');
}
};
// 检查设备访问权限
export const checkDeviceAccessPrivilege = async () => {
await checkCameraAccess();
await checkMicrophoneAccess();
const screenPrivilege = systemPreferences.getMediaAccessStatus('screen');
console.log('[checkDeviceAccessPrivilege] screenPrivilege:', screenPrivilege);
};