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

Flutter Sound音频播放计时器失效求助(空安全迁移后)

Flutter Sound 空安全迁移后播放进度监听未触发(onProgress 回调不执行)

我在聊天应用中使用flutter_sound包实现音频录制功能,原本播放录音时的计时器功能正常,但完成Dart空安全迁移及包更新后,该功能失效。核心问题是_myPlayer?.onProgress!.listen的回调完全未执行,连test inside日志都未打印。

迁移后代码

void _addListeners(messageProvider) {
  cancelPlayerSubscriptions();
  _playerSubscription = _myPlayer?.onProgress!.listen((e) {
    print('test inside');
    if (e != null) {
      debugPrint('playback position here');
      maxDuration = e.duration as double;
      if (maxDuration <= 0) maxDuration = 0.0;

      var date = DateTime.fromMillisecondsSinceEpoch(
          int.parse(e.position.toString()),
          isUtc: true);
      String txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
      messageProvider.playerText = txt.substring(0, 8);
      if (int.parse(e.position.toString()) == maxDuration) {
        messageProvider.currentIcon = 0;
      }
    }
  });
}

迁移前代码

void _addListeners(messageProvider) {
  cancelPlayerSubscriptions();
  _playerSubscription = playerModule.onPlayerStateChanged.listen((e) {
    if (e != null) {
      maxDuration = e.duration;
      if (maxDuration <= 0) maxDuration = 0.0;

      DateTime date = new DateTime.fromMillisecondsSinceEpoch(
          e.currentPosition.toInt(),
          isUtc: true);
      String txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
      messageProvider.playerText = txt.substring(0, 8);
      if (e.currentPosition.toInt() == maxDuration) {
        messageProvider.currentIcon = 0;
      }
    }
  });
}

解决思路

  • 检查_myPlayer初始化完整性
    空安全迁移后_myPlayer为可空类型,需确保添加监听前已完成初始化并打开音频会话:

    _myPlayer = FlutterSoundPlayer();
    await _myPlayer.openAudioSession();
    

    未完成初始化的话,_myPlayer?.onProgress会返回null,导致监听无法注册。

  • 确认flutter_sound版本的API参数要求
    新版本中onProgress的触发依赖startPlayer时指定progressInterval参数,未设置则不会触发回调:

    await _myPlayer.startPlayer(
      fromURI: audioFilePath,
      progressInterval: Duration(milliseconds: 100), // 指定进度回调间隔
    );
    
  • 排查cancelPlayerSubscriptions()逻辑
    确保该方法仅取消旧订阅,不会误删新注册的监听:

    void cancelPlayerSubscriptions() {
      _playerSubscription?.cancel();
      _playerSubscription = null;
    }
    

    避免出现订阅刚添加就被取消的情况。

  • 修正onProgress的可空处理
    替换强制解包的!,改用安全判空确保监听正确注册:

    if (_myPlayer?.onProgress != null) {
      _playerSubscription = _myPlayer!.onProgress.listen((e) {
        // 原有回调逻辑
      });
    }
    
  • 验证播放器状态与音频文件有效性
    确认音频文件路径正确,且startPlayer调用成功:

    final playbackResult = await _myPlayer.startPlayer(fromURI: audioFilePath);
    print('Playback status: $playbackResult');
    

    播放器未成功启动时,onProgress自然不会触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:33:20