Capture OpenSubtitles candidates from Stremio messages
+
Dreamio now inspects Stremio app-state and worker messages for subtitle objects, so OpenSubtitlesV3 entries that are already loaded in Stremio can become native subtitle candidates before VLC opens.
The failure is not embedded subtitle rendering and is probably not a native-player delay. Stremio can show OpenSubtitlesV3 as loaded before Dreamio launches VLC, while Dreamio still forwards zero external subtitle candidates. The bridge now watches message surfaces where Stremio is likely moving already-loaded subtitle state: window.postMessage, window message events, Worker messages, MessagePort messages, and BroadcastChannel messages.
+
+
+
+
Changes Made
+
+
Added inspectMessagePayload, which sends arbitrary app-state/message payloads through the existing subtitle payload parser.
+
Wrapped window.postMessage and listened for window message events.
+
Wrapped constructed Worker instances so messages to and from Stremio workers are inspected.
+
Wrapped MessagePort.postMessage and message listeners for channel-based state transport.
+
Wrapped BroadcastChannel construction to inspect broadcasted state messages.
+
Removed the earlier delayed-cleanup hypothesis; native-handled media cleanup remains immediate.
+
+
+
+
+
Context
+
The observed embedded-subtitle logs showed VLC successfully listing and selecting an embedded MKV subtitle track. The OpenSubtitles path is separate: Dreamio’s native player had subtitle candidates=0, meaning no external subtitle candidate reached the Swift attachment/resolution layer.
+
Stremio showing OpenSubtitlesV3 as loaded means the data likely exists in the web app before native launch. If that data moves through a worker or message channel rather than main-window fetch or DOM tracks, the old bridge would never see it.
+
+
+
+
Important Implementation Details
+
+
The new hooks reuse inspectSubtitlePayload, so they support the same URL fields, nested objects, and OpenSubtitles file_id handling as the fetch/XHR path.
+
The hooks inspect messages passively and then call the original browser APIs, preserving Stremio behavior.
+
Debug logs should now identify message-derived inspection via sources like worker.message, message-port.message, or broadcast-channel.message.
+
If candidates are discovered, the existing Swift path still resolves OpenSubtitles API/download URLs into direct subtitle files before attaching them to VLC.
+
+
+
+
+
Relevant Diff Snippets
+
Dreamio/DreamioWebViewController.swift
+82
303 unmodified lines
304
305
306
307
308
309
39 unmodified lines
349
350
351
352
353
354
303 unmodified lines
postSubtitleInspection(source, url, beforeCount, subtitleCandidates.length, text ? text.length : 0);
};
+
const originalFetch = window.fetch;
if (originalFetch) {
window.fetch = async (...args) => {
39 unmodified lines
return originalXHRSend.apply(this, args);
};
+
const stopNativeHandledMedia = (element) => {
const media = element instanceof HTMLVideoElement
? element
303 unmodified lines
304
305
306
307
308
309
310
311
312
313
314
315
39 unmodified lines
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
303 unmodified lines
postSubtitleInspection(source, url, beforeCount, subtitleCandidates.length, text ? text.length : 0);
Streams where Stremio has already loaded OpenSubtitlesV3 should have a better chance of handing those subtitles to native playback. The expected visible result is that the native captions menu gains external OpenSubtitles options instead of showing no external candidates.
Not manually confirmed: a real OpenSubtitlesV3 stream still needs to verify that bridge logs show nonzero candidates from one of the message sources.
+
+
+
+
+
Issues, Limitations, and Mitigations
+
+
This fix assumes Stremio exposes loaded subtitle objects through main-window or worker messaging. If OpenSubtitles still stays at zero candidates, the next likely gap is a storage-backed state path, such as IndexedDB or a framework store that never crosses an intercepted message boundary. The debug source labels should make that next step clearer.
+
+
+
+
+
Follow-up Work
+
+
Run the exact OpenSubtitlesV3 scenario and look for [DreamioSubtitles] bridge source=worker.message, message-port.message, or broadcast-channel.message with parsed above zero.
+
If message hooks still do not see candidates, inspect Stremio storage/state immediately before native launch.
+
Add a debug-only dump of subtitle-looking message keys if the next real run still shows zero candidates.