/** * Web Worker: 后台检测频道可用性 * 使用 Image 加载方式检测(更可靠) */ self.onmessage = async function(e) { const { channels, timeout = 2000, concurrency = 5 } = e.data // 收集所有源 const allSources = [] for (const ch of channels) { for (let i = 0; i < ch.sources.length; i++) { allSources.push({ channelId: ch.id, channelName: ch.name, url: ch.sources[i].url, sourceIndex: i }) } } let completed = 0 const total = allSources.length // 检测单个源 - 使用 Image 加载检测 function checkSource(source) { return new Promise((resolve) => { const startTime = performance.now() // 对于视频流,尝试用 fetch 快速检测 const controller = new AbortController() const timer = setTimeout(() => { controller.abort() resolve({ ...source, status: 'offline', delay: 99999 }) }, timeout) fetch(source.url, { method: 'HEAD', signal: controller.signal, mode: 'no-cors', cache: 'no-store' }).then(() => { clearTimeout(timer) const delay = Math.round(performance.now() - startTime) resolve({ ...source, status: 'online', delay }) }).catch(() => { clearTimeout(timer) resolve({ ...source, status: 'offline', delay: 99999 }) }) }) } // 分批并发处理 for (let i = 0; i < allSources.length; i += concurrency) { const batch = allSources.slice(i, i + concurrency) const promises = batch.map(source => checkSource(source).then(result => { completed++ self.postMessage({ type: 'progress', data: { total, completed, current: result.channelName, result } }) }) ) await Promise.all(promises) } // 完成 self.postMessage({ type: 'complete' }) }