Skip to content

Commit f6bfa81

Browse files
committed
Merge branch 'main' into filipi/video_transform_start_endpoint
2 parents 2ad08cb + b8dba25 commit f6bfa81

File tree

8 files changed

+101
-64
lines changed

8 files changed

+101
-64
lines changed

p2p-webrtc/video-transform/client/ios/SimpleChatbot.xcodeproj/project.pbxproj

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
90383A932D9C35B300D0DDA3 /* ChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90383A922D9C35B300D0DDA3 /* ChatView.swift */; };
2020
90383A962D9C35BD00D0DDA3 /* LiveMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90383A942D9C35BD00D0DDA3 /* LiveMessage.swift */; };
2121
90383A982D9D85E700D0DDA3 /* CameraButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90383A972D9D85E700D0DDA3 /* CameraButtonView.swift */; };
22-
90383A9B2DA4620800D0DDA3 /* PipecatClientIOSSmallWebrtc in Frameworks */ = {isa = PBXBuildFile; productRef = 90383A9A2DA4620800D0DDA3 /* PipecatClientIOSSmallWebrtc */; };
22+
9050F9A72EA976AA0041369E /* PipecatClientIOSSmallWebrtc in Frameworks */ = {isa = PBXBuildFile; productRef = 9050F9A62EA976AA0041369E /* PipecatClientIOSSmallWebrtc */; };
2323
90ABB98E2C735ED6000D9CC7 /* MeetingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90ABB98D2C735ED6000D9CC7 /* MeetingView.swift */; };
2424
90ABB9932C73820D000D9CC7 /* MicrophoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90ABB9922C73820D000D9CC7 /* MicrophoneView.swift */; };
2525
90ABB9982C738356000D9CC7 /* CustomColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90ABB9972C738356000D9CC7 /* CustomColors.swift */; };
@@ -28,6 +28,7 @@
2828
90ABB9A32C74E1CE000D9CC7 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90ABB9A22C74E1CE000D9CC7 /* SettingsView.swift */; };
2929
90ABB9A62C74EA8A000D9CC7 /* SettingsPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90ABB9A52C74EA8A000D9CC7 /* SettingsPreference.swift */; };
3030
90ABB9A82C74EAB1000D9CC7 /* SettingsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90ABB9A72C74EAB1000D9CC7 /* SettingsManager.swift */; };
31+
90C5CDCE2EA18A66000DD785 /* PipecatClientIOSSmallWebrtc in Frameworks */ = {isa = PBXBuildFile; productRef = 90C5CDCD2EA18A66000DD785 /* PipecatClientIOSSmallWebrtc */; };
3132
/* End PBXBuildFile section */
3233

3334
/* Begin PBXContainerItemProxy section */
@@ -78,8 +79,9 @@
7879
isa = PBXFrameworksBuildPhase;
7980
buildActionMask = 2147483647;
8081
files = (
82+
9050F9A72EA976AA0041369E /* PipecatClientIOSSmallWebrtc in Frameworks */,
8183
90383A912D9C357F00D0DDA3 /* PipecatClientIOSSmallWebrtc in Frameworks */,
82-
90383A9B2DA4620800D0DDA3 /* PipecatClientIOSSmallWebrtc in Frameworks */,
84+
90C5CDCE2EA18A66000DD785 /* PipecatClientIOSSmallWebrtc in Frameworks */,
8385
);
8486
runOnlyForDeploymentPostprocessing = 0;
8587
};
@@ -235,7 +237,8 @@
235237
name = SimpleChatbot;
236238
packageProductDependencies = (
237239
90383A902D9C357F00D0DDA3 /* PipecatClientIOSSmallWebrtc */,
238-
90383A9A2DA4620800D0DDA3 /* PipecatClientIOSSmallWebrtc */,
240+
90C5CDCD2EA18A66000DD785 /* PipecatClientIOSSmallWebrtc */,
241+
9050F9A62EA976AA0041369E /* PipecatClientIOSSmallWebrtc */,
239242
);
240243
productName = SimpleChatbot;
241244
productReference = 90031FA32C616EE700408370 /* SimpleChatbot.app */;
@@ -310,7 +313,7 @@
310313
);
311314
mainGroup = 90031F9A2C616EE700408370;
312315
packageReferences = (
313-
90383A992DA4620800D0DDA3 /* XCRemoteSwiftPackageReference "pipecat-client-ios-small-webrtc" */,
316+
9050F9A52EA976AA0041369E /* XCRemoteSwiftPackageReference "pipecat-client-ios-small-webrtc" */,
314317
);
315318
productRefGroup = 90031FA42C616EE700408370 /* Products */;
316319
projectDirPath = "";
@@ -701,12 +704,12 @@
701704
/* End XCConfigurationList section */
702705

