-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 620969a
Showing
7 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# OS X | ||
.DS_Store | ||
|
||
# Xcode | ||
build/ | ||
*.pbxuser | ||
!default.pbxuser | ||
*.mode1v3 | ||
!default.mode1v3 | ||
*.mode2v3 | ||
!default.mode2v3 | ||
*.perspectivev3 | ||
!default.perspectivev3 | ||
xcuserdata/ | ||
*.xccheckout | ||
profile | ||
*.moved-aside | ||
DerivedData | ||
*.hmap | ||
*.ipa | ||
|
||
# Bundler | ||
.bundle | ||
|
||
# Add this line if you want to avoid checking in source code from Carthage dependencies. | ||
# Carthage/Checkouts | ||
|
||
Carthage/Build | ||
|
||
# We recommend against adding the Pods directory to your .gitignore. However | ||
# you should judge for yourself, the pros and cons are mentioned at: | ||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control | ||
# | ||
# Note: if you ignore the Pods directory, make sure to uncomment | ||
# `pod install` in .travis.yml | ||
# | ||
Pods/ | ||
Podfile.lock | ||
*.xcworkspace | ||
|
||
# Swift Package Manager | ||
# | ||
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. | ||
# Packages/ | ||
# Package.pins | ||
.build/ | ||
xcshareddata/ | ||
Package.resolved | ||
|
||
docs/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 AgoraIO Community | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// swift-tools-version: 5.7 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "AgoraVideoSwiftUI", | ||
platforms: [.iOS(.v13)], | ||
products: [ | ||
.library(name: "AgoraVideoSwiftUI", targets: ["AgoraVideoSwiftUI"]), | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/AgoraIO/AgoraRtcEngine_iOS", from: "4.1.1"), | ||
], | ||
targets: [ | ||
.target( | ||
name: "AgoraVideoSwiftUI", | ||
dependencies: [.product(name: "RtcBasic", package: "AgoraRtcEngine_iOS")] | ||
), | ||
.testTarget( | ||
name: "AgoraVideoSwiftUITests", | ||
dependencies: ["AgoraVideoSwiftUI"]), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# AgoraVideoSwiftUI | ||
|
||
AgoraVideoSwiftUI is a package for building video call apps using the Agora RTC SDK and SwiftUI. It provides a set of SwiftUI views and classes that simplify setting up and managing Agora RTC sessions for video calls. | ||
|
||
## Installation | ||
|
||
AgoraVideoSwiftUI can be installed using Swift Package Manager in Xcode. Simply add the package to your project by navigating to File > Swift Packages > Add Package Dependency and entering the repository URL: | ||
|
||
``` | ||
``` | ||
|
||
|
||
## Usage | ||
|
||
To use AgoraVideoSwiftUI in your SwiftUI project, simply import the package and use the provided views and classes. For example, you can use `AgoraVideoCanvasView` and `AgoraManager` view to render all the video streams in an Agora RTC session: | ||
|
||
```swift | ||
import AgoraVideoSwiftUI | ||
import AgoraRtcKit | ||
|
||
struct AgoraGettingStartedView: View { | ||
@ObservedObject var agoraManager = GettingStartedManager(appId: <#AppId#>, role: .broadcaster) | ||
var channelId: String = "test" | ||
var body: some View { | ||
ScrollView { | ||
VStack { | ||
ForEach(Array(agoraManager.allUsers), id: \.self) { uid in | ||
AgoraVideoCanvasView(agoraKit: agoraManager.engine, uid: uid) | ||
.aspectRatio(contentMode: .fit).cornerRadius(10) | ||
} | ||
}.padding(20) | ||
}.onAppear { | ||
agoraManager.engine.joinChannel( | ||
byToken: <#Agora Temp Token#>, channelId: channelId, info: nil, uid: 0 | ||
) | ||
}.onDisappear { | ||
agoraManager.engine.leaveChannel() | ||
} | ||
} | ||
} | ||
|
||
// To show and hide all the users in the channel, we need to make a small subclass of AgoraManager. | ||
class GettingStartedManager: AgoraManager { | ||
@Published var allUsers: Set<UInt> = [] | ||
override func leaveChannel(leaveChannelBlock: ((AgoraChannelStats) -> Void)? = nil) { | ||
allUsers.removeAll() | ||
super.leaveChannel(leaveChannelBlock: leaveChannelBlock) | ||
} | ||
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { | ||
if self.role == .broadcaster { | ||
self.allUsers.insert(0) | ||
} | ||
} | ||
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { | ||
self.allUsers.insert(uid) | ||
} | ||
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { | ||
self.allUsers.remove(uid) | ||
} | ||
} | ||
|
||
``` | ||
|
||
## Contributing | ||
|
||
Contributions to AgoraVideoSwiftUI are welcome! If you encounter any issues or have feature requests, please submit an issue on the GitHub repository. Pull requests are also welcome. | ||
|
||
## License | ||
|
||
AgoraVideoSwiftUI is available under the MIT license. See the [LICENSE](LICENSE) file for more information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// | ||
// AgoraManager.swift | ||
// | ||
// | ||
// Created by Max Cobb on 24/03/2023. | ||
// | ||
|
||
import Foundation | ||
import AgoraRtcKit | ||
|
||
/** | ||
``AgoraManager`` is a class that provides an interface to the Agora RTC Engine Kit. It conforms to the `ObservableObject` and `AgoraRtcEngineDelegate` protocols. | ||
|
||
Use AgoraManager to set up and manage Agora RTC sessions, manage the client's role, and control the client's connection to the Agora RTC server. | ||
*/ | ||
open class AgoraManager: NSObject, ObservableObject, AgoraRtcEngineDelegate { | ||
/// The Agora App ID for the session. | ||
var appId: String | ||
/// The client's role in the session. | ||
var role: AgoraClientRole = .audience { | ||
didSet { engine.setClientRole(role) } | ||
} | ||
/// The Agora RTC Engine Kit for the session. | ||
var engine: AgoraRtcEngineKit { | ||
let eng = AgoraRtcEngineKit.sharedEngine(withAppId: appId, delegate: self) | ||
eng.enableVideo() | ||
eng.setClientRole(role) | ||
return eng | ||
} | ||
|
||
/** | ||
Initializes a new instance of `AgoraManager` with the specified app ID and client role. | ||
|
||
- Parameters: | ||
- appId: The Agora App ID for the session. | ||
- role: The client's role in the session. The default value is `.audience`. | ||
*/ | ||
init(appId: String, role: AgoraClientRole = .audience) { | ||
self.appId = appId | ||
self.role = role | ||
} | ||
|
||
/** | ||
Leaves the channel and stops the preview for the session. | ||
|
||
- Parameter leaveChannelBlock: An optional closure that will be called when the client leaves the channel. The closure takes an `AgoraChannelStats` object as its parameter. | ||
*/ | ||
func leaveChannel(leaveChannelBlock: ((AgoraChannelStats) -> Void)? = nil) { | ||
self.engine.leaveChannel(leaveChannelBlock) | ||
self.engine.stopPreview() | ||
AgoraRtcEngineKit.destroy() | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// | ||
// SwiftUIView.swift | ||
// | ||
// | ||
// Created by Max Cobb on 24/03/2023. | ||
// | ||
|
||
import SwiftUI | ||
import AgoraRtcKit | ||
|
||
extension AgoraRtcVideoCanvas: ObservableObject { | ||
/// This could be used instead of UIView directly, if the canvas view also needs to retain its state in SwiftUI | ||
// class CanvasView: UIView, ObservableObject {} | ||
} | ||
|
||
/** | ||
AgoraVideoCanvasView is a UIViewRepresentable struct that provides a view for displaying remote or local video in an Agora RTC session. | ||
|
||
Use AgoraVideoCanvasView to create a view that displays the video stream from a remote user or the local user's camera in an Agora RTC session. You can specify the render mode, crop area, and setup mode for the view. | ||
*/ | ||
public struct AgoraVideoCanvasView: UIViewRepresentable { | ||
/// The `AgoraRtcVideoCanvas` object that represents the video canvas for the view. | ||
@StateObject var canvas = AgoraRtcVideoCanvas() | ||
|
||
/// A weak reference to the `AgoraRtcEngineKit` object for the session. | ||
weak var agoraKit: AgoraRtcEngineKit? | ||
|
||
/// The user ID of the remote user whose video to display, or `0` to display the local user's video. | ||
let uid: UInt | ||
|
||
/// The render mode for the view. | ||
var renderMode: AgoraVideoRenderMode = .hidden | ||
|
||
/// The crop area for the view. | ||
var cropArea: CGRect = .zero | ||
|
||
/// The setup mode for the view. | ||
var setupMode: AgoraVideoViewSetupMode = .replace | ||
|
||
/** | ||
Creates and configures a `UIView` for the view. This UIView will be the view the video is rendered onto. | ||
|
||
- Parameter context: The `UIViewRepresentable` context. | ||
|
||
- Returns: A `UIView` for displaying the video stream. | ||
*/ | ||
public func makeUIView(context: Context) -> UIView { | ||
// Create and return the remote video view | ||
let canvasView = UIView() | ||
canvas.view = canvasView | ||
canvas.renderMode = renderMode | ||
canvas.cropArea = cropArea | ||
canvas.setupMode = setupMode | ||
canvas.uid = uid | ||
canvasView.isHidden = false | ||
if self.uid == 0 { | ||
// Start the local video preview | ||
agoraKit?.startPreview() | ||
agoraKit?.setupLocalVideo(canvas) | ||
} else { | ||
agoraKit?.setupRemoteVideo(canvas) | ||
} | ||
return canvasView | ||
} | ||
|
||
/** | ||
Updates the `AgoraRtcVideoCanvas` object for the view with new values, if necessary. | ||
*/ | ||
func updateCanvasValues() { | ||
if canvas.renderMode == renderMode, canvas.cropArea == cropArea, canvas.setupMode == setupMode { | ||
return | ||
} | ||
// Update the canvas properties if needed | ||
if canvas.renderMode != renderMode { canvas.renderMode = renderMode } | ||
if canvas.cropArea != cropArea { canvas.cropArea = cropArea } | ||
if canvas.setupMode != setupMode { canvas.setupMode = setupMode } | ||
|
||
if self.uid == 0 { agoraKit?.setupLocalVideo(canvas) | ||
} else { agoraKit?.setupRemoteVideo(canvas) } | ||
} | ||
|
||
/** | ||
Updates the `UIView` for the view. | ||
*/ | ||
public func updateUIView(_ uiView: UIView, context: Context) { | ||
self.updateCanvasValues() | ||
} | ||
} | ||
|
||
struct AgoraVideoCanvasView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
AgoraVideoCanvasView(uid: 0) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import XCTest | ||
@testable import AgoraVideoSwiftUI | ||
|
||
final class AgoraVideoSwiftUITests: XCTestCase {} |