# Render user video

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

> The code on this page works with either the **default UI** or the **custom UI**.

In custom UI mode, the SDK provides multiple options to render user video after a user subscribes to another user's video. After following the steps to render a user's video, each option contains a different type of video stream.

-   **Single attendee** - A single user's video.
-   **Active speaker** - A single user's video that automatically updates when the active speaker changes.
-   **Preview** - A preview of the local user's video.
-   **Share** - The content being shared by another user.

Regardless of which render option you're using, the SDK utilizes two main components.

-   `MobileRTCVideoView`, `MobileRTCActiveShareView`, `MobileRTCActiveVideoView`, or `MobileRTCPreviewVideoView` - Interface for video element rendering in custom UI.
-   `MobileRTCMeetingServiceDelegate` - A delegate that indicates if a video's subscription fails and more.

## Subscribe to error data

Before subscribing to the video, implement `MobileRTCMeetingServiceDelegate` to know when a video subscription fails.

```swift
// Add delegate first.
guard let meetingService = MobileRTC.shared().getMeetingService() else { return }
meetingService.delegate = self

// Also, conform your class to the MobileRTCMeetingServiceDelegate
extension ViewController: MobileRTCMeetingServiceDelegate
    func onSubscribeUserFail(_ errorCode: MobileRTCSubscribeFailReason, size: Int, userId: UInt) {

    }
}
```

```objectivec
// In your .h file, conform to the MobileRTCMeetingServiceDelegate protocol
@interface ViewController : UIViewController <MobileRTCMeetingServiceDelegate> {

}

// In your .m file, add delegate and add onSubscribeUserFail callback
MobileRTCMeetingService *meetingService = [[MobileRTC sharedRTC] getMeetingService];
if (!meetingService) {
    return;
}
meetingService.delegate = self;

- (void)onSubscribeUserFail:(MobileRTCSubscribeFailReason)errorCode size:(NSInteger)size userId:(NSUInteger)userId {

}
```

When you've finished using the video view, remove the listener to avoid leaks.

```swift
meetingService.delegate = nil
```

```objectivec
meetingService.delegate = nil;
```

## Define a video view

The primary user-facing video element is `MobileRTCVideoView` for rendering attendee video view. It is also inherited by these components.

-   `MobileRTCActiveVideoView` - for active speaker view
-   `MobileRTCActiveShareView` - for active share view
-   `MobileRTCPreviewVideoView` - for local user preview view

Create a new `MobileRTCVideoView` instance based on which UIView you need, and give that new instance the `CGRect` frame that you'll be using to add the video view.

```swift
let videoViewFrame = CGRect() // Your Video View

// MobileRTCVideoView
let  videoView = MobileRTCVideoView(frame: videoViewFrame)

// MobileRTCActiveShareView
let activeShareView = MobileRTCActiveShareView(frame: videoViewFrame)

// MobileRTCActiveVideoView
let activeVideoView = MobileRTCActiveVideoView(frame: videoViewFrame)
activeVideoView.setVideoAspect(MobileRTCVideoAspect_PanAndScan)

// MobileRTCPreviewVideoView
let previewVideoView = MobileRTCPreviewVideoView(frame: videoViewFrame)
previewVideoView.setVideoAspect(MobileRTCVideoAspect_PanAndScan)
```

```objectivec
CGRect videoViewFrame = CGRectZero; // Your Video View

// // MobileRTCVideoView
MobileRTCVideoView *videoView = [[MobileRTCVideoView alloc] initWithFrame:videoViewFrame];

// MobileRTCActiveShareView
MobileRTCActiveShareView *activeShareView =
    [[MobileRTCActiveShareView alloc] initWithFrame:videoViewFrame];
[activeShareView

// MobileRTCActiveVideoView
MobileRTCActiveVideoView *activeVideoView =
    [[MobileRTCActiveVideoView alloc] initWithFrame:videoViewFrame];
[activeVideoView setVideoAspect:MobileRTCVideoAspect_PanAndScan];

// MobileRTCPreviewVideoView
MobileRTCPreviewVideoView *previewVideoView =
    [[MobileRTCPreviewVideoView alloc] initWithFrame:videoViewFrame];
[previewVideoView setVideoAspect:MobileRTCVideoAspect_PanAndScan];
```

## Subscribe to video streams

To subscribe to a single attendee's video, you must provide the `userId` of the user whose video is being subscribed to. Access this in `MobileRTCMeetingUserInfo.userID`.

```swift
let  videoView = MobileRTCVideoView(frame: videoViewFrame)
videoView.showAttendeeVideo(withUserID: 123456789) // userID
videoView.stopAttendeeVideo()
```

```objectivec
MobileRTCVideoView *videoView = [[MobileRTCVideoView alloc] initWithFrame:videoViewFrame];
[videoView showAttendeeVideoWithUserID:123456789]; // userID
[videoView stopAttendeeVideo];
```

