diff --git a/src/app/commoncomponents/LocalVideo.qml b/src/app/commoncomponents/LocalVideo.qml
index 5bb34305dc40142cbdf83163a6cde27a36ec8e0d..3b7c43822f626bd285339e8153874ea87e3cb4de 100644
--- a/src/app/commoncomponents/LocalVideo.qml
+++ b/src/app/commoncomponents/LocalVideo.qml
@@ -35,12 +35,6 @@ VideoView {
             rendererId = VideoDevices.startDevice(id, force)
         }
     }
-
-    onVisibleChanged: {
-        rendererId = rendererId ? rendererId : VideoDevices.getDefaultDevice()
-        const id = visible ? rendererId : ""
-        startWithId(id)
-    }
 }
 
 
diff --git a/src/app/mainview/components/InitialCallPage.qml b/src/app/mainview/components/InitialCallPage.qml
index f27f38cec2648492cdbaaf9e7fae22ff3d4886b2..c0f63732b48042056ad84e69875d160a022e7daf 100644
--- a/src/app/mainview/components/InitialCallPage.qml
+++ b/src/app/mainview/components/InitialCallPage.qml
@@ -40,10 +40,40 @@ Rectangle {
     color: "black"
 
     LocalVideo {
+        id: previewRenderer
         anchors.centerIn: parent
         anchors.fill: parent
-        visible: !root.isAudioOnly && CurrentAccount.videoEnabled_Video && VideoDevices.listSize !== 0
+        visible: !root.isAudioOnly &&
+                 CurrentAccount.videoEnabled_Video &&
+                 VideoDevices.listSize !== 0 &&
+                 ((callStatus >= Call.Status.INCOMING_RINGING
+                   && callStatus <= Call.Status.SEARCHING)
+                  || callStatus === Call.Status.CONNECTED)
         opacity: 0.5
+
+        // HACK: this is a workaround to the preview video starting
+        // and stopping a few times. The root cause should be investigated ASAP.
+        Timer {
+            id: controlPreview
+            property bool startVideo
+            interval: 1000;
+            running: false;
+            repeat: false
+            onTriggered: {
+                var rendId = visible && start ? VideoDevices.getDefaultDevice() : ""
+                previewRenderer.startWithId(rendId)
+            }
+        }
+        onVisibleChanged: {
+            if (visible) {
+                controlPreview.startVideo = true
+                controlPreview.interval = 1000
+            } else {
+                controlPreview.startVideo = false
+                controlPreview.interval = 0
+            }
+            controlPreview.start()
+        }
     }
 
     ListModel {
diff --git a/src/app/mainview/components/OngoingCallPage.qml b/src/app/mainview/components/OngoingCallPage.qml
index d57a5d983df4e2ed96c4c7c4720ea27e4b2caeb4..546d33c74793cc72b64cb6f2bcbbef675435a461 100644
--- a/src/app/mainview/components/OngoingCallPage.qml
+++ b/src/app/mainview/components/OngoingCallPage.qml
@@ -196,14 +196,35 @@ Rectangle {
             LocalVideo {
                 id: previewRenderer
 
-                visible: false
-                rendererId: ""
-
                 height: width * invAspectRatio
                 width: Math.max(callPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
                 x: callPageMainRect.width - previewRenderer.width - previewMargin
                 y: previewMarginYTop
 
+                // HACK: this is a workaround to the preview video starting
+                // and stopping a few times. The root cause should be investigated ASAP.
+                Timer {
+                    id: controlPreview
+                    property bool startVideo
+                    interval: 1000
+                    running: false
+                    repeat: false
+                    onTriggered: {
+                        var rendId = visible && start ? root.callPreviewId : ""
+                        previewRenderer.startWithId(rendId)
+                    }
+                }
+                onVisibleChanged: {
+                    if (visible) {
+                        controlPreview.startVideo = true
+                        controlPreview.interval = 1000
+                    } else {
+                        controlPreview.startVideo = false
+                        controlPreview.interval = 0
+                    }
+                    controlPreview.start()
+                }
+
                 states: [
                     State {
                         name: "geoChanging"
@@ -286,13 +307,6 @@ Rectangle {
 
                     function onUpdateOverlay(isPaused, isAudioOnly, isAudioMuted,
                                              isSIP, isGrid, previewId) {
-                        if (previewId != "") {
-                            if (root.callPreviewId != previewId)
-                                VideoDevices.stopDevice(root.callPreviewId, true)
-                            VideoDevices.startDevice(previewId)
-                        } else {
-                            VideoDevices.stopDevice(root.callPreviewId, true)
-                        }
                         root.callPreviewId = previewId
                         callOverlay.showOnHoldImage(isPaused)
                         root.isAudioOnly = isAudioOnly
diff --git a/src/app/mainview/components/RecordBox.qml b/src/app/mainview/components/RecordBox.qml
index 31d62a136607e5ce4929472fe7e7773f0ffa6477..e6392ab80397f6129666fe610a09d875f3f8372c 100644
--- a/src/app/mainview/components/RecordBox.qml
+++ b/src/app/mainview/components/RecordBox.qml
@@ -66,7 +66,7 @@ Popup {
 
     function closeRecorder() {
         if (isVideo) {
-            VideoDevices.stopDevice(previewWidget.deviceId)
+            localVideo.startWithId("")
         }
         if (!root.isPhoto)
             stopRecording()
diff --git a/src/app/settingsview/components/VideoSettings.qml b/src/app/settingsview/components/VideoSettings.qml
index 2a859398620019003778b6bfeed1ffea20f2a95c..26aaa618970032a39eab9b45443c997e8c46a5b2 100644
--- a/src/app/settingsview/components/VideoSettings.qml
+++ b/src/app/settingsview/components/VideoSettings.qml
@@ -40,8 +40,7 @@ ColumnLayout {
         if (!visible) {
             return
         }
-        const deviceId = VideoDevices.getDefaultDevice()
-        previewWidget.startWithId(deviceId, force)
+        previewWidget.startWithId(VideoDevices.getDefaultDevice(), force)
     }
 
     onVisibleChanged: {
@@ -50,7 +49,7 @@ ColumnLayout {
             if (previewWidget.visible)
                 startPreviewing(true)
         } else {
-            VideoDevices.stopDevice(previewWidget.deviceId)
+            previewWidget.startWithId("")
         }
     }
 
@@ -138,7 +137,7 @@ ColumnLayout {
 
         onActivated: {
             // TODO: start and stop preview logic in here should be in LRC
-            VideoDevices.stopDevice(previewWidget.deviceId)
+            previewWidget.startWithId("")
             VideoDevices.setDefaultDevice(
                         filteredDevicesModel.mapToSource(modelIndex))
             startPreviewing()