diff --git a/Sources/LiveKit/SwiftUI/SwiftUIVideoView.swift b/Sources/LiveKit/SwiftUI/SwiftUIVideoView.swift
index 1a41fe33f..ef5e94693 100644
--- a/Sources/LiveKit/SwiftUI/SwiftUIVideoView.swift
+++ b/Sources/LiveKit/SwiftUI/SwiftUIVideoView.swift
@@ -29,6 +29,7 @@ public struct SwiftUIVideoView: NativeViewRepresentable {
     let renderMode: VideoView.RenderMode
     let rotationOverride: VideoRotation?
     let pinchToZoomOptions: VideoView.PinchToZoomOptions
+    let isPaused: Bool
     let isDebugMode: Bool
 
     let videoViewDelegateReceiver: VideoViewDelegateReceiver
@@ -40,6 +41,7 @@ public struct SwiftUIVideoView: NativeViewRepresentable {
                 rotationOverride: VideoRotation? = nil,
                 pinchToZoomOptions: VideoView.PinchToZoomOptions = [],
                 isDebugMode: Bool = false,
+                isPaused: Bool = false,
                 isRendering: Binding<Bool>? = nil)
     {
         self.track = track
@@ -48,6 +50,7 @@ public struct SwiftUIVideoView: NativeViewRepresentable {
         self.renderMode = renderMode
         self.rotationOverride = rotationOverride
         self.isDebugMode = isDebugMode
+        self.isPaused = isPaused
         self.pinchToZoomOptions = pinchToZoomOptions
 
         videoViewDelegateReceiver = VideoViewDelegateReceiver(isRendering: isRendering)
@@ -66,6 +69,7 @@ public struct SwiftUIVideoView: NativeViewRepresentable {
         videoView.renderMode = renderMode
         videoView.rotationOverride = rotationOverride
         videoView.pinchToZoomOptions = pinchToZoomOptions
+        videoView.isPaused = isPaused
         videoView.isDebugMode = isDebugMode
 
         Task.detached { @MainActor in
diff --git a/Sources/LiveKit/Views/VideoView.swift b/Sources/LiveKit/Views/VideoView.swift
index 2e50002e4..e5cad0773 100644
--- a/Sources/LiveKit/Views/VideoView.swift
+++ b/Sources/LiveKit/Views/VideoView.swift
@@ -118,6 +118,14 @@ public class VideoView: NativeView, Loggable {
         get { _state.isEnabled }
         set { _state.mutate { $0.isEnabled = newValue } }
     }
+    
+    @objc
+    public var isPaused: Bool {
+        get { _state.isPaused }
+        set { _state.mutate { $0.isPaused = newValue } }
+    }
+    
+    private var pausedVideoFrame: VideoFrame?
 
     @objc
     override public var isHidden: Bool {
@@ -190,6 +198,7 @@ public class VideoView: NativeView, Loggable {
     struct State {
         weak var track: Track?
         var isEnabled: Bool = true
+        var isPaused: Bool = false
         var isHidden: Bool = false
 
         // layout related
@@ -221,9 +230,11 @@ public class VideoView: NativeView, Loggable {
         var captureOptions: VideoCaptureOptions? = nil
         var captureDevice: AVCaptureDevice? = nil
 
+        var lastRenderedFrame: VideoFrame?
+        
         // whether if current state should be rendering
         var shouldRender: Bool {
-            track != nil && isEnabled && !isHidden
+            track != nil && isEnabled && !isHidden && !isPaused
         }
     }
 
@@ -284,15 +295,18 @@ public class VideoView: NativeView, Loggable {
                         // clean up old track
                         if let track = oldState.track as? VideoTrack {
                             track.remove(videoRenderer: self)
-
-                            if let r = self._primaryRenderer {
-                                r.removeFromSuperview()
-                                self._primaryRenderer = nil
-                            }
-
-                            if let r = self._secondaryRenderer {
-                                r.removeFromSuperview()
-                                self._secondaryRenderer = nil
+                            
+                            // avoid destroying and re-creating the renderers when the video is paused
+                            if !newState.isPaused {
+                                if let r = self._primaryRenderer {
+                                    r.removeFromSuperview()
+                                    self._primaryRenderer = nil
+                                }
+                                
+                                if let r = self._secondaryRenderer {
+                                    r.removeFromSuperview()
+                                    self._secondaryRenderer = nil
+                                }
                             }
                         }
 
@@ -305,7 +319,7 @@ public class VideoView: NativeView, Loggable {
                             track.add(videoRenderer: self)
 
                             if let frame = track._state.videoFrame {
-                                self.log("rendering cached frame tack: \(String(describing: track._state.sid))")
+                                self.log("rendering cached frame track: \(String(describing: track._state.sid))")
                                 nr.renderFrame(frame.toRTCType())
                                 self.setNeedsLayout()
                             }
@@ -313,7 +327,14 @@ public class VideoView: NativeView, Loggable {
                     }
 
                     if renderModeDidUpdate, !didReCreateNativeRenderer {
-                        self.recreatePrimaryRenderer(for: newState.renderMode)
+                        let nr = self.recreatePrimaryRenderer(for: newState.renderMode)
+                        
+                        // re-render last rendered frame before pause
+                        if let frame = newState.lastRenderedFrame, newState.isPaused {
+                            self.log("rendering last rendered frame before pause")
+                            nr.renderFrame(frame.toRTCType())
+                            self.setNeedsLayout()
+                        }
                     }
                 }
             }
@@ -625,6 +646,7 @@ extension VideoView: VideoRenderer {
             $0.didRenderFirstFrame = true
             $0.isRendering = true
             $0.renderDate = Date()
+            $0.lastRenderedFrame = frame
 
             // Update renderTarget if capture position changes
             if let oldCaptureDevicePosition, oldCaptureDevicePosition != captureDevice?.position {