Skip to content

Commit

Permalink
Optimize danmaku matching for segment's skipping
Browse files Browse the repository at this point in the history
优化逻辑,匹配更多时间格式的弹幕
  • Loading branch information
xiaoxuan010 committed Dec 26, 2024
1 parent 7967ec8 commit ced1368
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 76 deletions.
12 changes: 0 additions & 12 deletions public/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -786,18 +786,6 @@
"checkTimeDanmakuSkip": {
"message": "检查片段附近是否已有上传的跳过信息,已有则不触发此功能"
},
"danmakuTimeMatchingRegexPattern": {
"message": "空降时间匹配正则: "
},
"danmakuRegexPatternPlaceholder": {
"message": "能匹配2~3组数字的正则表达式"
},
"danmakuRegexTitle": {
"message": "请输入一个匹配时间格式的正则表达式,要求能捕获2~3组数字。如果不清楚如何写正则表达式,请勿修改此项"
},
"danmakuTimeMatchingRegexPatternDescription": {
"message": "空降时间匹配类似“01:23”“四分五十六秒”“1分2秒”等格式的弹幕。"
},
"danmakuOffsetMatchingRegexPattern": {
"message": "时间偏移匹配正则: "
},
Expand Down
12 changes: 0 additions & 12 deletions public/_locales/zh_CN/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -786,18 +786,6 @@
"checkTimeDanmakuSkip": {
"message": "检查片段附近是否已有上传的跳过信息,已有则不触发此功能"
},
"danmakuTimeMatchingRegexPattern": {
"message": "空降时间匹配正则: "
},
"danmakuRegexPatternPlaceholder": {
"message": "能匹配2~3组数字的正则表达式"
},
"danmakuRegexTitle": {
"message": "请输入一个匹配时间格式的正则表达式,要求能捕获2~3组数字。如果不清楚如何写正则表达式,请勿修改此项"
},
"danmakuTimeMatchingRegexPatternDescription": {
"message": "空降时间匹配类似“01:23”“四分五十六秒”“1分2秒”等格式的弹幕。"
},
"danmakuOffsetMatchingRegexPattern": {
"message": "时间偏移匹配正则: "
},
Expand Down
14 changes: 1 addition & 13 deletions public/_locales/zh_TW/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -786,18 +786,6 @@
"checkTimeDanmakuSkip": {
"message": "檢查片段附近是否已有上傳的跳過資訊,已有則不觸發此功能"
},
"danmakuTimeMatchingRegexPattern": {
"message": "空降時間匹配正則: "
},
"danmakuRegexPatternPlaceholder": {
"message": "能匹配2~3組數字的正則表達式"
},
"danmakuRegexTitle": {
"message": "請輸入一個匹配時間格式的正則表達式,要求能捕獲2~3組數字。如果不清楚如何寫正則表達式,請勿修改此項"
},
"danmakuTimeMatchingRegexPatternDescription": {
"message": "空降時間匹配類似“01:23”“四分五十六秒”“1分2秒”等格式的彈幕。"
},
"danmakuOffsetMatchingRegexPattern": {
"message": "時間偏移匹配正則: "
},
Expand All @@ -809,7 +797,7 @@
},
"danmakuOffsetRegexPatternDescription": {
"message": "時間偏移匹配類似“向右12下”“右方向34次”等格式的彈幕,並以此計算空降時間。"
},
},
"muteSegments": {
"message": "允許片段靜音而不是跳過"
},
Expand Down
23 changes: 8 additions & 15 deletions public/options/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@

<div id="createdBy" class="titleBar">
<div>
<img src="../icons/creator.png" height="30" class="profilepiccircle" alt="profile picture of creator" />
<img src="../icons/creator.png" height="30" class="profilepiccircle"
alt="profile picture of creator" />
__MSG_createdBy__
<a href="https://github.com/hanydd">hanyd</a>
</div>
Expand Down Expand Up @@ -277,7 +278,8 @@ <h3>__MSG_optionSectionPlayerAndButtons__</h3>
<div class="switch-label" data-dependent-on="showNewIcon" style="position: absolute;">
<img class="playerButtonImage" src="../icons/PlayerStartIconSponsorBlocker.svg">
</div>
<div class="switch-label" data-dependent-on="showNewIcon" data-dependent-on-inverted="true" style="position: absolute;">
<div class="switch-label" data-dependent-on="showNewIcon" data-dependent-on-inverted="true"
style="position: absolute;">
<img class="playerButtonImage" src="../icons/oldIcon/PlayerStartIconSponsorBlocker.svg">
</div>
</div>
Expand All @@ -295,7 +297,8 @@ <h3>__MSG_optionSectionPlayerAndButtons__</h3>
<div class="switch-label" data-dependent-on="showNewIcon" style="position: absolute;">
<img class="playerButtonImage" src="../icons/PlayerStartIconSponsorBlocker.svg">
</div>
<div class="switch-label" data-dependent-on="showNewIcon" data-dependent-on-inverted="true" style="position: absolute;">
<div class="switch-label" data-dependent-on="showNewIcon" data-dependent-on-inverted="true"
style="position: absolute;">
<img class="playerButtonImage" src="../icons/oldIcon/PlayerStartIconSponsorBlocker.svg">
</div>
</div>
Expand Down Expand Up @@ -357,7 +360,8 @@ <h3>__MSG_optionSectionPlayerAndButtons__</h3>
<div class="switch-label" data-dependent-on="showNewIcon" style="position: absolute;">
<img class="playerButtonImage" src="../icons/skip.svg">
</div>
<div class="switch-label" data-dependent-on="showNewIcon" data-dependent-on-inverted="true" style="position: absolute;">
<div class="switch-label" data-dependent-on="showNewIcon" data-dependent-on-inverted="true"
style="position: absolute;">
<img class="playerButtonImage" src="../icons/oldIcon/skipIcon.svg">
</div>
</div>
Expand Down Expand Up @@ -776,17 +780,6 @@ <h2>__MSG_exportOtherData__</h2>
</div>
</div>

