Skip to content

Commit 4db3f98

Browse files
authored
macOS screen share audio (#64)
1 parent 187d1e0 commit 4db3f98

File tree

6 files changed

+75
-16
lines changed

6 files changed

+75
-16
lines changed

LiveKitExample-dev.xcworkspace/xcshareddata/swiftpm/Package.resolved

+8-8
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,17 @@
4141
"kind" : "remoteSourceControl",
4242
"location" : "https://github.com/apple/swift-asn1.git",
4343
"state" : {
44-
"revision" : "7faebca1ea4f9aaf0cda1cef7c43aecd2311ddf6",
45-
"version" : "1.3.0"
44+
"revision" : "ae33e5941bb88d88538d0a6b19ca0b01e6c76dcf",
45+
"version" : "1.3.1"
4646
}
4747
},
4848
{
4949
"identity" : "swift-crypto",
5050
"kind" : "remoteSourceControl",
5151
"location" : "https://github.com/apple/swift-crypto.git",
5252
"state" : {
53-
"revision" : "ff0f781cf7c6a22d52957e50b104f5768b50c779",
54-
"version" : "3.10.0"
53+
"revision" : "45305d32cfb830faebcaa9a7aea66ad342637518",
54+
"version" : "3.11.1"
5555
}
5656
},
5757
{
@@ -86,17 +86,17 @@
8686
"kind" : "remoteSourceControl",
8787
"location" : "https://github.com/apple/swift-protobuf.git",
8888
"state" : {
89-
"revision" : "ebc7251dd5b37f627c93698e4374084d98409633",
90-
"version" : "1.28.2"
89+
"revision" : "d72aed98f8253ec1aa9ea1141e28150f408cf17f",
90+
"version" : "1.29.0"
9191
}
9292
},
9393
{
9494
"identity" : "webrtc-xcframework",
9595
"kind" : "remoteSourceControl",
9696
"location" : "https://github.com/livekit/webrtc-xcframework.git",
9797
"state" : {
98-
"revision" : "fb3e398c7298e0e497d3ff8bdd1119e364ac783c",
99-
"version" : "125.6422.15"
98+
"revision" : "8f0929a781da7c55f9ae95bc9fe3fd5c93809fe0",
99+
"version" : "125.6422.19"
100100
}
101101
}
102102
],

LiveKitExample.xcodeproj/project.pbxproj

+11-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
68019B9C2D00343700721481 /* LiveKit in Frameworks */ = {isa = PBXBuildFile; productRef = 68698E612C4C218B00221782 /* LiveKit */; };
1111
681A0AB727D888D80097E3F4 /* LiveKit in Frameworks */ = {isa = PBXBuildFile; productRef = 681A0AB627D888D80097E3F4 /* LiveKit */; };
1212
681A0AB827D88B190097E3F4 /* ReplayKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 683F05F4273F96B20080C7AC /* ReplayKit.framework */; platformFilter = maccatalyst; };
13+
6830E6BE2D5BE5E2001C5E83 /* AudioMixerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6830E6BD2D5BE5DF001C5E83 /* AudioMixerView.swift */; };
1314
68698E642C4C219500221782 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 68698E632C4C219500221782 /* KeychainAccess */; };
1415
68698E662C4C219A00221782 /* SFSafeSymbols in Frameworks */ = {isa = PBXBuildFile; productRef = 68698E652C4C219A00221782 /* SFSafeSymbols */; };
1516
6888FBE12C66B7B400AB93C1 /* Immersive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888FBE02C66B7B100AB93C1 /* Immersive.swift */; };
@@ -60,6 +61,7 @@
6061
/* End PBXCopyFilesBuildPhase section */
6162

