From c59b318d9bae974de5b5c23ab7bd38e1f6fb80dc Mon Sep 17 00:00:00 2001 From: dirtydishes Date: Mon, 25 May 2026 11:09:53 -0400 Subject: [PATCH] quiet repeated vlc subtitle reapply logs --- .beads/interactions.jsonl | 1 + .beads/issues.jsonl | 2 + Dreamio/VLCNativePlaybackBackend.swift | 15 +- ...6-05-25-throttle-vlc-subtitle-reapply.html | 240 ++++++++++++++++++ 4 files changed, 255 insertions(+), 3 deletions(-) create mode 100644 docs/turns/2026-05-25-throttle-vlc-subtitle-reapply.html diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index b5a0784..97e968d 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -23,3 +23,4 @@ {"id":"int-4e095d3f","kind":"field_change","created_at":"2026-05-25T14:38:21.968713Z","actor":"dirtydishes","issue_id":"dreamio-djc","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Auto-select the first discovered VLC subtitle track when playback is still disabled, while preserving manual caption choices."}} {"id":"int-96629c65","kind":"field_change","created_at":"2026-05-25T14:45:38.521113Z","actor":"dirtydishes","issue_id":"dreamio-ppj","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Re-applied the auto-selected VLC subtitle track after stream discovery and playback state changes to harden rendering timing."}} {"id":"int-027cec57","kind":"field_change","created_at":"2026-05-25T14:51:44.599319Z","actor":"dirtydishes","issue_id":"dreamio-3xi","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Captured OpenSubtitles V3 subtitle URLs from browser track elements and textTracks so they can be forwarded to native playback."}} +{"id":"int-3acaadff","kind":"field_change","created_at":"2026-05-25T15:09:02.023077Z","actor":"dirtydishes","issue_id":"dreamio-h5n","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Limited VLC auto-subtitle reapply to real selection recovery while keeping bounded delayed startup confirmations."}} diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 04ca83c..3726b5a 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -1,4 +1,5 @@ {"_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-bao","title":"add native player audio track selection","description":"Add audio track discovery and selection to the native VLC-backed player so multi-language files can be filtered from the player controls.","status":"closed","priority":1,"issue_type":"feature","owner":"dishes@dpdrm.com","created_at":"2026-05-25T14:57:14Z","created_by":"dirtydishes","updated_at":"2026-05-25T15:01:36Z","closed_at":"2026-05-25T15:01:36Z","close_reason":"Implemented native audio track discovery and selection with a far-left audio menu in the VLC-backed player.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-3xi","title":"Capture browser text tracks for OpenSubtitles V3","description":"OpenSubtitles V3 subtitles can be attached to the Stremio web player as HTML track/textTrack entries rather than appearing in the initial stream candidate. Extend the web bridge to inspect track elements and textTracks so external subtitles can be forwarded to native playback.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T14:49:50Z","created_by":"dirtydishes","updated_at":"2026-05-25T14:51:45Z","started_at":"2026-05-25T14:49:52Z","closed_at":"2026-05-25T14:51:45Z","close_reason":"Captured OpenSubtitles V3 subtitle URLs from browser track elements and textTracks so they can be forwarded to native playback.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-ppj","title":"Reapply VLC embedded subtitle selection after track discovery","description":"Device logs show VLC eventually exposes and selects the embedded English SDH subtitle track, but subtitles still do not render. Investigate and harden the VLC selection timing so embedded tracks are selected after discovery is stable.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T14:44:08Z","created_by":"dirtydishes","updated_at":"2026-05-25T14:45:38Z","started_at":"2026-05-25T14:44:18Z","closed_at":"2026-05-25T14:45:38Z","close_reason":"Re-applied the auto-selected VLC subtitle track after stream discovery and playback state changes to harden rendering timing.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-djc","title":"Auto-select embedded VLC subtitle tracks","description":"VLC discovers embedded MKV subtitle tracks after playback starts, but Dreamio leaves subtitles disabled when no external candidates were provided. Add automatic selection for the first selectable VLC subtitle track while preserving manual caption choices.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T14:36:11Z","created_by":"dirtydishes","updated_at":"2026-05-25T14:38:22Z","started_at":"2026-05-25T14:36:17Z","closed_at":"2026-05-25T14:38:22Z","close_reason":"Auto-select the first discovered VLC subtitle track when playback is still disabled, while preserving manual caption choices.","dependency_count":0,"dependent_count":0,"comment_count":0} @@ -16,6 +17,7 @@ {"_type":"issue","id":"dreamio-l68","title":"Add native playback for direct debrid streams","description":"Implement a WKWebView JavaScript bridge that detects direct-file debrid media URLs and routes unsupported containers to a native player backend, initially MobileVLCKit, while preserving normal Stremio Web playback for compatible streams.","status":"closed","priority":1,"issue_type":"feature","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T03:13:19Z","created_by":"dirtydishes","updated_at":"2026-05-25T03:20:17Z","started_at":"2026-05-25T03:13:28Z","closed_at":"2026-05-25T03:20:17Z","close_reason":"Implemented native direct-stream bridge, classification, MobileVLCKit backend wiring, CocoaPods workflow docs, and turn documentation. Full iOS build is blocked locally by missing CocoaPods and iPhoneOS SDK.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-tnv","title":"Fix iOS bundle identifier install failure","description":"Xcode built Dreamio.app without a valid CFBundleIdentifier, causing device install to fail with CoreDeviceError 3000/3002. Investigate project bundle settings, fix the source configuration, validate the app bundle Info.plist, and document the change.","status":"closed","priority":1,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T01:23:00Z","created_by":"dirtydishes","updated_at":"2026-05-25T01:25:36Z","started_at":"2026-05-25T01:23:07Z","closed_at":"2026-05-25T01:25:36Z","close_reason":"Added bundle metadata to Info.plist and validated processed app bundle identifier.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-4yn","title":"Build WKWebView MVP shell","description":"Create the first Dreamio MVP implementation: a minimal iOS WKWebView wrapper around hosted Stremio Web, with configuration, launch behavior, diagnostics, and documentation for real-device viability testing.","acceptance_criteria":"App project exists; WKWebView loads hosted Stremio Web; external/new-window navigation is handled; basic diagnostics and manual test documentation exist; quality gates are run or documented.","status":"closed","priority":1,"issue_type":"feature","owner":"dishes@dpdrm.com","created_at":"2026-05-24T14:55:12Z","created_by":"dirtydishes","updated_at":"2026-05-24T14:59:44Z","closed_at":"2026-05-24T14:59:44Z","close_reason":"Implemented the MVP WKWebView iOS shell, added run and validation documentation, and recorded current validation limits.","dependency_count":0,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"dreamio-h5n","title":"Throttle VLC subtitle reapply during buffering","description":"VLC subtitle auto-selection currently reapplies the same subtitle track on every buffering state notification, producing noisy logs and unnecessary repeated player writes. Limit state-driven reapply to meaningful selection recovery or state transitions while preserving delayed retries after initial auto-selection.","status":"closed","priority":2,"issue_type":"bug","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T15:06:48Z","created_by":"dirtydishes","updated_at":"2026-05-25T15:09:02Z","started_at":"2026-05-25T15:06:55Z","closed_at":"2026-05-25T15:09:02Z","close_reason":"Limited VLC auto-subtitle reapply to real selection recovery while keeping bounded delayed startup confirmations.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-c1m","title":"Add captions selection proof logging","description":"Add DEBUG-only logs around the native captions menu and VLC subtitle selection path so subtitle tap actions prove whether the UI fires and whether VLC accepts the selected embedded track index.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T14:18:06Z","created_by":"dirtydishes","updated_at":"2026-05-25T14:19:19Z","started_at":"2026-05-25T14:18:11Z","closed_at":"2026-05-25T14:19:19Z","close_reason":"Added DEBUG-only logs for captions menu actions and VLC subtitle selection results.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-e9p","title":"Add native subtitle pipeline proof logging","description":"Add DEBUG-only logs across the web bridge, native player, subtitle resolution, and VLC attachment points so the next Xcode run can identify where external subtitles disappear without changing playback behavior.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T14:03:18Z","created_by":"dirtydishes","updated_at":"2026-05-25T14:07:14Z","started_at":"2026-05-25T14:03:22Z","closed_at":"2026-05-25T14:07:14Z","close_reason":"Added DEBUG-only subtitle pipeline proof logging and documented validation.","dependency_count":0,"dependent_count":0,"comment_count":0} {"_type":"issue","id":"dreamio-88m","title":"Make caption selection states clearer","description":"The native player caption menu should behave like a simple single-choice menu with None and loaded caption tracks, making the current caption state visually obvious.","status":"closed","priority":2,"issue_type":"task","assignee":"dirtydishes","owner":"dishes@dpdrm.com","created_at":"2026-05-25T10:22:12Z","created_by":"dirtydishes","updated_at":"2026-05-25T10:25:23Z","started_at":"2026-05-25T10:22:48Z","closed_at":"2026-05-25T10:25:23Z","close_reason":"Implemented captions as a single-choice menu with None and selected loaded tracks, updated tests and turn documentation.","dependency_count":0,"dependent_count":0,"comment_count":0} diff --git a/Dreamio/VLCNativePlaybackBackend.swift b/Dreamio/VLCNativePlaybackBackend.swift index f23b8bc..4b77cb7 100644 --- a/Dreamio/VLCNativePlaybackBackend.swift +++ b/Dreamio/VLCNativePlaybackBackend.swift @@ -284,21 +284,30 @@ final class VLCNativePlaybackBackend: NSObject, NativePlaybackBackend { private func scheduleAutoSubtitleSelectionReapply(trackID: Int32) { [0.3, 1.0, 2.0, 4.0].forEach { delay in DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in - self?.reapplyAutoSelectedSubtitleTrackIfNeeded(reason: "delayed-\(String(format: "%.1f", delay))") + self?.reapplyAutoSelectedSubtitleTrackIfNeeded( + reason: "delayed-\(String(format: "%.1f", delay))", + shouldLogNoop: true + ) } } } - private func reapplyAutoSelectedSubtitleTrackIfNeeded(reason: String) { + private func reapplyAutoSelectedSubtitleTrackIfNeeded(reason: String, shouldLogNoop: Bool = false) { guard !didUserSelectSubtitleTrack, let trackID = autoSelectedSubtitleTrackID, subtitleTracks.contains(where: { $0.id == trackID }) else { return } + let selectedTrackID = mediaPlayer.currentVideoSubTitleIndex + guard selectedTrackID != trackID || shouldLogNoop else { + return + } + mediaPlayer.currentVideoSubTitleIndex = trackID #if DEBUG - print("[DreamioVLC] reapply subtitle id=\(trackID) reason=\(reason) selected=\(mediaPlayer.currentVideoSubTitleIndex)") + let action = selectedTrackID == trackID ? "confirm" : "recover" + print("[DreamioVLC] reapply subtitle id=\(trackID) reason=\(reason) action=\(action) selected=\(mediaPlayer.currentVideoSubTitleIndex)") #endif } #endif diff --git a/docs/turns/2026-05-25-throttle-vlc-subtitle-reapply.html b/docs/turns/2026-05-25-throttle-vlc-subtitle-reapply.html new file mode 100644 index 0000000..4c49374 --- /dev/null +++ b/docs/turns/2026-05-25-throttle-vlc-subtitle-reapply.html @@ -0,0 +1,240 @@ + + + + + + Throttle VLC Subtitle Reapply + + + +
+
+
Dreamio turn document
+

Throttle VLC subtitle reapply

+

Reduced noisy VLC subtitle reapply behavior so repeated buffering notifications no longer keep writing the same already-selected subtitle track.

+
+ May 25, 2026 + Issue dreamio-h5n + Native VLC playback +
+
+ +
+

Summary

+

Dreamio was auto-selecting embedded VLC subtitle tracks correctly, but VLC buffering callbacks repeatedly reapplied the same track while it was already selected. The change keeps recovery behavior for real subtitle-selection drift and startup timing, while suppressing repeated no-op reapply writes from player state changes.

+
+ +
+

Changes Made

+
    +
  • Added a selected-track guard inside reapplyAutoSelectedSubtitleTrackIfNeeded.
  • +
  • Kept delayed startup reapply attempts visible by passing shouldLogNoop: true for the 0.3, 1.0, 2.0, and 4.0 second retries.
  • +
  • Changed debug logging to label reapply events as action=confirm for delayed no-op confirmations or action=recover when VLC had drifted away from the intended subtitle.
  • +
+
+ +
+

Context

+

The diagnostic log showed VLC auto-selecting English (SDH), then repeatedly logging reapply subtitle during buffering even though selected=3 never changed. The external OpenSubtitles load failure was non-critical in that trace, and the working subtitle came from the MKV itself.

+
+ +
+

Important Implementation Details

+

The VLC state delegate still calls the reapply helper during .buffering and .playing. The helper now checks mediaPlayer.currentVideoSubTitleIndex before writing. If the intended auto-selected track is already active, state-driven calls return without touching VLC or logging. Delayed startup retries intentionally keep their confirmation logging because those are bounded and useful for diagnosing timing-sensitive subtitle attachment.

+
+ +
+

Relevant Diff Snippets

+
Dreamio/VLCNativePlaybackBackend.swift
-3+12
283 unmodified lines
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
283 unmodified lines
private func scheduleAutoSubtitleSelectionReapply(trackID: Int32) {
[0.3, 1.0, 2.0, 4.0].forEach { delay in
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
self?.reapplyAutoSelectedSubtitleTrackIfNeeded(reason: "delayed-\(String(format: "%.1f", delay))")
}
}
}
+
private func reapplyAutoSelectedSubtitleTrackIfNeeded(reason: String) {
guard !didUserSelectSubtitleTrack,
let trackID = autoSelectedSubtitleTrackID,
subtitleTracks.contains(where: { $0.id == trackID }) else {
return
}
+
mediaPlayer.currentVideoSubTitleIndex = trackID
#if DEBUG
print("[DreamioVLC] reapply subtitle id=\(trackID) reason=\(reason) selected=\(mediaPlayer.currentVideoSubTitleIndex)")
#endif
}
#endif
283 unmodified lines
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
283 unmodified lines
private func scheduleAutoSubtitleSelectionReapply(trackID: Int32) {
[0.3, 1.0, 2.0, 4.0].forEach { delay in
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
self?.reapplyAutoSelectedSubtitleTrackIfNeeded(
reason: "delayed-\(String(format: "%.1f", delay))",
shouldLogNoop: true
)
}
}
}
+
private func reapplyAutoSelectedSubtitleTrackIfNeeded(reason: String, shouldLogNoop: Bool = false) {
guard !didUserSelectSubtitleTrack,
let trackID = autoSelectedSubtitleTrackID,
subtitleTracks.contains(where: { $0.id == trackID }) else {
return
}
+
let selectedTrackID = mediaPlayer.currentVideoSubTitleIndex
guard selectedTrackID != trackID || shouldLogNoop else {
return
}
+
mediaPlayer.currentVideoSubTitleIndex = trackID
#if DEBUG
let action = selectedTrackID == trackID ? "confirm" : "recover"
print("[DreamioVLC] reapply subtitle id=\(trackID) reason=\(reason) action=\(action) selected=\(mediaPlayer.currentVideoSubTitleIndex)")
#endif
}
#endif
+
+ +
+

