You need to enable JavaScript to run this app.
文档中心
实时音视频

实时音视频

复制全文
下载 pdf
音视频通话
场景搭建(iOS)
复制全文
下载 pdf
场景搭建(iOS)
SDK集成​
如下是一个总体接入流程,详细细节请参见 RTC服务开通指南。​
​Image​​
整体实现流程​
整体业务流程图​
​Image​​
核心功能实现​
准备通话​
时序图​
​Image​​
示例代码​
​
- (void) startCallWithAppID:(NSString *)appid BID:(NSString *)bid {​
// 创建 RTC 引擎​
[self createRTCVideoWithAppID:appid BID:bid];​
​
// 设置本地视频画布​
ByteRTCVideoCanvas *canvas = [[ByteRTCVideoCanvas alloc] init]; ​
canvas.view = self.localView.RenderView;​
canvas.renderMode = ByteRTCRenderModeHidden;​
[self.rtcEngineKit setLocalVideoCanvas:ByteRTCStreamIndexMain withCanvas:canvas];​
​
// 设置本地视频采集,移动端默认会开启前置摄像头。​
if (userSetting.openCamera) {​
[self.rtcEngineKit startVideoCapture];​
} else {​
[self.rtcEngineKit stopVideoCapture];​
}​
​
// 设置本地音频采集​
if (userSetting.openMic) {​
[self.rtcEngineKit startAudioCapture];​
} else {​
[self.rtcEngineKit stopVideoCapture];​
}​
}​
​
- (void)createRTCVideoWithAppID:(NSString *)appId BID:(NSString *)bid {​
// 创建 RTC 引擎​
self.rtcEngineKit = [ByteRTCVideo createRTCVideo:appId delegate:self parameters:@{}];​
​
// 设置视频编码参数​
ByteRTCVideoEncoderConfig *config = [[ByteRTCVideoEncoderConfig alloc] init];​
config.width = 540;​
config.height = 960;​
config.frameRate = 15;​
config.maxBitrate = 1520; // 单位:kbs​
[self.rtcEngineKit setMaxVideoEncoderConfig:config];​
​
// 设置视频帧方向​
[self.rtcEngineKit setVideoOrientation:ByteRTCVideoOrientationPortrait]; ​
​
// 设置默认音频路由​
[self.rtcEngineKit setDefaultAudioRoute:ByteRTCAudioRouteSpeakerphone]; ​
​
// 该策略不适用于使用非 RTC SDK 播放音乐/音效的场景,如有背景音乐播放的游戏场景​
[self.rtcEngineKit setRuntimeParameters:@{@"rtc.audio_session_deactive" : @(YES)}]; ​
}​
​
​
响铃​
时序图​
​Image​​
示例代码​
​
- (void)startRinging {​
// 音频场景设置为媒体​
[self.rtcEngineKit setAudioScenario:ByteRTCAudioScenarioMedia];​
// audio file path​
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"VideoCallDemo" ofType:@"bundle"];​
NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];​
NSString *filePath = [bundle pathForResource:@"call_receive" ofType:@"mp3"];​
// 开始响铃​
ByteRTCAudioMixingConfig *config = [[ByteRTCAudioMixingConfig alloc] init];​
config.type = ByteRTCAudioMixingTypePlayout; // 播放响铃​
config.playCount = 0; // 停止混音前一直循环​
[[self.rtcEngineKit getAudioMixingManager] startAudioMixing:0 filePath:filePath config:config];​
}​
​
- (void)stopRinging {​
[[self.rtcEngineKit getAudioMixingManager] stopAudioMixing:0];​
}​
​
进行通话​
时序图​
​Image​​
示例代码​
​
// 加入房间​
- (void)joinRoomWithToken:(NSString *)token roomID:(NSString *)roomID uid:(NSString *)uid complete:(void(^)(BOOL success))complete {​
// 设置音频场景为 ByteRTCAudioScenarioHighqualityChat​
[self.rtcEngineKit setAudioScenario:ByteRTCAudioScenarioHighqualityChat];​
​
self.joinRoomBlock = complete;​
​
self.rtcRoom = [self.rtcEngineKit createRTCRoom:roomID];​
self.rtcRoom.delegate = self;​
​
ByteRTCUserInfo *info = [[ByteRTCUserInfo alloc] init];​
info.userId = uid;​
ByteRTCRoomConfig *roomConfig = [[ByteRTCRoomConfig alloc] init];​
// room profile使用ByteRTCRoomProfileCommunication​
roomConfig.profile = ByteRTCRoomProfileCommunication;​
// 开启手动发布​
roomConfig.isAutoPublish = NO;​
// 开启自动订阅​
roomConfig.isAutoSubscribeAudio = YES;​
roomConfig.isAutoSubscribeVideo = YES;​
​
[self.rtcRoom joinRoom:token userInfo:info roomConfig:roomConfig];​
}​
​
#pragma mark - ByteRTCRoomDelegate​
// 进房状态回调通知​
- (void)rtcRoom:(ByteRTCRoom *)rtcRoom onRoomStateChanged:(NSString *)roomId withUid:(NSString *)uid state:(NSInteger)state extraInfo:(NSString *)extraInfo { ​
dispatch_async(dispatch_get_main_queue(), ^{​
if (self.joinRoomBlock) {​
self.joinRoomBlock(state == 0);​
self.joinRoomBlock = nil;​
}​
});​
}​
​
// 远端用户加入房间后设置渲染画布。​
- (void)rtcRoom:(ByteRTCRoom *)rtcRoom onUserJoined:(ByteRTCUserInfo *)userInfo elapsed:(NSInteger)elapsed {​
dispatch_async(dispatch_get_main_queue(), ^{​
[self setRemoteVideoCanvas:self.remoteView.renderView userID:userInfo.userId]; ​
});​
}​
​
// 设置远端渲染画布​
- (void)setRemoteVideoCanvas:(UIView *)view userID:(NSString *)userID {​
ByteRTCRemoteStreamKey *streamKey = [[ByteRTCRemoteStreamKey alloc] init];​
streamKey.userId = userID;​
streamKey.roomId = [self.rtcRoom getRoomId];​
streamKey.streamIndex = ByteRTCStreamIndexMain;​
​
ByteRTCVideoCanvas *canvas = [[ByteRTCVideoCanvas alloc] init];​
canvas.view = view;​
canvas.renderMode = ByteRTCRenderModeHidden;​
​
[self.rtcEngineKit setRemoteVideoCanvas:streamKey withCanvas:canvas];​
}​
​
​
// 切换前后置摄像头​
- (void)switchToCamera:(ByteRTCCameraID)cameraID {​
if (cameraID == ByteRTCCameraIDFront) { // 前置:ByteRTCMirrorTypeRenderAndEncoder​
[self.rtcEngineKit setLocalVideoMirrorType:ByteRTCMirrorTypeRenderAndEncoder];​
} else { // 后置:ByteRTCMirrorTypeNone​
[self.rtcEngineKit setLocalVideoMirrorType:ByteRTCMirrorTypeNone];​
}​
​
// {zh} 设置采集摄像头ID​
// {en} Set camera ID​
[self.rtcEngineKit switchCamera:cameraID];​
self.currnetCameraID = cameraID;​
}​
​
网络状态提示​
用户加入 RTC 房间后,onNetworkQuality 每 2 s 回调一次,返回本地用户和已订阅远端用户的上下行网络质量评分。 RTC 根据 NetworkQuality 的数值,对网络状况进行判定,在网络质量不好时进行提示。​
  • 在本地断网(如开启飞行模式)时,onNetworkTypeChanged(kNetworkTypeDisconnected) 会立即触发。​
  • 连接断开时长达 12s 时,RTC 会触发 onConnectionStateChanged(kConnectionStateDisconnected) 回调通知连接断开。​
  • 连接断开后,RTC 内部会不断重连,超过一段时间未重连成功,会进入断联超时状态,建议业务 App 挂断通话。​
