import 'package:PiliPlus/grpc/bilibili/community/service/dm/v1.pb.dart'; import 'package:PiliPlus/grpc/dm.dart'; import 'package:PiliPlus/plugin/pl_player/controller.dart'; import 'package:PiliPlus/services/account_service.dart'; import 'package:get/get.dart'; class PlDanmakuController { PlDanmakuController( this.cid, this.plPlayerController, ) : mergeDanmaku = plPlayerController.mergeDanmaku; final int cid; final PlPlayerController plPlayerController; final bool mergeDanmaku; AccountService accountService = Get.find(); Map> dmSegMap = {}; // 已请求的段落标记 Set requestedSeg = {}; static const int segmentLength = 60 * 6 * 1000; void dispose() { dmSegMap.clear(); requestedSeg.clear(); } int calcSegment(int progress) { return progress ~/ segmentLength; } Future queryDanmaku(int segmentIndex) async { if (requestedSeg.contains(segmentIndex)) { return; } requestedSeg.add(segmentIndex); final result = await DmGrpc.dmSegMobile( cid: cid, segmentIndex: segmentIndex + 1, ); if (result.isSuccess) { final data = result.data; if (data.state == 1) { plPlayerController.dmState.add(cid); } if (data.elems.isNotEmpty) { final Map counts = {}; if (mergeDanmaku) { data.elems.retainWhere((item) { int? count = counts[item.content]; counts[item.content] = count != null ? count + 1 : 1; return count == null; }); } final shouldFilter = plPlayerController.filters.count != 0; for (final element in data.elems) { if (accountService.isLogin.value) { element.isSelf = element.midHash == plPlayerController.midHash; } if (!element.isSelf) { if (element.weight < plPlayerController.danmakuWeight || (shouldFilter && plPlayerController.filters.remove(element))) { continue; } } if (mergeDanmaku) { final count = counts[element.content]; if (count != 1) { element.count = count!; } } int pos = element.progress ~/ 100; //每0.1秒存储一次 (dmSegMap[pos] ??= []).add(element); } } } else { requestedSeg.remove(segmentIndex); } } List? getCurrentDanmaku(int progress) { int segmentIndex = calcSegment(progress); if (!requestedSeg.contains(segmentIndex)) { queryDanmaku(segmentIndex); return null; } return dmSegMap[progress ~/ 100]; } }