mybilibili-live-desktop OBS 端启动问题交接文档
生成时间:2026-06-12 项目目录:D:\files\mybilibili-next\mybilibili-cloud\mybilibili-live-desktop 用户数据/日志目录:C:\Users\a1\AppData\Roaming\mybilibili-live-desktop
1. 当前结论
目前能查到明确断点:Electron 主进程已经启动,窗口已经创建,slbundle:// 协议能命中并返回 bundles/vendors~renderer.js 和 bundles/renderer.js,但 renderer bundle 没有真正执行到 webpack/app 启动逻辑。
这不是简单的“缺 real OBS”问题。证据是:
- OBS native 层以前确实初始化成功过,
node-obs/logs/2026-06-03 16-10-28.txt里能看到 OBS API、D3D11、插件、编码器、canvas 初始化。 - 当前失败点发生在更早阶段:Vue/React/store/obs 都没有挂到 window 上,
#app为空。 - 也就是说:现在卡在 Electron renderer JS 执行/入口启动层,而不是卡在 OBS native 初始化层。
最可疑根因排序:
- CSP 阻止脚本执行或阻止 webpack runtime 需要的 eval/new Function/inline 逻辑。
slbundle://协议返回的响应/URL 形态与 Chromium/Electron 29 对 module/runtime/script 执行要求不兼容,导致文件“请求成功”但脚本没有运行。- index.html 中 CSP hash 与当前 inline script 内容不匹配,已经在日志中出现明确 CSP 报错;虽然后续可能调整过,但这类问题仍是当前链路中最高风险点。
- Electron 29 console-message 事件签名改了,当前日志里 renderer 错误被打印成 undefined,导致真正异常被吞掉/看不到。
webpack.base.config.js的output.publicPath: ''配合自定义协议可能导致 runtime/chunk/global 初始化异常;不过当前只有主 bundle 和 vendors,仍需进一步验证。
2. 关键证据
2.1 app.log 证明主进程正常启动,slbundle 协议命中 bundle
文件:C:\Users\a1\AppData\Roaming\mybilibili-live-desktop\app.log
关键日志:
[2026-06-12T05:05:44.981Z] [info] [electron-main] - [ok] slbundle:// 协议已注册 (handle)
[2026-06-12T05:05:45.233Z] [info] [electron-main] - [slbundle] 请求: slbundle://bundles/vendors~renderer.js -> 解析路径: D:\files\mybilibili-next\mybilibili-cloud\mybilibili-live-desktop\bundles\vendors~renderer.js
[2026-06-12T05:05:45.245Z] [info] [electron-main] - [slbundle] 请求: slbundle://bundles/renderer.js -> 解析路径: D:\files\mybilibili-next\mybilibili-cloud\mybilibili-live-desktop\bundles\renderer.js说明:协议 handler 和文件读取不是完全失败,bundle 文件路径存在并被请求。
2.2 renderer 没有真正跑起来
同一个日志文件:
[2026-06-12T05:05:46.057Z] [info] [electron-main] - [DIAG-M1] {"t":1,"w":"?windowId=main","d":""}
[2026-06-12T05:05:46.058Z] [info] [electron-main] - [DIAG-W1] {"t":1,"w":"?windowId=worker","d":""}
[2026-06-12T05:05:48.056Z] [info] [electron-main] - [DIAG-WORKER] {"win":"?windowId=worker","hasObs":false,"hasStore":false,"hasChunks":true,"chunksLen":1,"hasVue":false,"hasReact":false,"hasApp":true,"appHTML":"","OBS_API_result":"not_set","title":"","keys":234,"sampleKeys":"__filename,__dirname,webpackChunkmybilibili_live_desktop,__SENTRY__"}
[2026-06-12T05:05:49.052Z] [info] [electron-main] - [DIAG-MAIN] {"win":"?windowId=main","hasStore":false,"bulkLoadFinished":"no_store","i18nReady":"no_store","title":"","appHTML":"","registeredStores":"no_store","keys":234}解释:
hasChunks:true表示至少 webpack chunk 全局数组出现过,说明部分 JS 或 chunk bootstrap 相关逻辑可能触达。- 但
hasVue:false、hasReact:false、hasStore:false、hasObs:false、appHTML:""表示app/app.ts的实际应用初始化没有完成。 OBS_API_result:"not_set"表示还没进入 OBS API 初始化诊断,失败发生在 OBS init 前。
2.3 曾经有明确 CSP 报错
文件:C:\Users\a1\AppData\Roaming\mybilibili-live-desktop\app.log
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'unsafe-hashes' slbundle: 'sha256-wLcQqK3hC0mVyCtHmjyXOGmZGEWzdtE8WVZ8QazbBCI=' 'sha256-LvV9X60R0/ujDMWZrGm2zH4upC7BKHNh2a60+Ne3Xrc='". Either the 'unsafe-inline' keyword, a hash ('sha256-N0Xj0iMVoxyVcg6Sp5Xhq//DYYKZfJMCPajHfv06ZUY='), or a nonce ('nonce-...') is required to enable inline execution.说明:index.html 当前存在 CSP,并且至少之前 inline script hash 不匹配。当前 index.html:
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-hashes' slbundle: 'sha256-wLcQqK3hC0mVyCtHmjyXOGmZGEWzdtE8WVZ8QazbBCI=' 'sha256-LvV9X60R0/ujDMWZrGm2zH4upC7BKHNh2a60+Ne3Xrc='">
<script>
global = globalThis;
... startupErrorHandler ...
</script>
<script defer src="slbundle://bundles/vendors~renderer.js" ...></script>
<script defer src="slbundle://bundles/renderer.js" ...></script>建议优先临时放宽 CSP 验证是否恢复:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval' file: slbundle:; worker-src 'self' blob: file: slbundle:; connect-src *; img-src * data: file: slbundle:; style-src 'self' 'unsafe-inline' file: slbundle:; font-src * data: file: slbundle:">如果这样能启动,再收紧策略,而不是一开始就靠 hash。
2.4 OBS native 以前能启动,不能把问题归咎为没有 OBS
文件:C:\Users\a1\AppData\Roaming\mybilibili-live-desktop\node-obs\logs\2026-06-03 16-10-28.txt
关键日志:
OBS API version 31.1.3
Initializing D3D11...
D3D11 loaded successfully
Loaded Modules:
win-wasapi.dll
win-spout.dll
win-openvr.dll
win-dshow.dll
win-capture.dll
rtmp-services.dll
obs-x264.dll
obs-outputs.dll
obs-filters.dll
obs-ffmpeg.dll
obs-browser.dll
...
Set streaming encoder. name: simple_streaming_h264_main for service Main
Set streaming encoder. name: simple_streaming_h264_second for service Second说明 OBS 二进制/插件链路不是完全缺失,至少 2026-06-03 这次运行进入过 OBS 初始化与 encoder 设置。
3. 关键文件
main.js
重要片段:
protocol.registerSchemesAsPrivileged在 ready 前注册slbundleapp.on('ready')中protocol.handle('slbundle', ...)startApp()创建workerWindow/mainWindow/childWindow- 三个窗口都加载:
file://${__dirname}/index.html?windowId=worker/main/child- 目前诊断日志在
main.js约 383-436 行附近。
index.html
当前脚本:
<script defer src="slbundle://bundles/vendors~renderer.js"></script>
<script defer src="slbundle://bundles/renderer.js"></script>CSP 是首要怀疑点。
webpack.base.config.js
入口:
entry: {
renderer: './app/app.ts',
},
output: {
path: OUTPUT_DIR,
filename: '[name].js',
publicPath: '',
},
target: 'electron-renderer',externals 包含:
'obs-studio-node': 'require("obs-studio-node")'说明 OBS native 是运行期 require,不会被 bundle 内联。
app/app.ts
真正 renderer/app 入口。当前还没证据表明执行到此文件的 OBS 初始化段。
4. 建议下一步修复方案
第一步:修复/放宽 CSP,确认 renderer 是否能跑起来
临时改 index.html,把 CSP 改成开发态宽松策略:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval' file: slbundle:; worker-src 'self' blob: file: slbundle:; connect-src *; img-src * data: file: slbundle:; style-src 'self' 'unsafe-inline' file: slbundle:; font-src * data: file: slbundle:">然后启动:
yarn start预期如果命中根因,日志中应该出现:
hasVue:true或 Vue/store 相关状态AppInitFinished 收到! worker 初始化完成hasObs:true或 OBS_API_result 不再是not_set#app不再为空
第二步:补全 renderer 错误捕获,解决 Electron 29 console-message 签名问题
目前日志出现:
[renderer:[object Object]] undefined:undefined - undefined这说明 webContents.on('console-message') 处理还按旧签名读参数,Electron 29 新签名会传 event/details 对象,导致真实错误没打出来。
建议在 main.js 里给三个窗口统一加:
function attachWebContentsDiagnostics(name, win) {
win.webContents.on('console-message', (event, level, message, line, sourceId) => {
if (typeof level === 'object') {
const d = level;
console.log(`[renderer:${name}] ${d.level || ''} ${d.sourceId || ''}:${d.lineNumber || ''} - ${d.message || JSON.stringify(d)}`);
} else {
console.log(`[renderer:${name}] ${sourceId}:${line} - ${message}`);
}
});
win.webContents.on('did-fail-load', (event, errorCode, errorDescription, validatedURL) => {
console.error(`[renderer:${name}] did-fail-load ${errorCode} ${errorDescription} ${validatedURL}`);
});
win.webContents.on('render-process-gone', (event, details) => {
console.error(`[renderer:${name}] render-process-gone ${JSON.stringify(details)}`);
});
win.webContents.on('did-finish-load', () => {
console.log(`[renderer:${name}] did-finish-load ${win.webContents.getURL()}`);
});
}并在创建每个窗口后调用:
attachWebContentsDiagnostics('worker', workerWindow);
attachWebContentsDiagnostics('main', mainWindow);
attachWebContentsDiagnostics('child', childWindow);目的:把真正的 renderer exception / CSP / script blocked / MIME blocked 打出来。
第三步:验证 slbundle:// 响应是否被 Chromium 当作可执行脚本
当前 main.js 里 protocol.handle 返回:
return new Response(content, {
status: 200,
headers: { 'Content-Type': contentType }
});可继续强化:
headers: {
'Content-Type': contentType + '; charset=utf-8',
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'no-store'
}另外,若仍失败,可尝试不用 slbundle://,临时把 index.html 改成 file 相对路径:
<script defer src="./bundles/vendors~renderer.js"></script>
<script defer src="./bundles/renderer.js"></script>如果 file 相对路径能启动,说明问题集中在 slbundle:// 自定义协议与 Electron 29/Chromium 的执行策略上。
第四步:如果 renderer 能进 app.ts 后再查 OBS API
一旦 hasVue/hasStore 开始变 true,但 OBS 仍失败,再查:
obs-api/index.jsnode_modules/obs-studio-node/package.jsonnode_modules/obs-studio-node/obs-plugins/64bitnode_modules/obs-studio-node/data/obs-pluginsC:\Users\a1\AppData\Roaming\mybilibili-live-desktop\node-obs\logs\最新日志
当前不应优先在 OBS native 上耗时间,因为现有日志显示还没进入那一步。
5. 已查但未找到/未完成
- 没有在项目目录中找到
b3kyrn81b.output或*.output文件。 - 当前能看到的最新有效诊断来自
app.log。 - 尚未最终确认 CSP 放宽后是否恢复,因为用户要求立即写交接文档。
6. 推荐最小修复顺序
- 改
index.htmlCSP 为开发态宽松版本。 - 修
main.js的 renderer console-message 诊断,兼容 Electron 29。 - 启动
yarn start。 - 看
app.log:- 如果 renderer 开始报具体异常,按异常修。
- 如果
hasVue/hasStore/AppInitFinished出现,说明 CSP/脚本执行问题解决。 - 如果 renderer OK 但 OBS fail,再进入 OBS native 层。
- 若 CSP 放宽无效,临时将
<script src="slbundle://...">改成./bundles/...验证自定义协议是否为根因。
7. 一句话给接手人
别从“缺 OBS 二进制”开始查。这个 fork 的 OBS native 以前已经跑到 OBS API version 31.1.3 和 D3D11/encoder 初始化了;当前断点在 Electron renderer 启动层:bundle 被请求,但 app.ts 没真正启动,首查 CSP、自定义协议 slbundle://、Electron 29 console-message/脚本执行兼容性。