diff --git a/Sources/LiveKit/Participant/RemoteParticipant.swift b/Sources/LiveKit/Participant/RemoteParticipant.swift index 95384eab7..245d0d625 100644 --- a/Sources/LiveKit/Participant/RemoteParticipant.swift +++ b/Sources/LiveKit/Participant/RemoteParticipant.swift @@ -95,9 +95,15 @@ public class RemoteParticipant: Participant { switch rtcTrack.kind { case "audio": - track = RemoteAudioTrack(name: publication.name, source: publication.source, track: rtcTrack) + track = RemoteAudioTrack(name: publication.name, + source: publication.source, + track: rtcTrack, + reportStatistics: room._state.options.reportRemoteTrackStatistics) case "video": - track = RemoteVideoTrack(name: publication.name, source: publication.source, track: rtcTrack) + track = RemoteVideoTrack(name: publication.name, + source: publication.source, + track: rtcTrack, + reportStatistics: room._state.options.reportRemoteTrackStatistics) default: let error = TrackError.type(message: "Unsupported type: \(rtcTrack.kind.description)") delegates.notify(label: { "participant.didFailToSubscribe trackSid: \(sid)" }) { diff --git a/Sources/LiveKit/Track/Capturers/BufferCapturer.swift b/Sources/LiveKit/Track/Capturers/BufferCapturer.swift index f69851927..54390f9fd 100644 --- a/Sources/LiveKit/Track/Capturers/BufferCapturer.swift +++ b/Sources/LiveKit/Track/Capturers/BufferCapturer.swift @@ -85,15 +85,15 @@ public extension LocalVideoTrack { /// Creates a track that can directly capture `CVPixelBuffer` or `CMSampleBuffer` for convienience static func createBufferTrack(name: String = Track.screenShareVideoName, source: VideoTrack.Source = .screenShareVideo, - options: BufferCaptureOptions = BufferCaptureOptions()) -> LocalVideoTrack + options: BufferCaptureOptions = BufferCaptureOptions(), + reportStatistics: Bool = false) -> LocalVideoTrack { let videoSource = Engine.createVideoSource(forScreenShare: source == .screenShareVideo) let capturer = BufferCapturer(delegate: videoSource, options: options) - return LocalVideoTrack( - name: name, - source: source, - capturer: capturer, - videoSource: videoSource - ) + return LocalVideoTrack(name: name, + source: source, + capturer: capturer, + videoSource: videoSource, + reportStatistics: reportStatistics) } } diff --git a/Sources/LiveKit/Track/Capturers/CameraCapturer.swift b/Sources/LiveKit/Track/Capturers/CameraCapturer.swift index b6209a4b5..5f93263df 100644 --- a/Sources/LiveKit/Track/Capturers/CameraCapturer.swift +++ b/Sources/LiveKit/Track/Capturers/CameraCapturer.swift @@ -243,16 +243,16 @@ public extension LocalVideoTrack { @objc static func createCameraTrack(name: String? = nil, - options: CameraCaptureOptions? = nil) -> LocalVideoTrack + options: CameraCaptureOptions? = nil, + reportStatistics: Bool = false) -> LocalVideoTrack { let videoSource = Engine.createVideoSource(forScreenShare: false) let capturer = CameraCapturer(delegate: videoSource, options: options ?? CameraCaptureOptions()) - return LocalVideoTrack( - name: name ?? Track.cameraName, - source: .camera, - capturer: capturer, - videoSource: videoSource - ) + return LocalVideoTrack(name: name ?? Track.cameraName, + source: .camera, + capturer: capturer, + videoSource: videoSource, + reportStatistics: reportStatistics) } } diff --git a/Sources/LiveKit/Track/Capturers/InAppCapturer.swift b/Sources/LiveKit/Track/Capturers/InAppCapturer.swift index ba2192e25..3e86ffd0d 100644 --- a/Sources/LiveKit/Track/Capturers/InAppCapturer.swift +++ b/Sources/LiveKit/Track/Capturers/InAppCapturer.swift @@ -79,15 +79,15 @@ public extension LocalVideoTrack { /// Creates a track that captures in-app screen only (due to limitation of ReplayKit) @available(macOS 11.0, iOS 11.0, *) static func createInAppScreenShareTrack(name: String = Track.screenShareVideoName, - options: ScreenShareCaptureOptions = ScreenShareCaptureOptions()) -> LocalVideoTrack + options: ScreenShareCaptureOptions = ScreenShareCaptureOptions(), + reportStatistics: Bool = false) -> LocalVideoTrack { let videoSource = Engine.createVideoSource(forScreenShare: true) let capturer = InAppScreenCapturer(delegate: videoSource, options: options) - return LocalVideoTrack( - name: name, - source: .screenShareVideo, - capturer: capturer, - videoSource: videoSource - ) + return LocalVideoTrack(name: name, + source: .screenShareVideo, + capturer: capturer, + videoSource: videoSource, + reportStatistics: reportStatistics) } } diff --git a/Sources/LiveKit/Track/Capturers/MacOSScreenCapturer.swift b/Sources/LiveKit/Track/Capturers/MacOSScreenCapturer.swift index 619a60884..ad49dfc0d 100644 --- a/Sources/LiveKit/Track/Capturers/MacOSScreenCapturer.swift +++ b/Sources/LiveKit/Track/Capturers/MacOSScreenCapturer.swift @@ -264,16 +264,16 @@ import Foundation @objc static func createMacOSScreenShareTrack(name: String = Track.screenShareVideoName, source: MacOSScreenCaptureSource, - options: ScreenShareCaptureOptions = ScreenShareCaptureOptions()) -> LocalVideoTrack + options: ScreenShareCaptureOptions = ScreenShareCaptureOptions(), + reportStatistics: Bool = false) -> LocalVideoTrack { let videoSource = Engine.createVideoSource(forScreenShare: true) let capturer = MacOSScreenCapturer(delegate: videoSource, captureSource: source, options: options) - return LocalVideoTrack( - name: name, - source: .screenShareVideo, - capturer: capturer, - videoSource: videoSource - ) + return LocalVideoTrack(name: name, + source: .screenShareVideo, + capturer: capturer, + videoSource: videoSource, + reportStatistics: reportStatistics) } } diff --git a/Sources/LiveKit/Track/Local/LocalAudioTrack.swift b/Sources/LiveKit/Track/Local/LocalAudioTrack.swift index 394a2315b..0a2790f0b 100644 --- a/Sources/LiveKit/Track/Local/LocalAudioTrack.swift +++ b/Sources/LiveKit/Track/Local/LocalAudioTrack.swift @@ -22,12 +22,14 @@ import Foundation public class LocalAudioTrack: Track, LocalTrack, AudioTrack { init(name: String, source: Track.Source, - track: LKRTCMediaStreamTrack) + track: LKRTCMediaStreamTrack, + reportStatistics: Bool) { super.init(name: name, kind: .audio, source: source, - track: track) + track: track, + reportStatistics: reportStatistics) } public static func createTrack(name: String = Track.microphoneName, @@ -54,7 +56,8 @@ public class LocalAudioTrack: Track, LocalTrack, AudioTrack { return LocalAudioTrack(name: name, source: .microphone, - track: rtcTrack) + track: rtcTrack, + reportStatistics: true) } @discardableResult diff --git a/Sources/LiveKit/Track/Local/LocalVideoTrack.swift b/Sources/LiveKit/Track/Local/LocalVideoTrack.swift index 7c7cccb73..bf9d28388 100644 --- a/Sources/LiveKit/Track/Local/LocalVideoTrack.swift +++ b/Sources/LiveKit/Track/Local/LocalVideoTrack.swift @@ -28,7 +28,8 @@ public class LocalVideoTrack: Track, LocalTrack, VideoTrack { init(name: String, source: Track.Source, capturer: VideoCapturer, - videoSource: LKRTCVideoSource) + videoSource: LKRTCVideoSource, + reportStatistics: Bool) { let rtcTrack = Engine.createVideoTrack(source: videoSource) rtcTrack.isEnabled = true @@ -39,7 +40,8 @@ public class LocalVideoTrack: Track, LocalTrack, VideoTrack { super.init(name: name, kind: .video, source: source, - track: rtcTrack) + track: rtcTrack, + reportStatistics: reportStatistics) } public func mute() async throws { @@ -83,6 +85,7 @@ public extension LocalVideoTrack { LocalVideoTrack(name: name, source: source, capturer: capturer, - videoSource: videoSource) + videoSource: videoSource, + reportStatistics: _state.reportStatistics) } } diff --git a/Sources/LiveKit/Track/Remote/RemoteAudioTrack.swift b/Sources/LiveKit/Track/Remote/RemoteAudioTrack.swift index 88707b1a7..edb226927 100644 --- a/Sources/LiveKit/Track/Remote/RemoteAudioTrack.swift +++ b/Sources/LiveKit/Track/Remote/RemoteAudioTrack.swift @@ -34,12 +34,14 @@ public class RemoteAudioTrack: Track, RemoteTrack, AudioTrack { init(name: String, source: Track.Source, - track: LKRTCMediaStreamTrack) + track: LKRTCMediaStreamTrack, + reportStatistics: Bool) { super.init(name: name, kind: .audio, source: source, - track: track) + track: track, + reportStatistics: reportStatistics) } public func add(audioRenderer: AudioRenderer) { diff --git a/Sources/LiveKit/Track/Remote/RemoteVideoTrack.swift b/Sources/LiveKit/Track/Remote/RemoteVideoTrack.swift index 8a834eb9c..58f128477 100644 --- a/Sources/LiveKit/Track/Remote/RemoteVideoTrack.swift +++ b/Sources/LiveKit/Track/Remote/RemoteVideoTrack.swift @@ -22,12 +22,14 @@ import Foundation public class RemoteVideoTrack: Track, RemoteTrack, VideoTrack { init(name: String, source: Track.Source, - track: LKRTCMediaStreamTrack) + track: LKRTCMediaStreamTrack, + reportStatistics: Bool) { super.init(name: name, kind: .video, source: source, - track: track) + track: track, + reportStatistics: reportStatistics) } } diff --git a/Sources/LiveKit/Track/Track.swift b/Sources/LiveKit/Track/Track.swift index 11e151d4f..0f8be0790 100644 --- a/Sources/LiveKit/Track/Track.swift +++ b/Sources/LiveKit/Track/Track.swift @@ -138,12 +138,14 @@ public class Track: NSObject, Loggable { init(name: String, kind: Kind, source: Source, - track: LKRTCMediaStreamTrack) + track: LKRTCMediaStreamTrack, + reportStatistics: Bool) { _state = StateSync(State( name: name, kind: kind, - source: source + source: source, + reportStatistics: reportStatistics )) mediaTrack = track @@ -173,6 +175,8 @@ public class Track: NSObject, Loggable { statisticsTimer.handler = { [weak self] in self?.onStatsTimer() } + + resumeOrSuspendStatisticsTimer() } deinit { diff --git a/Sources/LiveKit/Types/Options/RoomOptions.swift b/Sources/LiveKit/Types/Options/RoomOptions.swift index f10e0f943..d40d62d4b 100644 --- a/Sources/LiveKit/Types/Options/RoomOptions.swift +++ b/Sources/LiveKit/Types/Options/RoomOptions.swift @@ -66,6 +66,9 @@ public class RoomOptions: NSObject { /// E2EE Options public let e2eeOptions: E2EEOptions? + @objc + public let reportRemoteTrackStatistics: Bool + public init(defaultCameraCaptureOptions: CameraCaptureOptions = CameraCaptureOptions(), defaultScreenShareCaptureOptions: ScreenShareCaptureOptions = ScreenShareCaptureOptions(), defaultAudioCaptureOptions: AudioCaptureOptions = AudioCaptureOptions(), @@ -76,7 +79,8 @@ public class RoomOptions: NSObject { dynacast: Bool = false, stopLocalTrackOnUnpublish: Bool = true, suspendLocalVideoTracksInBackground: Bool = true, - e2eeOptions: E2EEOptions? = nil) + e2eeOptions: E2EEOptions? = nil, + reportTrackStatistics: Bool = false) { self.defaultCameraCaptureOptions = defaultCameraCaptureOptions self.defaultScreenShareCaptureOptions = defaultScreenShareCaptureOptions @@ -89,6 +93,7 @@ public class RoomOptions: NSObject { self.stopLocalTrackOnUnpublish = stopLocalTrackOnUnpublish self.suspendLocalVideoTracksInBackground = suspendLocalVideoTracksInBackground self.e2eeOptions = e2eeOptions + reportRemoteTrackStatistics = reportTrackStatistics } // MARK: - Equal @@ -104,7 +109,8 @@ public class RoomOptions: NSObject { adaptiveStream == other.adaptiveStream && dynacast == other.dynacast && stopLocalTrackOnUnpublish == other.stopLocalTrackOnUnpublish && - suspendLocalVideoTracksInBackground == other.suspendLocalVideoTracksInBackground + suspendLocalVideoTracksInBackground == other.suspendLocalVideoTracksInBackground && + reportRemoteTrackStatistics == other.reportRemoteTrackStatistics } override public var hash: Int { @@ -119,6 +125,7 @@ public class RoomOptions: NSObject { hasher.combine(dynacast) hasher.combine(stopLocalTrackOnUnpublish) hasher.combine(suspendLocalVideoTracksInBackground) + hasher.combine(reportRemoteTrackStatistics) return hasher.finalize() } }