<div data-type="text-change" data-sync="danmakuTimeMatchingRegexPattern" class="no-bottom-border">
<div class="input-container">
<label for="danmakuTimeMatchingRegexPattern">__MSG_danmakuTimeMatchingRegexPattern__</label>
<input id="danmakuTimeMatchingRegexPattern" class="option-text-box" type="text"
placeholder="__MSG_danmakuTimeMatchingRegexPatternPlaceholder__" title="__MSG_danmakuRegexTitle__" />
<button class="text-change-set">__MSG_save__</button>
<button class="text-change-reset">__MSG_reset__</button>
</div>
<div class="small-description">__MSG_danmakuTimeMatchingRegexPatternDescription__</div>
</div>

<div data-type="text-change" data-sync="danmakuOffsetMatchingRegexPattern">
<div class="input-container">
<label for="danmakuOffsetMatchingRegexPattern">__MSG_danmakuOffsetMatchingRegexPattern__</label>
Expand Down
20 changes: 14 additions & 6 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as CompileConfig from "../config.json";
import { Keybind, ProtoConfig, keybindEquals } from "./config/config";
import {
Category,
CategorySelection,
CategorySkipOption,
NoticeVisbilityMode,
PreviewBarOption,
SponsorHideType,
SponsorTime,
VideoID,
SponsorHideType,
} from "./types";
import { Keybind, ProtoConfig, keybindEquals } from "./config/config";
import { HashedValue } from "./utils/hash";

