1.play时的核心调用流程
在d:\work\jessibuca\src\jessibuca.js的play方法中,实际上存在一个等待机制。
第一阶段:Jessibuca 层 (jessibuca.js)
- 检查加载状态:调用
hasLoaded()。- 如果已加载(Worker 等资源就绪):直接调用
this.player.play()。 - 如果未加载:监听
decoderWorkerInit事件(第 698 行),等待 Worker 初始化完成后,再执行第 704 行的this.player.play()。
- 如果已加载(Worker 等资源就绪):直接调用
- 核心代码:
// d:\work\jessibuca\src\jessibuca.js (L698-704)this.player.once(EVENTS.decoderWorkerInit,()=>{// ... 清理超时 ...this.debug.log('Jessibuca','_play decoderWorkerInit success and play');this.player.play(url,options).then(()=>{// <--- 也就是您看到的这里resolve();})// ...})
第二阶段:Player 层 (player/index.js)Jessibuca将操作委托给Player实例,Player.play(L471) 是真正的调度中心:
- 初始化检查:调用
this.init()(L487)。- 确保
Stream(流处理)、Audio(音频)、Demux(解复用)、DecoderWorker(解码器) 等模块已创建。
- 确保
- 获取流:
init完成后,调用this.stream.fetchStream(url, options)(L531)。- 这是开始网络请求(如 WebSocket/Fetch)获取视频流的地方。
- 流成功回调:监听
EVENTS.streamSuccess(L554)。- 流建立成功后,调用
resolve()并触发this.video.play()开始渲染。
- 流建立成功后,调用
2. Worker 是在哪引入、在哪启动的?
Worker 的管理被封装在Player类的初始化逻辑中。
引入位置:
在d:\work\jessibuca\src\player\index.js头部引入了 Worker 的封装类:
importDecoderWorkerfrom"../worker/index";// L21启动位置(实例化):
Worker 的启动(new)发生在Player类的两个地方,取决于初始化时机:
- 构造函数中(L144-145):
如果检测到不仅仅是使用 MSE/WCS (即需要软解或 WASM 解码),则立即启动。if(!this._onlyMseOrWcsVideo()){this.decoderWorker=newDecoderWorker(this);} init()方法中(L450-451):
如果构造时未启动,会在play调用的init阶段补救启动。if(!this.decoderWorker&&!this._onlyMseOrWcsVideo()){this.decoderWorker=newDecoderWorker(this);// ...}
真正的 Worker 线程创建:
进入d:\work\jessibuca\src\worker\index.js,在DecoderWorker的构造函数中:
// d:\work\jessibuca\src\worker\index.js (L7)this.decoderWorker=newWorker(player._opt.decoder)这里使用player._opt.decoder配置的路径(通常是decoder.js的 URL)真正创建了浏览器原生 Worker 线程。
总结图解
graph TD A[Jessibuca.play()] --> B{hasLoaded?} B -- Yes --> C[Player.play()] B -- No --> D[Wait EVENTS.decoderWorkerInit] D --> C C --> E[Player.init()] E --> F{Need Worker?} F -- Yes --> G[new DecoderWorker()] G --> H[new Worker(decoder.js)] E --> I[Stream.fetchStream()] I --> J[Stream Success] J --> K[Video.play()]核心就是:先确保 Worker 环境 (DecoderWorker) 就绪,再拉流 (Stream),流数据回来后通过 Worker 解码,最后渲染。