diff --git a/src/media/audio/audio_rtp_session.cpp b/src/media/audio/audio_rtp_session.cpp
index 93613fb1a9402f38f87e1337725b36644ec31b7b..e7f16077a17a69728627b05ac2cc8df99a6d069e 100644
--- a/src/media/audio/audio_rtp_session.cpp
+++ b/src/media/audio/audio_rtp_session.cpp
@@ -196,10 +196,14 @@ AudioRtpSession::setMuted(bool isMuted)
 void
 AudioRtpSession::initRecorder(std::shared_ptr<MediaRecorder>& rec)
 {
-    if (receiveThread_)
+    if (receiveThread_) {
         receiveThread_->attach(rec.get());
-    if (auto input = ring::getAudioInput(callID_))
+        rec->addStream(receiveThread_->getInfo());
+    }
+    if (auto input = ring::getAudioInput(callID_)) {
         input->attach(rec.get());
+        rec->addStream(input->getInfo());
+    }
 }
 
 void
diff --git a/src/media/localrecorder.cpp b/src/media/localrecorder.cpp
index 2aaebc94f27a3fb1d4d73ce6cd182c4029fbed3e..8eaed6c993829aa3ab989c544cda7e7a9b589f0b 100644
--- a/src/media/localrecorder.cpp
+++ b/src/media/localrecorder.cpp
@@ -73,6 +73,7 @@ LocalRecorder::startRecording()
 
     audioInput_ = ring::getAudioInput(path_);
     audioInput_->setFormat(AudioFormat::STEREO());
+    recorder_->addStream(audioInput_->getInfo());
     audioInput_->attach(recorder_.get());
 
 #ifdef RING_VIDEO
@@ -80,6 +81,7 @@ LocalRecorder::startRecording()
     if (!isAudioOnly_) {
         videoInput_ = std::static_pointer_cast<video::VideoInput>(ring::getVideoCamera());
         if (videoInput_) {
+            recorder_->addStream(videoInput_->getInfo());
             videoInput_->attach(recorder_.get());
         } else {
             RING_ERR() << "Unable to record video (no video input)";
@@ -96,6 +98,9 @@ LocalRecorder::stopRecording()
 {
     Recordable::stopRecording();
     Manager::instance().getRingBufferPool().unBindHalfDuplexOut(path_, RingBufferPool::DEFAULT_ID);
+    audioInput_->detach(recorder_.get());
+    if (videoInput_)
+        videoInput_->detach(recorder_.get());
     audioInput_.reset();
     videoInput_.reset();
 }
diff --git a/src/media/media_recorder.cpp b/src/media/media_recorder.cpp
index 82dc9e55714aac8183d3b8b52b741782c0b5a186..c182b673e2e72277f8052db4d21c04e44d0816ad 100644
--- a/src/media/media_recorder.cpp
+++ b/src/media/media_recorder.cpp
@@ -150,17 +150,6 @@ MediaRecorder::update(Observable<std::shared_ptr<AudioFrame>>* ob, const std::sh
     recordData(a->pointer(), streams_[name]);
 }
 
-void MediaRecorder::attached(Observable<std::shared_ptr<AudioFrame>>* ob)
-{
-    MediaStream ms;
-    if (auto receiver = dynamic_cast<AudioReceiveThread*>(ob))
-        ms = receiver->getInfo();
-    else if (auto input = dynamic_cast<AudioInput*>(ob))
-        ms = input->getInfo();
-    if (addStream(ms) >= 0)
-        hasAudio_ = true;
-}
-
 void MediaRecorder::update(Observable<std::shared_ptr<VideoFrame>>* ob, const std::shared_ptr<VideoFrame>& v)
 {
     std::string name;
@@ -171,17 +160,6 @@ void MediaRecorder::update(Observable<std::shared_ptr<VideoFrame>>* ob, const st
     recordData(v->pointer(), streams_[name]);
 }
 
-void MediaRecorder::attached(Observable<std::shared_ptr<VideoFrame>>* ob)
-{
-    MediaStream ms;
-    if (auto receiver = dynamic_cast<video::VideoReceiveThread*>(ob))
-        ms = receiver->getInfo();
-    else if (auto input = dynamic_cast<video::VideoInput*>(ob))
-        ms = input->getInfo();
-    if (addStream(ms) >= 0)
-        hasVideo_ = true;
-}
-
 int
 MediaRecorder::addStream(const MediaStream& ms)
 {
@@ -192,6 +170,10 @@ MediaRecorder::addStream(const MediaStream& ms)
 
     if (streams_.insert(std::make_pair(ms.name, ms)).second) {
         RING_DBG() << "Recorder input #" << streams_.size() << ": " << ms;
+        if (ms.isVideo)
+            hasVideo_ = true;
+        else
+            hasAudio_ = true;
         return 0;
     } else {
         RING_ERR() << "Could not add stream '" << ms.name << "' to record";
diff --git a/src/media/media_recorder.h b/src/media/media_recorder.h
index 4c0b0c0d3c71fbabcd68b840fdc4a698accaea8e..7dd4d1faa1459035701769a8465225fee8376286 100644
--- a/src/media/media_recorder.h
+++ b/src/media/media_recorder.h
@@ -70,19 +70,18 @@ public:
 
     void stopRecording();
 
+    int addStream(const MediaStream& ms);
+
     /* Observer methods*/
     void update(Observable<std::shared_ptr<AudioFrame>>* ob, const std::shared_ptr<AudioFrame>& a) override;
-    void attached(Observable<std::shared_ptr<AudioFrame>>* ob) override;
 
     void update(Observable<std::shared_ptr<VideoFrame>>* ob, const std::shared_ptr<VideoFrame>& v) override;
-    void attached(Observable<std::shared_ptr<VideoFrame>>* ob) override;
 
 private:
     NON_COPYABLE(MediaRecorder);
 
     int recordData(AVFrame* frame, const MediaStream& ms);
 
-    int addStream(const MediaStream& ms);
     int initRecord();
     MediaStream setupVideoOutput();
     std::string buildVideoFilter(const std::vector<MediaStream>& peers, const MediaStream& local) const;
diff --git a/src/media/video/video_rtp_session.cpp b/src/media/video/video_rtp_session.cpp
index 07818aad6dba160cb396e4ecbb6e35ccfa82934e..9cf78560558a2f8e85c74edbd2a3f9723c81f863 100644
--- a/src/media/video/video_rtp_session.cpp
+++ b/src/media/video/video_rtp_session.cpp
@@ -567,10 +567,14 @@ VideoRtpSession::processPacketLoss()
 void
 VideoRtpSession::initRecorder(std::shared_ptr<MediaRecorder>& rec)
 {
-    if (receiveThread_)
+    if (receiveThread_) {
         receiveThread_->attach(rec.get());
-    if (auto vidInput = std::static_pointer_cast<VideoInput>(videoLocal_))
+        rec->addStream(receiveThread_->getInfo());
+    }
+    if (auto vidInput = std::static_pointer_cast<VideoInput>(videoLocal_)) {
         vidInput->attach(rec.get());
+        rec->addStream(vidInput->getInfo());
+    }
 }
 
 void