示例代码​
​
// 网络质量提示​
- (void)rtcRoom:(ByteRTCRoom *)rtcRoom onNetworkQuality:(ByteRTCNetworkQualityStats *)localQuality remoteQualities:(NSArray<ByteRTCNetworkQualityStats *> *)remoteQualities {​
ByteRTCNetworkQualityStats *remoteQuality = remoteQualities.firstObject;​
if (!remoteQuality) {​
return;​
}​
​
NSUInteger localQuality = MAX(localQuality.txQuality, localQuality.rxQuality);​
NSUInteger remoteQuality = MAX(remoteQuality.txQuality, remoteQuality.rxQuality);​
​
// NSLog(@"onNetworkQuality-local:%ld-remote:%ld", localQuality, remoteQuality);​
​
if (localQuality <= ByteRTCNetworkQualityPoor &&​
remoteQuality <= ByteRTCNetworkQualityPoor) {​
dispatch_async(dispatch_get_main_queue(), ^{​
// 网络恢复,清除弱网提示。​
}​
return;​
}​
​
// 优先提示本地弱网状态​
if (localQuality > ByteRTCNetworkQualityPoor) {​
dispatch_async(dispatch_get_main_queue(), ^{​
// 提示本地弱网​
// 若 localQuality == ByteRTCNetworkQualityVeryBad,提示建议用户关闭摄像头。​
}​
return;​
}​
​
// 本地网络正常,对端网络异常,提示对端弱网​
if (remoteQuality > ByteRTCNetworkQualityPoor) {​
dispatch_async(dispatch_get_main_queue(), ^{​
// 提示对端弱网​
}​
return;​
} ​
}​
​
结束通话​
时序图​
​Image​​
示例代码​
​
- (void)onLeaveCall {​
if (self.rtcRoom != nil) {​
[self.rtcRoom leaveRoom];​
[self.rtcRoom destroy];​
self.rtcRoom = nil;​
}​
if (self.rtcVideoKit) {​
[self.rtcVideoKit stopAudioCapture];​
[self.rtcVideoKit stopVideoCapture];​
[ByteRTCVideo destroyRTCVideo];​
self.rtcVideoKit = nil;​
}​
}​
​
核心功能 API 与回调参考​
API​
​
​
功能点​
API​
创建 ByteRTCVideo 实例​
createRTCVideo:delegate:parameters:​
设置视频发布参数​
设置默认音频播放路由​
设置视频朝向​
开启本地音频采集​
开启本地视频采集​
设置本地视频渲染​
setLocalVideoCanvas:withCanvas:​
获取混音管理接口​
getAudioMixingManager​
开启 PCM 音频数据混音​
startAudioMixing​
关闭PCM 混音​
disableAudioMixingFrame:​
创建 RTCRoom 实例​
设置房间事件处理器​
加入 RTC 房间​
joinRoom:userInfo:roomConfig:​
切换前后置摄像头​
开启镜像​
关闭内部音频采集​
关闭内部视频采集​
设置视频渲染视图​
离开房间​
销毁引擎实例对象​
destroyRTCVideo​
​
回调​
​
​
功能点​
回调​
用户开启音频采集​
rtcEngine:onUserStartAudioCapture:uid:​
用户停止音频采集​
rtcEngine:onUserStopAudioCapture:uid:​
用户开启视频采集​
rtcEngine:onUserStartVideoCapture:uid:​
用户停止视频采集​
rtcEngine:onUserStopVideoCapture:uid:​
用户停止视频采集​
rtcEngine:onUserStopVideoCapture:uid:​
音频混音文件播放状态改变​
rtcEngine:onAudioMixingStateChanged:state:error:​
远端首帧解码​
rtcEngine:onFirstRemoteVideoFrameDecoded:withFrameInfo:​
房间 token 即将失效回调​
本地进房成功回调​
远端可见用户加入房间​
rtcRoom:onUserJoined:elapsed:​
​
​
最近更新时间:2026.09.22 14:41:51
这个页面对您有帮助吗?
有用
有用
无用
无用