You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Riverpod和Flutter多Provider正确实现音频播放实时字幕渲染

可行解决方案

核心思路

将业务逻辑按职责拆分到不同Provider,避免单个大状态频繁刷新导致的性能问题,利用Riverpod的派生Provider能力做轻量计算,既保证更新实时性也不会出现性能损耗。


步骤1:新增实时播放进度流Provider

单独暴露音频播放进度的流,可自行调整流的发射频率平衡性能和精准度,Riverpod的StreamProvider会自动管理订阅生命周期,无需手动取消监听:

final currentAudioPositionProvider = StreamProvider<Duration>((ref) {
  final audioPlayer = ref.watch(voiceoverAudioPlayerProvider);
  // 可通过throttleTime限制发射频率,示例为每100毫秒发射一次进度
  return audioPlayer.onAudioPositionChanged
    .throttleTime(const Duration(milliseconds: 100))
    .handleError((_) => Duration.zero);
});

步骤2:新增高亮单词索引计算Provider

创建只读派生Provider,仅依赖播放进度和字幕数据计算当前需要高亮的单词下标,计算逻辑完全独立,只有依赖项变更时才会重新计算,性能开销极低:

final currentHighlightWordIndexProvider = Provider<int?>((ref) {
  final currentPosition = ref.watch(currentAudioPositionProvider).valueOrNull;
  final voiceoverData = ref.watch(voiceoverTextProvider).valueOrNull;

  if (currentPosition == null || voiceoverData == null) return null;

  // 单词数量较多时建议替换为二分查找,进一步提升计算效率
  for (int i = 0; i < voiceoverData.paragraph.length; i++) {
    final word = voiceoverData.paragraph[i];
    if (currentPosition >= word.startTime && currentPosition <= word.endTime) {
      return i;
    }
  }
  return null;
});

步骤3:调整Widget层实现

Widget层仅做状态监听和视图渲染,无需处理任何业务逻辑:

@override
Widget build(BuildContext context, WidgetRef ref) {
  final voiceoverTextState = ref.watch(voiceoverTextProvider);
  final highlightIndex = ref.watch(currentHighlightWordIndexProvider);

  return voiceoverTextState.when(
    data: (voiceoverText) => Wrap(
      children: List.generate(voiceoverText.paragraph.length, (index) {
        final isHighlight = index == highlightIndex;
        return Text(
          voiceoverText.paragraph[index].text,
          style: TextStyle(
            color: isHighlight ? Colors.red : Colors.black,
          ),
        );
      }),
    ),
    loading: () => const CircularProgressIndicator(),
    error: (error, stackTrace) => Text('加载失败:$error'),
  );
}

优化建议

  • 若单词总数超过100,将遍历匹配逻辑替换为二分查找,计算效率可提升一个数量级
  • 根据实际业务需求调整throttleTime的时长,最低建议不低于50毫秒,避免无效刷新过多导致性能损耗
  • 原有voiceoverTextNotifier无需修改,仅保留字幕数据请求、音频播放/停止控制逻辑即可

内容的提问来源于stack exchange,提问作者claptimes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 10:48:02