attachMedia method

Future<void> attachMedia(
  1. JsonMap mediaJson, [
  2. int? heartbeatSeconds
])

连接媒体:按 media.provider 选择适配;连上后第一次心跳带 media_connected。

Implementation

Future<void> attachMedia(JsonMap mediaJson, [int? heartbeatSeconds]) async {
  final media = MediaCredential(freezeMap(mediaJson));
  _media = media;
  _heartbeatMs = (heartbeatSeconds ?? defaultHeartbeatS) * 1000;
  _mediaConnectedSent = false;
  _holding = true;
  _module.reportHolder(callId, true);
  _startHeartbeat();
  _scheduleRenew();
  final adapter = _module.provider(media.provider);
  if (adapter == null) {
    _holding = false;
    _set(media: 'disconnected');
    throw DRException(
      code: 'permission_denied',
      details: {'reason': 'media_provider_unsupported', 'provider': media.provider},
      source: ErrorSource.local,
      message: 'media_provider_unsupported',
    );
  }
  _set(media: 'connecting');
  final kind = snapshot.call.media;
  try {
    await adapter.load();
    final session = await adapter.connect(media, media: kind, identityToUid: (identity) => snapshot.call.member(identity)?.mediaUid);
    if (_ended) {
      await session.disconnect().catchError((Object _) {});
      return;
    }
    _bindSession(session);
    _set(media: 'connected');
    unawaited(_beat());
    Object? failure;
    try {
      await session.setMicrophoneEnabled(true);
      _set(local: CallLocalMedia(microphone: true, camera: snapshot.local.camera));
    } catch (e) {
      failure = e;
    }
    if (kind == 'video') {
      try {
        await session.setCameraEnabled(true);
        _set(local: CallLocalMedia(microphone: snapshot.local.microphone, camera: true));
      } catch (e) {
        failure ??= e;
      }
    }
    // 已经接听,只是没有打开设备:App 引导授权后再打开
    if (failure != null) throw failure;
  } catch (err) {
    if (_session == null) {
      _module.log.warn('连接媒体服务失败', code: err is DRException ? err.code : err.runtimeType.toString());
      // 与 Web SDK 不同:连接失败后可以 resume() 重试(Web SDK 中这个标签页仍算持有媒体连接,不能恢复)
      _holding = false;
      _set(media: 'disconnected');
    }
    rethrow;
  }
}