703706
/* Begin XCRemoteSwiftPackageReference section */
704-
90383A992DA4620800D0DDA3 /* XCRemoteSwiftPackageReference "pipecat-client-ios-small-webrtc" */ = {
707+
9050F9A52EA976AA0041369E /* XCRemoteSwiftPackageReference "pipecat-client-ios-small-webrtc" */ = {
705708
isa = XCRemoteSwiftPackageReference;
706709
repositoryURL = "https://github.com/pipecat-ai/pipecat-client-ios-small-webrtc";
707710
requirement = {
708711
kind = upToNextMajorVersion;
709-
minimumVersion = 0.0.1;
712+
minimumVersion = 1.1.1;
710713
};
711714
};
712715
/* End XCRemoteSwiftPackageReference section */
@@ -716,9 +719,13 @@
716719
isa = XCSwiftPackageProductDependency;
717720
productName = PipecatClientIOSSmallWebrtc;
718721
};
719-
90383A9A2DA4620800D0DDA3 /* PipecatClientIOSSmallWebrtc */ = {
722+
9050F9A62EA976AA0041369E /* PipecatClientIOSSmallWebrtc */ = {
723+
isa = XCSwiftPackageProductDependency;
724+
package = 9050F9A52EA976AA0041369E /* XCRemoteSwiftPackageReference "pipecat-client-ios-small-webrtc" */;
725+
productName = PipecatClientIOSSmallWebrtc;
726+
};
727+
90C5CDCD2EA18A66000DD785 /* PipecatClientIOSSmallWebrtc */ = {
720728
isa = XCSwiftPackageProductDependency;
721-
package = 90383A992DA4620800D0DDA3 /* XCRemoteSwiftPackageReference "pipecat-client-ios-small-webrtc" */;
722729
productName = PipecatClientIOSSmallWebrtc;
723730
};
724731
/* End XCSwiftPackageProductDependency section */

p2p-webrtc/video-transform/client/ios/SimpleChatbot.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

p2p-webrtc/video-transform/client/ios/SimpleChatbot/model/CallContainerModel.swift

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class CallContainerModel: ObservableObject {
2121
@Published var liveBotMessage: LiveMessage?
2222
@Published var liveUserMessage: LiveMessage?
2323

24-
var rtviClientIOS: RTVIClient?
24+
var pipecatClientIOS: PipecatClient?
2525

2626
@Published var selectedMic: MediaDeviceId? = nil {
2727
didSet {
@@ -40,7 +40,7 @@ class CallContainerModel: ObservableObject {
4040
}
4141

4242
@MainActor
43-
func connect(backendURL: String) {
43+
func connect(backendURL: String, apiKey: String) {
4444
self.resetLiveMessages()
4545

4646
let baseUrl = backendURL.trimmingCharacters(in: .whitespacesAndNewlines)
@@ -50,52 +50,48 @@ class CallContainerModel: ObservableObject {
5050
}
5151

5252
let currentSettings = SettingsManager.getSettings()
53-
let rtviClientOptions = RTVIClientOptions.init(
53+
let pipecatClientOptions = PipecatClientOptions.init(
54+
transport: SmallWebRTCTransport.init(),
5455
enableMic: currentSettings.enableMic,
5556
enableCam: currentSettings.enableCam,
56-
params: RTVIClientParams(
57-
config: [
58-
.init(
59-
service: SmallWebRTCTransport.SERVICE_NAME,
60-
options: [
61-
.init(name: "server_url", value: .string(baseUrl))
62-
]
63-
)
64-
]
65-
)
6657
)
67-
self.rtviClientIOS = RTVIClient.init(
68-
transport: SmallWebRTCTransport.init(options: rtviClientOptions),
69-
options: rtviClientOptions
58+
self.pipecatClientIOS = PipecatClient.init(
59+
options: pipecatClientOptions
7060
)
71-
self.rtviClientIOS?.delegate = self
61+
self.pipecatClientIOS?.delegate = self
7262

73-
// Registering the llm helper, we will need this to handle the function calling
74-
let llmHelper = try? self.rtviClientIOS?.registerHelper(service: "llm", helper: LLMHelper.self)
75-
llmHelper?.delegate = self
76-
77-
self.rtviClientIOS?.start() { result in
63+
let authorizationToken = apiKey.trimmingCharacters(in: .whitespacesAndNewlines)
64+
print("authorizationToken: \(authorizationToken)")
65+
let headers = [["Authorization": "Bearer \(authorizationToken)"]]
66+
let startParams = APIRequest.init(
67+
endpoint: URL(string: baseUrl + "/start")!,
68+
headers: headers,
69+
requestData: Value.object([
70+
"enableDefaultIceServers": .boolean(true)
71+
])
72+
)
73+
self.pipecatClientIOS?.startBotAndConnect(startBotParams: startParams) { (result: Result<SmallWebRTCStartBotResult, AsyncExecutionError>) in
7874
switch result {
7975
case .failure(let error):
8076
self.showError(message: error.localizedDescription)
81-
self.rtviClientIOS = nil
82-
case .success():
77+
self.pipecatClientIOS = nil
78+
case .success(_):
8379
// Apply initial mic preference
8480
if let selectedMic = SettingsManager.getSettings().selectedMic {
8581
self.selectMic(MediaDeviceId(id: selectedMic))
8682
}
8783
// Populate available devices list
88-
self.availableMics = self.rtviClientIOS?.getAllMics() ?? []
84+
self.availableMics = self.pipecatClientIOS?.getAllMics() ?? []
8985
}
9086
}
91-
self.saveCredentials(backendURL: backendURL)
87+
self.saveCredentials(backendURL: baseUrl, apiKey: authorizationToken)
9288
}
9389

9490
@MainActor
9591
func disconnect() {
96-
self.rtviClientIOS?.disconnect(completion: nil)
97-
self.rtviClientIOS?.release()
98-
self.rtviClientIOS = nil
92+
self.pipecatClientIOS?.disconnect(completion: nil)
93+
self.pipecatClientIOS?.release()
94+
self.pipecatClientIOS = nil
9995
}
10096

10197
func showError(message: String) {
@@ -110,10 +106,10 @@ class CallContainerModel: ObservableObject {
110106

111107
@MainActor
112108
func toggleMicInput() {
113-
self.rtviClientIOS?.enableMic(enable: !self.isMicEnabled) { result in
109+
self.pipecatClientIOS?.enableMic(enable: !self.isMicEnabled) { result in
114110
switch result {
115111
case .success():
116-
self.isMicEnabled = self.rtviClientIOS?.isMicEnabled ?? false
112+
self.isMicEnabled = self.pipecatClientIOS?.isMicEnabled ?? false
117113
case .failure(let error):
118114
self.showError(message: error.localizedDescription)
119115
}
@@ -122,27 +118,29 @@ class CallContainerModel: ObservableObject {
122118

123119
@MainActor
124120
func toggleCamInput() {
125-
self.rtviClientIOS?.enableCam(enable: !self.isCamEnabled) { result in
121+
print("Is cam enabled: \(self.isCamEnabled)")
122+
self.pipecatClientIOS?.enableCam(enable: !self.isCamEnabled) { result in
126123
switch result {
127124
case .success():
128-
self.isCamEnabled = self.rtviClientIOS?.isCamEnabled ?? false
125+
self.isCamEnabled = self.pipecatClientIOS?.isCamEnabled ?? false
129126
case .failure(let error):
130127
self.showError(message: error.localizedDescription)
131128
}
132129
}
133130
}
134131

135-
func saveCredentials(backendURL: String) {
132+
func saveCredentials(backendURL: String, apiKey: String) {
136133
var currentSettings = SettingsManager.getSettings()
137134
currentSettings.backendURL = backendURL
135+
currentSettings.apiKey = apiKey
138136
// Saving the settings
139137
SettingsManager.updateSettings(settings: currentSettings)
140138
}
141139

142140
@MainActor
143141
func selectMic(_ mic: MediaDeviceId) {
144142
self.selectedMic = mic
145-
self.rtviClientIOS?.updateMic(micId: mic, completion: nil)
143+
self.pipecatClientIOS?.updateMic(micId: mic, completion: nil)
146144
}
147145

148146
private func createLiveMessage(content:String = "", type:MessageType) {
@@ -176,7 +174,7 @@ class CallContainerModel: ObservableObject {
176174
}
177175
}
178176

179-
extension CallContainerModel:RTVIClientDelegate, LLMHelperDelegate {
177+
extension CallContainerModel:PipecatClientDelegate {
180178

181179
private func handleEvent(eventName: String, eventValue: Any? = nil) {
182180
if let value = eventValue {
@@ -205,8 +203,8 @@ extension CallContainerModel:RTVIClientDelegate, LLMHelperDelegate {
205203
func onConnected() {
206204
Task { @MainActor in
207205
self.handleEvent(eventName: "onConnected")
208-
self.isMicEnabled = self.rtviClientIOS?.isMicEnabled ?? false
209-
self.isCamEnabled = self.rtviClientIOS?.isCamEnabled ?? false
206+
self.isMicEnabled = self.pipecatClientIOS?.isMicEnabled ?? false
207+
self.isCamEnabled = self.pipecatClientIOS?.isCamEnabled ?? false
210208
}
211209
}
212210

@@ -217,10 +215,10 @@ extension CallContainerModel:RTVIClientDelegate, LLMHelperDelegate {
217215
}
218216
}
219217

220-
func onError(message: String) {
218+
func onError(message: RTVIMessageInbound) {
221219
Task { @MainActor in
222220
self.handleEvent(eventName: "onError", eventValue: message)
223-
self.showError(message: message)
221+
self.showError(message: message.data ?? "")
224222
}
225223
}
226224

@@ -236,15 +234,33 @@ extension CallContainerModel:RTVIClientDelegate, LLMHelperDelegate {
236234
}
237235
}
238236

239-
func onBotTranscript(data: String) {
240-
self.handleEvent(eventName: "onBotTranscript", eventValue: data)
237+
func onTrackStarted(track: MediaStreamTrack, participant: Participant?) {
238+
Task { @MainActor in
239+
self.handleEvent(eventName: "onTrackStarted", eventValue: track)
240+
241+
guard track.kind == .video else { return }
242+
243+
// Use optional binding to simplify the check for local participant
244+
if participant?.local ?? true {
245+
self.localCamId = track.id
246+
} else {
247+
self.botCamId = track.id
248+
}
249+
}
241250
}
242-
243-
func onTracksUpdated(tracks: Tracks) {
244-
self.handleEvent(eventName: "onTracksUpdated", eventValue: tracks)
251+
252+
func onTrackStopped(track: MediaStreamTrack, participant: Participant?) {
245253
Task { @MainActor in
246-
self.localCamId = tracks.local.video
247-
self.botCamId = tracks.bot?.video ?? nil
254+
self.handleEvent(eventName: "onTrackStopped", eventValue: track)
255+
256+
guard track.kind == .video else { return }
257+
258+
// Use optional binding to simplify the check for local participant
259+
if participant?.local ?? true {
260+
self.localCamId = nil
261+
} else {
262+
self.botCamId = nil
263+
}
248264
}
249265
}
250266

@@ -277,7 +293,8 @@ extension CallContainerModel:RTVIClientDelegate, LLMHelperDelegate {
277293
}
278294
}
279295

280-
func onBotTTSText(data: BotTTSText) {
296+
func onBotTranscript(data: BotLLMText) {
297+
self.handleEvent(eventName: "onBotTranscript", eventValue: data)
281298
self.appendTextToLiveMessage(fromBot: true, content: data.text)
282299
}
283300

p2p-webrtc/video-transform/client/ios/SimpleChatbot/model/MockCallContainerModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class MockCallContainerModel: CallContainerModel {
2323
self.messages = [ liveMessageFromSystem, liveMessageFromUser, liveMessageFromBot ]
2424
}
2525

26-
override func connect(backendURL: String) {
26+
override func connect(backendURL: String, apiKey: String) {
2727
print("connect")
2828
}
2929

p2p-webrtc/video-transform/client/ios/SimpleChatbot/views/PreJoinView.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import SwiftUI
33
struct PreJoinView: View {
44

55
@State var backendURL: String
6+
@State var apiKey: String
67

78
@EnvironmentObject private var model: CallContainerModel
89

910
init() {
1011
let currentSettings = SettingsManager.getSettings()
1112
self.backendURL = currentSettings.backendURL
13+
self.apiKey = currentSettings.apiKey
1214
}
1315

1416
var body: some View {
@@ -22,9 +24,13 @@ struct PreJoinView: View {
2224
.textFieldStyle(RoundedBorderTextFieldStyle())
2325
.frame(maxWidth: .infinity)
2426
.padding([.bottom, .horizontal])
27+
SecureField("Authorization token", text: $apiKey)
28+
.textFieldStyle(RoundedBorderTextFieldStyle())
29+
.frame(maxWidth: .infinity)
30+
.padding([.horizontal])
2531
Button("Connect") {
2632
Task {
27-
await self.model.connect(backendURL: self.backendURL)
33+
self.model.connect(backendURL: self.backendURL, apiKey: self.apiKey)
2834
}
2935
}
3036
.padding()

p2p-webrtc/video-transform/client/ios/SimpleChatbot/views/settings/SettingsManager.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class SettingsManager {
99
return settings
1010
} else {
1111
// default values in case we don't have any settings
12-
return SettingsPreference(enableMic: true, enableCam: true, backendURL: "http://YOUR_IP:7860")
12+
return SettingsPreference(enableMic: true, enableCam: true, backendURL: "http://YOUR_IP:7860", apiKey: "Authorization token")
1313
}
1414
}
1515

p2p-webrtc/video-transform/client/ios/SimpleChatbot/views/settings/SettingsPreference.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ struct SettingsPreference: Codable {
55
var enableMic: Bool
66
var enableCam: Bool
77
var backendURL: String
8+
var apiKey: String
89
}
910

0 commit comments

Comments
 (0)