/// 把账号服务 `/api/rtc_token` 的响应收成进房凭证。 /// /// 现网成功体:`{ code: 0, data: { token } }`,可选 `liveURL` / `serverUrl`。 /// 缺少直播地址时由调用方填 [fallbackLiveUrl],不得改服务端。 class CompanyRtcCredential { const CompanyRtcCredential({required this.token, required this.liveURL}); final String token; final String liveURL; } class RtcTokenMapper { RtcTokenMapper._(); static CompanyRtcCredential parse( dynamic body, { required String fallbackLiveUrl, }) { if (body is! Map) { throw const FormatException('语音通话凭证格式不正确'); } final map = Map.from(body); final code = map['code']; if (code != null && code != 0) { final msg = map['msg']?.toString() ?? ''; throw FormatException(msg.isNotEmpty ? msg : '获取通话凭证失败'); } final data = map['data']; final payload = data is Map ? Map.from(data) : map; final token = payload['token']?.toString() ?? ''; if (token.isEmpty) { throw const FormatException('服务器未返回通话凭证'); } final live = payload['liveURL']?.toString() ?? payload['serverUrl']?.toString() ?? ''; return CompanyRtcCredential( token: token, liveURL: live.isNotEmpty ? live : fallbackLiveUrl, ); } }