export interface Permission {
Expand All @@ -33,7 +33,6 @@ interface SBConfig {
enableDanmakuSkip: boolean;
enableAutoSkipDanmakuSkip: boolean;
enableMenuDanmakuSkip: boolean;
danmakuTimeMatchingRegexPattern: string;
danmakuOffsetMatchingRegexPattern: string;
checkTimeDanmakuSkip: boolean;
muteSegments: boolean;
Expand Down Expand Up @@ -192,9 +191,20 @@ function migrateOldSyncFormats(config: SBConfig) {
config["serverAddress"] = CompileConfig.serverAddress;
}

// "danmakuRegexPattern" 在 0.5.9 版本中被移除,
// "danmakuRegexPattern" 在 0.6.0 版本中被移除,
// 取而代之的是 "danmakuTimeMatchingRegexPattern" 和 "danmakuOffsetMatchingRegexPattern"
delete config["danmakuRegexPattern"];

//"danmakuTimeMatchingRegexPattern" 在 0.6.1 版本中被移除(预计)
delete config["danmakuTimeMatchingRegexPattern"];

// 更新默认的弹幕偏移匹配正则表达式
const oldDanmakuOffsetMatchingRegexPatterns = [
"(?:^|(右|右滑|按|右下|右向|右方向|→|⇒|⇢|⇨|⮕|🡆|🠺|🠾|🢒|👉))(\\d+)(下|次)?$", // 0.6.0
];
if (oldDanmakuOffsetMatchingRegexPatterns.includes(config["danmakuOffsetMatchingRegexPattern"])) {
config["danmakuOffsetMatchingRegexPattern"] = syncDefaults.danmakuOffsetMatchingRegexPattern;
}
}

const syncDefaults = {
Expand All @@ -216,8 +226,6 @@ const syncDefaults = {
enableDanmakuSkip: false,
enableAutoSkipDanmakuSkip: false,
enableMenuDanmakuSkip: false,
danmakuTimeMatchingRegexPattern:
"(?:(\\d{1,2})\\s*(?:小时|h|H|:|:|;|;|\\.|-|—)\\s*)?(?:(\\d{1,2})\\s*(?:分钟|分|:|:|;|;|\\.|-|—|m|M)\\s*)?(?:(\\d{1,2})\\s*(秒|s|S)?)",
danmakuOffsetMatchingRegexPattern: "(?:^|(右|右滑|按|右下|右向|右方向|→|⇒|⇢|⇨|⮕|🡆|🠺|🠾|🢒|👉))(\\d+)(下|次)?$",
checkTimeDanmakuSkip: true,

Expand Down
50 changes: 32 additions & 18 deletions src/utils/danmakusUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,33 @@ export function parseTargetTimeFromDanmaku(text: string, currentTime: number) {
* @param text - 包含需要解析的时间的输入字符串。
* @returns 由时间字符串表示的总秒数,如果时间字符串无效则返回null。
*
* 该函数使用在 `Config.config.danmakuTimeMatchingRegexPattern` 中定义的正则表达式模式
* 来匹配和提取输入字符串中的小时、分钟和秒。如果匹配成功且有效,
* 它通过将小时转换为秒、分钟转换为秒并将它们加到解析的秒数中来计算总秒数。
* 该函数使用正则表达式来匹配和提取输入字符串中的小时、分钟和秒。
* 如果匹配成功且有效,则返回总秒数;否则返回null。
*/
function parseTime(text: string) {
const regex = new RegExp(Config.config.danmakuTimeMatchingRegexPattern, "g");
const danmakuTimeMatchingRegex =
/(?:(\d{1,2})\s*(?:(|h|H)|(:|||;|\.|-|))\s*)?(?:(\d{1,2})\s*(||:|||;|\.|-||m|M)\s*)?(?:(\d{1,2}|)\s*(|s|S)?)/g;

let match: RegExpExecArray | null;
while ((match = regex.exec(text)) !== null) {
const [, , minutes, seconds, secondsSuffix] = match;
while ((match = danmakuTimeMatchingRegex.exec(text)) !== null) {
const [, hours, hourSpecificSuffix, , minutes, minuteSuffix, seconds, secondSuffix] = match;

if (seconds !== undefined && (secondSuffix !== undefined || minutes !== undefined || hours !== undefined)) {
let hoursNum = hours ? parseInt(hours) : 0;
let minutesNum = minutes ? parseInt(minutes) : 0;
const secondsNum = seconds === "整" ? 0 : parseInt(seconds);

if (seconds && (secondsSuffix || minutes)) {
const hours = parseInt(match[1] || "0");
const minutes = parseInt(match[2] || "0");
const seconds = parseInt(match[3] || "0");
return hours * 3600 + minutes * 60 + seconds;
if (
hours !== undefined &&
hourSpecificSuffix === undefined &&
minutes === undefined &&
minuteSuffix === undefined
) {
minutesNum = hoursNum;
hoursNum = 0;
}

return hoursNum * 3600 + minutesNum * 60 + secondsNum;
}
}

Expand Down Expand Up @@ -65,10 +76,13 @@ export function parseTargetTimeFromDanmaku(text: string, currentTime: number) {
text = text.replace(/[]+/g, (cnNum) => parseChineseNumber(cnNum));

const directParsedTime = parseTime(text);
if (directParsedTime) return directParsedTime;
else {
if (directParsedTime) {
return directParsedTime;
} else {
const offsetParsedTime = parseOffsetTime(text);
if (offsetParsedTime) return offsetParsedTime + currentTime;
if (offsetParsedTime) {
return offsetParsedTime + currentTime;
}
}
return null;
}
Expand All @@ -77,18 +91,18 @@ export function parseTargetTimeFromDanmaku(text: string, currentTime: number) {
* 将中文数字字符串转换为阿拉伯数字字符串。
*
* @param inputText - 包含中文数字的字符串。
* @returns 转换后的阿拉伯数字字符串。如果输入包含无效字符,则返回 null
* @returns 转换后的阿拉伯数字字符串。如果输入包含无效字符,则返回空字符串
*
* @example
* ```typescript
* parseChineseNumber("一"); // 返回 "1"
* parseChineseNumber("十二"); // 返回 "12"
* parseChineseNumber("二十"); // 返回 "20"
* parseChineseNumber("二十一"); // 返回 "21"
* parseChineseNumber("一百"); // 返回 null
* parseChineseNumber("一百"); // 返回 ""
* ```
*/
export function parseChineseNumber(inputText: string) {
export function parseChineseNumber(inputText: string): string {
const cnChrMap: { [key: string]: number } = {
: 0,
: 1,
Expand Down Expand Up @@ -130,7 +144,7 @@ export function parseChineseNumber(inputText: string) {
num = num * unit;
unit = 1;
} else {
return null;
return "";
}
}

Expand Down

0 comments on commit ced1368

Please sign in to comment.