Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changes/logger
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
minor type="added" "Improved logging with the interface for custom loggers"
1 change: 0 additions & 1 deletion LiveKitClient.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ Pod::Spec.new do |spec|

spec.dependency("LiveKitWebRTC", "= 137.7151.09")
spec.dependency("SwiftProtobuf")
spec.dependency("Logging", "= 1.5.4")
spec.dependency("DequeModule", "= 1.1.4")
spec.dependency("OrderedCollections", " = 1.1.4")

Expand Down
2 changes: 0 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ let package = Package(
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "137.7151.09"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.31.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
.package(url: "https://github.com/apple/swift-collections.git", "1.1.0" ..< "1.3.0"),
// Only used for DocC generation
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.3.0"),
Expand All @@ -40,7 +39,6 @@ let package = Package(
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "OrderedCollections", package: "swift-collections"),
.product(name: "Logging", package: "swift-log"),
"LKObjCHelpers",
],
exclude: [
Expand Down
2 changes: 0 additions & 2 deletions [email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ let package = Package(
// LK-Prefixed Dynamic WebRTC XCFramework
.package(url: "https://github.com/livekit/webrtc-xcframework.git", exact: "137.7151.09"),
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.31.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
.package(url: "https://github.com/apple/swift-collections.git", "1.1.0" ..< "1.3.0"),
// Only used for DocC generation
.package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.3.0"),
Expand All @@ -41,7 +40,6 @@ let package = Package(
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "DequeModule", package: "swift-collections"),
.product(name: "OrderedCollections", package: "swift-collections"),
.product(name: "Logging", package: "swift-log"),
"LKObjCHelpers",
],
exclude: [
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,19 @@ For the full example, see 👉 [UIKit Minimal Example](https://github.com/liveki

# Frequently asked questions

### How to publish camera in 60 FPS ?
### How to adjust the log level?

The SDK will write to `OSLog` by default (`io.livekit.*`) with a minimum log level of `info`. Logs can be filtered by level, category, etc. using Xcode console.

- To adjust the log level, call `LiveKitSDK.setLogLevel(_:)`
- To set a custom logger (e.g. to pass to a custom logging system), call `LiveKitSDK.setLogger(_:)`
- To disable logging completely, call `LiveKitSDK.disableLogging()`

All methods must be called before any other logging is done, e.g. in the `App.init()` or `AppDelegate/SceneDelegate`.

Alternatively, you can subclass `OSLogger` and override the `log(...)` method to capture e.g. warning and error logs.

### How to publish camera in 60 FPS?

- Create a `LocalVideoTrack` by calling `LocalVideoTrack.createCameraTrack(options: CameraCaptureOptions(fps: 60))`.
- Publish with `LocalParticipant.publish(videoTrack: track, publishOptions: VideoPublishOptions(encoding: VideoEncoding(maxFps: 60)))`.
Expand Down
8 changes: 4 additions & 4 deletions Sources/LiveKit/Broadcast/BroadcastScreenCapturer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ class BroadcastScreenCapturer: BufferCapturer, @unchecked Sendable {

private func createReceiver() -> Bool {
guard let socketPath = BroadcastBundleInfo.socketPath else {
logger.error("Bundle settings improperly configured for screen capture")
log("Bundle settings improperly configured for screen capture", .error)
return false
}
Task { [weak self] in
guard let self else { return }
do {
let receiver = try await BroadcastReceiver(socketPath: socketPath)
logger.debug("Broadcast receiver connected")
log("Broadcast receiver connected", .debug)
self.receiver = receiver

if appAudio {
Expand All @@ -70,9 +70,9 @@ class BroadcastScreenCapturer: BufferCapturer, @unchecked Sendable {
case let .audio(buffer): AudioManager.shared.mixer.capture(appAudio: buffer)
}
}
logger.debug("Broadcast receiver closed")
log("Broadcast receiver closed", .debug)
} catch {
logger.error("Broadcast receiver error: \(error)")
log("Broadcast receiver error: \(error)", .error)
}
_ = try? await stopCapture()
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/LiveKit/Broadcast/IPC/BroadcastReceiver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ final class BroadcastReceiver: Sendable {
channel.close()
}

struct AsyncSampleSequence: AsyncSequence, AsyncIteratorProtocol {
struct AsyncSampleSequence: AsyncSequence, AsyncIteratorProtocol, Loggable {
fileprivate let upstream: IPCChannel.AsyncMessageSequence<BroadcastIPCHeader>

private let imageCodec = BroadcastImageCodec()
Expand All @@ -66,7 +66,7 @@ final class BroadcastReceiver: Sendable {
return IncomingSample.audio(audioBuffer)

default:
logger.debug("Unhandled incoming message: \(header)")
log("Unhandled incoming message: \(header)", .debug)
continue
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/LiveKit/Broadcast/IPC/BroadcastUploader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import CoreMedia
import ReplayKit

/// Uploads broadcast samples to another process.
final class BroadcastUploader: Sendable {
final class BroadcastUploader: Sendable, Loggable {
private let channel: IPCChannel

private let imageCodec = BroadcastImageCodec()
Expand Down Expand Up @@ -98,7 +98,7 @@ final class BroadcastUploader: Sendable {
case let .wantsAudio(wantsAudio):
state.mutate { $0.shouldUploadAudio = wantsAudio }
default:
logger.debug("Unhandled incoming message: \(header)")
log("Unhandled incoming message: \(header)", .debug)
continue
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/LiveKit/Broadcast/IPC/IPCProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Foundation
import Network

/// A simple framing protocol suitable for inter-process communication.
final class IPCProtocol: NWProtocolFramerImplementation {
final class IPCProtocol: NWProtocolFramerImplementation, Loggable {
static let definition = NWProtocolFramer.Definition(implementation: IPCProtocol.self)
static var label: String { "LKIPCProtocol" }

Expand All @@ -41,7 +41,7 @@ final class IPCProtocol: NWProtocolFramerImplementation {
do {
try framer.writeOutputNoCopy(length: messageLength)
} catch {
logger.error("\(Self.label) error: \(error)")
log("\(Self.label) error: \(error)", .error)
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/LiveKit/Broadcast/IPC/SocketPath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@
import Network

/// A UNIX domain path valid on this system.
struct SocketPath {
struct SocketPath: Loggable {
let path: String

/// Creates a socket path or returns nil if the given path string is not valid.
init?(_ path: String) {
guard Self.isValid(path) else {
logger.error("Invalid socket path: \(path)")
Self.log("Invalid socket path: \(path)", .error)
return nil
}
self.path = path
Expand Down
38 changes: 12 additions & 26 deletions Sources/LiveKit/Broadcast/LKSampleHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#if canImport(ReplayKit)
import ReplayKit
#endif
internal import Logging

import Combine
import OSLog
Expand All @@ -33,41 +32,42 @@ open class LKSampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
private var uploader: BroadcastUploader?
private var cancellable = Set<AnyCancellable>()

private lazy var log: OSLog = enableLogging ? OSLog(subsystem: "io.livekit.sdk", category: "LKSampleHandler") : .disabled

override public init() {
super.init()
bootstrapLogging()
logger.info("LKSampleHandler created")
os_log("LKSampleHandler created", log: log, type: .info)

createUploader()

DarwinNotificationCenter.shared
.publisher(for: .broadcastRequestStop)
.sink { [weak self] _ in
logger.info("Received stop request")
os_log("Received stop request", log: self?.log ?? .disabled, type: .info)
self?.finishBroadcastWithoutError()
}
.store(in: &cancellable)
}

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.
logger.info("Broadcast started")
os_log("Broadcast started", log: log, type: .info)
DarwinNotificationCenter.shared.postNotification(.broadcastStarted)
}

override public func broadcastPaused() {
// User has requested to pause the broadcast. Samples will stop being delivered.
logger.info("Broadcast paused")
os_log("Broadcast paused", log: log, type: .info)
}

override public func broadcastResumed() {
// User has requested to resume the broadcast. Samples delivery will resume.
logger.info("Broadcast resumed")
os_log("Broadcast resumed", log: log, type: .info)
}

override public func broadcastFinished() {
// User has requested to finish the broadcast.
logger.info("Broadcast finished")
os_log("Broadcast finished", log: log, type: .info)
DarwinNotificationCenter.shared.postNotification(.broadcastStopped)
uploader?.close()
}
Expand All @@ -77,7 +77,7 @@ open class LKSampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
try uploader?.upload(sampleBuffer, with: type)
} catch {
guard case .connectionClosed = error as? BroadcastUploader.Error else {
logger.error("Failed to send sample: \(error)")
os_log("Failed to send sample: %{public}@", log: log, type: .error, String(describing: error))
return
}
finishBroadcastWithoutError()
Expand Down Expand Up @@ -112,15 +112,15 @@ open class LKSampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {

private func createUploader() {
guard let socketPath = BroadcastBundleInfo.socketPath else {
logger.error("Bundle settings improperly configured for screen capture")
os_log("Bundle settings improperly configured for screen capture", log: log, type: .error)
return
}
Task {
do {
uploader = try await BroadcastUploader(socketPath: socketPath)
logger.info("Uploader connected")
os_log("Uploader connected", log: log, type: .info)
} catch {
logger.error("Uploader connection failed: \(error)")
os_log("Uploader connection failed: %{public}@", log: log, type: .error, String(describing: error))
connectionDidClose(error: error)
}
}
Expand All @@ -140,20 +140,6 @@ open class LKSampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
/// - SeeAlso: ``enableLogging``
///
open var verboseLogging: Bool { false }

private func bootstrapLogging() {
guard enableLogging else { return }

let bundleIdentifier = Bundle.main.bundleIdentifier ?? ""
let logger = OSLog(subsystem: bundleIdentifier, category: "LKSampleHandler")
let logLevel = verboseLogging ? Logger.Level.trace : .info

LoggingSystem.bootstrap { _ in
var logHandler = OSLogHandler(logger)
logHandler.logLevel = logLevel
return logHandler
}
}
}

#endif
109 changes: 0 additions & 109 deletions Sources/LiveKit/Broadcast/Support/OSLogHandler.swift

This file was deleted.

Loading
Loading