音视频接入总览
本文面向需要接入即时呼或普通/预约会议的 iOS 应用。两种能力使用同一套媒体运行时,但业务模型和 Session 相互独立。
音视频版本最低支持 iOS 13.4。请先完成 BIMSdk 初始化和登录,再调用任何 Call 或 Meeting API。
快速接入清单
- 使用
BIMSdk/Call集成完整音视频运行时。 - 在
Info.plist声明麦克风和摄像头用途,并在进入音视频前由宿主申请权限。 - 初始化 BIMSdk,配置不含
/app的baseURL,然后登录。 - 长期持有实现
BIMCallListener、BIMMeetingListener的对象并注册监听。 - 发起或进入前检查媒体模块可用性,并确保没有其他活跃音视频 Session。
- 保存成功回调返回的 Session,用 Snapshot 驱动 UI,并把画面挂载到业务容器。
- 页面销毁时卸载画面;真正退出时调用 Call 的
hangup或 Meeting 的leave。
即时呼的完整流程见实时音视频通话,普通与预约会议见即时与预约会议。
安装完整音视频模块
CocoaPods
只需要安装 Call subspec。它同时包含即时呼和普通/预约会议能力:
ruby
platform :ios, '13.4'
target 'YourApp' do
pod 'BIMSdk/Call', '1.0.7'
endbash
pod install --repo-update不要同时声明 BIMSdk 和 BIMSdk/Call,后者已经依赖 Core。FMDB 2.7.12 与 Protobuf 3.29.5 由 Podspec 自动安装,底层 IMSdk 已静态封装进 Core,业务工程不需要重复声明。
BIMSdk/Call 会进一步安装 BeeWorksMeetSDK 1.1.9,JitsiWebRTC、Giphy、libwebp 等依赖由 CocoaPods 自动解析。BIMSdk 1.0.7 暂未发布完整可用的 Swift Package,详见安装与升级。
手动集成
手动集成必须使用完整音视频交付包,至少包含 BIMSdk.xcframework、BIMCallJitsiAdapter.xcframework、FMDB 2.7.12、Protobuf 3.29.5 及交付包列出的 Meet 运行时动态 Framework。将动态 Framework 设置为 Embed & Sign,不要只复制 Core。
业务代码统一导入:
objc
#import <BIMSdk/BIMSdk.h>swift
import BIMSdk媒体适配器会自动加载,业务方不需要初始化或引用 Jitsi 类型。
配置系统权限
在 Info.plist 中声明:
xml
<key>NSMicrophoneUsageDescription</key>
<string>用于语音通话和会议</string>
<key>NSCameraUsageDescription</key>
<string>用于视频通话和会议</string>宿主应在用户点击发起、接听、开始或加入之前请求所需权限。语音场景至少需要麦克风权限,视频场景还需要摄像头权限。权限被拒绝时,应停留在业务 UI 引导用户去系统设置,不要继续创建媒体 Session。
屏幕共享由 Meet 运行时控制;如果产品需要系统级后台屏幕广播,还需要由宿主按产品方案配置 ReplayKit Broadcast Upload Extension。
初始化并检查环境
baseURL 填写网关根地址,不要自行拼接 /app。SDK 会为音视频请求添加 /app/call、/app/meet 和 /app/meetings 路径。
objc
BIMSDKConfig *config = [BIMSDKConfig new];
config.baseURL = @"https://im.example.com";
config.imEndpoint = @"im.example.com:8029";
config.logLevel = BIM_LOG_INFO;
BIMManager *manager = [BIMManager sharedInstance];
BOOL initialized = [manager initSDK:@"your-app-id" config:config];
if (!initialized) {
// 配置无效,不要继续登录或进入音视频。
}
[manager login:@"user-001" jwt:jwt succ:^{
BOOL callReady = manager.isCallMediaAvailable;
BOOL meetingReady = manager.isMeetingMediaAvailable;
NSLog(@"call=%d meeting=%d", callReady, meetingReady);
} fail:^(int code, NSString *desc) {
NSLog(@"login failed: %d %@", code, desc);
}];正常的完整音视频包中两个可用性属性都应为 YES。返回 NO 时应隐藏或禁用入口,并检查是否只集成了 Core、Adapter 是否被链接、Meet 动态 Framework 是否已 Embed。
注册全局监听
监听器按弱引用保存,因此应用需要强持有监听对象。建议在登录前注册,在退出登录或对象销毁时移除。
objc
@interface AppAudioVideoObserver : NSObject <BIMCallListener, BIMMeetingListener>
@end
@implementation AppAudioVideoObserver
- (void)startObserving {
BIMManager *manager = [BIMManager sharedInstance];
[manager addCallListener:self];
[manager addMeetingListener:self];
}
- (void)stopObserving {
BIMManager *manager = [BIMManager sharedInstance];
[manager removeCallListener:self];
[manager removeMeetingListener:self];
}
@end即时呼来电需要全局监听,不能只在聊天页注册。会议邀请和状态消息也建议由应用级监听器接收,再路由到通知、会话列表或会议页。
管理 Session 和页面
Call 与 Meeting 全局只允许一个活跃音视频 Session。进入前可以检查:
objc
BIMManager *manager = [BIMManager sharedInstance];
BOOL occupied = manager.currentCallSession != nil ||
manager.currentMeetingSession != nil;已有会议或通话时主动进入另一场音视频会返回 BIMCallErrorAlreadyActive。已有 Session 时收到新的即时呼,SDK 会自动回复 busy,但宿主仍应根据业务需要展示未接来电记录。
成功回调表示本地 Session 已建立,不等于媒体已经连接。页面必须:
- 强持有 Session,直到收到
Ended状态。 - 使用 Listener 返回的 Snapshot 更新按钮、成员和错误 UI。
- 可以在连接完成前调用
attachRenderViewToContainer:。 - 页面临时消失只调用
detachRenderView;只有用户明确退出时才调用hangup或leave。 - 不缓存短期媒体 token,也不要自行调用
/app音视频接口。
宿主与 SDK 的职责边界
| 能力 | BIMSdk | 宿主应用 |
|---|---|---|
| 音视频 REST、IM 信令、断线校准 | 负责 | 不直接请求 |
| Jitsi 参数获取和媒体房间连接 | 负责 | 不接触 Jitsi 类型 |
| Call/Meeting Session 与状态快照 | 负责 | 强持有并驱动 UI |
| 麦克风、摄像头系统权限 | 提供错误码 | 负责申请和引导 |
| 来电页、通话工具栏、会议页 | 不提供 | 负责实现 |
| 铃声和震动 | 不提供 | 负责播放和停止 |
| PushKit、CallKit 注册和系统 UI | 不接管 | 负责实现并转交 payload |
| 业务埋点、通话记录样式 | 提供强类型消息 | 负责展示和上报 |
通用错误处理
所有音视频 API 的失败回调都返回 code 和 desc。desc 适合日志记录,交互文案应由业务方按 code 映射。
| code | 常量 | 建议处理 |
|---|---|---|
| 7001 | BIMCallErrorNotInitialized | 检查 initSDK 和 baseURL |
| 7002 | BIMCallErrorNotLoggedIn | 重新登录后再操作 |
| 7003 | BIMCallErrorInvalidArgument | 检查用户 ID、会议号、主题和预约时间 |
| 7004 | BIMCallErrorAlreadyActive | 返回或展示当前音视频 Session |
| 7005 | BIMCallErrorInvalidState | 使用最新 Snapshot 判断当前是否允许操作 |
| 7006 | BIMCallErrorPermissionDenied | 引导用户开启麦克风或摄像头权限 |
| 7101 | BIMCallErrorCallNotFound | 刷新列表并关闭已失效入口 |
| 7102 | BIMCallErrorCallExpired | 结束本地等待 UI |
| 7103 | BIMCallErrorSignalingFailed | 展示网络错误,可让用户重试操作 |
| 7104 | BIMCallErrorParticipantLimit | 减少成员或提示人数上限 |
| 7201 | BIMCallErrorMediaUnavailable | 检查完整音视频模块是否集成 |
| 7202 | BIMCallErrorJoinRoomFailed | 保持 Session 状态,等待自动重试或退出 |
| 7203 | BIMCallErrorDeviceUnavailable | 检查音频路由、摄像头和系统占用 |
| 7204 | BIMCallErrorNetworkUnavailable | 展示重连态,等待网络恢复 |
| 7205 | BIMCallErrorFeatureUnsupported | 隐藏当前运行时不支持的能力 |
| 7299 | BIMCallErrorInternal | 记录 SDK 日志并上报 |
媒体连接失败后,SDK 会以 1、2、4 秒退避自动重试最多 3 次。UI 应保持在 Reconnecting,不要同时创建第二个 Session。每次失败都会通过 Listener 的错误回调通知;有限重试后仍未恢复时,业务 UI 应保留退出入口。只有 Snapshot 进入 Ended 才表示 Session 已终止。
上线前验收
- 使用标准签名 Debug 构建在两台真机、两个账号之间验证,不能使用未签名产物验证 v2 接口。
- 验证语音和视频的发起、接听、拒绝、取消、忙线、挂断和断网恢复。
- 验证即时会议、预约会议、编辑、开始、加入、取消和本地离会。
- 验证前后台切换、锁屏、蓝牙/听筒/扬声器切换及权限拒绝后的 UI。
- 验证同时存在 Call/Meeting 时的互斥和新来电 busy 行为。
- 验证 VoIP Push 冷启动恢复,以及 CallKit UI 与 SDK Session 的终态一致。
