You need to enable JavaScript to run this app.
导航

场景搭建(iOS)

最近更新时间2024.04.22 17:52:23

首次发布时间2022.11.15 16:06:43

SDK集成

为了保证最佳体验效果,本场景需要集成火山引擎的RTC SDK 以及火山直播播放器(建议)。您需要在 RTC、直播的控制台开通服务,相应开通指南如下:

1、RTC SDK总体接入流程,详细细节请参见 RTC服务开通指南

alt

2、直播播放器接入流程,详细步骤请参见接入流程

您也可使用原有三方直播播放器来实现,但为保障最佳体验,需实现音频托管功能,具体可与火山技术支持同学联系;

整体实现流程

整体业务流程图

alt

核心功能实现

创建/加入房间

时序图

alt

示例代码

/**
 * 加入RTC房间并初始化参数
 * @param token: RTC Token
 * @param roomID: RTC room id
 * @param uid: RTC user id
 **/
- (void)joinRTCRoomWithToken:(NSString *)token
                      roomID:(NSString *)roomID
                         uid:(NSString *)uid {
    // 初始化 ByteRTCVideo 对象
    self.rtcEngineKit = [ByteRTCVideo createRTCVideo:APPID
                                        delegate:self
                                      parameters:@{}];
    
    // 初始化 ByteRTCRoom 对象
    self.rtcRoom = [self.rtcEngineKit createRTCRoom:roomID];
    self.rtcRoom.delegate = self;
    
    // 设置为可见
    [self.rtcRoom setUserVisibility:YES];
    
    // 加入房间需要开启麦克风、相机,观众需要关闭麦克风、相机
    [self.rtcEngineKit startVideoCapture];
    [self.rtcEngineKit startAudioCapture];
        
    // 设置本地渲染和编码镜像
    [self.rtcEngineKit setLocalVideoMirrorType:ByteRTCMirrorTypeRenderAndEncoder];
   
    // 绑定本地视频预览视图
    UIView *view = [[UIView alloc] init];
    ByteRTCVideoCanvas *videoCanvas = [[ByteRTCVideoCanvas alloc] init];
    videoCanvas.uid = uid;
    videoCanvas.renderMode = ByteRTCRenderModeHidden;
    videoCanvas.view = view;
    [self.rtcEngineKit setLocalVideoCanvas:ByteRTCStreamIndexMain
                                withCanvas:videoCanvas];
    
    // 设置音频场景类型
    [self.rtcEngineKit setAudioScenario:ByteRTCAudioScenarioCommunication];
 
    // 开启发言者音量监听
    ByteRTCAudioPropertiesConfig *audioPropertiesConfig = [[ByteRTCAudioPropertiesConfig alloc] init];
    audioPropertiesConfig.interval = 300;
    [self.rtcEngineKit enableAudioPropertiesReport:audioPropertiesConfig];
    
    // 加入房间,开始连麦,需要申请AppId和Token
    ByteRTCUserInfo *userInfo = [[ByteRTCUserInfo alloc] init];
    userInfo.userId = uid;
    ByteRTCRoomConfig *config = [[ByteRTCRoomConfig alloc] init];
    config.profile = ByteRTCRoomProfileLwTogether;
    config.isAutoPublish = YES;
    config.isAutoSubscribeAudio = YES;
    config.isAutoSubscribeVideo = YES;
    [self.rtcRoom joinRoom:token
                  userInfo:userInfo
                roomConfig:config];
}
- (void)rtcRoom:(ByteRTCRoom *)rtcRoom onRoomStateChanged:(NSString *)roomId
                                                  withUid:(NSString *)uid
                                                    state:(NSInteger)state
                                                extraInfo:(NSString *)extraInfo {
    // Receive RTC joining room results
}

- (void)rtcEngine:(ByteRTCVideo *)engine onLocalAudioPropertiesReport:(NSArray<ByteRTCLocalAudioPropertiesInfo *> *)audioPropertiesInfos {
    // Local user volume callback      
}

- (void)rtcEngine:(ByteRTCVideo *)engine onRemoteAudioPropertiesReport:(NSArray<ByteRTCRemoteAudioPropertiesInfo *> *)audioPropertiesInfos 
                                                     totalRemoteVolume:(NSInteger)totalRemoteVolume {
    // Remote user volume callback
}

- (void)rtcRoom:(ByteRTCRoom *)rtcRoom onUserJoined:(ByteRTCUserInfo *)userInfo elapsed:(NSInteger)elapsed {
    // Remote user joining room callbacks
}

/**
 * Callbacks of media streams captured by the newly added remote camera/microphone in the room
 */
- (void)rtcRoom:( ByteRTCRoom *)rtcRoom onUserPublishStream:(NSString *)userId type:(ByteRTCMediaStreamType)type {
    if (type == ByteRTCMediaStreamTypeAudio) {
        return;
    }
    // Bind remote user video view 
    UIView *view = [[UIView alloc] init];
    ByteRTCVideoCanvas *videoCanvas = [[ByteRTCVideoCanvas alloc] init];
    videoCanvas.renderMode = ByteRTCRenderModeHidden;
    videoCanvas.view = view;
    
    ByteRTCRemoteStreamKey *streamKey = [[ByteRTCRemoteStreamKey alloc] init];
    streamKey.userId = userId;
    streamKey.roomId = self.rtcRoom.getRoomId;
    streamKey.streamIndex = ByteRTCStreamIndexMain;

    [self.rtcEngineKit setRemoteVideoCanvas:streamKey
                                 withCanvas:videoCanvas];
}

一起看直播