Expected Impact for End-Users

+

Playback should behave the same when the embedded subtitle is successfully auto-selected. Debug logs should become much quieter during buffering, making real subtitle failures easier to spot. If VLC drops the subtitle selection, Dreamio will still reapply the intended auto-selected track.

+
+ +
+

Validation

+
    +
  • Ran xcodebuild -workspace Dreamio.xcworkspace -scheme Dreamio -destination 'generic/platform=iOS Simulator' build.
  • +
  • The build succeeded. Xcode emitted the existing MobileVLCKit run-script output warning and AppIntents metadata skip warning, neither related to this change.
  • +
+
+ +
+

Issues, Limitations, and Mitigations

+
    +
  • This was validated with a simulator build, not a live Stremio playback session against the exact South Park stream from the provided log.
  • +
  • The OpenSubtitles external subtitle load failure is separate. This change addresses VLC reapply spam after embedded subtitle auto-selection, not remote subtitle download reliability.
  • +
  • Delayed retry logs remain by design, but they are bounded to four scheduled checks.
  • +
+
+ +
+

Follow-up Work

+

No follow-up issue is required for this specific buffering log noise. A separate issue would be appropriate if external OpenSubtitles subtitle downloads still fail for streams without embedded subtitles.

+
+
+ + \ No newline at end of file