diff --git a/src/media/audio/audio_frame_resizer.cpp b/src/media/audio/audio_frame_resizer.cpp
index 311860de95195c1a7136b8919bf2254a56327d09..4bcf86d28f3f8e1748bf012d3217514e4e00d75f 100644
--- a/src/media/audio/audio_frame_resizer.cpp
+++ b/src/media/audio/audio_frame_resizer.cpp
@@ -30,13 +30,11 @@ extern "C" {
 
 namespace ring {
 
-// NOTE 160 samples should the minimum that will be provided (20 ms @ 8kHz),
-// barring files that for some obscure reason have smaller packets
-AudioFrameResizer::AudioFrameResizer(const AudioFormat& format, int frameSize, std::function<void(std::unique_ptr<AudioFrame>&&)> cb)
+AudioFrameResizer::AudioFrameResizer(const AudioFormat& format, int size, std::function<void(std::shared_ptr<AudioFrame>&&)> cb)
     : format_(format)
-    , frameSize_(frameSize)
+    , frameSize_(size)
     , cb_(cb)
-    , queue_(av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, 160))
+    , queue_(av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, frameSize_))
 {}
 
 AudioFrameResizer::~AudioFrameResizer()
@@ -63,7 +61,32 @@ AudioFrameResizer::format() const
 }
 
 void
-AudioFrameResizer::enqueue(std::unique_ptr<AudioFrame>&& frame)
+AudioFrameResizer::setFormat(const AudioFormat& format, int size)
+{
+    if (format != format_) {
+        if (auto discaded = samples())
+            RING_WARN("Discarding %d samples", discaded);
+        av_audio_fifo_free(queue_);
+        format_ = format;
+        queue_ = av_audio_fifo_alloc(format.sampleFormat, format.nb_channels, frameSize_);
+    }
+    if (size)
+        setFrameSize(size);
+}
+
+void
+AudioFrameResizer::setFrameSize(int frameSize)
+{
+    if (frameSize_ != frameSize) {
+        frameSize_ = frameSize;
+        if (cb_)
+            while (auto frame = dequeue())
+                cb_(std::move(frame));
+    }
+}
+
+void
+AudioFrameResizer::enqueue(std::shared_ptr<AudioFrame>&& frame)
 {
     int ret = 0;
     auto f = frame->pointer();
@@ -83,11 +106,12 @@ AudioFrameResizer::enqueue(std::unique_ptr<AudioFrame>&& frame)
         throw std::runtime_error("Failed to add audio to frame resizer");
     }
 
-    while (auto frame = dequeue())
-        cb_(std::move(frame));
+    if (cb_)
+        while (auto frame = dequeue())
+            cb_(std::move(frame));
 }
 
-std::unique_ptr<AudioFrame>
+std::shared_ptr<AudioFrame>
 AudioFrameResizer::dequeue()
 {
     if (samples() < frameSize_)
diff --git a/src/media/audio/audio_frame_resizer.h b/src/media/audio/audio_frame_resizer.h
index c80780dc5389ba55a680a302a0622ded1543234e..0023ae99c082aec9e49680aaf4c67498837ce908 100644
--- a/src/media/audio/audio_frame_resizer.h
+++ b/src/media/audio/audio_frame_resizer.h
@@ -39,7 +39,7 @@ namespace ring {
  */
 class AudioFrameResizer {
 public:
-    AudioFrameResizer(const AudioFormat& format, int frameSize, std::function<void(std::unique_ptr<AudioFrame>&&)> cb);
+    AudioFrameResizer(const AudioFormat& format, int frameSize, std::function<void(std::shared_ptr<AudioFrame>&&)> cb = {});
     ~AudioFrameResizer();
 
     /**
@@ -53,6 +53,9 @@ public:
      */
     AudioFormat format() const;
 
+    void setFormat(const AudioFormat& format, int frameSize);
+    void setFrameSize(int frameSize);
+
     /**
      * Gets the number of samples per output frame.
      */
@@ -66,15 +69,15 @@ public:
      *
      * NOTE @frame's format must match @format_, or this will fail.
      */
-    void enqueue(std::unique_ptr<AudioFrame>&& frame);
-
-private:
-    NON_COPYABLE(AudioFrameResizer);
+    void enqueue(std::shared_ptr<AudioFrame>&& frame);
 
     /**
      * Notifies owner of a new frame.
      */
-    std::unique_ptr<AudioFrame> dequeue();
+    std::shared_ptr<AudioFrame> dequeue();
+
+private:
+    NON_COPYABLE(AudioFrameResizer);
 
     /**
      * Format used for input and output audio frames.
@@ -89,7 +92,7 @@ private:
     /**
      * Function to call once @queue_ contains enough samples to produce a frame.
      */
-    std::function<void(std::unique_ptr<AudioFrame>&&)> cb_;
+    std::function<void(std::shared_ptr<AudioFrame>&&)> cb_;
 
     /**
      * Audio queue operating on the sample level instead of byte level.