To subscribe to the active speaker stream, call these codes.

```swift
let activeUserID = meetingService.activeUserID()
let activeVideoView = MobileRTCActiveVideoView(frame: videoViewFrame)
activeVideoView.setVideoAspect(MobileRTCVideoAspect_PanAndScan)

activeVideoView.showAttendeeVideo(withUserID: activeUserID) // Show
activeVideoView.stopAttendeeVideo() // Stop
```

```objectivec
NSUInteger activeUserID = meetingService.activeUserID;
MobileRTCActiveVideoView *activeVideoView = [[MobileRTCActiveVideoView alloc] initWithFrame:videoViewFrame];
[activeVideoView setVideoAspect:MobileRTCVideoAspect_PanAndScan];

[activeVideoView showAttendeeVideoWithUserID:activeUserID]; // Show
[activeVideoView stopAttendeeVideo]; // Stop
```

To subscribe to the local preview of the user associated with this SDK instance, call these codes.

```swift
let localUserID = meetingService.myselfUserID()
let previewVideoView = MobileRTCPreviewVideoView(frame: videoViewFrame)
previewVideoView.setVideoAspect(MobileRTCVideoAspect_PanAndScan)

previewVideoView.showAttendeeVideo(withUserID: localUserID) // Show
previewVideoView.stopAttendeeVideo() // Stop
```

```objectivec
NSUInteger localUserID = meetingService.myselfUserID;
MobileRTCPreviewVideoView *previewVideoView = [[MobileRTCPreviewVideoView alloc] initWithFrame:videoViewFrame];
[previewVideoView setVideoAspect:MobileRTCVideoAspect_PanAndScan];

[previewVideoView showAttendeeVideoWithUserID:activeUserID]; // Show
[previewVideoView stopAttendeeVideo]; // Stop
```

To subscribe to the shared content shared by another user, call `showActiveSharealong` with the `shareSourceID`.

To keep listening to the current sharing status and know when to subscribe to the shared view, use the `onSinkSharingStatus` callback from `MobileRTCMeetingServiceDelegate`. Alternatively, get the `shareSourceID` by calling the `getSharingSourceInfoList` from `MobileRTCMeetingService` using the sharer's userID and from the list and use `getShareSourceID`.

```swift
var shareSourceID: UInt!

// 1st way - Using the onSinkSharingStatus callback to get the latest share source ID
func onSinkSharingStatus(_ shareInfo: MobileRTCSSharingSourceInfo) {
    // Check shareInfo's status to see if it's other share begin, only then we subscribe later on.
    if shareInfo.getStatus() == .other_Share_Begin {
        shareSourceID = shareInfo.getShareSourceID()
    }
}

// OR 2nd way - if you know the sharer's userID you want to subscribe to
guard let sharingSourceInfoList = MobileRTC.shared().getMeetingService()?.getSharingSourceInfoList(12345) else { return }
// If multi share is enabled, one user can share multiple times. Hence this might be a list of more than 1 share info.
for shareInfo in sharingSourceInfoList {
    shareSourceID = shareInfo.getShareSourceID() // First identify the correct share info from the list and then get the Share Source ID.
}

// Once you have the desired Share Source ID, show or start active share.
let activeShareView = MobileRTCActiveShareView(frame: videoViewFrame)
activeShareView.showActiveShare(withShareSourceID: shareSourceID) // shareSourceID
activeShareView.stopActiveShare()
```

```objectivec
NSUInteger shareSourceID;

// 1st way - Using the onSinkSharingStatus callback to get the latest share source ID
- (void)onSinkSharingStatus:(MobileRTCSSharingSourceInfo *)shareInfo {
    // Check shareInfo's status to see if it's other share begin, only then we subscribe later on.
    if (shareInfo.getStatus == MobileRTCSharingStatus_Other_Share_Begin) {
        shareSourceID = shareInfo.getShareSourceID;
    }
}

// OR 2nd way - if you know the sharer's userID you want to subscribe to
guard let sharingSourceInfoList = MobileRTC.shared().getMeetingService()?.getSharingSourceInfoList(123456789) else { return }
// If multi share is enabled, one user can share multiple times. Hence this might be a list of more than 1 share info.
for (MobileRTCSSharingSourceInfo *shareInfo in sharingSourceInfoList) {
    shareSourceID = shareInfo.getShareSourceID; // First identify the correct share info from the list and then get the Share Source ID.
}

// Once you have the desired Share Source ID, show or start active share.
MobileRTCActiveShareView *activeShareView = [[MobileRTCActiveShareView alloc] initWithFrame:videoViewFrame];
[activeShareView showActiveShareWithShareSourceID:shareSourceID];
[activeShareView stopActiveShare];
```

---
