mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: merge danmaku
Closes #150 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import 'package:PiliPlus/grpc/dm/v1/dm.pb.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'index.dart';
|
||||
|
||||
@@ -7,6 +8,7 @@ class DanmakaHttp {
|
||||
static Future queryDanmaku({
|
||||
required int cid,
|
||||
required int segmentIndex,
|
||||
required bool mergeDanmaku,
|
||||
}) async {
|
||||
// 构建参数对象
|
||||
Map<String, int> params = {
|
||||
@@ -22,7 +24,11 @@ class DanmakaHttp {
|
||||
if (response.statusCode != 200 || response.data == null) {
|
||||
return DmSegMobileReply();
|
||||
}
|
||||
return DmSegMobileReply.fromBuffer(response.data);
|
||||
DmSegMobileReply data = DmSegMobileReply.fromBuffer(response.data);
|
||||
if (mergeDanmaku) {
|
||||
data.elems.unique((item) => item.content);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static Future shootDanmaku({
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:PiliPlus/grpc/dm/v1/dm.pb.dart';
|
||||
import 'package:PiliPlus/http/danmaku.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/utils/storage.dart';
|
||||
|
||||
class PlDanmakuController {
|
||||
PlDanmakuController(
|
||||
@@ -18,6 +19,8 @@ class PlDanmakuController {
|
||||
|
||||
static int segmentLength = 60 * 6 * 1000;
|
||||
|
||||
late final mergeDanmaku = GStorage.mergeDanmaku;
|
||||
|
||||
void initiate(int videoDuration, int progress) {
|
||||
if (videoDuration <= 0) {
|
||||
return;
|
||||
@@ -45,7 +48,10 @@ class PlDanmakuController {
|
||||
assert(requestedSeg[segmentIndex] == false);
|
||||
requestedSeg[segmentIndex] = true;
|
||||
final DmSegMobileReply result = await DanmakaHttp.queryDanmaku(
|
||||
cid: cid, segmentIndex: segmentIndex + 1);
|
||||
cid: cid,
|
||||
segmentIndex: segmentIndex + 1,
|
||||
mergeDanmaku: mergeDanmaku,
|
||||
);
|
||||
if (result.elems.isNotEmpty) {
|
||||
for (var element in result.elems) {
|
||||
int pos = element.progress ~/ 100; //每0.1秒存储一次
|
||||
|
||||
@@ -1754,6 +1754,14 @@ List<SettingsModel> get extraSettings => [
|
||||
setKey: SettingBoxKey.showVipDanmaku,
|
||||
defaultVal: true,
|
||||
),
|
||||
SettingsModel(
|
||||
settingsType: SettingsType.sw1tch,
|
||||
title: '合并弹幕',
|
||||
subtitle: '合并一段时间内获取到的相同弹幕',
|
||||
leading: Icon(Icons.merge),
|
||||
setKey: SettingBoxKey.mergeDanmaku,
|
||||
defaultVal: false,
|
||||
),
|
||||
SettingsModel(
|
||||
settingsType: SettingsType.sw1tch,
|
||||
enableFeedback: true,
|
||||
|
||||
@@ -88,3 +88,12 @@ extension BuildContextExt on BuildContext {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension Unique<E, Id> on List<E> {
|
||||
List<E> unique([Id Function(E element)? id, bool inplace = true]) {
|
||||
final ids = <dynamic>{};
|
||||
var list = inplace ? this : List<E>.from(this);
|
||||
list.retainWhere((x) => ids.add(id != null ? id(x) : x as Id));
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,6 +339,9 @@ class GStorage {
|
||||
static bool get showVipDanmaku =>
|
||||
GStorage.setting.get(SettingBoxKey.showVipDanmaku, defaultValue: true);
|
||||
|
||||
static bool get mergeDanmaku =>
|
||||
GStorage.setting.get(SettingBoxKey.mergeDanmaku, defaultValue: false);
|
||||
|
||||
static List<double> get dynamicDetailRatio => List<double>.from(setting
|
||||
.get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0]));
|
||||
|
||||
@@ -558,6 +561,7 @@ class SettingBoxKey {
|
||||
refreshDragPercentage = 'refreshDragPercentage',
|
||||
refreshDisplacement = 'refreshDisplacement',
|
||||
showVipDanmaku = 'showVipDanmaku',
|
||||
mergeDanmaku = 'mergeDanmaku',
|
||||
|
||||
// Sponsor Block
|
||||
enableSponsorBlock = 'enableSponsorBlock',
|
||||
|
||||
Reference in New Issue
Block a user