diff --git a/lib/http/danmaku.dart b/lib/http/danmaku.dart index 020c89ea..87f08d8b 100644 --- a/lib/http/danmaku.dart +++ b/lib/http/danmaku.dart @@ -17,17 +17,11 @@ class DanmakaHttp { 'oid': cid, 'segment_index': segmentIndex, }; - - // 计算函数 - Future computeTask(Map 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); } } diff --git a/lib/pages/danmaku/controller.dart b/lib/pages/danmaku/controller.dart index ebe7712d..576d4f3c 100644 --- a/lib/pages/danmaku/controller.dart +++ b/lib/pages/danmaku/controller.dart @@ -10,22 +10,32 @@ class PlDanmakuController { // 按 6min 分段 int segCount = 0; List dmSegList = []; - int currentSegIndex = 0; + int currentSegIndex = 1; int currentDmIndex = 0; void calcSegment() { + dmSegList.clear(); + // 视频分段数 segCount = (videoDuration.inSeconds / (60 * 6)).ceil(); + dmSegList = List.generate( + segCount < 1 ? 1 : segCount, (index) => DmSegMobileReply()); + // 当前分段 + try { + currentSegIndex = + (playerController.position.value.inSeconds / (60 * 6)).ceil(); + currentSegIndex = currentSegIndex < 1 ? 1 : currentSegIndex; + } catch (_) {} } Future> 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); diff --git a/lib/pages/danmaku/view.dart b/lib/pages/danmaku/view.dart index 640a4744..5a5d8a11 100644 --- a/lib/pages/danmaku/view.dart +++ b/lib/pages/danmaku/view.dart @@ -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 { 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 { @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) {}, ), - ), - ); + ); + }); } }