playVoiceMessage method

Future<void> playVoiceMessage(
  1. RCIMIWMediaMessage message, [
  2. BuildContext? context
])

Implementation

Future<void> playVoiceMessage(RCIMIWMediaMessage message,
    [BuildContext? context]) async {
  if (_disposed) return;

  if (context != null) {
    final recordProvider =
        Provider.of<RCKVoiceRecordProvider>(context, listen: false);
    if (recordProvider.voiceSendingType ==
            RCIMIWMessageVoiceSendingType.sending ||
        recordProvider.voiceSendingType ==
            RCIMIWMessageVoiceSendingType.canceling) {
      await recordProvider.cancelRecord();
    }
  }

  if (_currentPlayingMessageId != null &&
      _state == RCKAudioPlayerState.playing) {
    final willPlayMessageId = _currentPlayingMessageId;
    await stopVoiceMessage();
    if (willPlayMessageId == message.messageId.toString()) {
      // 如果当前正在播放的消息id与即将播放的消息id相同,则不进行播放
      return;
    }
  }

  final localPath = message.local;
  String? filePath = localPath;

  // 如果路径以file://开头,去掉这个前缀
  if (filePath != null && filePath.startsWith('file://')) {
    filePath = filePath.substring(7);
  }

  // 如果是iOS,复制成一个m4a后缀的文件,相同文件夹
  if (filePath != null && Platform.isIOS) {
    final originalFile = File(filePath);
    if (await originalFile.exists()) {
      final dir = originalFile.parent;
      final newFileName =
          '${originalFile.uri.pathSegments.last.split('.').first}_${DateTime.now().millisecondsSinceEpoch}.m4a';
      final newFilePath = '${dir.path}/$newFileName';
      if (!await File(newFilePath).exists()) {
        await originalFile.copy(newFilePath);
      }
      filePath = newFilePath;
    }
  }

  if (filePath != null && !kIsWeb && File(filePath).existsSync()) {
    try {
      // 使用 file:// 协议
      final fileUri = Uri.file(filePath).toString();

      await _player.setAudioSource(
        AudioSource.uri(Uri.parse(fileUri)),
      );

      _currentPlayingMessageId = message.messageId.toString();
      _state = RCKAudioPlayerState.playing;
      if (!_disposed) {
        notifyListeners();
      }

      await _player.play();

      // 取消之前的订阅
      _playerStateSubscription?.cancel();

      // 创建新的订阅
      _playerStateSubscription = _player.playerStateStream.listen((state) {
        if (!_disposed &&
            state.processingState == ProcessingState.completed) {
          _currentPlayingMessageId = null;
          _state = RCKAudioPlayerState.stopped;
          notifyListeners();
        }
      });
    } catch (e) {
      if (!_disposed) {
        _currentPlayingMessageId = null;
        _state = RCKAudioPlayerState.stopped;
        notifyListeners();
      }
    }
  } else {
    bool autoPlay = true;
    if (filePath != null && !kIsWeb && !File(filePath).existsSync()) {
      autoPlay = false;
    }

    // 通过context获取ChatProvider来下载语音消息
    if (context != null && context.mounted) {
      final chatProvider = context.read<RCKChatProvider>();
      chatProvider.downloadVoiceMessage(message, autoPlay, context);
    }
  }
}