diff --git a/src/AppDelegate.h b/src/AppDelegate.h
index a376fab00d0da37f05689ca6bb361380cfb56694..0731f1fde5d4ce4029bef2236a9fe5ffca153c57 100644
--- a/src/AppDelegate.h
+++ b/src/AppDelegate.h
@@ -29,7 +29,6 @@
 - (void) showDialpad;
 - (BOOL) checkForRingAccount;
 - (QVector<QString>) getActiveCalls;
-- (QVector<QString>)getConferenceSubcalls:(QString)confId;
 - (void) disableScreenSleep;
 - (void) restoreScreenSleep;
 
diff --git a/src/AppDelegate.mm b/src/AppDelegate.mm
index b7063adce61803dafe9f08e1c2ea14c4eb114d19..da43658502dc1c2639e7d8098d1eb24b7cf36dbc 100644
--- a/src/AppDelegate.mm
+++ b/src/AppDelegate.mm
@@ -383,10 +383,6 @@ static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNet
     return lrc->activeCalls();
 }
 
--(QVector<QString>)getConferenceSubcalls:(QString)confId {
-    return lrc->getConferenceSubcalls(confId);
-}
-
 -(void)setRingtonePath {
     QStringList accounts = lrc->getAccountModel().getAccountList();
     NSFileManager *fileManager = [NSFileManager defaultManager];
diff --git a/src/CurrentCallVC.mm b/src/CurrentCallVC.mm
index 23983d666eaf01a60fd59c6b5910846a3a6cb525..b7b2933f03fffbe6207d0f1e74c67dea76c774da 100644
--- a/src/CurrentCallVC.mm
+++ b/src/CurrentCallVC.mm
@@ -61,6 +61,7 @@ extern "C" {
     QString convUid_;
     QString callUid_;
     QString confUid_;
+    QString currentRenderer_;
     const lrc::api::account::Info *accountInfo_;
     lrc::api::PluginModel *pluginModel_;
     NSTimer* refreshDurationTimer;
@@ -231,7 +232,7 @@ CVPixelBufferRef pixelBufferPreview;
     if (activeCalls.isEmpty()) {
         return;
     }
-    auto subcalls = [appDelegate getConferenceSubcalls: confId];
+    auto subcalls = callModel->getConferenceSubcalls(confId);
     QString callId;
     if (subcalls.isEmpty()) {
         for(auto subcall: activeCalls) {
@@ -759,7 +760,11 @@ CVPixelBufferRef pixelBufferPreview;
 }
 
 -(void)updateShareButtonAnimation {
-    auto type = mediaModel->getCurrentRenderedDevice(callUid_).type;
+    if (accountInfo_ == nil)
+        return;
+
+    auto* callModel = accountInfo_->callModel.get();
+    auto type = callModel->getCurrentRenderedDevice(callUid_).type;
     if (type == lrc::api::video::DeviceType::DISPLAY || type == lrc::api::video::DeviceType::FILE) {
         [self.shareButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1 duration: 1.5];
         NSString *tooltip = type == lrc::api::video::DeviceType::DISPLAY ? NSLocalizedString(@"Stop screen sharing", @"share button tooltip") : NSLocalizedString(@"Stop file streaming", @"share button tooltip");
@@ -770,6 +775,25 @@ CVPixelBufferRef pixelBufferPreview;
     }
 }
 
+-(void)updateCurrentRendererDeivce {
+    auto* callModel = accountInfo_->callModel.get();
+    auto device = callModel->getCurrentRenderedDevice(callUid_);
+    auto deviceName = device.name;
+    switch (device.type) {
+        case lrc::api::video::DeviceType::DISPLAY:
+            currentRenderer_ = "display://" + deviceName;
+            return;
+        case lrc::api::video::DeviceType::FILE:
+            currentRenderer_ = "file://" + deviceName;
+            return;
+        case lrc::api::video::DeviceType::CAMERA:
+            currentRenderer_ = "camera://" + deviceName;
+            return;
+        default:
+            break;
+    }
+}
+
 -(void) connectRenderer
 {
     QObject::disconnect(renderConnections.frameUpdated);
@@ -779,7 +803,9 @@ CVPixelBufferRef pixelBufferPreview;
     QObject::connect(mediaModel,
                      &lrc::api::AVModel::rendererStarted,
                      [=](const QString& id) {
-                         if (id == lrc::api::video::PREVIEW_RENDERER_ID) {
+        qDebug() << "rendererStarted***" << id;
+                         [self updateCurrentRendererDeivce];
+                         if (id == currentRenderer_) {
                              dispatch_async(dispatch_get_main_queue(), ^{
                                  [self.previewView setHidden:NO];
                                  [hidePreviewBackground setHidden: NO];
@@ -800,7 +826,7 @@ CVPixelBufferRef pixelBufferPreview;
     QObject::connect(mediaModel,
                      &lrc::api::AVModel::rendererStopped,
                      [=](const QString& id) {
-                         if (id == lrc::api::video::PREVIEW_RENDERER_ID) {
+                         if (id == currentRenderer_) {
                              dispatch_async(dispatch_get_main_queue(), ^{
                                  [self.previewView setHidden:YES];
                                  self.previewView.videoRunning = false;
@@ -820,8 +846,8 @@ CVPixelBufferRef pixelBufferPreview;
     QObject::connect(mediaModel,
                      &lrc::api::AVModel::frameUpdated,
                      [=](const QString& id) {
-                         if (id == lrc::api::video::PREVIEW_RENDERER_ID) {
-                             auto renderer = &mediaModel->getRenderer(lrc::api::video::PREVIEW_RENDERER_ID);
+                         if (id == currentRenderer_) {
+                             auto renderer = &mediaModel->getRenderer(id);
                              if(!renderer->isRendering()) {
                                  return;
                              }
@@ -1307,7 +1333,8 @@ CVPixelBufferRef pixelBufferPreview;
         {
             auto* mediaSelectorVC = [[ChooseMediaVC alloc] initWithNibName:@"ChooseMediaVC" bundle:nil];
             auto videoDevices = [self getDeviceList];
-            auto device = mediaModel->getCurrentRenderedDevice(callUid_).name;
+            auto* callModel = accountInfo_->callModel.get();
+            auto device = callModel->getCurrentRenderedDevice(callUid_).name;
             auto settings = mediaModel->getDeviceSettings(device);
             auto currentDevice = settings.name;
             [mediaSelectorVC setMediaDevices: videoDevices andDefaultDevice: currentDevice];
@@ -1382,8 +1409,11 @@ CVPixelBufferRef pixelBufferPreview;
 }
 
 - (IBAction)toggleShare:(id)sender {
-    auto type = mediaModel->getCurrentRenderedDevice(callUid_).type;
-    if (type == lrc::api::video::DeviceType::DISPLAY || type == lrc::api::video::DeviceType::FILE) {
+    if (accountInfo_ == nil)
+        return;
+    auto* callModel = accountInfo_->callModel.get();
+    auto device = callModel->getCurrentRenderedDevice(callUid_);
+    if (device.type == lrc::api::video::DeviceType::DISPLAY || device.type == lrc::api::video::DeviceType::FILE) {
         [self switchToDevice:0];
         if (brokerPopoverVC != nullptr) {
             [brokerPopoverVC performClose:self];
@@ -1454,10 +1484,13 @@ CVPixelBufferRef pixelBufferPreview;
 }
 
 -(void) screenShare {
+    if (accountInfo_ == nil)
+        return;
+    auto* callModel = accountInfo_->callModel.get();
     NSScreen *mainScreen = [NSScreen mainScreen];
     NSRect screenFrame = mainScreen.frame;
     QRect captureRect = QRect(screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height);
-    mediaModel->setDisplay(0, screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height, [self getcallID]);
+    callModel->setDisplay(0, screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height, [self getcallID]);
 }
 
 -(void)streamFile {
@@ -1482,10 +1515,13 @@ CVPixelBufferRef pixelBufferPreview;
 }
 
 -(void) switchToDevice:(int)index {
+    if (accountInfo_ == nil)
+        return;
+    auto* callModel = accountInfo_->callModel.get();
     auto devices = mediaModel->getDevices();
     auto device = devices[index];
     mediaModel->setCurrentVideoCaptureDevice(device);
-    mediaModel->switchInputTo(device, [self getcallID]);
+    callModel->switchInputTo(device, [self getcallID]);
 }
 
 -(QVector<QString>) getDeviceList {
@@ -1500,7 +1536,10 @@ CVPixelBufferRef pixelBufferPreview;
 }
 
 -(void) switchToFile:(QString)uri {
-    mediaModel->setInputFile(uri, [self getcallID]);
+    if (accountInfo_ == nil)
+        return;
+    auto* callModel = accountInfo_->callModel.get();
+    callModel->setInputFile(uri, [self getcallID]);
 }
 
 -(CGRect) getVideoPreviewCollapsedSize {
@@ -1564,8 +1603,10 @@ CVPixelBufferRef pixelBufferPreview;
     if (!callView) {
         return;
     }
+    if ([self.callingWidgetsContainer.subviews containsObject: callView.view]) {
+        [self.callingWidgetsContainer removeView:callView.view];
+    }
     calls[uri.toNSString()] = nil;
-    [self.callingWidgetsContainer removeView:callView.view];
 }
 
 -(void)addPreviewForContactUri:(const QString&)uri call:(const QString&)callId {
diff --git a/src/LeaveMessageVC.mm b/src/LeaveMessageVC.mm
index e9d2252270e5dd8c915f8b916ce1b11b0eccea40..ada1e217c1c06610c6ecebb1f8a63920b6582e75 100644
--- a/src/LeaveMessageVC.mm
+++ b/src/LeaveMessageVC.mm
@@ -94,7 +94,7 @@ lrc::api::ConversationModel* conversationModel;
 - (IBAction)recordMessage:(NSButton *)sender {
     if (!isRecording) {
         [self clearData];
-        QString file_name = avModel->startLocalRecorder(true);
+        QString file_name = avModel->startLocalMediaRecorder("");
         if (file_name.isEmpty()) {
             return;
         }
diff --git a/src/RecordFileVC.mm b/src/RecordFileVC.mm
index edd1ce6ce2c9ca965587f34f52126d566e07dccf..33c025b568b0fc412838647708910070a019c56a 100644
--- a/src/RecordFileVC.mm
+++ b/src/RecordFileVC.mm
@@ -59,6 +59,7 @@ NSString *fileName;
 NSTimer* durationTimer;
 int timePassing = 0;
 bool isAudio = NO;
+QString defaultCamera;
 
 @synthesize avModel, renderConnections,
 previewView, timeLabel, recordOnOffButton, sendButton, fileImage, infoLabel, timeRightConstraint,timeTopConstraint, timeCenterX, timeCenterY;
@@ -92,7 +93,7 @@ previewView, timeLabel, recordOnOffButton, sendButton, fileImage, infoLabel, tim
     QObject::connect(avModel,
                      &lrc::api::AVModel::frameUpdated,
                      [=](const QString& id) {
-                         if (id != lrc::api::video::PREVIEW_RENDERER_ID) {
+                         if (id != defaultCamera) {
                              return;
                          }
                          auto renderer = &avModel->getRenderer(id);
@@ -215,11 +216,9 @@ previewView, timeLabel, recordOnOffButton, sendButton, fileImage, infoLabel, tim
 
 -(void) startRecord {
     dispatch_async(dispatch_get_main_queue(), ^{
-        if (!isAudio) {
-            avModel->startPreview();
-        }
         [self setRecordingState];
-        QString file_name = avModel->startLocalRecorder(isAudio);
+        auto deviceId = isAudio ? "" : defaultCamera;
+        QString file_name = avModel->startLocalMediaRecorder(deviceId);
         if (file_name.isEmpty()) {
             return;
         }
@@ -251,7 +250,7 @@ previewView, timeLabel, recordOnOffButton, sendButton, fileImage, infoLabel, tim
 -(void) disconnectVideo {
     AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
     if (![appDelegate getActiveCalls].size()) {
-        avModel->stopPreview();
+        avModel->stopPreview(defaultCamera);
         QObject::disconnect(renderConnections.frameUpdated);
         avModel->stopLocalRecorder(QString::fromNSString(fileName));
     }
@@ -272,8 +271,9 @@ previewView, timeLabel, recordOnOffButton, sendButton, fileImage, infoLabel, tim
 
     self.previewView.videoRunning = true;
     [self connectPreviewSignals];
-    avModel->stopPreview();
-    avModel->startPreview();
+    defaultCamera = "camera://" + avModel->getDefaultDevice();
+    avModel->stopPreview(defaultCamera);
+    avModel->startPreview(defaultCamera);
 }
 
 -(void) setInitialState {
diff --git a/src/RingWindowController.mm b/src/RingWindowController.mm
index f38ae070b62ed9db3699b273b0f2f7c494a98c5f..b0ec56fd52b21e84af003444a02375729bb419aa 100644
--- a/src/RingWindowController.mm
+++ b/src/RingWindowController.mm
@@ -139,7 +139,6 @@ typedef NS_ENUM(NSInteger, ViewState) {
             [settingsVC hide];
             break;
         case SHOW_CALL_SCREEN:
-            self.avModel->useAVFrame(YES);
             [self accountSettingsShouldOpen: NO];
             if (![currentCallVC.view superview]) {
             [callView addSubview:[currentCallVC view] positioned:NSWindowAbove relativeTo:nil];
diff --git a/src/VideoPrefsVC.mm b/src/VideoPrefsVC.mm
index df9ac9846d3308ece114ab4155977237fa4df88c..d211479e67000eeb1101d317a456b05060f70652 100644
--- a/src/VideoPrefsVC.mm
+++ b/src/VideoPrefsVC.mm
@@ -86,7 +86,7 @@ QString currentVideoDevice;
     AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
     if (![appDelegate getActiveCalls].size()) {
         self.previewView.videoRunning = false;
-        avModel->stopPreview();
+        avModel->stopPreview("camera://" + currentVideoDevice);
         [previewView fillWithBlack];
     }
 }
@@ -104,6 +104,7 @@ QString currentVideoDevice;
     auto newDevice = devices.at(index);
     auto deviceString = newDevice.toNSString();
     avModel->setDefaultDevice(newDevice);
+    currentVideoDevice = newDevice;
     [self devicesChanged];
     [self startPreview];
 }
@@ -127,7 +128,7 @@ QString currentVideoDevice;
                 [ratesList addItemWithTitle: [NSString stringWithFormat:@"%f", rate]];
             }
         }
-        [self connectPreviewSignals];
+        [self startPreview];
         [sizesList selectItemWithTitle: currentSettings.size.toNSString()];
         [ratesList selectItemWithTitle:[NSString stringWithFormat:@"%f", currentSettings.rate]];
     } catch (...) {}
@@ -140,8 +141,8 @@ QString currentVideoDevice;
     try {
         auto settings = avModel->getDeviceSettings(device);
         settings.rate = rate;
-        [self connectPreviewSignals];
         avModel->setDeviceSettings(settings);
+        [self startPreview];
     } catch (...) {}
 }
 
@@ -159,7 +160,7 @@ QString currentVideoDevice;
     QObject::connect(avModel,
                      &lrc::api::AVModel::rendererStarted,
                      [=](const QString& id) {
-                         if (id != lrc::api::video::PREVIEW_RENDERER_ID) {
+                         if (id != "camera://" + currentVideoDevice) {
                              return;
                          }
                         self.previewView.videoRunning = true;
@@ -170,7 +171,7 @@ QString currentVideoDevice;
                          QObject::connect(avModel,
                                           &lrc::api::AVModel::frameUpdated,
                                           [=](const QString& id) {
-                                              if (id != lrc::api::video::PREVIEW_RENDERER_ID) {
+                                              if (id != "camera://" + currentVideoDevice) {
                                                   return;
                                               }
                                               auto renderer = &avModel->getRenderer(id);
@@ -183,8 +184,7 @@ QString currentVideoDevice;
                          previewStopped = QObject::connect(avModel,
                                                            &lrc::api::AVModel::rendererStopped,
                                                            [=](const QString& id) {
-                                                               if (id != lrc::api::video
-                                                                   ::PREVIEW_RENDERER_ID) {
+                                                               if (id != "camera://" + currentVideoDevice) {
                                                                    return;
                                                                }
                                                                self.previewView.videoRunning = false;
@@ -200,7 +200,7 @@ QString currentVideoDevice;
                                    &lrc::api::AVModel::deviceEvent,
                                    [=]() {
                                        auto defaultDevice = avModel->getDefaultDevice();
-                                       bool updatePreview = avModel->getRenderer(lrc::api ::video::PREVIEW_RENDERER_ID).isRendering() && (defaultDevice != currentVideoDevice);
+                                       bool updatePreview = avModel->getRenderer("camera://" + currentVideoDevice).isRendering() && (defaultDevice != currentVideoDevice);
                                        if (updatePreview) {
                                            [previewView fillWithBlack];
                                            self.previewView.videoRunning = false;
@@ -276,8 +276,8 @@ QString currentVideoDevice;
     if (calls.empty()) {
         self.previewView.videoRunning = true;
         [self connectPreviewSignals];
-        avModel->stopPreview();
-        avModel->startPreview();
+        avModel->stopPreview("camera://" + currentVideoDevice);
+        avModel->startPreview("camera://" + currentVideoDevice);
     }
 }