房主发起一起看直播,观众侧同步进入一起看直播。房主、观众各自通过直播播放器拉取同一个直播流观看。
注意:播放器接入及详细使用,请参考视频直播拉流 SDK

时序图

alt

示例代码

/**
 * 开启PCM混音
 * @param mixId 混音ID。用于标识混音,保证混音 ID 唯一性。 如果使用相同的 ID 重复调用本*方法后,前一次混音会停止,后一次混音开始。
 */
- (void)startAudioMixing:(int)mixId {
    // 开启本地混音播放
    ByteRTCMediaPlayer *mediaPlayer = [self.rtcEngineKit getMediaPlayer:0];
    ByteRTCMediaPlayerCustomSource *mdsSource = [[ByteRTCMediaPlayerCustomSource alloc] init];
    mdsSource.provider = (id<ByteRTCMediaPlayerCustomSourceProvider>)source;
    mdsSource.mode = ByteRTCMediaPlayerCustomSourceModePull;
    mdsSource.type = ByteRTCMediaPlayerCustomSourceStreamTypeEncoded;

    ByteRTCMediaPlayerConfig *config = [[ByteRTCMediaPlayerConfig alloc] init];
    config.type = ByteRTCAudioMixingTypePlayoutAndPublish;
    config.playCount = 1;
    config.startPos = startPos;
    config.callbackOnProgressInterval = self.ktvInfo.callbackOnProgressInterval;
    config.syncProgressToRecordFrame = YES;
    config.autoPlay = NO;
    
    [mediaPlayer openWithCustomSource:self.mdsSource config:config];
}

/** 
 * 播放器音频数据回调,推送音频数据到RTC
 */
- (void)pushAudioMixingFrame:(int)mixId audioFrame:(ByteRTCAudioFrame *)audioFrame {
    // 将播放器回调出的数据送入RTC播放
    ByteRTCMediaPlayer *mediaPlayer = [self.rtcEngineKit getMediaPlayer:0];
    [mediaPlayer pushExternalAudioFrame:audioFrame];
}

/**
* 关闭PCM混音
*/
- (void)stopAudioMixing:(int)mixId {
    // 关闭混音
    ByteRTCMediaPlayer *mediaPlayer = [self.rtcEngineKit getMediaPlayer:0];
    [mediaPlayer stop];
}

控制台

alt

示例代码

/** 
 * 打开/关闭音量闪避功能。 
 * 开启该功能后,当检测到远端人声时,本地的媒体播放音量会自动减弱,从而保证远端人声的清晰可辨;当远端人声消失时,本地媒体音量会恢复到闪避前的音量水平。
 * @param enable 是否开启音量闪避
 */
- (void)enablePlaybackDucking:(BOOL)enable {
    [self.rtcEngineKit enablePlaybackDucking:enable];
}

/** 
 * 调节混音的音量大小,包括音频文件混音和 PCM 混音。
 * @param mixId 混音 ID
 * @param volume 混音音量相对原音量的比值。范围为 `[0, 400]`,建议范围是 `[0, 100]`。
 */
- (void)setAudioMixingVolume:(int)mixId volume:(int)volume {
    ByteRTCMediaPlayer *mediaPlayer = [self.rtcEngineKit getMediaPlayer:0];
    [mediaPlayer setVolume:volume type:ByteRTCAudioMixingTypePlayoutAndPublish];
}

/** 
 * 调节本地播放的所有远端用户混音后的音量。播放音频前或播放音频时,你都可以使用此接口设定播放音量。
 * @param volume 音频播放音量值和原始音量的比值,范围是 [0, 400],单位为 %,自带溢出保护。
 */
- (void)setPlaybackVolume:(NSInteger)volume {
    [self.rtcEngineKit setPlaybackVolume:volume];
}

核心功能 API 与回调参考

API

功能点API
创建 RTCVideo 对象createRTCVideo:delegate:parameters:
创建 RTCRoom 对象createRTCRoom:
设置用户可见性setUserVisibility:
设置本地渲染和编码镜像setLocalVideoMirrorType:
设置本地视频渲染视图setLocalVideoCanvas:withCanvas:
设置音频场景类型setAudioScenario:
启用音频信息提示enableAudioPropertiesReport:
开启本地音频采集startAudioCapture:
开启本地视频采集startVideoCapture
加入RTC 房间joinRoom:userInfo:roomConfig:
设置远端用户视频渲染视图setRemoteVideoCanvas:withCanvas:
开启PCM 音频数据混音openWithCustomSource:config:
推送 PCM 音频帧数据用于混音pushExternalAudioFrame:
调节混音的音量大小setVolume:volume:
调节远端用户用通话音量setPlaybackVolume:
打开音量闪避功能enablePlaybackDucking:
离开房间leaveRoom
销毁 RTCRoom 对象destroy
关闭内部音频采集stopAudioCapture
关闭内部视频采集stopVideoCapture
销毁 RTCVideo 对象destroyRTCVideo

回调

功能点回调
本地用户加入 RTC 房间回调rtcRoom:onRoomStateChanged:uid:state:extraInfo
音频播放路由变化回调rtcEngine:onAudioRouteChanged:
本地音频的相关信息回调rtcEngine:onLocalAudioPropertiesReport:
订阅的远端用户的音频信息回调rtcEngine:onRemoteAudioPropertiesReport:totalRemoteVolume:
远端用户加入 RTC 房间回调rtcRoom:onUserJoined:elapsed:
房间内新增远端摄像头/麦克风采集的媒体流的回调rtcRoom:onUserPublishStream:type: