Skip to content

Commit

Permalink
update ifdef no-indent format
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroshihorie committed Mar 7, 2024
1 parent 9aa6cf7 commit 255af25
Show file tree
Hide file tree
Showing 23 changed files with 878 additions and 877 deletions.
1 change: 1 addition & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
--exclude Sources/LiveKit/Protos
--header "/*\n * Copyright {year} LiveKit\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */"
--ifdef no-indent
140 changes: 70 additions & 70 deletions Sources/LiveKit/Broadcast/BroadcastScreenCapturer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,94 +16,94 @@

#if os(iOS)

import Foundation
import Foundation

#if canImport(UIKit)
import UIKit
#endif

@_implementationOnly import LiveKitWebRTC
#if canImport(UIKit)
import UIKit
#endif

class BroadcastScreenCapturer: BufferCapturer {
static let kRTCScreensharingSocketFD = "rtc_SSFD"
static let kAppGroupIdentifierKey = "RTCAppGroupIdentifier"
static let kRTCScreenSharingExtension = "RTCScreenSharingExtension"
@_implementationOnly import LiveKitWebRTC

var frameReader: SocketConnectionFrameReader?
class BroadcastScreenCapturer: BufferCapturer {
static let kRTCScreensharingSocketFD = "rtc_SSFD"
static let kAppGroupIdentifierKey = "RTCAppGroupIdentifier"
static let kRTCScreenSharingExtension = "RTCScreenSharingExtension"

override func startCapture() async throws -> Bool {
let didStart = try await super.startCapture()
var frameReader: SocketConnectionFrameReader?

guard didStart else { return false }
override func startCapture() async throws -> Bool {
let didStart = try await super.startCapture()

guard let identifier = lookUpAppGroupIdentifier(),
let filePath = filePathForIdentifier(identifier) else { return false }
guard didStart else { return false }

let bounds = await UIScreen.main.bounds
let width = bounds.size.width
let height = bounds.size.height
let screenDimension = Dimensions(width: Int32(width), height: Int32(height))
guard let identifier = lookUpAppGroupIdentifier(),
let filePath = filePathForIdentifier(identifier) else { return false }

// pre fill dimensions, so that we don't have to wait for the broadcast to start to get actual dimensions.
// should be able to safely predict using actual screen dimensions.
let targetDimensions = screenDimension
.aspectFit(size: options.dimensions.max)
.toEncodeSafeDimensions()
let bounds = await UIScreen.main.bounds
let width = bounds.size.width
let height = bounds.size.height
let screenDimension = Dimensions(width: Int32(width), height: Int32(height))

defer { self.dimensions = targetDimensions }
let frameReader = SocketConnectionFrameReader()
guard let socketConnection = BroadcastServerSocketConnection(filePath: filePath, streamDelegate: frameReader)
else { return false }
frameReader.didCapture = { pixelBuffer, rotation in
self.capture(pixelBuffer, rotation: rotation.toLKType())
}
frameReader.startCapture(with: socketConnection)
self.frameReader = frameReader
// pre fill dimensions, so that we don't have to wait for the broadcast to start to get actual dimensions.
// should be able to safely predict using actual screen dimensions.
let targetDimensions = screenDimension
.aspectFit(size: options.dimensions.max)
.toEncodeSafeDimensions()

return true
defer { self.dimensions = targetDimensions }
let frameReader = SocketConnectionFrameReader()
guard let socketConnection = BroadcastServerSocketConnection(filePath: filePath, streamDelegate: frameReader)
else { return false }
frameReader.didCapture = { pixelBuffer, rotation in
self.capture(pixelBuffer, rotation: rotation.toLKType())
}
frameReader.startCapture(with: socketConnection)
self.frameReader = frameReader

override func stopCapture() async throws -> Bool {
let didStop = try await super.stopCapture()

// Already stopped
guard didStop else { return false }
return true
}

frameReader?.stopCapture()
frameReader = nil
return true
}
override func stopCapture() async throws -> Bool {
let didStop = try await super.stopCapture()

private func lookUpAppGroupIdentifier() -> String? {
Bundle.main.infoDictionary?[BroadcastScreenCapturer.kAppGroupIdentifierKey] as? String
}
// Already stopped
guard didStop else { return false }

private func filePathForIdentifier(_ identifier: String) -> String? {
guard let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: identifier)
else { return nil }
frameReader?.stopCapture()
frameReader = nil
return true
}

let filePath = sharedContainer.appendingPathComponent(BroadcastScreenCapturer.kRTCScreensharingSocketFD).path
return filePath
}
private func lookUpAppGroupIdentifier() -> String? {
Bundle.main.infoDictionary?[BroadcastScreenCapturer.kAppGroupIdentifierKey] as? String
}

public extension LocalVideoTrack {
/// Creates a track that captures screen capture from a broadcast upload extension
static func createBroadcastScreenCapturerTrack(name: String = Track.screenShareVideoName,
source: VideoTrack.Source = .screenShareVideo,
options: ScreenShareCaptureOptions = ScreenShareCaptureOptions(),
reportStatistics: Bool = false) -> LocalVideoTrack
{
let videoSource = Engine.createVideoSource(forScreenShare: true)
let capturer = BroadcastScreenCapturer(delegate: videoSource, options: BufferCaptureOptions(from: options))
return LocalVideoTrack(
name: name,
source: source,
capturer: capturer,
videoSource: videoSource,
reportStatistics: reportStatistics
)
}
private func filePathForIdentifier(_ identifier: String) -> String? {
guard let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: identifier)
else { return nil }

let filePath = sharedContainer.appendingPathComponent(BroadcastScreenCapturer.kRTCScreensharingSocketFD).path
return filePath
}
}

public extension LocalVideoTrack {
/// Creates a track that captures screen capture from a broadcast upload extension
static func createBroadcastScreenCapturerTrack(name: String = Track.screenShareVideoName,
source: VideoTrack.Source = .screenShareVideo,
options: ScreenShareCaptureOptions = ScreenShareCaptureOptions(),
reportStatistics: Bool = false) -> LocalVideoTrack
{
let videoSource = Engine.createVideoSource(forScreenShare: true)
let capturer = BroadcastScreenCapturer(delegate: videoSource, options: BufferCaptureOptions(from: options))
return LocalVideoTrack(
name: name,
source: source,
capturer: capturer,
videoSource: videoSource,
reportStatistics: reportStatistics
)
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Darwin
import Foundation

#if canImport(CHeaders)
import CHeaders
import CHeaders
#endif

class BroadcastServerSocketConnection: NSObject {
Expand Down
140 changes: 70 additions & 70 deletions Sources/LiveKit/Broadcast/Uploader/LKSampleHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,97 +16,97 @@

#if os(iOS)

#if canImport(ReplayKit)
import ReplayKit
#endif

open class LKSampleHandler: RPBroadcastSampleHandler {
private var clientConnection: BroadcastUploadSocketConnection?
private var uploader: SampleUploader?
#if canImport(ReplayKit)
import ReplayKit
#endif

public var appGroupIdentifier: String? {
Bundle.main.infoDictionary?[BroadcastScreenCapturer.kAppGroupIdentifierKey] as? String
}
open class LKSampleHandler: RPBroadcastSampleHandler {
private var clientConnection: BroadcastUploadSocketConnection?
private var uploader: SampleUploader?

public var socketFilePath: String {
guard let appGroupIdentifier,
let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
else {
return ""
}
public var appGroupIdentifier: String? {
Bundle.main.infoDictionary?[BroadcastScreenCapturer.kAppGroupIdentifierKey] as? String
}

return sharedContainer.appendingPathComponent(BroadcastScreenCapturer.kRTCScreensharingSocketFD).path
public var socketFilePath: String {
guard let appGroupIdentifier,
let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier)
else {
return ""
}

override public init() {
super.init()
return sharedContainer.appendingPathComponent(BroadcastScreenCapturer.kRTCScreensharingSocketFD).path
}

if let connection = BroadcastUploadSocketConnection(filePath: socketFilePath) {
clientConnection = connection
setupConnection()
override public init() {
super.init()

uploader = SampleUploader(connection: connection)
}
}
if let connection = BroadcastUploadSocketConnection(filePath: socketFilePath) {
clientConnection = connection
setupConnection()

override public func broadcastStarted(withSetupInfo _: [String: NSObject]?) {
// User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.d
DarwinNotificationCenter.shared.postNotification(.broadcastStarted)
openConnection()
uploader = SampleUploader(connection: connection)
}
}

override public func broadcastPaused() {
// User has requested to pause the broadcast. Samples will stop being delivered.
}
override public func broadcastStarted(withSetupInfo _: [String: NSObject]?) {
// User has requested to start the broadcast. Setup info from the UI extension can be supplied but optional.d
DarwinNotificationCenter.shared.postNotification(.broadcastStarted)
openConnection()
}

override public func broadcastResumed() {
// User has requested to resume the broadcast. Samples delivery will resume.
}
override public func broadcastPaused() {
// User has requested to pause the broadcast. Samples will stop being delivered.
}

override public func broadcastFinished() {
// User has requested to finish the broadcast.
DarwinNotificationCenter.shared.postNotification(.broadcastStopped)
clientConnection?.close()
}
override public func broadcastResumed() {
// User has requested to resume the broadcast. Samples delivery will resume.
}

override public func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
switch sampleBufferType {
case RPSampleBufferType.video:
uploader?.send(sample: sampleBuffer)
default:
break
}
override public func broadcastFinished() {
// User has requested to finish the broadcast.
DarwinNotificationCenter.shared.postNotification(.broadcastStopped)
clientConnection?.close()
}

override public func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
switch sampleBufferType {
case RPSampleBufferType.video:
uploader?.send(sample: sampleBuffer)
default:
break
}
}

private func setupConnection() {
clientConnection?.didClose = { [weak self] error in
logger.log(level: .debug, "client connection did close \(String(describing: error))")

if let error {
self?.finishBroadcastWithError(error)
} else {
// the displayed failure message is more user friendly when using NSError instead of Error
let LKScreenSharingStopped = 10001
let customError = NSError(domain: RPRecordingErrorDomain, code: LKScreenSharingStopped, userInfo: [NSLocalizedDescriptionKey: "Screen sharing stopped"])
self?.finishBroadcastWithError(customError)
}
private func setupConnection() {
clientConnection?.didClose = { [weak self] error in
logger.log(level: .debug, "client connection did close \(String(describing: error))")

if let error {
self?.finishBroadcastWithError(error)
} else {
// the displayed failure message is more user friendly when using NSError instead of Error
let LKScreenSharingStopped = 10001
let customError = NSError(domain: RPRecordingErrorDomain, code: LKScreenSharingStopped, userInfo: [NSLocalizedDescriptionKey: "Screen sharing stopped"])
self?.finishBroadcastWithError(customError)
}
}
}

private func openConnection() {
let queue = DispatchQueue(label: "broadcast.connectTimer")
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline: .now(), repeating: .milliseconds(100), leeway: .milliseconds(500))
timer.setEventHandler { [weak self] in
guard self?.clientConnection?.open() == true else {
return
}

timer.cancel()
private func openConnection() {
let queue = DispatchQueue(label: "broadcast.connectTimer")
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline: .now(), repeating: .milliseconds(100), leeway: .milliseconds(500))
timer.setEventHandler { [weak self] in
guard self?.clientConnection?.open() == true else {
return
}

timer.resume()
timer.cancel()
}

timer.resume()
}
}

#endif
Loading

0 comments on commit 255af25

Please sign in to comment.