From 4fd3c848de3d1e8fb77652bfe1511e39b37fe329 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Fri, 27 Feb 2026 03:38:27 +0900 Subject: [PATCH 1/4] fix --- lib/src/track/audio_visualizer_native.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/track/audio_visualizer_native.dart b/lib/src/track/audio_visualizer_native.dart index a7ed37692..926049c45 100644 --- a/lib/src/track/audio_visualizer_native.dart +++ b/lib/src/track/audio_visualizer_native.dart @@ -53,11 +53,13 @@ class AudioVisualizerNative extends AudioVisualizer { return; } - await Native.stopVisualizer(mediaStreamTrack.id!, visualizerId: visualizerId); - + // Cancel subscription before native stop, otherwise the native + // StreamHandler is already removed and cancel throws MissingPluginException. await _streamSubscription?.cancel(); _streamSubscription = null; _eventChannel = null; + + await Native.stopVisualizer(mediaStreamTrack.id!, visualizerId: visualizerId); } } From 73961ecc313aa527c5c8bb2a7b2aa1d9ca1e0966 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Fri, 27 Feb 2026 03:45:58 +0900 Subject: [PATCH 2/4] fix ios --- shared_swift/LiveKitPlugin.swift | 1 + shared_swift/Visualizer.swift | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/shared_swift/LiveKitPlugin.swift b/shared_swift/LiveKitPlugin.swift index 8d11d9ef3..a2d8d8639 100644 --- a/shared_swift/LiveKitPlugin.swift +++ b/shared_swift/LiveKitPlugin.swift @@ -201,6 +201,7 @@ public class LiveKitPlugin: NSObject, FlutterPlugin { } for processors in audioProcessors.values { + processors.visualizers[visualizerId]?.stop() processors.visualizers.removeValue(forKey: visualizerId) } diff --git a/shared_swift/Visualizer.swift b/shared_swift/Visualizer.swift index c856ec5ca..aad4c9f44 100644 --- a/shared_swift/Visualizer.swift +++ b/shared_swift/Visualizer.swift @@ -69,6 +69,11 @@ public class Visualizer: NSObject, RTCAudioRenderer, FlutterStreamHandler { channel?.setStreamHandler(self) } + public func stop() { + _track?.remove(audioRenderer: self) + channel?.setStreamHandler(nil) + } + deinit { _track?.remove(audioRenderer: self) } From b6186356d36a633d525463e00769e546282b2f54 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Fri, 27 Feb 2026 03:39:51 +0900 Subject: [PATCH 3/4] changes --- .changes/fix-audio-visualizer-missing-plugin-exception | 1 + 1 file changed, 1 insertion(+) create mode 100644 .changes/fix-audio-visualizer-missing-plugin-exception diff --git a/.changes/fix-audio-visualizer-missing-plugin-exception b/.changes/fix-audio-visualizer-missing-plugin-exception new file mode 100644 index 000000000..d0e10a5c8 --- /dev/null +++ b/.changes/fix-audio-visualizer-missing-plugin-exception @@ -0,0 +1 @@ +patch type="fixed" "MissingPluginException when stopping audio visualizer on Android/iOS" From 1c982828662fd78af397cf3d40c600d26e91c61d Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Fri, 27 Feb 2026 03:57:33 +0900 Subject: [PATCH 4/4] nit --- shared_swift/Visualizer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared_swift/Visualizer.swift b/shared_swift/Visualizer.swift index aad4c9f44..19c6bd95d 100644 --- a/shared_swift/Visualizer.swift +++ b/shared_swift/Visualizer.swift @@ -75,7 +75,7 @@ public class Visualizer: NSObject, RTCAudioRenderer, FlutterStreamHandler { } deinit { - _track?.remove(audioRenderer: self) + stop() } public func render(pcmBuffer: AVAudioPCMBuffer) {