1717 <div id =" danmaku-record" class =" setting-box" >
1818 <n-h3 >弹幕录制</n-h3 >
1919 <optional-input type =" boolean" label =" 保存弹幕" v-model:value =" newConfig['optionalRecordDanmaku']"
20- :same-as-default =" true" @changed =" onChanged" />
20+ :same-as-default =" true" @changed =" onChanged" />
2121 <p >本设置同时是所有“弹幕录制”的总开关,当本设置为 false 时其他所有“弹幕录制”设置无效,不会写入弹幕XML文件。</p >
2222 <n-collapse-transition :show =" newConfig['optionalRecordDanmaku']?.value || false" >
23- <optional-input type =" boolean" label =" 保存 SuperChat" v-model:value = " newConfig['optionalRecordDanmakuSuperChat'] "
24- : same-as-default =" true" @changed =" onChanged" />
23+ <optional-input type =" boolean" label =" 保存 SuperChat"
24+ v-model:value = " newConfig['optionalRecordDanmakuSuperChat'] " : same-as-default =" true" @changed =" onChanged" />
2525 <optional-input type =" boolean" label =" 保存 舰长购买" v-model:value =" newConfig['optionalRecordDanmakuGuard']"
26- :same-as-default =" true" @changed =" onChanged" />
26+ :same-as-default =" true" @changed =" onChanged" />
2727 <optional-input type =" boolean" label =" 保存 送礼信息" v-model:value =" newConfig['optionalRecordDanmakuGift']"
28- :same-as-default =" true" @changed =" onChanged" />
28+ :same-as-default =" true" @changed =" onChanged" />
2929 <optional-input type =" boolean" label =" 保存 弹幕原始数据" v-model:value =" newConfig['optionalRecordDanmakuRaw']"
30- :same-as-default =" true" @changed =" onChanged" />
30+ :same-as-default =" true" @changed =" onChanged" />
3131 <n-collapse-transition :show =" showAdvanced" >
3232 <optional-input type =" number" label =" 触发写硬盘所需的弹幕数量"
3333 v-model:value =" newConfig['optionalRecordDanmakuFlushInterval']" :same-as-default =" true" unit =" 个"
34- max-input-width =" 150px" @changed =" onChanged" />
34+ max-input-width =" 150px" @changed =" onChanged" />
3535 </n-collapse-transition >
3636 </n-collapse-transition >
3737 </div >
3838 <div id =" record-mode" class =" setting-box" >
3939 <n-h3 >录制模式</n-h3 >
4040 <optional-input type =" enum" v-model:value =" newConfig['optionalRecordMode']" :enums =" RecordModes"
41- :same-as-default =" true" @changed =" onChanged" />
41+ :same-as-default =" true" @changed =" onChanged" />
4242 <n-collapse-transition :show =" newConfig['optionalRecordMode']?.value == 0" >
4343 <n-h3 >标准模式录制修复设置</n-h3 >
4444 <optional-input type =" boolean" label =" 检测到可能缺少数据时分段"
45- v-model:value =" newConfig['optionalFlvProcessorSplitOnScriptTag']" :same-as-default =" true" @changed =" onChanged" />
45+ v-model:value =" newConfig['optionalFlvProcessorSplitOnScriptTag']" :same-as-default =" true"
46+ @changed =" onChanged" />
47+ <optional-input type =" boolean" label =" 检测到 H264 Annex-B 时禁用修复分段"
48+ v-model:value =" newConfig['optionalFlvProcessorDisableSplitOnH264AnnexB']" :same-as-default =" true"
49+ @changed =" onChanged" />
4650 </n-collapse-transition >
4751 </div >
4852 <div id =" auto-split" class =" setting-box" >
4953 <n-h3 >自动分段</n-h3 >
5054 <optional-input type =" enum" label =" 分段模式" v-model:value =" newConfig['optionalCuttingMode']" :enums =" CuttingModes"
51- :same-as-default =" true" @changed =" onChanged" />
55+ :same-as-default =" true" @changed =" onChanged" />
5256 <n-collapse-transition :show =" newConfig['optionalCuttingMode']?.value == 1" >
5357 <optional-input type =" number" prefix =" 每" suffix =" 保存为一个文件" v-model:value =" newConfig['optionalCuttingNumber']"
54- :same-as-default =" true" unit =" 分" max-input-width =" 150px" @changed =" onChanged" />
58+ :same-as-default =" true" unit =" 分" max-input-width =" 150px" @changed =" onChanged" />
5559 </n-collapse-transition >
5660 <n-collapse-transition :show =" newConfig['optionalCuttingMode']?.value == 2" >
5761 <optional-input type =" number" prefix =" 每" suffix =" 保存为一个文件" v-model:value =" newConfig['optionalCuttingNumber']"
58- :same-as-default =" true" unit =" MiB" max-input-width =" 150px" @changed =" onChanged" />
62+ :same-as-default =" true" unit =" MiB" max-input-width =" 150px" @changed =" onChanged" />
5963 </n-collapse-transition >
6064 <optional-input type =" boolean" label =" 直播间标题修改时切分文件" v-model:value =" newConfig['optionalCuttingByTitle']"
61- :same-as-default =" true" @changed =" onChanged" />
65+ :same-as-default =" true" @changed =" onChanged" />
66+ </div >
67+ <div id =" record-condition" class =" setting-box" >
68+ <n-h3 >录制条件</n-h3 >
69+ <p >直播间标题过滤 </p >
70+ <p >跳过录制的直播标题正则匹配表达式,每行一个</p >
71+ <optional-input type =" textarea" v-model:value =" newConfig['optionalTitleFilterPatterns']" :same-as-default =" true"
72+ @changed =" onChanged" />
6273 </div >
6374 <div id =" storage" class =" setting-box" >
6475 <n-h3 >文件写入</n-h3 >
6576 <optional-input style =" max-width : 700px ;" label =" 文件名" type =" text"
66- v-model:value =" newConfig['optionalFileNameRecordTemplate']" :same-as-default =" false" @changed =" onChanged" />
77+ v-model:value =" newConfig['optionalFileNameRecordTemplate']" :same-as-default =" false" @changed =" onChanged" />
6778 <n-button @click =" toggleFileNamePreviewModal" >预览文件名</n-button >
6879 <optional-input type =" boolean" label =" 保存直播封面" v-model:value =" newConfig['optionalSaveStreamCover']"
69- :same-as-default =" true" @changed =" onChanged" />
80+ :same-as-default =" true" @changed =" onChanged" />
7081 <optional-input type =" boolean" label =" 在flv中写入直播信息" v-model:value =" newConfig['optionalFlvWriteMetadata']"
71- :same-as-default =" true" @changed =" onChanged" />
82+ :same-as-default =" true" @changed =" onChanged" />
7283 </div >
7384 <div id =" record-quality" class =" setting-box" >
7485 <n-h3 >录制画质</n-h3 >
7586 <optional-input style =" max-width : 700px ;" type =" text" v-model:value =" newConfig['optionalRecordingQuality']"
76- :same-as-default =" false" @changed =" onChanged" />
87+ :same-as-default =" false" @changed =" onChanged" />
7788 </div >
7889 <div id =" webhook" class =" setting-box" >
7990 <n-h3 >Webhook</n-h3 >
8394 </p >
8495 <p >Webhook V1</p >
8596 <optional-input type =" textarea" :max-input-width =" '700px'" v-model:value =" newConfig['optionalWebHookUrls']"
86- :same-as-default =" true" @changed =" onChanged" />
97+ :same-as-default =" true" @changed =" onChanged" />
8798 <p >Webhook V2</p >
8899 <optional-input type =" textarea" :max-input-width =" '700px'" v-model:value =" newConfig['optionalWebHookUrlsV2']"
89- :same-as-default =" true" @changed =" onChanged" />
100+ :same-as-default =" true" @changed =" onChanged" />
90101 </div >
91102 <n-collapse-transition :show =" showAdvanced" >
92103 <div id =" live-api-host" >
93104 <n-h3 >请求的 API Host</n-h3 >
94105 <optional-input style =" max-width : 700px ;" type =" text" v-model:value =" newConfig['optionalLiveApiHost']"
95- :same-as-default =" false" @changed =" onChanged" />
106+ :same-as-default =" false" @changed =" onChanged" />
96107 </div >
97108 <div id =" cookie" class =" setting-box" >
98109 <n-h3 >Cookie</n-h3 >
102113 <p >如您知晓您的账号会因以上所列出来的部分原因所导致无法使用或权益受损等情况,并愿意承担由此所会带来的一系列后果,请继续以下的操作,软件开发者不会对您账号所发生的任何后果承担责任。 </p >
103114 </n-alert >
104115 <optional-input type =" text" :max-input-width =" '700px'" v-model:value =" newConfig['optionalCookie']"
105- :same-as-default =" true" @changed =" onChanged" />
116+ :same-as-default =" true" @changed =" onChanged" />
106117 </div >
107118 <div id =" network" class =" setting-box" >
108119 <n-h3 >网络设置</n-h3 >
109120 <optional-input type =" boolean" label =" 使用系统代理"
110- v-model:value =" newConfig['optionalNetworkTransportUseSystemProxy']" :same-as-default =" true" @changed =" onChanged" />
121+ v-model:value =" newConfig['optionalNetworkTransportUseSystemProxy']" :same-as-default =" true"
122+ @changed =" onChanged" />
111123 <optional-input type =" enum" label =" 允许使用的网络类型"
112124 v-model:value =" newConfig['optionalNetworkTransportAllowedAddressFamily']" :enums =" IPFamilies"
113- :same-as-default =" true" @changed =" onChanged" />
125+ :same-as-default =" true" @changed =" onChanged" />
114126 <optional-input type =" enum" label =" 弹幕链接协议" v-model:value =" newConfig['optionalDanmakuTransport']"
115- :enums =" DanmakuTransport" :same-as-default =" true" @changed =" onChanged" />
127+ :enums =" DanmakuTransport" :same-as-default =" true" @changed =" onChanged" />
116128 <optional-input type =" boolean" label =" 使用直播间主播的uid进行弹幕服务器认证"
117- v-model:value =" newConfig['optionalDanmakuAuthenticateWithStreamerUid']" :same-as-default =" true" @changed =" onChanged" />
129+ v-model:value =" newConfig['optionalDanmakuAuthenticateWithStreamerUid']" :same-as-default =" true"
130+ @changed =" onChanged" />
118131 </div >
119132 <div id =" timing" class =" setting-box" >
120133 <n-h3 >时间间隔</n-h3 >
121134 <optional-input style =" max-width : 700px ;" type =" number" label =" HTTP API 检查时间间隔"
122- v-model:value =" newConfig['optionalTimingCheckInterval']" unit =" 秒" max-input-width =" 150px" @changed =" onChanged" />
135+ v-model:value =" newConfig['optionalTimingCheckInterval']" unit =" 秒" max-input-width =" 150px"
136+ @changed =" onChanged" />
123137 <optional-input style =" max-width : 700px ;" type =" number" label =" API请求超时时间"
124- v-model:value =" newConfig['optionalTimingApiTimeout']" unit =" 毫秒" max-input-width =" 150px" @changed =" onChanged" />
138+ v-model:value =" newConfig['optionalTimingApiTimeout']" unit =" 毫秒" max-input-width =" 150px"
139+ @changed =" onChanged" />
125140 <optional-input style =" max-width : 700px ;" type =" number" label =" 录制断开重连时间间隔"
126- v-model:value =" newConfig['optionalTimingStreamRetry']" unit =" 毫秒" max-input-width =" 150px" @changed =" onChanged" />
141+ v-model:value =" newConfig['optionalTimingStreamRetry']" unit =" 毫秒" max-input-width =" 150px"
142+ @changed =" onChanged" />
127143 <optional-input style =" max-width : 700px ;" type =" number" label =" 录制无指定画质重连时间间隔"
128- v-model:value =" newConfig['optionalTimingStreamRetryNoQn']" unit =" 秒" max-input-width =" 150px" @changed =" onChanged" />
144+ v-model:value =" newConfig['optionalTimingStreamRetryNoQn']" unit =" 秒" max-input-width =" 150px"
145+ @changed =" onChanged" />
129146 <optional-input style =" max-width : 700px ;" type =" number" label =" 最大允许未收到直播数据时间"
130- v-model:value =" newConfig['optionalTimingWatchdogTimeout']" unit =" 毫秒" max-input-width =" 150px" @changed =" onChanged" />
147+ v-model:value =" newConfig['optionalTimingWatchdogTimeout']" unit =" 毫秒" max-input-width =" 150px"
148+ @changed =" onChanged" />
131149 <optional-input style =" max-width : 700px ;" type =" number" label =" 连接直播服务器超时时间"
132- v-model:value =" newConfig['optionalTimingStreamConnect']" unit =" 毫秒" max-input-width =" 150px" @changed =" onChanged" />
150+ v-model:value =" newConfig['optionalTimingStreamConnect']" unit =" 毫秒" max-input-width =" 150px"
151+ @changed =" onChanged" />
133152 <optional-input style =" max-width : 700px ;" type =" number" label =" 弹幕服务器重连时间间隔"
134- v-model:value =" newConfig['optionalTimingDanmakuRetry']" unit =" 毫秒" max-input-width =" 150px" @changed =" onChanged" />
153+ v-model:value =" newConfig['optionalTimingDanmakuRetry']" unit =" 毫秒" max-input-width =" 150px"
154+ @changed =" onChanged" />
135155 </div >
136156 <div id =" userscript" class =" setting-box" >
137157 <n-h3 >用户脚本</n-h3 >
138158 <optional-input type =" textarea" :max-input-width =" '700px'" v-model:value =" newConfig['optionalUserScript']"
139- :same-as-default =" true" @changed =" onChanged" />
159+ :same-as-default =" true" @changed =" onChanged" />
140160 </div >
141161 </n-collapse-transition >
142- <n-affix v-if =" isChanged"
143- :bottom =" 32"
144- :trigger-bottom =" 128"
145- :listen-to =" () => containerRef"
162+ <n-affix v-if =" isChanged" :bottom =" 32" :trigger-bottom =" 128" :listen-to =" () => containerRef"
146163 style =" max-width : 700px ; width : calc (100% - 80px );" >
147164 <n-card size =" small" >
148- <div style =" margin :4px 0 ;font-size : 1.125em ; display : inline-block ;" >注意!你尚未保存修改!</div ><n-button @click =" saveConfig" type =" primary" style =" float : right ;" >保存</n-button >
165+ <div style =" margin :4px 0 ;font-size : 1.125em ; display : inline-block ;" >注意!你尚未保存修改!</div ><n-button
166+ @click =" saveConfig" type =" primary" style =" float : right ;" >保存</n-button >
149167 </n-card >
150168 </n-affix >
151169 </div >
@@ -274,6 +292,7 @@ const newConfig = ref<{ [key: string]: ConfigItem }>({
274292 ' optionalCuttingMode' : getEmptyConfigItem (defaultConfig .value .cuttingMode ),
275293 ' optionalFileNameRecordTemplate' : getEmptyConfigItem (defaultConfig .value .fileNameRecordTemplate ),
276294 ' optionalFlvProcessorSplitOnScriptTag' : getEmptyConfigItem (defaultConfig .value .flvProcessorSplitOnScriptTag ),
295+ ' optionalFlvProcessorDisableSplitOnH264AnnexB' : getEmptyConfigItem (defaultConfig .value .flvProcessorDisableSplitOnH264AnnexB ),
277296 ' optionalRecordingQuality' : getEmptyConfigItem (defaultConfig .value .recordingQuality ),
278297 ' optionalCuttingNumber' : getEmptyConfigItem (defaultConfig .value .cuttingNumber ),
279298 ' optionalCuttingByTitle' : getEmptyConfigItem (defaultConfig .value .cuttingByTitle ),
@@ -294,6 +313,7 @@ const newConfig = ref<{ [key: string]: ConfigItem }>({
294313 ' optionalUserScript' : getEmptyConfigItem (defaultConfig .value .userScript ),
295314 ' optionalSaveStreamCover' : getEmptyConfigItem (defaultConfig .value .saveStreamCover ),
296315 ' optionalFlvWriteMetadata' : getEmptyConfigItem (defaultConfig .value .flvWriteMetadata ),
316+ ' optionalTitleFilterPatterns' : getEmptyConfigItem (defaultConfig .value .titleFilterPatterns ),
297317});
298318
299319let lastload: string | undefined = ' ' ;
@@ -422,8 +442,8 @@ const containerRef = ref(document.getElementById('content-scrollbar')?.children[
422442 flex-direction : row
423443}
424444
425- .settings-container-internal {
426- flex :1 ;
445+ .settings-container-internal {
446+ flex : 1 ;
427447 max-width : 700px ;
428448 margin : auto ;
429449 padding-bottom : 64px ;
0 commit comments