@@ -63,6 +63,12 @@ class RepeatFlowConfig {
6363 /// promptId 前缀(默认 'lar',各页面可自定义)
6464 final String promptIdPrefix;
6565
66+ /// 当前播放倍速(默认 1.0)。
67+ ///
68+ /// 用户跟读的是按此倍速播放后的音频,录音的参考时长与最大时长都按
69+ /// 「实际听到的时长」= 原句时长 ÷ 倍速 计算,避免慢速播放时提前截断录音。
70+ final double Function ()? playbackSpeed;
71+
6672 const RepeatFlowConfig ({
6773 required this .audioItemId,
6874 required this .getRepeatCount,
@@ -71,6 +77,7 @@ class RepeatFlowConfig {
7177 this .onBeforeSentenceStart,
7278 this .onSentencePlayed,
7379 this .promptIdPrefix = 'lar' ,
80+ this .playbackSpeed,
7481 });
7582}
7683
@@ -820,21 +827,37 @@ class RepeatFlowEngine {
820827 'promptId=$promptId ' ,
821828 );
822829
830+ final heardDuration = _heardDuration (sentence);
823831 final computed =
824- sentence.duration * kRecordingDurationMultiplier +
825- kRecordingTimeoutBase;
832+ heardDuration * kRecordingDurationMultiplier + kRecordingTimeoutBase;
826833 final maxDuration = computed < kRecordingMinTimeout
827834 ? kRecordingMinTimeout
828835 : computed;
829836
830837 callbacks.setMaxRecordingDuration (maxDuration);
831838
832- AppLogger .log (logTag, '开始录音: $promptId ' );
839+ AppLogger .log (
840+ logTag,
841+ '开始录音: $promptId referenceDuration=${heardDuration .inMilliseconds }ms '
842+ '(原句${sentence .duration .inMilliseconds }ms) '
843+ 'maxDuration=${maxDuration .inMilliseconds }ms' ,
844+ );
833845 callbacks.startRecording (
834846 promptId: promptId,
835847 referenceText: sentence.text,
836848 maxDuration: maxDuration,
837- referenceDuration: sentence.duration,
849+ referenceDuration: heardDuration,
850+ );
851+ }
852+
853+ /// 用户实际听到的句子时长:原句时长 ÷ 播放倍速。
854+ ///
855+ /// 倍速未配置或非法(≤0、非有限值)时按 1.0x 处理。
856+ Duration _heardDuration (Sentence sentence) {
857+ final speed = _config.playbackSpeed? .call () ?? 1.0 ;
858+ if (! speed.isFinite || speed <= 0 ) return sentence.duration;
859+ return Duration (
860+ microseconds: (sentence.duration.inMicroseconds / speed).round (),
838861 );
839862 }
840863
0 commit comments