From 92ab18ff32ca971e67ab30295998ac8093fe92d2 Mon Sep 17 00:00:00 2001 From: llfbandit Date: Wed, 22 May 2024 21:49:29 +0200 Subject: [PATCH] fix: Pausing for too long with Chromium based browsers breaks the recording. closes #316 --- record_web/CHANGELOG.md | 3 +++ .../delegate/mic_recorder_delegate.dart | 25 ++++++++++++++----- record_web/pubspec.yaml | 2 +- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/record_web/CHANGELOG.md b/record_web/CHANGELOG.md index 422a2881..cde9d2d5 100644 --- a/record_web/CHANGELOG.md +++ b/record_web/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.1.1 +* fix: Pausing for too long with Chromium based browsers breaks the recording. + ## 1.1.0 * feat: Migrated implementation to package:web. diff --git a/record_web/lib/recorder/delegate/mic_recorder_delegate.dart b/record_web/lib/recorder/delegate/mic_recorder_delegate.dart index 7ffbd036..0a17ffc8 100644 --- a/record_web/lib/recorder/delegate/mic_recorder_delegate.dart +++ b/record_web/lib/recorder/delegate/mic_recorder_delegate.dart @@ -18,6 +18,9 @@ class MicRecorderDelegate extends RecorderDelegate { // Media stream get from getUserMedia web.MediaStream? _mediaStream; web.AudioContext? _context; + web.AudioWorkletNode? _workletNode; + web.MediaStreamAudioSourceNode? _source; + StreamController? _recordStreamCtrl; Encoder? _encoder; // Amplitude @@ -49,8 +52,8 @@ class MicRecorderDelegate extends RecorderDelegate { Future pause() async { final context = _context; if (context != null && context.state == 'running') { - onStateChanged(RecordState.pause); await context.suspend().toDart; + onStateChanged(RecordState.pause); } } @@ -58,8 +61,16 @@ class MicRecorderDelegate extends RecorderDelegate { Future resume() async { final context = _context; if (context != null && context.state == 'suspended') { - onStateChanged(RecordState.record); await context.resume().toDart; + + if (_workletNode != null) { + // Workaround for Chromium based browsers, + // Audio worklet node is disconnected + // when pause state is too long (> 12~15 secs) + _source?.connect(_workletNode!)?.connect(context.destination); + } + + onStateChanged(RecordState.record); } } @@ -118,7 +129,7 @@ class MicRecorderDelegate extends RecorderDelegate { .addModule('./assets/packages/record_web/assets/js/record.worklet.js') .toDart; - final recorder = web.AudioWorkletNode( + final workletNode = web.AudioWorkletNode( context, 'recorder.worklet', web.AudioWorkletNodeOptions( @@ -129,7 +140,7 @@ class MicRecorderDelegate extends RecorderDelegate { ), ); - source.connect(recorder)?.connect(context.destination); + source.connect(workletNode)?.connect(context.destination); if (!isStream) { _encoder?.cleanup(); @@ -145,13 +156,15 @@ class MicRecorderDelegate extends RecorderDelegate { } if (isStream) { - recorder.port.onmessage = + workletNode.port.onmessage = ((web.MessageEvent event) => _onMessageStream(event)).toJS; } else { - recorder.port.onmessage = + workletNode.port.onmessage = ((web.MessageEvent event) => _onMessage(event)).toJS; } + _source = source; + _workletNode = workletNode; _context = context; _mediaStream = mediaStream; diff --git a/record_web/pubspec.yaml b/record_web/pubspec.yaml index 4436d0c0..0ca679d0 100644 --- a/record_web/pubspec.yaml +++ b/record_web/pubspec.yaml @@ -1,6 +1,6 @@ name: record_web description: Web specific implementation for record package called by record_platform_interface. -version: 1.1.0 +version: 1.1.1 homepage: https://github.com/llfbandit/record/tree/master/record_web environment: