Use this guide to quickly start the interactive live video streaming with the Agora Video SDK for macOS.
The following figure shows the workflow to integrate into your app in order to add Interactive Live Streaming Standard functionality.
As shown in the figure, the workflow for adding Interactive Live Streaming Standard in your project is as follows:
Set the client role and latency level
Each user in an Interactive Live Streaming Standard channel is either a host or an audience member. Hosts publish streams to the channel, and the audience subscribe to the streams. When a user is an audience member, you can control the delay the user receives host streams using ClientRoleOptions
.
Retrieve a token
A token is the credential that authenticates a user when your app client joins a channel. In a test or production environment, your app client retrieves tokens from a server in your security infrastructure.
Join a channel
Call joinChannel
to create and join a channel. App clients that pass the same channel name join the same channel.
Publish and subscribe to audio and video in the channel
After joining a channel, app clients with the role of the host can publish audio and video. For an auidence memeber to send audio and video, call setClientRole
to switch the client role.
For an app client to join a channel, you need the following information:
Open Xcode, and click Create a new Xcode project.
Choose macOS as the target platform, App as the template, and click Next.
Input the project information, such as the product name, team, organization name, and language, and click Next.
Choose the storage path of the project, and click Create.
Choose one of the following methods to obtain the Agora macOS SDK:
Ensure that you have installed CocoaPods before the following steps. See the installation guide in Getting Started with CocoaPods.
In Terminal, navigate to the project path, and run the pod init
command to create a Podfile
in the project folder.
Open the Podfile
, delete all contents, and input the following codes. Remember to replace Your App
with the target name of your project.
# platform :macos, '10.11'
target 'Your App' do
pod 'AgoraRtcEngine_macOS'
end
Return to Terminal, and run the pod install
command to install the Agora SDK. Once you successfully install the SDK, it shows Pod installation complete!
in Terminal, and you can see an xcworkspace
file in the project folder.
Open the generated xcworkspace
file.
Navigate to SDK Downloads, download the latest version of the Agora macOS SDK, and extract the files from the downloaded SDK package.
According to your requirements, copy the libraries from the libs
folder of the SDK to the ./project_name
folder in your project (project_name
is an example of your project name).
Open Xcode, and navigate to TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content.
Click + > Add Other… > Add Files to add the corresponding libraries. Ensure that the Embed attribute of these dynamic libraries is Embed & Sign.
In Xcode, go to File > Swift Packages > Add Package Dependencies..., and paste the following URL:
<%= url %>
In Choose Package Options, specify the SDK version that you want to integrate. If the version number is x.y.z, fill in x.y.z; if the version number is x.y.z.a, fill in x.y.z-r.a.
Once you have integrated the Agora macOS SDK into your project, you need to call the core APIs provided by the Agora macOS SDK in the ViewController
file to implement basic interactive live video streaming. The API call sequence is shown in the following figure:
When creating the user interface for basic interactive live video streaming, Agora recommends adding the video view of the host on both the local and remote clients. Refer to the following code samples to create a basic UI from scratch.
// ViewController.h
// Import AppKit
#import <AppKit/AppKit.h>
@interface ViewController ()
// Defines localView
@property (nonatomic, strong) NSView *localView;
// Defines remoteView
@property (nonatomic, strong) NSView *remoteView;
@end
@implementation ViewController
...
- (void)viewDidLoad {
...
// This function initializes the local and remote video views
[self initViews];
}
// Sets the video view layout
- (void)viewDidLayout {
[super viewDidLayout];
self.remoteView.frame = self.view.bounds;
self.localView.frame = CGRectMake(self.view.bounds.size.width - 90, 0, 90, 160);
}
- (void)initViews {
// Initializes the remote video view
// This view displays video when a remote host joins the channel
self.remoteView = [[NSView alloc] init];
[self.view addSubview:self.remoteView];
// Initializes the local video view
// This view displays video when the local user is a host
self.localView = [[NSView alloc] init];
[self.view addSubview:self.localView];
}
...
@end
// ViewController.swift
// Import AppKit
import AppKit
class ViewController: NSViewController {
...
// Defines localView
var localView: NSView!
// Defines remoteView
var remoteView: NSView!
override func viewDidLoad() {
...
// This function initializes the local and remote video views
initView()
}
// Sets the video view layout
override func viewDidLayout() {
super.viewDidLayout()
remoteView.frame = self.view.bounds
localView.frame = CGRect(x: self.view.bounds.width - 90, y: 0, width: 90, height: 160)
}
func initView() {
// Initializes the remote video view
// This view displays video when a remote host joins the channel
remoteView = NSView()
self.view.addSubview(remoteView)
// Initializes the local video view
// This view displays video when the local user is a host
localView = NSView()
self.view.addSubview(localView)
}
...
}
Before calling any Agora API, import the AgoraRtcKit
class, and define agoraKit
.
// ViewController.h
// Imports the AgoraRtcKit class
// For SDKs earlier than 3.0.0, AgoraRtcKit is named AgoraRtcEngineKit
// If you use a SDK earlier than 3.0.0, use "#import <AgoraRtcEngineKit/AgoraRtcEngineKit.h>" instead
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
// Specifies AgoraRtcEngineDelegate for monitoring a callback
@interface ViewController : NSViewController <AgoraRtcEngineDelegate>
// Defines agoraKit
@property (strong, nonatomic) AgoraRtcEngineKit *agoraKit;
// ViewController.swift
// Imports the AgoraRtcKit class
// For SDKs earlier than 3.0.0, AgoraRtcKit is named AgoraRtcEngineKit
// If you use a SDK earlier than 3.0.0, use "import AgoraRtcEngineKit" instead
import AgoraRtcKit
class ViewController: NSViewController {
...
// Defines agoraKit
var agoraKit: AgoraRtcEngineKit?
}
Call the sharedEngineWithAppId
method to create and initialize the AgoraRtcEngineKit
object.
When adding the following code in your project, replace YourAppID
with the App ID of your project. See Get an App ID.
If you want to monitor a callback for your app scenario, register it when initializing AgoraRtcEngineKit
.
// ViewController.m
// Types the followiing code in the function you defines, such as viewDidLoad()
self.agoraKit = [AgoraRtcEngineKit sharedEngineWithAppId:@"YourAppID" delegate:self];
// ViewController.swift
// Types the followiing code in the function you defines, such as viewDidLoad()
agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: "YourAppID", delegate: self)
Call the setChannelProfile
method to set the channel profile as LiveBroadcasting
.
Each AgoraRtcEngineKit
object supports one profile only. If you want to switch to another profile, destroy the current AgoraRtcEngineKit
object with destroy
, and create a new one with sharedEngineWithAppId
; then, call setChannelProfile
again.
// ViewController.m
// Types the followiing code in the function you defines, such as viewDidLoad()
[self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
// ViewController.swift
// Types the followiing code in the function you defines, such as viewDidLoad()
agoraKit?.setChannelProfile(.liveBroadcasting)
In a live-streaming channel, you need to set the role and level of a user:
You may use the following steps to set the user role and level in your app:
Allow the end user to set the role as host or audience.
Call the setClientRole
method and set the role
and options
parameters according to the user's choice:
role
as AgoraClientRoleBroadcaster
, set options
as null
. The latency between two hosts is < 400 ms.role
as AgoraClientRoleAudience
, set the audienceLatencyLevel
parameter in options
as AgoraAudienceLatencyLevelLowLatency
. The latency from the host's client to the audience's client is 1500 ms - 2000 ms.AgoraAudienceLatencyLevelLowLatency
to AgoraAudienceLatencyLevelUltraLowLatency
, in essence, you switch from Interactive Live Streaming Standard to Interactive Live Streaming Premium and the latency from the host's client to the audience's client changes to 400 ms - 800 ms.AgoraClientRoleAudience
to AgoraClientRoleBroadcaster
, in essence, you switch from Interactive Live Streaming Standard to Interactive Live Streaming Premium and the latency between two hosts is < 400 ms.AgoraAudienceLatencyLevelLowLatency
, the jitterBufferDelay
property in RemoteAudioStats
does not take effect.// ViewController.m
// Types the followiing code in the function you defines, such as viewDidLoad()
// Sets the client role as the host
[self.agoraKit setClientRole:AgoraClientRoleBroadcaster];
// Sets the client role as the audience
AgoraClientRoleOptions *options = [AgoraClientRoleOptions alloc];
options.audienceLatencyLevel = AgoraAudienceLatencyLevelLowLatency;
[self.rtcEngineKit setClientRole:AgoraClientRoleAudience options:options];
// ViewController.swift
// Types the followiing code in the function you defines, such as viewDidLoad()
// Sets the client role as the host
agoraKit?.setClientRole(.broadcaster)
// Sets the client role as the audience
let options: AgoraClientRoleOptions = AgoraClientRoleOptions()
options.audienceLatencyLevel = AgoraAudienceLatencyLevelType.lowLatency
agoraKit.setClientRole(.audience, options: options)
Set the local video view before joining a channel so that hosts can see themselves during live video streaming. Refer to the following steps to set the local video view for a host:
enableVideo
method to enable the video module.setupLocalVideo
method to configure the local video display settings.// ViewController.m
// Types the followiing code in the function you defines, such as viewDidLoad()
// Enables the video module
[self.agoraKit enableVideo];
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = 0;
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
videoCanvas.view = self.localView;
// Sets the local video view
[self.agoraKit setupLocalVideo:videoCanvas];
// ViewController.swift
// Types the followiing code in the function you defines, such as viewDidLoad()
// Enables the video module
agoraKit?.enableVideo()
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = 0
videoCanvas.renderMode = .hidden
videoCanvas.view = localView
// Sets the local video view
agoraKit?.setupLocalVideo(videoCanvas)
Call the joinChannelByToken
method to join a channel. When adding the following code in your project, replace YourToken
with the token of your project, and replace YourChannelName
with the channel name used to generate the token of your project.
// ViewController.m
// Types the followiing code in the function you defines, such as viewDidLoad()
// The uid of each user in the channel must be unique.
[self.agoraKit joinChannelByToken:@"YourToken" channelId:@"YourChannelName" info:nil uid:0 joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
}];
// ViewController.swift
// Types the followiing code in the function you defines, such as viewDidLoad()
// The uid of each user in the channel must be unique.
agoraKit?.joinChannel(byToken: "YourToken", channelId: "YourChannelName", info: nil, uid: 0, joinSuccess: { (channel, uid, elapsed) in
})
In interactive live video streaming, you should be able to see all hosts.
To set the video view of a remote host, monitor the didJoinedOfUid
callback, which returns the remote host's ID shortly after the remote host joins the channel; then, call the setupRemoteVideo
method in the callback, and pass in the retrieved uid
.
// ViewController.m
// Monitors the didJoinedOfUid callback
// The SDK triggers the callback when a remote host joins the channel
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed {
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = uid;
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
videoCanvas.view = self.remoteView;
// Sets the remote video view
[self.agoraKit setupRemoteVideo:videoCanvas];
}
// ViewController.swift
// Specifies AgoraRtcEngineDelegate for monitoring a callback
extension ViewController: AgoraRtcEngineDelegate {
// Monitors the didJoinedOfUid callback
// The SDK triggers the callback when a remote host joins the channel
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.renderMode = .hidden
videoCanvas.view = remoteView
// Sets the remote video view
agoraKit?.setupRemoteVideo(videoCanvas)
}
}
Call the leaveChannel
method when you need to leave the channel, for example, to end interactive live video streaming, close the app, or run the app in the background.
// ViewController.m
// Types the followiing code in the function you defines
[self.agoraKit leaveChannel:nil];
// ViewController.swift
// Types the followiing code in the function you defines
agoraKit?.leaveChannel(nil)
After leaving the channel, if you want to release all resources used by the Agora SDK, call the destroy
method to destroy the AgoraRtcEngineKit
object.
// ViewController.m
// Types the followiing code in the function you defines
[AgoraRtcEngineKit destroy];
// ViewController.swift
// Types the followiing code in the function you defines
AgoraRtcEngineKit.destroy()
Before running the project, you need to set your signing and team, and add device permissions.
info.plist
file. Add the following contents to add permissions for your device:Key | Type | Value |
---|---|---|
Privacy - Microphone Usage Description | String | The purpose for accessing the microphone, such as for a call or interactive live streaming. |
Privacy - Camera Usage Description | String | The purpose for accessing the camera, such as for a call or interactive live streaming. |
Capability | Category | Permission |
---|---|---|
App Sandbox | Network |
|
App Sandbox | Hardware |
|
Hardened Runtime | Resource Access |
|
Agora recommends running the project on a real device instead of a simulator. If your app is installed and running successfully, hosts should see the video view of themselves.
To test the remote video view of the host, visit the Web Demo, and enter the same App ID, channel name, and token to join the same channel. If interactive live video streaming runs successfully, a host should see both the local video view and video views of other hosts; an audience member should see video views of hosts.
Choose one of the following methods to integrate a version of the Agora macOS SDK earlier than v3.2.0.
Ensure that you have installed CocoaPods before performing the following steps. See the installation guide in Getting Started with CocoaPods.
In Terminal, navigate to the project path, and run the pod init
command to create a Podfile
in the project folder.
Podfile
, delete all contents, and input the following codes. Remember to replace Your App
with the target name of your project and replace version
with the version of the SDK that you want to integrate. For information about the SDK version, see Release Notes.# platform :macos, '10.11'
target 'Your App' do
pod 'AgoraRtcEngine_macOS', 'version'
end
Return to Terminal, and run the pod install
command to install the Agora SDK. Once you successfully install the SDK, it shows Pod installation complete!
in Terminal, and you can see an xcworkspace
file in the project folder.
Open the generated xcworkspace
file.
You need to use different integration methods to integrate different versions of the SDK. Click the following version categories to expand the corresponding integration steps.
AgoraRtcKit.framework
, Agorafdkaac.framework
, Agoraffmpeg.framework
, and AgoraSoundTouch.framework
dynamic libraries to the ./project_name
folder in your project (project_name
is an example of your project name).Click + > Add Other… > Add Files to add the AgoraRtcKit.framework
, Agorafdkaac.framework
, Agoraffmpeg.framework
, and AgoraSoundTouch.framework
dynamic libraries. Ensure that the Embed attribute of these dynamic libraries is Embed & Sign.
Once these dynamic libraries are added, the project automatically links to other system libraries.
Copy the AgoraRtcKit.framework
dynamic library to the ./project_name
folder in your project (project_name
is an example of your project name).
Open Xcode, and navigate to TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content.
Click + > Add Other… > Add Files to add the AgoraRtcKit.framework
dynamic library. Ensure that the Embed attribute of the dynamic library is Embed & Sign. Once the dynamic library is added, the project automatically links to other system libraries.
In v3.0.0, the SDK package contains an AgoraRtcKit.framework
dynamic library and an AgoraRtcKit.framework
static library. Choose which of these libraries to add according to your needs.
The paths of the two libraries in the SDK package are as follows:
./Agora_Native_SDK_for_macOS_..._Dynamic/libs
../Agora_Native_SDK_for_macOS_.../libs
.Integrate the dynamic library:
Copy the AgoraRtcKit.framework
dynamic library from the ./libs
path of the SDK package to the ./project_name
folder in your project (project_name
is an example of your project name).
Open Xcode, and navigate to TARGETS > Project Name > General > Frameworks, Libraries, and Embedded Content.
Click + > Add Other… > Add Files to add the AgoraRtcKit.framework
dynamic library. Ensure that the Embed attribute of the dynamic library is Embed & Sign.
Once the dynamic library is added, the project automatically links to other system libraries.
Integrate the static library:
AgoraRtcKit.framework
static library from the ./libs
path of the SDK package to the ./project_name
folder in your project (project_name
is an example of your project name).AgoraRtcKit.framework
static library, you need to click +, and then click Add Other....SDK | Library |
---|---|
Voice SDK | AgoraRtcKit.framework Accelerate.framework CoreWLAN.framework libc++.tbd libresolv.9.tbd SystemConfiguration.framework |
Video SDK | AgoraRtcKit.framework Accelerate.framework CoreWLAN.framework libc++.tbd libresolv.9.tbd SystemConfiguration.framework VideoToolbox.framework |
AgoraRtcEngineKit.framework
static library from the ./libs
path of the SDK package to the ./project_name
folder in your project (project_name
is an example of your project name).AgoraRtcEngineKit.framework
static library, you need to click +, and then click Add Other....SDK | Library |
---|---|
Voice SDK | AgoraRtcEngineKit.framework Accelerate.framework CoreWLAN.framework libc++.tbd libresolv.9.tbd SystemConfiguration.framework |
Video SDK | AgoraRtcEngineKit.framework Accelerate.framework CoreWLAN.framework libc++.tbd libresolv.9.tbd SystemConfiguration.framework VideoToolbox.framework |