human: 如何处理七牛云的实时音视频发布和订阅

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > iOS >发布和订阅

#  发布和订阅

最近更新时间: 2022-09-08 11:56:19

本部分介绍如何实现在房间发布、订阅媒体流。

>   * **发布** 是指将创建好的音视频 Track
> 对应的音视频数据推送到七牛实时音视频服务的操作，执行发布操作后，远端用户可以选择性的进行订阅观看。
>   * **订阅** 是指向七牛实时音视频服务请求拉取远端发布的音视频数据的操作。订阅后，本地即可实时的接收远端发布的音视频数据。
>   * **有别于 CDN 转推** ，发布和订阅的音视频数据将通过 UDP 协议在房间内流转，若您想要实现 RTMP 直播流分发的场景，请在音视频
> Track 发布后，参考使用指南的 [CDN
> 转推](https://developer.qiniu.com/rtc/development_guidelines/9262/turn-the-
> cdn-push-iOS)进行实现。
>

# 发布 Track

发布 [Track](https://developer.qiniu.com/rtc/quick_start/9909/the-rtc-basic-
concept#track) 前，需要对 Track
进行配置和创建，详情请见[音视频采集](https://developer.qiniu.com/rtc/development_guidelines/9258/audio-
and-video-collection-iOS)，创建好 Track 后即可将该 Track 通过
[QNRTCClient.publish](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#publish%5B1/2%5D) 向房间内进行发布。

> 请确保在发布前已经成功加入房间，否则将发布失败。
    
    
    // 发布本地音视频 Track 数组
    [rtcClient publish:trackList];
    // 发布本地音视频 Track 数组并回调发布结果
    [rtcClient publish:trackList completeCallback:callback];
    

其中，[QNPublishResultCallback](https://developer.qiniu.com/rtc/api/9254/QNTypeDefines#QNPublishResultCallback)
回调了发布操作的结果通知，其接口定义如下：

    
    
    typedef void (^QNPublishResultCallback)(BOOL onPublished, NSError *error);
    

发布 Track 失败的错误码可参考[发布 Track 相关错误码](https://developer.qiniu.com/rtc/10084/rtc-
error-code-iOS#2)。

发布 Track 成功后，远端用户会收到
[QNRTCClientDelegate.didUserPublishTracks](https://developer.qiniu.com/rtc/api/9248/QNRTCClientDelegate#didUserPublishTracks)
回调：

    
    
    - (void)RTCClient:(QNRTCClient *)client didUserPublishTracks:(NSArray<QNRemoteTrack *> *)tracks ofUserID:(NSString *)userID;
    

# 取消发布 Track

调用
[QNRTCClient.unpublish](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#unpublish) 取消发布本地媒体流。

    
    
    // 取消发布本地音视频 Track 数组
    [rtcClient unpublish:trackList];
    

取消发布成功后，远端用户会收到
[QNRTCClientDelegate.didUserUnpublishTracks](https://developer.qiniu.com/rtc/api/9248/QNRTCClientDelegate#didUserUnpublishTracks)
回调：

    
    
    - (void)RTCClient:(QNRTCClient *)client didUserUnpublishTracks:(NSArray<QNRemoteTrack *> *)tracks ofUserID:(NSString *)userID;
    

# 订阅远端 Track

## 自动订阅

在 v2.x.x 版本后提供了默认自动订阅的功能，用户可以通过设置
[QNRTCClient.autoSubscribe](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#autoSubscribe) 进行对自动订阅功能的开启与关闭。

    
    
    // 默认为开启状态
    rtcClient.autoSubscribe = YES;
    

## 手动订阅

在自动订阅功能关闭时，用户可以通过调用
[QNRTCClient.subscribe](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#subscribe) 接口订阅远端 Tracks。

    
    
    // 订阅远端音视频 Track 数组
    [rtcClient subscribe:trackList];
    

**无论是自动订阅还是手动订阅，当成功订阅远端用户媒体流后，都会触发[QNRTCClientDelegate.didSubscribedRemoteVideoTracks](https://developer.qiniu.com/rtc/api/9248/QNRTCClientDelegate#didSubscribedRemoteVideoTracks)，回调如下：**

    
    
    - (void)RTCClient:(QNRTCClient *)client didSubscribedRemoteVideoTracks:(NSArray<QNRemoteVideoTrack *> *)videoTracks audioTracks:(NSArray<QNRemoteAudioTrack *> *)audioTracks ofUserID:(NSString *)userID;
    

成功订阅远端视频后，即可通过
[QNRemoteVideoTrack.play](https://developer.qiniu.com/rtc/api/8858/QNRemoteVideoTrack-
iOS#play) 接口传入预先创建好的
[QNVideoGLView](https://developer.qiniu.com/rtc/api/11950/QNVideoGLView-iOS)
实例进行远端视频画面的渲染。

示例代码如下：

    
    
    - (void)RTCClient:(QNRTCClient *)client didSubscribedRemoteVideoTracks:(NSArray<QNRemoteVideoTrack *> *)videoTracks audioTracks:(NSArray<QNRemoteAudioTrack *> *)audioTracks ofUserID:(NSString *)userID {
        dispatch_async(dispatch_get_main_queue(), ^{
            for (QNRemoteVideoTrack * videoTrack in videoTracks) {
                [videoTrack play:remoteView];
            }
        });
    }
    

# 取消订阅远端 Track

调用
[QNRTCClient.unsubscribe](https://developer.qiniu.com/rtc/api/8836/QNRTCClient-
iOS#unsubscribe) 接口取消订阅远端 Track。

    
    
    // 取消订阅远端音视频 Track 数组
    [rtcClient unsubscribe:trackList];
    

# 示例代码

发布订阅场景的示例代码可参考 [API-Examples-iOS](https://github.com/pili-engineering/QNRTC-
iOS/blob/master/QNRTC-API-Examples/Api-Examples-
iOS/Module/Video/CameraVideo/CameraVideoExample.m)

以上内容是否对您有帮助？