@@ -31,13 +31,21 @@ typealias PlatformColor = NSColor
3131
3232struct ContentView : View {
3333 @State private var mock = MockVideoSource ( )
34+ @Environment ( \. displayScale) private var displayScale
3435
3536 var body : some View {
3637 VStack ( spacing: 20 ) {
3738 Text ( " LiveKitSDK: v \( LiveKitSDK . version) " )
38- SwiftUIVideoView ( mock. track, renderMode: . sampleBuffer)
39- . clipShape ( RoundedRectangle ( cornerRadius: 12 ) )
40- . frame ( minWidth: 100 , minHeight: 100 )
39+ GeometryReader { geometry in
40+ SwiftUIVideoView ( mock. track, renderMode: . sampleBuffer)
41+ . clipShape ( RoundedRectangle ( cornerRadius: 12 ) )
42+ . onChange ( of: geometry. size, initial: true ) { _, newSize in
43+ mock. setBufferSize ( CGSize (
44+ width: newSize. width * displayScale,
45+ height: newSize. height * displayScale
46+ ) )
47+ }
48+ }
4149 }
4250 . padding ( )
4351 }
@@ -50,7 +58,13 @@ struct ContentView: View {
5058@Observable
5159final class MockVideoSource {
5260 let track : LocalVideoTrack
61+ private var bufferSize : CGSize = . init( width: 640 , height: 360 )
5362 private var timer : Timer ?
63+
64+ func setBufferSize( _ size: CGSize ) {
65+ bufferSize = size
66+ }
67+
5468 private var frameCount : Int = 0
5569 private var currentFps : Int = 0
5670 private var framesThisSecond : Int = 0
@@ -69,7 +83,8 @@ final class MockVideoSource {
6983 timer = Timer . scheduledTimer ( withTimeInterval: 1.0 / fps, repeats: true ) { [ weak self] _ in
7084 guard
7185 let self,
72- let capturer = track. capturer as? BufferCapturer
86+ let capturer = track. capturer as? BufferCapturer ,
87+ bufferSize. width > 0 , bufferSize. height > 0
7388 else { return }
7489
7590 // Update FPS counter every second
@@ -86,7 +101,7 @@ final class MockVideoSource {
86101 let hue = CGFloat ( frameCount % 150 ) / 150.0
87102 let color = PlatformColor ( hue: hue, saturation: 1.0 , brightness: 0.8 , alpha: 1.0 )
88103
89- guard let buffer = Self . makePixelBuffer ( color: color, frameCount: frameCount, fps: currentFps, size: CGSize ( width : 640 , height : 360 ) )
104+ guard let buffer = Self . makePixelBuffer ( color: color, frameCount: frameCount, fps: currentFps, size: bufferSize )
90105 else { return }
91106
92107 capturer. capture ( buffer)
@@ -132,22 +147,36 @@ final class MockVideoSource {
132147 ctx. setFillColor ( color. cgColor)
133148 ctx. fill ( CGRect ( origin: . zero, size: size) )
134149
135- // Draw frame counter and FPS
136- let text = " Frame: \( frameCount ) | FPS: \( fps ) " as CFString
137- let font = CTFontCreateUIFontForLanguage ( . system, 18 , nil ) !
150+ // Draw frame counter, FPS, and resolution (font size ~5% of height)
151+ let fontSize = max ( 12 , min ( size . width , size . height ) * 0.05 )
152+ let font = CTFontCreateUIFontForLanguage ( . system, fontSize , nil ) !
138153 let attributes : [ CFString : Any ] = [
139154 kCTFontAttributeName: font,
140155 kCTForegroundColorAttributeName: CGColor ( gray: 1.0 , alpha: 1.0 ) ,
141156 ]
142- let attributedString = CFAttributedStringCreate ( nil , text, attributes as CFDictionary ) !
143- let line = CTLineCreateWithAttributedString ( attributedString)
144-
145- // Center the text
146- let textBounds = CTLineGetBoundsWithOptions ( line, [ ] )
147- let x = ( size. width - textBounds. width) / 2
148- let y = ( size. height - textBounds. height) / 2
149- ctx. textPosition = CGPoint ( x: x, y: y)
150- CTLineDraw ( line, ctx)
157+
158+ let line1Text = " Frame: \( frameCount) | FPS: \( fps) " as CFString
159+ let line1Attr = CFAttributedStringCreate ( nil , line1Text, attributes as CFDictionary ) !
160+ let line1 = CTLineCreateWithAttributedString ( line1Attr)
161+
162+ let line2Text = " \( Int ( size. width) ) × \( Int ( size. height) ) " as CFString
163+ let line2Attr = CFAttributedStringCreate ( nil , line2Text, attributes as CFDictionary ) !
164+ let line2 = CTLineCreateWithAttributedString ( line2Attr)
165+
166+ let line1Bounds = CTLineGetBoundsWithOptions ( line1, [ ] )
167+ let line2Bounds = CTLineGetBoundsWithOptions ( line2, [ ] )
168+ let lineSpacing : CGFloat = fontSize * 0.3
169+ let totalHeight = line1Bounds. height + line2Bounds. height + lineSpacing
170+
171+ // Center both lines
172+ let y1 = ( size. height + totalHeight) / 2 - line1Bounds. height
173+ let y2 = y1 - lineSpacing - line2Bounds. height
174+
175+ ctx. textPosition = CGPoint ( x: ( size. width - line1Bounds. width) / 2 , y: y1)
176+ CTLineDraw ( line1, ctx)
177+
178+ ctx. textPosition = CGPoint ( x: ( size. width - line2Bounds. width) / 2 , y: y2)
179+ CTLineDraw ( line2, ctx)
151180
152181 return buffer
153182 }
0 commit comments