Skip to content

Commit

Permalink
Use Combine to avoid extra dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
ladvoc committed Jan 18, 2025
1 parent b9566c5 commit d4f5156
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 49 deletions.
2 changes: 0 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ let package = Package(
),
],
dependencies: [
.package(url: "https://github.com/apple/swift-async-algorithms", from: "1.0.0"),
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "125.6422.11"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.26.0"),
Expand All @@ -37,7 +36,6 @@ let package = Package(
dependencies: [
.product(name: "LiveKitWebRTC", package: "webrtc-xcframework"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
.product(name: "Logging", package: "swift-log"),
"LKObjCHelpers",
],
Expand Down
2 changes: 0 additions & 2 deletions Package@swift-5.9.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ let package = Package(
),
],
dependencies: [
.package(url: "https://github.com/apple/swift-async-algorithms", from: "1.0.0"),
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "125.6422.11"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.26.0"),
Expand All @@ -39,7 +38,6 @@ let package = Package(
dependencies: [
.product(name: "LiveKitWebRTC", package: "webrtc-xcframework"),
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "AsyncAlgorithms", package: "swift-async-algorithms"),
.product(name: "Logging", package: "swift-log"),
"LKObjCHelpers",
],
Expand Down
36 changes: 11 additions & 25 deletions Sources/LiveKit/Broadcast/BroadcastExtensionState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,31 @@

#if os(iOS)

import AsyncAlgorithms
import Combine
import Foundation

#if canImport(ReplayKit)
import ReplayKit
#endif

actor BroadcastExtensionState {
/// Whether or not the broadcast extension is currently broadcasting.
private(set) var isBroadcasting = false
class BroadcastExtensionState {
/// A publisher that emits a Boolean value indicating whether or not the extension is currently broadcasting.
static var isBroadcasting: some Publisher<Bool, Never> {
Publishers.Merge(
DarwinNotificationCenter.shared.publisher(for: .broadcastStarted).map { _ in true },
DarwinNotificationCenter.shared.publisher(for: .broadcastStopped).map { _ in false }
)
.eraseToAnyPublisher()
}

/// Displays the system broadcast picker, allowing the user to start the broadcast.
/// - Note: This is merely a request and does not guarantee the user will choose to start the broadcast.
nonisolated func requestActivation() async {
static func requestActivation() async {
await RPSystemBroadcastPickerView.show(
for: BroadcastScreenCapturer.screenSharingExtension,
showsMicrophoneButton: false
)
}

private var listenTask: Task<Void, Never>?

/// Creates a new instance and begins listening.
init(_ changeHandler: ((Bool) async -> Void)? = nil) async {
listenTask = Task {
let stateStream = merge(
DarwinNotificationCenter.shared.notifications(named: .broadcastStarted).map { true },
DarwinNotificationCenter.shared.notifications(named: .broadcastStopped).map { false }
)
for await isBroadcasting in stateStream {
self.isBroadcasting = isBroadcasting
await changeHandler?(isBroadcasting)
}
}
}

deinit {
listenTask?.cancel()
}
}

#endif
56 changes: 36 additions & 20 deletions Sources/LiveKit/Participant/LocalParticipant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import Foundation
import Combine

#if swift(>=5.9)
internal import LiveKitWebRTC
Expand Down Expand Up @@ -237,27 +238,42 @@ public class LocalParticipant: Participant {
/// returning `true` or `false` based on the user's response .
///
public var broadcastStarted: (() async -> Bool)?

private var extensionState: BroadcastExtensionState!

private var isBroadcasting = false {
didSet { broadcastStateChanged() }
}
private var cancellable = Set<AnyCancellable>()

override init(room: Room, sid: Participant.Sid? = nil, identity: Participant.Identity? = nil) {
super.init(room: room, sid: sid, identity: identity)
Task {
extensionState = await BroadcastExtensionState { [weak self] isBroadcasting in
guard isBroadcasting else { return }

logger.debug("Broadcast extension initiated screen share")
let shouldPublish = await self?.broadcastStarted?() ?? true

guard shouldPublish else {
logger.debug("Will not publish screen share track")
return
}
do {
try await self?.setScreenShare(enabled: true)
} catch {
logger.error("Failed to enable screen share: \(error)")
}

BroadcastExtensionState
.isBroadcasting
.sink { [weak self] in
guard let self else { return }
self.isBroadcasting = $0
}
.store(in: &cancellable)
}

private func broadcastStateChanged() {
guard isBroadcasting else {
logger.debug("Broadcast stopped")
return
}
logger.debug("Broadcast started")

Task { [weak self] in
guard let self else { return }
let shouldPublish = await self.broadcastStarted?() ?? true
guard shouldPublish else {
logger.debug("Will not publish screen share track")
return
}
do {
try await self.setScreenShare(enabled: true)
} catch {
logger.error("Failed to enable screen share: \(error)")
}
}
}
Expand Down Expand Up @@ -372,8 +388,8 @@ public extension LocalParticipant {
let localTrack: LocalVideoTrack
let options = (captureOptions as? ScreenShareCaptureOptions) ?? room._state.roomOptions.defaultScreenShareCaptureOptions
if options.useBroadcastExtension {
guard await self.extensionState.isBroadcasting else {
await self.extensionState.requestActivation()
guard self.isBroadcasting else {
await BroadcastExtensionState.requestActivation()
return nil
}
// Wait until broadcasting to publish track
Expand Down

0 comments on commit d4f5156

Please sign in to comment.