From 1f3ffd120cffe3f84d39c4b29aa2e0b886ed1b5f Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Tue, 11 Apr 2023 10:51:15 +0700 Subject: [PATCH 1/2] impl --- Sources/LiveKit/Core/SignalClient.swift | 2 +- .../Publications/RemoteTrackPublication.swift | 36 ++++++++++++++++--- Sources/LiveKit/Types/TrackSettings.swift | 13 +++---- Sources/LiveKit/Types/VideoQuality.swift | 2 +- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/Sources/LiveKit/Core/SignalClient.swift b/Sources/LiveKit/Core/SignalClient.swift index 3187b9ecf..7d7d0125c 100644 --- a/Sources/LiveKit/Core/SignalClient.swift +++ b/Sources/LiveKit/Core/SignalClient.swift @@ -522,7 +522,7 @@ internal extension SignalClient { $0.width = UInt32(settings.dimensions.width) $0.height = UInt32(settings.dimensions.height) $0.quality = settings.videoQuality.toPBType() - $0.fps = UInt32(settings.preferredFPS) + $0.fps = UInt32(settings.fps) } } diff --git a/Sources/LiveKit/Publications/RemoteTrackPublication.swift b/Sources/LiveKit/Publications/RemoteTrackPublication.swift index a86f9cc8c..ae0230ede 100644 --- a/Sources/LiveKit/Publications/RemoteTrackPublication.swift +++ b/Sources/LiveKit/Publications/RemoteTrackPublication.swift @@ -36,7 +36,7 @@ public class RemoteTrackPublication: TrackPublication { // MARK: - Private // user's preference to subscribe or not - private var preferSubscribed: Bool? + private var preferSubscribed: Bool private var metadataMuted: Bool = false // adaptiveStream @@ -47,6 +47,8 @@ public class RemoteTrackPublication: TrackPublication { track: Track? = nil, participant: Participant) { + preferSubscribed = participant.room.engine._state.connectOptions.autoSubscribe + super.init(info: info, track: track, participant: participant) @@ -115,11 +117,29 @@ public class RemoteTrackPublication: TrackPublication { public func set(preferredFPS newValue: UInt) -> Promise { // no-op if already the desired value let trackSettings = _state.trackSettings - guard trackSettings.preferredFPS != newValue else { return Promise(()) } + guard trackSettings.fps != newValue else { return Promise(()) } + + guard userCanModifyTrackSettings else { return Promise(TrackError.state(message: "adaptiveStream must be disabled and track must be subscribed")) } + + let settings = trackSettings.copyWith(fps: newValue) + // attempt to set the new settings + return send(trackSettings: settings) + } + + /// For tracks that support simulcasting, adjust subscribed quality. + /// + /// This indicates the highest quality the client can accept. if network + /// bandwidth does not allow, server will automatically reduce quality to + /// optimize for uninterrupted video. + @discardableResult + public func set(preferredVideoQuality newValue: VideoQuality) -> Promise { + // no-op if already the desired value + let trackSettings = _state.trackSettings + guard trackSettings.videoQuality != newValue else { return Promise(()) } guard userCanModifyTrackSettings else { return Promise(TrackError.state(message: "adaptiveStream must be disabled and track must be subscribed")) } - let settings = trackSettings.copyWith(preferredFPS: newValue) + let settings = trackSettings.copyWith(videoQuality: newValue) // attempt to set the new settings return send(trackSettings: settings) } @@ -184,7 +204,15 @@ private extension RemoteTrackPublication { var userCanModifyTrackSettings: Bool { // adaptiveStream must be disabled and must be subscribed - !isAdaptiveStreamEnabled && subscribed + if kind == .video && isAdaptiveStreamEnabled { + log("Adaptive stream is enabled, cannot change video track settings", .warning) + return false + } + if !(preferSubscribed || subscribed) { + log("Cannot update track settings when not subscribed", .warning) + return false + } + return true } } diff --git a/Sources/LiveKit/Types/TrackSettings.swift b/Sources/LiveKit/Types/TrackSettings.swift index 3c2691b14..6afb217e2 100644 --- a/Sources/LiveKit/Types/TrackSettings.swift +++ b/Sources/LiveKit/Types/TrackSettings.swift @@ -21,26 +21,27 @@ internal struct TrackSettings: Equatable { let enabled: Bool let dimensions: Dimensions let videoQuality: VideoQuality - let preferredFPS: UInt + let fps: UInt init(enabled: Bool = false, dimensions: Dimensions = .zero, - videoQuality: VideoQuality = .low, - preferredFPS: UInt = 0) { + videoQuality: VideoQuality = .high, + fps: UInt = 0) { self.enabled = enabled self.dimensions = dimensions self.videoQuality = videoQuality - self.preferredFPS = preferredFPS + self.fps = fps } func copyWith(enabled: Bool? = nil, dimensions: Dimensions? = nil, videoQuality: VideoQuality? = nil, - preferredFPS: UInt? = nil) -> TrackSettings { + fps: UInt? = nil) -> TrackSettings { + TrackSettings(enabled: enabled ?? self.enabled, dimensions: dimensions ?? self.dimensions, videoQuality: videoQuality ?? self.videoQuality, - preferredFPS: preferredFPS ?? self.preferredFPS) + fps: fps ?? self.fps) } } diff --git a/Sources/LiveKit/Types/VideoQuality.swift b/Sources/LiveKit/Types/VideoQuality.swift index 3aa0ce635..0f6f3ca6b 100644 --- a/Sources/LiveKit/Types/VideoQuality.swift +++ b/Sources/LiveKit/Types/VideoQuality.swift @@ -16,7 +16,7 @@ import Foundation -internal enum VideoQuality { +public enum VideoQuality { case low case medium case high From 188ecf69fa85a92619df38dd69b81c58c013ca29 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Sun, 16 Apr 2023 22:15:44 +0700 Subject: [PATCH 2/2] preferredDimensions instead of video quality --- .../LiveKit/Publications/RemoteTrackPublication.swift | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Sources/LiveKit/Publications/RemoteTrackPublication.swift b/Sources/LiveKit/Publications/RemoteTrackPublication.swift index ae0230ede..bac707092 100644 --- a/Sources/LiveKit/Publications/RemoteTrackPublication.swift +++ b/Sources/LiveKit/Publications/RemoteTrackPublication.swift @@ -126,20 +126,15 @@ public class RemoteTrackPublication: TrackPublication { return send(trackSettings: settings) } - /// For tracks that support simulcasting, adjust subscribed quality. - /// - /// This indicates the highest quality the client can accept. if network - /// bandwidth does not allow, server will automatically reduce quality to - /// optimize for uninterrupted video. @discardableResult - public func set(preferredVideoQuality newValue: VideoQuality) -> Promise { + public func set(preferredDimensions newValue: Dimensions) -> Promise { // no-op if already the desired value let trackSettings = _state.trackSettings - guard trackSettings.videoQuality != newValue else { return Promise(()) } + guard trackSettings.dimensions != newValue else { return Promise(()) } guard userCanModifyTrackSettings else { return Promise(TrackError.state(message: "adaptiveStream must be disabled and track must be subscribed")) } - let settings = trackSettings.copyWith(videoQuality: newValue) + let settings = trackSettings.copyWith(dimensions: newValue) // attempt to set the new settings return send(trackSettings: settings) }