mirror of
https://github.com/dirtydishes/dreamio.git
synced 2026-06-06 21:38:15 +00:00
keep stremio subtitle loads untouched
This commit is contained in:
parent
dc11afc45f
commit
6a29dde857
5 changed files with 196 additions and 8 deletions
|
|
@ -14,3 +14,4 @@
|
|||
{"id":"int-9ddb7b1a","kind":"field_change","created_at":"2026-05-25T10:18:30.826897Z","actor":"dirtydishes","issue_id":"dreamio-7w6","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Streamlined native player controls into a compact bottom overlay and validated the simulator build."}}
|
||||
{"id":"int-2a84633f","kind":"field_change","created_at":"2026-05-25T10:25:22.649574Z","actor":"dirtydishes","issue_id":"dreamio-88m","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented captions as a single-choice menu with None and selected loaded tracks, updated tests and turn documentation."}}
|
||||
{"id":"int-38a97132","kind":"field_change","created_at":"2026-05-25T10:43:21.805452Z","actor":"dirtydishes","issue_id":"dreamio-lw6","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Implemented late subtitle forwarding into active native playback, added VLC append path and parser tests."}}
|
||||
{"id":"int-ddab585f","kind":"field_change","created_at":"2026-05-25T11:07:34.849628Z","actor":"dirtydishes","issue_id":"dreamio-8cz","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Hardened subtitle bridge network observers so non-text Stremio subtitle loads are not touched, and made parser traversal deterministic for metadata preservation."}}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
{"_type":"issue","id":"dreamio-8cz","title":"fix stremio external subtitle loading regression","description":"After adding late subtitle forwarding for native playback, Stremio external subtitle loading is failing. Investigate the injected bridge and native subtitle forwarding path, then adjust behavior so Stremio can still load external subtitles while native playback receives late candidates.","status":"closed","priority":0,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T11:05:42Z","created_by":"dirtydishes","updated_at":"2026-05-25T11:07:35Z","started_at":"2026-05-25T11:05:55Z","closed_at":"2026-05-25T11:07:35Z","close_reason":"Hardened subtitle bridge network observers so non-text Stremio subtitle loads are not touched, and made parser traversal deterministic for metadata preservation.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"dreamio-lw6","title":"forward late opensubtitles subtitles to native player","description":"Native playback only receives subtitle candidates discovered before the stream candidate is posted. OpenSubtitles V3 candidates can arrive later through addon/network responses, so the active native player needs an append path for newly discovered external subtitles.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T10:40:28Z","created_by":"dirtydishes","updated_at":"2026-05-25T10:43:22Z","started_at":"2026-05-25T10:40:36Z","closed_at":"2026-05-25T10:43:22Z","close_reason":"Implemented late subtitle forwarding into active native playback, added VLC append path and parser tests.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"dreamio-poo","title":"Native player controls captions and close flow","description":"Add and validate VLC-backed native playback transport controls, subtitle track controls, external subtitle discovery, and Stremio Web close cleanup after native playback dismisses.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T09:47:56Z","created_by":"dirtydishes","updated_at":"2026-05-25T09:49:40Z","started_at":"2026-05-25T09:48:00Z","closed_at":"2026-05-25T09:49:40Z","close_reason":"Implemented and validated native player controls, subtitle handling refinements, and close-flow cleanup.","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
{"_type":"issue","id":"dreamio-wgk","title":"Fix native player controls tap-to-show","description":"Native player controls can be hidden by tapping, but subsequent taps on the player do not bring them back. Investigate the overlay gesture handling and restore reliable tap-to-show/tap-to-hide behavior.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T09:27:58Z","created_by":"dirtydishes","updated_at":"2026-05-25T09:51:17Z","started_at":"2026-05-25T09:28:11Z","closed_at":"2026-05-25T09:51:17Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,16 @@ final class DreamioWebViewController: UIViewController {
|
|||
window.fetch = async (...args) => {
|
||||
const response = await originalFetch(...args);
|
||||
try {
|
||||
response.clone().text().then(inspectSubtitlePayload).catch(() => {});
|
||||
const contentType = response.headers && response.headers.get("content-type") || "";
|
||||
const url = response.url || "";
|
||||
subtitleURLPattern.lastIndex = 0;
|
||||
const shouldInspect = !contentType
|
||||
|| /json|text|javascript|xml|subtitle|vtt|srt/i.test(contentType)
|
||||
|| subtitleURLPattern.test(url);
|
||||
if (shouldInspect) {
|
||||
subtitleURLPattern.lastIndex = 0;
|
||||
response.clone().text().then(inspectSubtitlePayload).catch(() => {});
|
||||
}
|
||||
} catch (_) {}
|
||||
return response;
|
||||
};
|
||||
|
|
@ -203,7 +212,15 @@ final class DreamioWebViewController: UIViewController {
|
|||
const originalXHRSend = XMLHttpRequest.prototype.send;
|
||||
XMLHttpRequest.prototype.send = function(...args) {
|
||||
try {
|
||||
this.addEventListener("load", () => inspectSubtitlePayload(this.responseText));
|
||||
this.addEventListener("load", () => {
|
||||
try {
|
||||
const responseType = this.responseType || "";
|
||||
if (responseType && responseType !== "text") {
|
||||
return;
|
||||
}
|
||||
inspectSubtitlePayload(this.responseText);
|
||||
} catch (_) {}
|
||||
});
|
||||
} catch (_) {}
|
||||
return originalXHRSend.apply(this, args);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ enum SubtitleCandidateParser {
|
|||
if let candidate = candidate(from: dictionary) {
|
||||
results.append(candidate)
|
||||
}
|
||||
dictionary.values.forEach { collect(from: $0, into: &results) }
|
||||
orderedNestedValues(in: dictionary).forEach { collect(from: $0, into: &results) }
|
||||
case let array as [Any]:
|
||||
array.forEach { collect(from: $0, into: &results) }
|
||||
case let string as String:
|
||||
|
|
@ -159,6 +159,27 @@ enum SubtitleCandidateParser {
|
|||
)
|
||||
}
|
||||
|
||||
private static func orderedNestedValues(in dictionary: [String: Any]) -> [Any] {
|
||||
let preferredKeys = ["subtitles", "subtitle", "files", "downloads", "download"]
|
||||
var visitedKeys = Set<String>()
|
||||
var values: [Any] = []
|
||||
|
||||
preferredKeys.forEach { key in
|
||||
if let value = dictionary[key] {
|
||||
values.append(value)
|
||||
visitedKeys.insert(key)
|
||||
}
|
||||
}
|
||||
|
||||
dictionary.keys
|
||||
.filter { !visitedKeys.contains($0) && !urlFields.contains($0) }
|
||||
.sorted()
|
||||
.compactMap { dictionary[$0] }
|
||||
.forEach { values.append($0) }
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
private static func subtitleURL(from string: String?) -> URL? {
|
||||
guard let string,
|
||||
let url = URL(string: string),
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue