diff --git a/src/media/media_filter.cpp b/src/media/media_filter.cpp
index c00181e91965ce94ee898f9a52269a6230c51fbc..8bc730e65cea38c8e0631a27cf9ef55921bdda01 100644
--- a/src/media/media_filter.cpp
+++ b/src/media/media_filter.cpp
@@ -161,6 +161,9 @@ MediaFilter::feedInput(AVFrame* frame, const std::string& inputName)
     if (!initialized_)
         return fail("Filter not initialized", -1);
 
+    if (!frame)
+        return 0;
+
     for (size_t i = 0; i < inputs_.size(); ++i) {
         auto& ms = inputParams_[i];
         if (ms.name != inputName)
@@ -210,6 +213,13 @@ MediaFilter::readOutput()
     return nullptr;
 }
 
+void
+MediaFilter::flush()
+{
+    for (size_t i = 0; i < inputs_.size(); ++i)
+        av_buffersrc_add_frame_flags(inputs_[i], nullptr, 0);
+}
+
 int
 MediaFilter::initOutputFilter(AVFilterInOut* out)
 {
diff --git a/src/media/media_filter.h b/src/media/media_filter.h
index 3b05a13db2cc0abe65f1bb91b70532f3465fb03f..0ca66dbdd4e26ba3192c209fcc55bf9891bc31d7 100644
--- a/src/media/media_filter.h
+++ b/src/media/media_filter.h
@@ -99,6 +99,11 @@ class MediaFilter {
          */
         AVFrame* readOutput();
 
+        /**
+         * Flush filter to indicate EOF.
+         */
+        void flush();
+
     private:
         NON_COPYABLE(MediaFilter);
 
diff --git a/src/media/media_recorder.cpp b/src/media/media_recorder.cpp
index 1b8005fdd9c47f3394fc21dff97916ec85959497..f57d0acb95ba1f5a94b7b080118fd7b19daf60c9 100644
--- a/src/media/media_recorder.cpp
+++ b/src/media/media_recorder.cpp
@@ -156,9 +156,10 @@ MediaRecorder::onFrame(const std::string& name, const std::shared_ptr<MediaFrame
 
     // copy frame to not mess with the original frame's pts (does not actually copy frame data)
     MediaFrame clone;
+    const auto& ms = streams_[name]->info;
     clone.copyFrom(*frame);
-    clone.pointer()->pts -= streams_[name]->info.firstTimestamp;
-    if (clone.pointer()->width > 0 && clone.pointer()->height > 0)
+    clone.pointer()->pts -= ms.firstTimestamp;
+    if (ms.isVideo)
         videoFilter_->feedInput(clone.pointer(), name);
     else
         audioFilter_->feedInput(clone.pointer(), name);
@@ -417,8 +418,12 @@ void
 MediaRecorder::flush()
 {
     std::lock_guard<std::mutex> lk(mutex_);
+    if (videoFilter_)
+        videoFilter_->flush();
+    if (audioFilter_)
+        audioFilter_->flush();
     filterAndEncode(videoFilter_.get(), videoIdx_);
-    filterAndEncode(audioFilter_.get(), videoIdx_);
+    filterAndEncode(audioFilter_.get(), audioIdx_);
     encoder_->flush();
 }