diff --git a/shared/video-sdk/authentication-workflow/project-implementation/unreal.mdx b/shared/video-sdk/authentication-workflow/project-implementation/unreal.mdx index 464423537..67e2e2100 100644 --- a/shared/video-sdk/authentication-workflow/project-implementation/unreal.mdx +++ b/shared/video-sdk/authentication-workflow/project-implementation/unreal.mdx @@ -4,7 +4,7 @@ The client requests a token from your authentication server corresponding to the user ID and the channel name. You use the received token to join a channel. -```java +```cpp // Channel name const char* channelId; // User ID @@ -39,7 +39,7 @@ If you call `joinChannelEx` to join multiple channels, call the `updateChannelMe The following sample code shows calling `renewToken` to update the token when receiving an `onTokenPrivilegeWillExpire` callback notification. -```java +```cpp class CJoinChannelVideoByTokenRtcEngineEventHandler : public IRtcEngineEventHandler { diff --git a/shared/video-sdk/authentication-workflow/project-implementation/windows.mdx b/shared/video-sdk/authentication-workflow/project-implementation/windows.mdx index e9cf93555..de5a71e92 100644 --- a/shared/video-sdk/authentication-workflow/project-implementation/windows.mdx +++ b/shared/video-sdk/authentication-workflow/project-implementation/windows.mdx @@ -39,7 +39,7 @@ If you call `joinChannelEx` to join multiple channels, call the `updateChannelMe The following sample code shows calling `renewToken` to update the token when receiving an `onTokenPrivilegeWillExpire` callback notification. -```java +```cpp class CJoinChannelVideoByTokenRtcEngineEventHandler : public IRtcEngineEventHandler { diff --git a/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx b/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx index 1d2b8d004..466bbf2dc 100644 --- a/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/project-implementation/android.mdx @@ -18,8 +18,7 @@ To use the sample code, copy the following lines into the `/app/src/main/java/co -{` -import android.Manifest; +{`import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.SurfaceView; @@ -687,7 +686,7 @@ public class MainActivity extends AppCompatActivity { -In the `appId` and `token` fields, enter the corresponding values you obtained from . Use the same `channelName` you filled in when generating the temporary token. +For the `appId` and `token` variables, replace the placeholders with the values you obtained from . Ensure you enter the same `channelName` you used when generating the temporary token. Follow the implementation steps to understand the core API calls in the sample code. diff --git a/shared/video-sdk/get-started/get-started-sdk/project-implementation/swift.mdx b/shared/video-sdk/get-started/get-started-sdk/project-implementation/swift.mdx index c221aa23c..1a6579876 100644 --- a/shared/video-sdk/get-started/get-started-sdk/project-implementation/swift.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/project-implementation/swift.mdx @@ -24,8 +24,7 @@ A complete code sample that implements the basic process of real-time -{`// ViewController.swift - +{`// ViewController.swift import UIKit import AgoraRtcKit @@ -34,10 +33,10 @@ class ViewController: UIViewController { var localView: UIView! // Define the remoteView variable var remoteView: UIView! - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - // Set up the video window layout + // Set up the video layout override func viewDidLoad() { super.viewDidLoad() @@ -49,7 +48,7 @@ class ViewController: UIViewController { self.view.addSubview(localView) self.view.addSubview(remoteView) - // Initialize agoraKit with your App ID and delegate to self + // Initialize the AgoraRtcEngineKit instance with your App ID and and set the delegate to self agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: "<#Your App ID#>", delegate: self) // Enable the video module (audio module is enabled by default) agoraKit.enableVideo() @@ -99,12 +98,12 @@ class ViewController: UIViewController { // Extension for implementing AgoraRtcEngineDelegate methods extension ViewController: AgoraRtcEngineDelegate { - // Called when the local user successfully joins the channel + // Callback when the local user successfully joins a channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { print("didJoinChannel: \(channel), uid: \(uid)") } - // Called when a remote user joins the channel + // Callback when a remote user joins the current channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { // When a remote user joins the channel, display the remote video stream with the specified uid let videoCanvas = AgoraRtcVideoCanvas() @@ -113,14 +112,21 @@ extension ViewController: AgoraRtcEngineDelegate { videoCanvas.renderMode = .hidden agoraKit.setupRemoteVideo(videoCanvas) } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } }`} -{`// ViewController.swift - +{`// ViewController.swift import UIKit import AgoraRtcKit @@ -129,10 +135,10 @@ class ViewController: UIViewController { var localView: UIView! // Define the remoteView variable var remoteView: UIView! - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - // Set up the video window layout + // Set up the video layout override func viewDidLoad() { super.viewDidLoad() @@ -144,7 +150,7 @@ class ViewController: UIViewController { self.view.addSubview(localView) self.view.addSubview(remoteView) - // Initialize agoraKit with your App ID and delegate to self + // Initialize the AgoraRtcEngineKit instance with your App ID and and set the delegate to self agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: "<#Your App ID#>", delegate: self) // Enable the video module (audio module is enabled by default) agoraKit.enableVideo() @@ -198,12 +204,12 @@ class ViewController: UIViewController { // Extension for implementing AgoraRtcEngineDelegate methods extension ViewController: AgoraRtcEngineDelegate { - // Called when the local user successfully joins the channel + // Callback when the local user successfully joins a channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { print("didJoinChannel: \(channel), uid: \(uid)") } - // Called when a remote user joins the channel + // Callback when a remote user joins the current channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { // When a remote user joins the channel, display the remote video stream with the specified uid let videoCanvas = AgoraRtcVideoCanvas() @@ -212,14 +218,21 @@ extension ViewController: AgoraRtcEngineDelegate { videoCanvas.renderMode = .hidden agoraKit.setupRemoteVideo(videoCanvas) } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } }`} -{`// ViewController.swift - +{`// ViewController.swift import UIKit import AgoraRtcKit @@ -228,7 +241,7 @@ class ViewController: UIViewController { var localView: UIView! // Define the remoteView variable var remoteView: UIView! - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! // Set up the video window layout @@ -243,7 +256,7 @@ class ViewController: UIViewController { self.view.addSubview(localView) self.view.addSubview(remoteView) - // Initialize agoraKit with your App ID and delegate to self + // Initialize the AgoraRtcEngineKit instance with your App ID and and set the delegate to self agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: "<#Your App ID#>", delegate: self) // Enable the video module (audio module is enabled by default) agoraKit.enableVideo() @@ -254,7 +267,7 @@ class ViewController: UIViewController { joinChannel() } - // Clean up resources when deallocating + // Clean up resources when de-allocating deinit { agoraKit.stopPreview() agoraKit.leaveChannel(nil) @@ -297,12 +310,12 @@ class ViewController: UIViewController { // Extension for implementing AgoraRtcEngineDelegate methods extension ViewController: AgoraRtcEngineDelegate { - // Called when the local user successfully joins the channel + // Callback when the local user successfully joins a channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { print("didJoinChannel: \(channel), uid: \(uid)") } - // Called when a remote user joins the channel + // Callback when a remote user joins the current channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { // When a remote user joins the channel, display the remote video stream with the specified uid let videoCanvas = AgoraRtcVideoCanvas() @@ -311,52 +324,73 @@ extension ViewController: AgoraRtcEngineDelegate { videoCanvas.renderMode = .hidden agoraKit.setupRemoteVideo(videoCanvas) } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } }`} -{`import UIKit +{`// ViewController.swift +import UIKit import AgoraRtcKit -class ViewController: UIViewController{ - // Define agoraKit +class ViewController: UIViewController { + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - func initializeAgoraEngine(){ - let config = AgoraRtcEngineConfig() - // Enter your App ID here - config.appId = "<#Your App ID#>" - // Call AgoraRtcEngineDelegate - agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) - } - - func joinChannel(){ - let option = AgoraRtcChannelMediaOptions() - // Set channel profile to liveBroadcasting - option.channelProfile = .liveBroadcasting - // Set the user role as broadcaster - option.clientRoleType = .broadcaster - // Join the channel with a temporary Token, provide your project's Token and channel name here - agoraKit?.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name#>", uid: 0, mediaOptions: option) - } override func viewDidLoad() { super.viewDidLoad() - // After the view is loaded, you can perform additional settings - // When calling Agora API, the following functions will be called - initializeAgoraEngine() + // Initialize the AgoraRtcEngineKit instance with your App ID and and set the delegate to self + agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId:<#Your App ID#>, delegate: self) joinChannel() } - func leaveChannel() { - agoraKit?.leaveChannel(nil) - } + deinit { + agoraKit.leaveChannel(nil) + AgoraRtcEngineKit.destroy() + } + func joinChannel() { + let options = AgoraRtcChannelMediaOptions() + options.channelProfile = .communication + // Set user role to broadcaster; to set user role to audience, keep the default value + options.clientRoleType = .broadcaster + // Publish microphone audio + options.publishMicrophoneTrack = true + // Automatically subscribe to all audio streams + options.autoSubscribeAudio = true + // Join the channel using a temporary token and channel name + // If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback + agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) + } } -extension ViewController: AgoraRtcEngineDelegate{ +extension ViewController: AgoraRtcEngineDelegate { + // Callback when the local user successfully joins a channel + func rtcEngine( + _ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int + ) { + print("didJoinChannel: \(channel), uid: \(uid)") + } + + // Callback when a remote user joins the current channel func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ - } + // Print debug information + print("User (uid) joined after (elapsed) milliseconds") + } + + // Callback when a remote user leaves the current channel + func rtcEngine( + _ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason + ) { + } }`} @@ -369,265 +403,299 @@ extension ViewController: AgoraRtcEngineDelegate{ -{`// ViewController.swift -import Cocoa +{`// ViewController.swift import AgoraRtcKit +import Cocoa class ViewController: NSViewController { - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - func initializeAgoraEngine(){ - let config = AgoraRtcEngineConfig() - // Enter your App ID here - config.appId = <#Your App ID#> - // Call AgoraRtcEngineDelegate - agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) + func initView() { + // Initialize the AgoraRtcEngineKit instance with your App ID and and set the delegate to self + agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: <#Your App ID#>, delegate: self) } - - func joinChannel(){ - let option = AgoraRtcChannelMediaOptions() - // Set the channel scene to liveBroadcasting - option.channelProfile = .liveBroadcasting - // Set the user role to broadcaster - option.clientRoleType = .broadcaster - // Join the channel with a temporary Token, enter your project's Token and channel name here - agoraKit?.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: option) + + deinit { + agoraKit.leaveChannel(nil) + AgoraRtcEngineKit.destroy() + } + + + func joinChannel() { + let options = AgoraRtcChannelMediaOptions() + + options.channelProfile = .liveBroadcasting + // Set user role to broadcaster; to set user role to audience, keep the default value + options.clientRoleType = .broadcaster + // Publish microphone audio + options.publishMicrophoneTrack = true + // Automatically subscribe to all audio streams + options.autoSubscribeAudio = true + // Join the channel using a temporary token and channel name + // If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback + agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) } override func viewDidLoad() { super.viewDidLoad() - // After the view is loaded, you can perform other settings - initializeAgoraEngine() + initView() joinChannel() } - func leaveChannel() { - agoraKit?.leaveChannel(nil) - } } extension ViewController: AgoraRtcEngineDelegate{ - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ - } + // Callback when a remote user joins the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ + // Print debug information + print("User \(uid) joined after \(elapsed) milliseconds") + } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + + // Print debug information + print("User \(uid) went offline due to \(reason)") + } }`} -{`// ViewController.swift -import Cocoa +{`// ViewController.swift import AgoraRtcKit +import Cocoa class ViewController: NSViewController { - // Define localView variable - var localView: CustomView! - // Define remoteView variable - var remoteView: CustomView! - // Define agoraKit + // Local video view + var localView: NSView! + // Remote video view + var remoteView: NSView! + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - // Set the video window layout - class CustomView: NSView { - override func layout() { - super.layout() - // Get the view controller - guard let viewController = self.window?.contentViewController as? ViewController else { - return - } - - // Calculate the position and size of the local view - let localViewWidth: CGFloat = 135 - let localViewHeight: CGFloat = 240 - let localViewX: CGFloat = self.bounds.width - localViewWidth - -2 - let localViewY: CGFloat = 2 - - // Set the frame of the local view - viewController.localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) - - // Set the frame of the remote view so that it fills the entire CustomView - viewController.remoteView.frame = self.bounds - } - } - - func initView(){ - // Initialize the remote video window - remoteView = CustomView() + override func viewDidLayout() { + super.viewDidLayout() + + // Set the position and size of the local view + let localViewWidth: CGFloat = 135 + let localViewHeight: CGFloat = 240 + let localViewX: CGFloat = 2 + let localViewY: CGFloat = 2 + + // Set the local view frame + localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) + + // Set the remote view frame to fill the entire CustomView + remoteView.frame = view.bounds + } + + func initView() { + // Initialize the remote video view + remoteView = NSView() self.view.addSubview(remoteView) - // Initialize the local video window - localView = CustomView() + // Initialize the local video view + localView = NSView() self.view.addSubview(localView) + + // Initialize the AgoraRtcEngineKit instance + agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: <#Your App ID#>, delegate: self) } - - func initializeAgoraEngine(){ - let config = AgoraRtcEngineConfig() - // Enter your app ID here - config.appId = <#Your app ID#> - // Call AgoraRtcEngineDelegate - agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) + + deinit { + agoraKit.stopPreview() + agoraKit.leaveChannel(nil) + AgoraRtcEngineKit.destroy() } - - func setupLocalVideo(){ - // Enable video module - agoraKit?.enableVideo() - // Start local preview - agoraKit?.startPreview() + + func startPreview() { let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = 0 - videoCanvas.renderMode = .hidden videoCanvas.view = localView - // Set local view - agoraKit?.setupLocalVideo(videoCanvas) + videoCanvas.renderMode = .hidden + agoraKit.setupLocalVideo(videoCanvas) + agoraKit.startPreview() } - - func joinChannel(){ - let option = AgoraRtcChannelMediaOptions() - // In a live streaming scenario, set the channel scenario to liveBroadcasting + + func joinChannel() { + let options = AgoraRtcChannelMediaOptions() + // In a live streaming scenario, set the channel profile to liveBroadcasting option.channelProfile = .liveBroadcasting - // Set the user role as host - option.clientRoleType = .broadcaster + // Set the user role to broadcaster; if you want to set the user role to audience, keep the default value + options.clientRoleType = .broadcaster // Set the audience latency level option.audienceLatencyLevel = .ultraLowLatency - // Use a temporary token to join the channel, and pass in your project's token and channel name here. - agoraKit?.joinChannel(byToken: <#Your token#>, channelId: <#Your channel name#>, uid: 0, mediaOptions: option) + // Publish the microphone audio + options.publishMicrophoneTrack = true + // Publish the camera video + options.publishCameraTrack = true + // Automatically subscribe to all audio streams + options.autoSubscribeAudio = true + // Automatically subscribe to all video streams + options.autoSubscribeVideo = true + // Use a temporary token to join the channel, pass in your project's token and channel name + // If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback + agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) } - + override func viewDidLoad() { super.viewDidLoad() - // After loading the view, you can make other settings - // Initialize the video window initView() - initializeAgoraEngine() - setupLocalVideo() + agoraKit.enableVideo() + startPreview() joinChannel() } - - func leaveChannel() { - agoraKit?.stopPreview() - agoraKit?.leaveChannel(nil) - } } -extension ViewController: AgoraRtcEngineDelegate{ - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = uid - videoCanvas.renderMode = .hidden - videoCanvas.view = remoteView - agoraKit?.setupRemoteVideo(videoCanvas) - } +extension ViewController: AgoraRtcEngineDelegate { + + // Callback when the local user successfully joins a channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { + print("didJoinChannel: \(channel), uid: \(uid)") + } + + // Callback when a remote user joins the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { + // Print debug information + print("User \(uid) joined after \(elapsed) milliseconds") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = remoteView + videoCanvas.renderMode = .hidden + agoraKit.setupRemoteVideo(videoCanvas) + } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + // Print debug information + print("User \(uid) went offline due to \(reason)") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } }`} -{`// ViewController.swift -import Cocoa +{`// ViewController.swift import AgoraRtcKit +import Cocoa class ViewController: NSViewController { - // Define localView variable - var localView: CustomView! - // Define remoteView variable - var remoteView: CustomView! - // Define agoraKit + // Local video view + var localView: NSView! + // Remote video view + var remoteView: NSView! + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - // Set the video window layout - class CustomView: NSView { - override func layout() { - super.layout() - // Get the view controller - guard let viewController = self.window?.contentViewController as? ViewController else { - return - } - - // Calculate the position and size of the local view - let localViewWidth: CGFloat = 135 - let localViewHeight: CGFloat = 240 - let localViewX: CGFloat = self.bounds.width - localViewWidth - -2 - let localViewY: CGFloat = 2 - - // Set the frame of the local view - viewController.localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) - - // Set the frame of the remote view so that it fills the entire CustomView - viewController.remoteView.frame = self.bounds - } - } - - func initView(){ - // Initialize the remote video window - remoteView = CustomView() + override func viewDidLayout() { + super.viewDidLayout() + + // Set the position and size of the local view + let localViewWidth: CGFloat = 135 + let localViewHeight: CGFloat = 240 + let localViewX: CGFloat = 2 + let localViewY: CGFloat = 2 + + // Set the local view frame + localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) + + // Set the remote view frame to fill the entire CustomView + remoteView.frame = view.bounds + } + + func initView() { + // Initialize the remote video view + remoteView = NSView() self.view.addSubview(remoteView) - // Initialize the local video window - localView = CustomView() + // Initialize the local video view + localView = NSView() self.view.addSubview(localView) + + // Initialize the AgoraRtcEngineKit instance + agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: <#Your App ID#>, delegate: self) } - - func initializeAgoraEngine(){ - let config = AgoraRtcEngineConfig() - // Enter your app ID here - config.appId = <#Your app ID#> - // Call AgoraRtcEngineDelegate - agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) + + deinit { + agoraKit.stopPreview() + agoraKit.leaveChannel(nil) + AgoraRtcEngineKit.destroy() } - - func setupLocalVideo(){ - // Enable video module - agoraKit?.enableVideo() - // Start local preview - agoraKit?.startPreview() + + func startPreview() { let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = 0 - videoCanvas.renderMode = .hidden videoCanvas.view = localView - // Set local view - agoraKit?.setupLocalVideo(videoCanvas) + videoCanvas.renderMode = .hidden + agoraKit.setupLocalVideo(videoCanvas) + agoraKit.startPreview() } - - func joinChannel(){ - let option = AgoraRtcChannelMediaOptions() - // In a live streaming scenario, set the channel scenario to liveBroadcasting + + func joinChannel() { + let options = AgoraRtcChannelMediaOptions() + // In a live streaming scenario, set the channel profile to liveBroadcasting option.channelProfile = .liveBroadcasting - // Set the user role as host - option.clientRoleType = .broadcaster + // Set the user role to broadcaster; if you want to set the user role to audience, keep the default value + options.clientRoleType = .broadcaster // Set the audience latency level option.audienceLatencyLevel = .lowLatency - // Use a temporary token to join the channel, and pass in your project's token and channel name here. - agoraKit?.joinChannel(byToken: <#Your token#>, channelId: <#Your channel name#>, uid: 0, mediaOptions: option) + // Publish the microphone audio + options.publishMicrophoneTrack = true + // Publish the camera video + options.publishCameraTrack = true + // Automatically subscribe to all audio streams + options.autoSubscribeAudio = true + // Automatically subscribe to all video streams + options.autoSubscribeVideo = true + // Use a temporary token to join the channel, pass in your project's token and channel name + // If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback + agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) } - + override func viewDidLoad() { super.viewDidLoad() - // After loading the view, you can make other settings - // Initialize the video window initView() - initializeAgoraEngine() - setupLocalVideo() + agoraKit.enableVideo() + startPreview() joinChannel() } - - func leaveChannel() { - agoraKit?.stopPreview() - agoraKit?.leaveChannel(nil) - } } -extension ViewController: AgoraRtcEngineDelegate{ - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = uid - videoCanvas.renderMode = .hidden - videoCanvas.view = remoteView - agoraKit?.setupRemoteVideo(videoCanvas) - } +extension ViewController: AgoraRtcEngineDelegate { + + // Callback when the local user successfully joins a channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { + print("didJoinChannel: \(channel), uid: \(uid)") + } + + // Callback when a remote user joins the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { + // Print debug information + print("User \(uid) joined after \(elapsed) milliseconds") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = remoteView + videoCanvas.renderMode = .hidden + agoraKit.setupRemoteVideo(videoCanvas) + } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + // Print debug information + print("User \(uid) went offline due to \(reason)") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } }`} @@ -635,107 +703,118 @@ extension ViewController: AgoraRtcEngineDelegate{ -{`// ViewController.swift -import Cocoa +{`// ViewController.swift import AgoraRtcKit +import Cocoa class ViewController: NSViewController { - // Define localView variable - var localView: CustomView! - // Define remoteView variable - var remoteView: CustomView! - // Define agoraKit + // Local video view + var localView: NSView! + // Remote video view + var remoteView: NSView! + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - // Set the video window layout - class CustomView: NSView { - override func layout() { - super.layout() - // Get the view controller - guard let viewController = self.window?.contentViewController as? ViewController else { - return - } - - // Calculate the position and size of the local view - let localViewWidth: CGFloat = 135 - let localViewHeight: CGFloat = 240 - let localViewX: CGFloat = self.bounds.width - localViewWidth - -2 - let localViewY: CGFloat = 2 - - // Set the frame of the local view - viewController.localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) - - // Set the frame of the remote view so that it fills the entire CustomView - viewController.remoteView.frame = self.bounds - } - } - - func initView(){ - // Initialize the remote video window - remoteView = CustomView() + override func viewDidLayout() { + super.viewDidLayout() + + // Set the position and size of the local view + let localViewWidth: CGFloat = 135 + let localViewHeight: CGFloat = 240 + let localViewX: CGFloat = 2 + let localViewY: CGFloat = 2 + + // Set the local view frame + localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) + + // Set the remote view frame to fill the entire CustomView + remoteView.frame = view.bounds + } + + func initView() { + // Initialize the remote video view + remoteView = NSView() self.view.addSubview(remoteView) - // Initialize the local video window - localView = CustomView() + // Initialize the local video view + localView = NSView() self.view.addSubview(localView) + + // Initialize the AgoraRtcEngineKit instance + agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: <#Your App ID#>, delegate: self) } - - func initializeAgoraEngine(){ - let config = AgoraRtcEngineConfig() - // Enter your app ID here - config.appId = <#Your app ID#> - // Call AgoraRtcEngineDelegate - agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) + + deinit { + agoraKit.stopPreview() + agoraKit.leaveChannel(nil) + AgoraRtcEngineKit.destroy() } - - func setupLocalVideo(){ - // Enable video module - agoraKit?.enableVideo() - // Start local preview - agoraKit?.startPreview() + + func startPreview() { let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = 0 - videoCanvas.renderMode = .hidden videoCanvas.view = localView - // Set local view - agoraKit?.setupLocalVideo(videoCanvas) + videoCanvas.renderMode = .hidden + agoraKit.setupLocalVideo(videoCanvas) + agoraKit.startPreview() } - - func joinChannel(){ - let option = AgoraRtcChannelMediaOptions() - // In the video call scenario, set the channel scenario to communication - option.channelProfile = .communication - // Set the user role as host - option.clientRoleType = .broadcaster - // Use a temporary token to join the channel, and pass in your project's token and channel name here. - agoraKit?.joinChannel(byToken: <#Your token#>, channelId: <#Your channel name#>, uid: 0, mediaOptions: option) + + func joinChannel() { + let options = AgoraRtcChannelMediaOptions() + // Set the channel profile + options.channelProfile = .communication + // Set the user role to broadcaster; if you want to set the user role to audience, keep the default value + options.clientRoleType = .broadcaster + // Publish the microphone audio + options.publishMicrophoneTrack = true + // Publish the camera video + options.publishCameraTrack = true + // Automatically subscribe to all audio streams + options.autoSubscribeAudio = true + // Automatically subscribe to all video streams + options.autoSubscribeVideo = true + // Use a temporary token to join the channel, pass in your project's token and channel name + // If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback + agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) } - + override func viewDidLoad() { super.viewDidLoad() - // After loading the view, you can make other settings - // Initialize the video window initView() - initializeAgoraEngine() - setupLocalVideo() + agoraKit.enableVideo() + startPreview() joinChannel() } - - func leaveChannel() { - agoraKit?.stopPreview() - agoraKit?.leaveChannel(nil) - } } -extension ViewController: AgoraRtcEngineDelegate{ - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = uid - videoCanvas.renderMode = .hidden - videoCanvas.view = remoteView - agoraKit?.setupRemoteVideo(videoCanvas) - } -}`} +extension ViewController: AgoraRtcEngineDelegate { + + // Callback when the local user successfully joins a channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { + print("didJoinChannel: \(channel), uid: \(uid)") + } + + // Callback when a remote user joins the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { + // Print debug information + print("User \(uid) joined after \(elapsed) milliseconds") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = remoteView + videoCanvas.renderMode = .hidden + agoraKit.setupRemoteVideo(videoCanvas) + } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + // Print debug information + print("User \(uid) went offline due to \(reason)") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } +} +`} @@ -756,6 +835,10 @@ import AgoraRtcKit To initialize the SDK, call `sharedEngineWithConfig` to create and initialize an instance of `AgoraRtcEngineKit`: + +Before initializing the SDK, ensure that the user has fully understood and agreed to the relevant privacy policy. + + ```swift // Enter the App ID you obtained from the Agora Console here @@ -764,17 +847,11 @@ agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId:<#Your App ID#>, delegate: s ```swift -// Enter your App ID here -config.appId = "<#Your App ID#>" -// Call AgoraRtcEngineDelegate -agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self) +// Initialize the AgoraRtcEngineKit instance with your App ID and and set the delegate to self +agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId:<#Your App ID#>, delegate: self) ``` - -Before initializing the SDK, ensure that the user has fully understood and agreed to the relevant privacy policy. - - ### Enable the video module @@ -792,6 +869,7 @@ agoraKit.enableVideo() let videoCanvas = AgoraRtcVideoCanvas() videoCanvas.view = localView videoCanvas.renderMode = .hidden +videoCanvas.view = localView // Set up the local video view agoraKit.setupLocalVideo(videoCanvas) // Start local video preview @@ -806,23 +884,24 @@ To join a channel, and set the user role, call `joinChannelByToken [2/4]`. Fill ```swift let options = AgoraRtcChannelMediaOptions() -// In a live streaming scenario, set the channel scenario to liveBroadcasting +// In a live streaming scenario, set the channel profile to liveBroadcasting option.channelProfile = .liveBroadcasting -// Set the user role as broadcaster; keep default value for audience role +// Set the user role to broadcaster; if you want to set the user role to audience, keep the default value options.clientRoleType = .broadcaster -// Publish audio captured by microphone +// Set the audience latency level +option.audienceLatencyLevel = .lowLatency +// Publish the microphone audio options.publishMicrophoneTrack = true -// Publish video captured by camera +// Publish the camera video options.publishCameraTrack = true -// Auto subscribe to all audio streams +// Automatically subscribe to all audio streams options.autoSubscribeAudio = true -// Auto subscribe to all video streams +// Automatically subscribe to all video streams options.autoSubscribeVideo = true -// Set the audience latency level -option.audienceLatencyLevel = .lowLatency -// Join the channel with a temporary Token, provide your project's Token and channel name here -// If you set uid=0, the engine generates a uid internally; on success, it triggers didJoinChannel callback -agoraKit.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name#>", uid: 0, mediaOptions: options) +// Use a temporary token to join the channel, pass in your project's token and channel name +// If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback +agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) + ``` @@ -830,23 +909,23 @@ agoraKit.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name# ```swift let options = AgoraRtcChannelMediaOptions() -// In a live streaming scenario, set the channel scenario to liveBroadcasting +// In a live streaming scenario, set the channel profile to liveBroadcasting option.channelProfile = .liveBroadcasting -// Set the user role as broadcaster; keep default value for audience role +// Set the user role to broadcaster; if you want to set the user role to audience, keep the default value options.clientRoleType = .broadcaster -// Publish audio captured by microphone +// Set the audience latency level +option.audienceLatencyLevel = .ultraLowLatency +// Publish the microphone audio options.publishMicrophoneTrack = true -// Publish video captured by camera +// Publish the camera video options.publishCameraTrack = true -// Auto subscribe to all audio streams +// Automatically subscribe to all audio streams options.autoSubscribeAudio = true -// Auto subscribe to all video streams +// Automatically subscribe to all video streams options.autoSubscribeVideo = true -// Set the audience latency level -option.audienceLatencyLevel = .ultraLowLatency -// Join the channel with a temporary Token, provide your project's Token and channel name here -// If you set uid=0, the engine generates a uid internally; on success, it triggers didJoinChannel callback -agoraKit.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name#>", uid: 0, mediaOptions: options) +// Use a temporary token to join the channel, pass in your project's token and channel name +// If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback +agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) ``` @@ -854,19 +933,21 @@ agoraKit.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name# ```swift let options = AgoraRtcChannelMediaOptions() -// Set the user role as broadcaster; keep default value for audience role +// Set the channel profile +options.channelProfile = .communication +// Set the user role to broadcaster; if you want to set the user role to audience, keep the default value options.clientRoleType = .broadcaster -// Publish audio captured by microphone +// Publish the microphone audio options.publishMicrophoneTrack = true -// Publish video captured by camera +// Publish the camera video options.publishCameraTrack = true -// Auto subscribe to all audio streams +// Automatically subscribe to all audio streams options.autoSubscribeAudio = true -// Auto subscribe to all video streams +// Automatically subscribe to all video streams options.autoSubscribeVideo = true -// Join the channel with a temporary Token, provide your project's Token and channel name here -// If you set uid=0, the engine generates a uid internally; on success, it triggers didJoinChannel callback -agoraKit.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name#>", uid: 0, mediaOptions: options) +// Use a temporary token to join the channel, pass in your project's token and channel name +// If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback +agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) ``` @@ -874,28 +955,68 @@ agoraKit.joinChannel(byToken: "<#Your Token#>", channelId: "<#Your Channel Name# To initialize the remote user view, call `setupRemoteVideo` and set the local display properties for the remote user. Use the `didJoinedOfUid` callback to get the UID of the remote user. ```swift -let videoCanvas = AgoraRtcVideoCanvas() -// UID of the remote user -videoCanvas.uid = uid -videoCanvas.renderMode = .hidden -videoCanvas.view = remoteView -agoraKit?.setupRemoteVideo(videoCanvas) +func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ + // When a remote user joins the channel, display the remote video stream using the returned uid + print("User \(uid) joined after \(elapsed) milliseconds") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = remoteView + videoCanvas.renderMode = .hidden + agoraKit.setupRemoteVideo(videoCanvas) +} ``` +### Implement Common Callbacks + +Define necessary callbacks based on the usage scenario. The following sample code demonstrates how to implement the `didJoinChannel` and `didOfflineOfUid` callbacks: + +```swift +extension ViewController: AgoraRtcEngineDelegate { + // Callback when the local user successfully joins a channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { + print("didJoinChannel: (channel), uid: (uid)") + } + + // Callback when a remote user leaves the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { + // Print debug information + print("User (uid) went offline due to (reason)") + let videoCanvas = AgoraRtcVideoCanvas() + videoCanvas.uid = uid + videoCanvas.view = nil + agoraKit.setupRemoteVideo(videoCanvas) + } +} +``` ### Start audio and video interaction Use the `viewDidLoad` callback to join the channel and start audio and video interaction. + ```swift override func viewDidLoad() { super.viewDidLoad() + // Start audio and video interaction after the view loads + agoraKit.enableVideo() + startPreview() + joinChannel() +} +``` + + + +```swift +override func viewDidLoad() { + super.viewDidLoad() + // Start audio and video interaction after the view loads // Initialize the video window initView() - initializeAgoraEngine() - setupLocalVideo() + agoraKit.enableVideo() + startPreview() joinChannel() } ``` + ### End audio and video interaction @@ -918,14 +1039,44 @@ override func viewDidLoad() { To join the channel, call `joinChannelByToken`. Provide the temporary token obtained from the console and the channel name used when acquiring the token. Additionally, set the user role before joining the channel: - ```swift - let option = AgoraRtcChannelMediaOptions() - option.channelProfile = .communication - // Set the user role to broadcaster - option.clientRoleType = .broadcaster - // Join the channel with a temporary Token, enter your project's Token and channel name here - agoraKit?.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: option) - ``` +```swift +let options = AgoraRtcChannelMediaOptions() +options.channelProfile = .communication +// Set user role to broadcaster; to set user role to audience, keep the default value +options.clientRoleType = .broadcaster +// Publish microphone audio +options.publishMicrophoneTrack = true +// Automatically subscribe to all audio streams +options.autoSubscribeAudio = true +// Join the channel using a temporary token and channel name +// If you set the uid of 0, a value is randomly generated by the engine; success triggers the didJoinChannel callback +agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options) +``` + +### Implement Common Callbacks + +Define necessary callbacks based on the usage scenario. The following sample code demonstrates how to implement the `didJoinChannel`, `didJoinedOfUid`, and `didOfflineOfUid` callbacks: + +```swift +extension ViewController: AgoraRtcEngineDelegate { + // Callback when the local user successfully joins a channel + func rtcEngine( + _ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int + ) { + print("didJoinChannel: (channel), uid: (uid)") + } + // Callback when a remote user joins the current channel + func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){ + // Print debug information + print("User (uid) joined after (elapsed) milliseconds") + } + // Callback when a remote user leaves the current channel + func rtcEngine( + _ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason + ) { + } +} +``` ### Start and stop voice calling When the user launches this app, it joins the channel and starts voice calling. When the user closes this app, it leaves the channel and ends voice calling. To implement this logic: @@ -944,8 +1095,12 @@ When the user launches this app, it joins the channel and starts voice calling. 1. To release all resources used by Agora SDK, call `leaveChannel` when the app is closed. ```swift - agoraKit?.leaveChannel(nil) + // Leave the channel and release session-related resources + agoraKit.leaveChannel(nil) + // Release all resources used by the Agora SDK + AgoraRtcEngineKit.destroy() ``` - After destroying the engine, you can no longer use SDK methods and callbacks. To use the real-time interaction functions again, create a new engine. See [Initialize the engine](#initialize-the-engine) for details. + +After destroying the engine, you can no longer use SDK methods and callbacks. To use the real-time interaction functions again, create a new engine. See [Initialize the engine](#initialize-the-engine) for details. \ No newline at end of file diff --git a/shared/video-sdk/get-started/get-started-sdk/project-setup/android.mdx b/shared/video-sdk/get-started/get-started-sdk/project-setup/android.mdx index 25eed538c..df7847b25 100644 --- a/shared/video-sdk/get-started/get-started-sdk/project-setup/android.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/project-setup/android.mdx @@ -78,13 +78,16 @@ Choose either of the following methods to integrate into your pro mavenCentral() } ``` - + + If your Android project uses dependencyResolutionManagement, the method of adding the Maven Central dependency may differ. + + 1. Open the `/app/build.gradle` file and add the under `dependencies`. Check the latest version of the SDK from the [release notes](../overview/release-notes) and replace `x.y.z` with the specific version number. ```groovy dependencies { - // Replace x.y.z with a specific SDK version number. For example, 4.3.0 + // Replace x.y.z with a specific SDK version number. For example, 4.3.2 implementation 'io.agora.rtc:voice-sdk:x.y.z' } ``` @@ -93,7 +96,7 @@ Choose either of the following methods to integrate into your pro ```groovy dependencies { - // Replace x.y.z with a specific SDK version number. For example, 4.3.0 + // Replace x.y.z with a specific SDK version number. For example, 4.3.2 implementation 'io.agora.rtc:full-sdk:x.y.z' } ``` diff --git a/shared/video-sdk/get-started/get-started-sdk/project-setup/swift.mdx b/shared/video-sdk/get-started/get-started-sdk/project-setup/swift.mdx index 51abb9c1c..47602e710 100644 --- a/shared/video-sdk/get-started/get-started-sdk/project-setup/swift.mdx +++ b/shared/video-sdk/get-started/get-started-sdk/project-setup/swift.mdx @@ -20,6 +20,12 @@ Follow these steps to create a project in Xcode: Open the `info.plist` file from the project navigation bar, edit [the property list](https://help.apple.com/xcode/mac/current/#/dev3f399a2a6), and add the required recording and camera permissions for real-time interaction. + + - The permissions listed below are optional. However, if you do not add these permissions, you will not be able to use the microphone for audio interaction. + - If your project depends on third-party plugins or libraries, such as a third-party camera library, and the signature of the plug-in or library is inconsistent with the signature of the project, check the **Hardened Runtime** settings. Specifically, review and potentially disable **Runtime Exceptions** and **Library Validation** in the project configuration. + - For further information, refer to [Preparing your app for distribution](https://developer.apple.com/documentation/xcode/preparing_your_app_for_distribution). + + | Key | Type | Value | |:----|:-----|:------| @@ -44,8 +50,6 @@ Follow these steps to create a project in Xcode: -
  • If you need to add a third-party plug-in or library, such as a third-party camera, to your project, and the signature of the plug-in or library is inconsistent with the signature of the project, you need to check the **Hardened Runtime** settings. Specifically, you should review and potentially disable **Runtime Exceptions** and **Library Validation** in the project configuration.
  • For further information, refer to [Preparing your app for distribution](https://developer.apple.com/documentation/xcode/preparing_your_app_for_distribution).
- ### Integrate the SDK Use one of the following methods to integrate into your project. @@ -73,25 +77,25 @@ Use one of the following methods to integrate into your project. - ```shell - platform :ios, '9.0' + + {`platform :ios, '9.0' target 'Your App' do # For x.y.z fill in the specific SDK version number, such as 4.3.0. # The latest version number can be obtained from the release notes. pod 'AgoraAudio_iOS', 'x.y.z' - end - ``` + end`} + - ```shell - platform :ios, '9.0' + + {`platform :ios, '9.0' target 'Your App' do # For x.y.z fill in the specific SDK version number, such as 4.3.0. # The latest version number can be obtained from the release notes. pod 'AgoraRtcEngine_iOS', 'x.y.z' - end - ``` + end`} + @@ -147,18 +151,19 @@ class ViewController: UIViewController{ var localView: UIView! // Define the remoteView variable var remoteView: UIView! - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! // Set up the video window layout - override func viewDidLoad() { - super.viewDidLoad() - - localView = UIView(frame: UIScreen.main.bounds) - remoteView = UIView(frame: CGRect(x: self.view.bounds.width - 135, y: 50, width: 135, height: 240)) - self.view.addSubview(localView) - self.view.addSubview(remoteView) - } + override func viewDidLoad() { + super.viewDidLoad() + + localView = UIView(frame: UIScreen.main.bounds) + remoteView = UIView( + frame: CGRect(x: self.view.bounds.width - 135, y: 50, width: 135, height: 240)) + self.view.addSubview(localView) + self.view.addSubview(remoteView) + } }`}
@@ -170,7 +175,7 @@ class ViewController: UIViewController{ import AgoraRtcKit class ViewController: UIViewController{ - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! }`} @@ -187,35 +192,27 @@ class ViewController: UIViewController{ import AgoraRtcKit class ViewController: NSViewController { - // Define a localView variable - var localView: CustomView! + var localView: NSView! // Define a remoteView variable - var remoteView: CustomView! - // Define agoraKit + var remoteView: NSView! + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! - // Set the video window layout - class CustomView: NSView { - override func layout() { - super.layout() - // Get the view controller - guard let viewController = self.window?.contentViewController as? ViewController else { - return - } - - // Calculate the position and size of the local view - let localViewWidth: CGFloat = 135 - let localViewHeight: CGFloat = 240 - let localViewX: CGFloat = self.bounds.width - localViewWidth - -2 - let localViewY: CGFloat = 2 - - // Set the local view frame - viewController.localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) - - // Set the frame of the remote view so that it fills the entire CustomView - viewController.remoteView.frame = self.bounds - } + override func viewDidLayout() { + super.viewDidLayout() + + // Set the position and size of the local view + let localViewWidth: CGFloat = 135 + let localViewHeight: CGFloat = 240 + let localViewX: CGFloat = 2 + let localViewY: CGFloat = 2 + + // Set the local view frame + localView.frame = CGRect(x: localViewX, y: localViewY, width: localViewWidth, height: localViewHeight) + + // Set the remote view frame to fill the entire CustomView + remoteView.frame = view.bounds } }`} @@ -227,7 +224,7 @@ class ViewController: NSViewController { import AgoraRtcKit class ViewController: UIViewController{ - // Define agoraKit + // Declare a variable for the AgoraRtcEngineKit instance var agoraKit: AgoraRtcEngineKit! }`}