Use this guide to quickly start the interactive live video streaming with the Agora Video SDK for macOS.
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' use_frameworks!
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.
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.
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)
An interactive live streaming channel has two client roles: Broadcaster
and Audience
; the default role is Audience
. After setting the channel profile to LiveBroadcasting
, set the client role using the following steps:
setClientRole
method, and pass in the client role set by the user.Note that in interactive live streaming, only the host can be seen and heard. If you want to switch the client role after joining the channel, call the setClientRole
method again.
// 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];
// ViewController.swift
// Types the followiing code in the function you defines, such as viewDidLoad()
// Sets the client role as the host
agoraKit?.setClientRole(.broadcaster)
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()
[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()
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 firstRemoteVideoDecodedOfUid
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 firstRemoteVideoDecodedOfUid callback
// The SDK triggers the callback when it has received and decoded the first video frame from a remote host
- (void)rtcEngine:(AgoraRtcEngineKit *)engine firstRemoteVideoDecodedOfUid:(NSUInteger)uid size: (CGSize)size 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 firstRemoteVideoDecodedOfUid callback
// The SDK triggers the callback when it has received and decoded the first video frame from a remote host
func rtcEngine(_ engine: AgoraRtcEngineKit, firstRemoteVideoDecodedOfUid uid: UInt, size: CGSize, 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' use_frameworks!
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.
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 |