fix: 弹幕数量少于实际数量&优化弹幕请求 issues #78

This commit is contained in:
guozhigq
2023-09-17 22:30:22 +08:00
parent 7fa7152245
commit dd97636494
3 changed files with 58 additions and 41 deletions

View File

@ -17,17 +17,11 @@ class DanmakaHttp {
'oid': cid,
'segment_index': segmentIndex,
};
// 计算函数
Future<DmSegMobileReply> computeTask(Map<String, int> params) async {
var response = await Request().get(
Api.webDanmaku,
data: params,
extra: {'resType': ResponseType.bytes},
);
return DmSegMobileReply.fromBuffer(response.data);
}
return await compute(computeTask, params);
var response = await Request().get(
Api.webDanmaku,
data: params,
extra: {'resType': ResponseType.bytes},
);
return DmSegMobileReply.fromBuffer(response.data);
}
}

View File

@ -10,22 +10,32 @@ class PlDanmakuController {
// 按 6min 分段
int segCount = 0;
List<DmSegMobileReply> dmSegList = [];
int currentSegIndex = 0;
int currentSegIndex = 1;
int currentDmIndex = 0;
void calcSegment() {
dmSegList.clear();
// 视频分段数
segCount = (videoDuration.inSeconds / (60 * 6)).ceil();
dmSegList = List<DmSegMobileReply>.generate(
segCount < 1 ? 1 : segCount, (index) => DmSegMobileReply());
// 当前分段
try {
currentSegIndex =
(playerController.position.value.inSeconds / (60 * 6)).ceil();
currentSegIndex = currentSegIndex < 1 ? 1 : currentSegIndex;
} catch (_) {}
}
Future<List<DmSegMobileReply>> queryDanmaku() async {
dmSegList.clear();
for (int segIndex = 1; segIndex <= segCount; segIndex++) {
DmSegMobileReply result =
await DanmakaHttp.queryDanmaku(cid: cid, segmentIndex: segIndex);
if (result.elems.isNotEmpty) {
result.elems.sort((a, b) => (a.progress).compareTo(b.progress));
dmSegList.add(result);
}
// dmSegList.clear();
DmSegMobileReply result =
await DanmakaHttp.queryDanmaku(cid: cid, segmentIndex: currentSegIndex);
if (result.elems.isNotEmpty) {
result.elems.sort((a, b) => (a.progress).compareTo(b.progress));
// dmSegList.add(result);
currentSegIndex = currentSegIndex < 1 ? 1 : currentSegIndex;
dmSegList[currentSegIndex - 1] = result;
}
if (dmSegList.isNotEmpty) {
findClosestPositionIndex(playerController.position.value.inMilliseconds);

View File

@ -1,3 +1,4 @@
import 'package:easy_debounce/easy_throttle.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
@ -88,7 +89,15 @@ class _PlDanmakuState extends State<PlDanmaku> {
PlDanmakuController ctr = _plDanmakuController;
int currentPosition = position.inMilliseconds;
blockTypes = playerController.blockTypes;
// 根据position判断是否有已缓存弹幕。没有则请求对应段
int segIndex = (currentPosition / (6 * 60 * 1000)).ceil();
segIndex = segIndex < 1 ? 1 : segIndex;
if (ctr.dmSegList[segIndex - 1].elems.isEmpty) {
ctr.currentSegIndex = segIndex;
EasyThrottle.throttle('follow', const Duration(seconds: 1), () {
ctr.queryDanmaku();
});
}
if (!playerController.isOpenDanmu.value) {
return;
}
@ -140,26 +149,30 @@ class _PlDanmakuState extends State<PlDanmaku> {
@override
Widget build(BuildContext context) {
return Obx(
() => AnimatedOpacity(
opacity: playerController.isOpenDanmu.value ? 1 : 0,
duration: const Duration(milliseconds: 100),
child: DanmakuView(
createdController: (DanmakuController e) async {
widget.playerController.danmakuController = _controller = e;
},
option: DanmakuOption(
fontSize: 15 * fontSizeVal,
area: showArea,
opacity: opacityVal,
hideTop: blockTypes.contains(5),
hideScroll: blockTypes.contains(2),
hideBottom: blockTypes.contains(4),
duration: danmakuSpeedVal * widget.playerController.playbackSpeed,
return LayoutBuilder(builder: (context, box) {
double initDuration = box.maxWidth / 12;
return Obx(
() => AnimatedOpacity(
opacity: playerController.isOpenDanmu.value ? 1 : 0,
duration: const Duration(milliseconds: 100),
child: DanmakuView(
createdController: (DanmakuController e) async {
widget.playerController.danmakuController = _controller = e;
},
option: DanmakuOption(
fontSize: 15 * fontSizeVal,
area: showArea,
opacity: opacityVal,
hideTop: blockTypes.contains(5),
hideScroll: blockTypes.contains(2),
hideBottom: blockTypes.contains(4),
duration: initDuration /
(danmakuSpeedVal * widget.playerController.playbackSpeed),
),
statusChanged: (isPlaying) {},
),
statusChanged: (isPlaying) {},
),
),
);
);
});
}
}