fix(downloads): iPad audio playback + honest non-retryable failure for auth-walled hosts

5a — the public watch page rendered every asset in a <video>, but WebKit (all
iOS browsers) refuses to play an audio-only mp3 in <video>, so shared audio
links were broken on iPad while working on desktop Chromium. public_meta now
flags audio-only assets (codec present, no video stream) and WatchPage renders
a native <audio> in a padded surface card (no artwork exists for these).

5c — a login-walled Facebook post failed as a bare 'unknown', which offered a
misleading Retry. Classify closed-group / cookie-suggestion auth walls as
login_required and genuinely unsupported sites as a new unsupported_host class
(both non-retryable), and drop unknown from the modal's retryable set — an
unclassified failure is most often an unparsed auth wall. The queue row keeps
its own force-retry for real transients.
This commit is contained in:
2026-08-28 02:22:28 +02:00
parent 11e32163b8
commit b7a6451dba
9 changed files with 158 additions and 21 deletions
+6 -3
View File
@@ -114,9 +114,12 @@ export function MetaEditModal({ job, onClose }: { job: DownloadJob; onClose: ()
);
}
// Transient failures worth an in-modal Retry button; the rest are permanent (private/geo/DRM/…),
// where a retry can't help — the queue row still keeps its own retry control regardless.
const RETRYABLE_ERRORS = ["postprocess", "network", "unknown"];
// Transient failures worth an in-modal Retry button; the rest are permanent (private/geo/DRM/
// sign-in/unsupported-host/…), where a retry can't help — the queue row still keeps its own retry
// control regardless. `unknown` is deliberately NOT here: an unclassified failure is most often an
// auth wall we couldn't parse (a login-walled Facebook post reads as a bare "no format"), so a
// prominent Retry would mislead; force-retrying from the row stays available for genuine transients.
const RETRYABLE_ERRORS = ["postprocess", "network"];
// A readable "why did this fail" window for a failed job: a category headline + plain explanation,
// the raw yt-dlp/ffmpeg text behind a disclosure, and a Retry when the failure may be transient.