6263
/* Begin PBXFileReference section */
64+
6830E6BD2D5BE5DF001C5E83 /* AudioMixerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioMixerView.swift; sourceTree = "<group>"; };
6365
683F05F3273F96B20080C7AC /* BroadcastExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = BroadcastExt.appex; sourceTree = BUILT_PRODUCTS_DIR; };
6466
683F05F4273F96B20080C7AC /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
6567
683F05F9273F96B20080C7AC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -171,6 +173,7 @@
171173
68A50ED42C4C1ED500D2DE17 /* Views */ = {
172174
isa = PBXGroup;
173175
children = (
176+
6830E6BD2D5BE5DF001C5E83 /* AudioMixerView.swift */,
174177
68A50ED22C4C1ED500D2DE17 /* PublishOptionsView.swift */,
175178
68A50ED32C4C1ED500D2DE17 /* ScreenShareSourcePickerView.swift */,
176179
);
@@ -341,6 +344,7 @@
341344
files = (
342345
68A50EE02C4C1ED500D2DE17 /* LiveKitExample.swift in Sources */,
343346
68A50EE12C4C1ED500D2DE17 /* Custom.swift in Sources */,
347+
6830E6BE2D5BE5E2001C5E83 /* AudioMixerView.swift in Sources */,
344348
68A50EE22C4C1ED500D2DE17 /* RoomView.swift in Sources */,
345349
68A50EE32C4C1ED500D2DE17 /* PublishOptionsView.swift in Sources */,
346350
68A50EE42C4C1ED500D2DE17 /* SecureStore.swift in Sources */,
@@ -447,7 +451,7 @@
447451
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
448452
CODE_SIGN_ENTITLEMENTS = Multiplatform/SwiftSDK_1.entitlements;
449453
CODE_SIGN_STYLE = Automatic;
450-
CURRENT_PROJECT_VERSION = 2025020401;
454+
CURRENT_PROJECT_VERSION = 2025022401;
451455
DEVELOPMENT_TEAM = 76TVFCUKK7;
452456
ENABLE_HARDENED_RUNTIME = YES;
453457
ENABLE_PREVIEWS = YES;
@@ -476,7 +480,7 @@
476480
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
477481
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
478482
MACOSX_DEPLOYMENT_TARGET = 12.0;
479-
MARKETING_VERSION = 2.1.0;
483+
MARKETING_VERSION = 2.2.0;
480484
PRODUCT_BUNDLE_IDENTIFIER = io.livekit.example.SwiftSDK.1;
481485
PRODUCT_NAME = "$(TARGET_NAME)";
482486
REGISTER_APP_GROUPS = NO;
@@ -504,7 +508,7 @@
504508
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
505509
CODE_SIGN_ENTITLEMENTS = Multiplatform/SwiftSDK_1.entitlements;
506510
CODE_SIGN_STYLE = Automatic;
507-
CURRENT_PROJECT_VERSION = 2025020401;
511+
CURRENT_PROJECT_VERSION = 2025022401;
508512
DEVELOPMENT_TEAM = 76TVFCUKK7;
509513
ENABLE_HARDENED_RUNTIME = YES;
510514
ENABLE_PREVIEWS = YES;
@@ -529,7 +533,7 @@
529533
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
530534
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
531535
MACOSX_DEPLOYMENT_TARGET = 12.0;
532-
MARKETING_VERSION = 2.1.0;
536+
MARKETING_VERSION = 2.2.0;
533537
PRODUCT_BUNDLE_IDENTIFIER = io.livekit.example.SwiftSDK.1;
534538
PRODUCT_NAME = "$(TARGET_NAME)";
535539
REGISTER_APP_GROUPS = NO;
@@ -728,15 +732,15 @@
728732
repositoryURL = "https://github.com/livekit/client-sdk-swift";
729733
requirement = {
730734
kind = exactVersion;
731-
version = 2.1.0;
735+
version = 2.2.1;
732736
};
733737
};
734738
B5C2EF142D0114C800FAC766 /* XCRemoteSwiftPackageReference "components-swift" */ = {
735739
isa = XCRemoteSwiftPackageReference;
736740
repositoryURL = "https://github.com/livekit/components-swift";
737741
requirement = {
738-
kind = exactVersion;
739-
version = 0.1.1;
742+
kind = upToNextMajorVersion;
743+
minimumVersion = 0.1.1;
740744
};
741745
};
742746
/* End XCRemoteSwiftPackageReference section */

Multiplatform/Controllers/AppContext.swift

+8
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ final class AppContext: ObservableObject {
7676
didSet { AudioManager.shared.isVoiceProcessingBypassed = isVoiceProcessingBypassed }
7777
}
7878

79+
@Published var micVolume: Float = 1.0 {
80+
didSet { AudioManager.shared.mixer.micVolume = micVolume }
81+
}
82+
83+
@Published var appVolume: Float = 1.0 {
84+
didSet { AudioManager.shared.mixer.appVolume = appVolume }
85+
}
86+
7987
public init(store: ValueStore<Preferences>) {
8088
self.store = store
8189

Multiplatform/Controllers/RoomContext.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ final class RoomContext: ObservableObject {
203203
@available(macOS 12.3, *)
204204
func setScreenShareMacOS(isEnabled: Bool, screenShareSource: MacOSScreenCaptureSource? = nil) async throws {
205205
if isEnabled, let screenShareSource {
206-
let track = LocalVideoTrack.createMacOSScreenShareTrack(source: screenShareSource)
206+
let track = LocalVideoTrack.createMacOSScreenShareTrack(source: screenShareSource, options: ScreenShareCaptureOptions(appAudio: true))
207207
let options = VideoPublishOptions(preferredCodec: VideoCodec.h264)
208208
screenShareTrack = try await room.localParticipant.publish(videoTrack: track, options: options)
209209
}

Multiplatform/RoomView.swift

+14
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct RoomView: View {
8787

8888
@State private var screenPickerPresented = false
8989
@State private var publishOptionsPickerPresented = false
90+
@State private var audioMixerOptionsPresented = false
9091

9192
@State private var cameraPublishOptions = VideoPublishOptions()
9293

@@ -396,6 +397,19 @@ struct RoomView: View {
396397
// disable while publishing/un-publishing
397398
.disabled(isMicrophonePublishingBusy)
398399

400+
Button {
401+
audioMixerOptionsPresented = true
402+
} label: {
403+
Image(systemSymbol: .switch2)
404+
}
405+
.disabled(!isMicrophoneEnabled)
406+
#if !os(tvOS)
407+
.popover(isPresented: $audioMixerOptionsPresented) {
408+
AudioMixerView()
409+
.padding()
410+
}
411+
#endif
412+
399413
#if os(iOS)
400414
Button(action: {
401415
Task {
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2025 LiveKit
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import SwiftUI
18+
19+
struct AudioMixerView: View {
20+
@EnvironmentObject var appCtx: AppContext
21+
22+
var body: some View {
23+
Text("Mic audio mixer")
24+
HStack {
25+
Text("Mic")
26+
Slider(value: $appCtx.micVolume, in: 0.0 ... 1.0)
27+
}
28+
HStack {
29+
Text("App")
30+
Slider(value: $appCtx.appVolume, in: 0.0 ... 1.0)
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)