在使用 RTC 过程中,需要获取设备权限以确保实时通信体验,例如音频通信需要麦克风权限、视频通信需要摄像头权限、PC 端屏幕共享需要屏幕录制权限等。
通过阅读本文,您将获得麦克风、摄像头权限配置的最佳实践指导。
在 /app/Manifests/AndroidManifest.xml 文件中的 </application> 标签后添加以下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 对于 Android 12.0 及以上设备,还需要添加如下权限: -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
java//常量,用于回调
int MY_PERMISSION_APPLY = 1;
//要使用的摄像头权限。摄像头:CAMERA;麦克风:RECORD_AUDIO
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
//判断是否有摄像头权限
if (permission == PackageManager.PERMISSION_GRANTED) {
//有权限,直接执行
} else {
//没有权限,提示获取权限
String[] perms = {"android.permission.CAMERA"};
ActivityCompat.requestPermissions(this, perms, MY_PERMISSION_APPLY);
}
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case MY_PERMISSION_APPLY:
boolean accepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
if(!accepted){
//用户拒绝了权限
}else{
//用户同意了权限
}
break;
}
}
java权限未获取时,会收到以下回调:
//未获取麦克风权限,错误类型为 MEDIA_DEVICE_ERROR_NOPERMISSION
public void com.ss.bytertc.engine.handler.IRTCVideoEventHandler.onAudioDeviceStateChanged(
String deviceID,
AudioDeviceType deviceType,
int deviceState,
int deviceError)
//未获取摄像头权限,错误类型为 MEDIA_DEVICE_ERROR_NOPERMISSION
public void com.ss.bytertc.engine.handler.IRTCVideoEventHandler.onVideoDeviceStateChanged(
String deviceID,
VideoDeviceType deviceType,
int deviceState,
int deviceError)
java在 App 的 Info.plist 中添加以下两项,分别对应麦克风和摄像头在系统弹出授权对话框时的提示信息。
Privacy - Microphone Usage Description,并填入麦克风使用目的提示语。
Privacy - Camera Usage Description,并填入摄像头使用目的提示语。
//检查权限状态。摄像头:AVMediaTypeVideo;麦克风:AVMediaTypeAudio
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
//权限定义
typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
AVAuthorizationStatusNotDetermined = 0, /* 尚未询问是否开启麦克风*/
AVAuthorizationStatusRestricted = 1, /* 未授权,家长限制*/
AVAuthorizationStatusDenied = 2, /* 用户未授权*/
AVAuthorizationStatusAuthorized = 3, /* 用户授权*/
} API_AVAILABLE(macos(10.14), ios(7.0)) __WATCHOS_PROHIBITED __TVOS_PROHIBITED;
//申请权限
if (authStatus == AVAuthorizationStatusNotDetermined) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
dispatch_async(dispatch_get_main_queue(), ^{
if (granted) {
[self doSomething];
} else {
[self showAlertWithTitle:@"温馨提示" message:@"您没有开启\"麦克风\"权限\n 无法进行通话。请在设置中开启麦克风权限。"];
}
});
}];
} else if (authStatus == AVAuthorizationStatusDenied || authStatus == AVAuthorizationStatusRestricted) {
[self showAlertWithTitle:@"温馨提示" message:@"您没有开启\"麦克风\"权限\n 无法进行通话。\n 请在设置中开启麦克风权限。"];
} else if (authStatus == AVAuthorizationStatusAuthorized) {
[self doSomething];
}
objectivec权限未获取时,会收到以下回调:
//未获取麦克风权限,错误类型为 ByteRTCMediaDeviceErrorDeviceNoPermission
- (void)rtcEngine:(ByteRTCVideo * _Nonnull)engine onAudioDeviceStateChanged:(NSString*_Nonnull)deviceID device_type:(ByteRTCAudioDeviceType)deviceType device_state:(ByteRTCMediaDeviceState)deviceState device_error:(ByteRTCMediaDeviceError)deviceError;
//未获取摄像头权限,错误类型为 ByteRTCMediaDeviceErrorDeviceNoPermission
- (void)rtcEngine:(ByteRTCVideo * _Nonnull)engine onVideoDeviceStateChanged:(NSString*_Nonnull)deviceID device_type:(ByteRTCVideoDeviceType)deviceType device_state:(ByteRTCMediaDeviceState)deviceState device_error:(ByteRTCMediaDeviceError)deviceError;
objectivec注意:如果 iOS 未开启后台模式,进入后台后音视频通话会中断。开启后即可保持后台音视频通话。

不更改 Windows 系统设置前提下,麦克风/摄像头权限无需申请即可直接访问。
如果在系统设置界面关闭麦克风/摄像头权限,会收到以下回调:
//未获取麦克风权限,错误类型为 kMediaDeviceErrorDeviceNoPermission
virtual void bytertc::IRTCVideoEventHandler::onAudioDeviceStateChanged(
const char* device_id,
bytertc::RTCAudioDeviceType device_type,
bytertc::MediaDeviceState device_state,
bytertc::MediaDeviceError device_error)
//未获取摄像头权限,错误类型为 kMediaDeviceErrorDeviceNoPermission
virtual void bytertc::IRTCVideoEventHandler::onVideoDeviceStateChanged(
const char* device_id,
bytertc::RTCVideoDeviceType device_type,
bytertc::MediaDeviceState device_state,
bytertc::MediaDeviceError device_error)
cpp注意:设置内权限被关闭导致无法获取权限时,需在设置-隐私-麦克风/摄像头内开启权限。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>
java"mac": {
"entitlements": "build/entitlements.mac.plist",
"extendInfo": {
"NSMicrophoneUsageDescription": "授权访问麦克风",
"NSCameraUsageDescription": "授权访问摄像头"
}
}
javaconst { ipcMain,systemPreferences } = require('electron')
//获取麦克风权限
ipcMain.on("getMediaAccessStatus",async ()=>{
//检测麦克风权限是否开启
let getMediaAccessStatus = systemPreferences.getMediaAccessStatus('microphone')
if(getMediaAccessStatus !== 'granted'){
//请求麦克风权限
if (process.platform === "darwin") {
await systemPreferences.askForMediaAccess("microphone");
}
}
})
//获取摄像头权限
ipcMain.on("getMediaAccessStatus",async ()=>{
//检测摄像头权限是否开启
let getMediaAccessStatus = systemPreferences.getMediaAccessStatus('camera')
if(getMediaAccessStatus !== 'granted'){
//请求摄像头权限
if (process.platform === "darwin") {
await systemPreferences.askForMediaAccess("camera");
}
}
})
//可以通过以下方法确认屏幕录制权限的状态
const screenPrivilege = systemPreferences.getMediaAccessStatus("screen");
java注意:在 macOS 12.1 以上系统中,调试运行时正常,但打包成安装包后安装并启动时出现崩溃的问题。为解决这一问题,需要在主进程内主动申请麦克风/摄像头权限,具体参考上文 Electron 获取权限的相关内容。