You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
develop: YouTube playback is fully broken — four regressions since 5.0.0 (17 of 60 demo pages throw) #775
A build of current develop cannot play a YouTube video, and 17 of the repository's own 60 demo pages throw a JavaScript error during player initialization. We hit this while preparing to adopt the 5.1.0 line and traced it to four independent regressions, none of which exist in the released 5.0.0. Filing them together because two share an origin commit and the fixes overlap; happy to split into separate issues if you prefer.
We have working fixes for all four (plus a fifth, smaller Vimeo one) running in our fork, each on its own branch cut from develop, and we're glad to open them as PRs in whatever form suits you — after #770/#771/#773, we didn't want to stack more unrequested PRs, so this is a report first.
Version tested
Develop (the next release). Verified NOT present in v5.0.0 (details per item). Also worth noting: the committed build/ directory currently predates all of these (its banner says V5.0.0, last rebuilt in June), so testing against the checked-in bundles masks every one of them — they only appear after a fresh npm run build.
1. initSignLanguage throws for any media element with no <source> children — this alone breaks every YouTube demo
getSources() (scripts/initialize.js:377) returns [] when the media element has no <source> children — the normal markup for a YouTube-only embed, e.g. demos/youtube1.html:
So this.sources[0] is undefined and the call throws:
TypeError: Cannot read properties of undefined (reading 'getAttribute')
at AblePlayer.initSignLanguage
at AblePlayer.recreatePlayer
initSignLanguage() is called unconditionally from recreatePlayer() (scripts/initialize.js:433) beforeinitPlayer(), so the player is never built: the IFrame API is never requested, window.YT stays undefined, and the page degrades to a bare <video>. scripts/description.js:38 has the same unguarded read and throws next if only sign.js is patched (note the audio early-exit at description.js:31–33 resolves its deferred but doesn't return, so it falls through to that line).
Origin: 834d003 converted these reads from this.$sources.first().attr(…) — which returns undefined on an empty jQuery set — to this.sources[0].getAttribute(…), which throws.
Same commit also changed the absent-attribute sentinel: .attr() returned undefined for a missing attribute, getAttribute() returns null. The surrounding !== undefined / typeof !== 'undefined' tests therefore now read a missing attribute as present — e.g. every video without a described version still sets hasOpenDesc = true once execution gets that far.
2. All data-youtube-* attributes are silently ignored (wrong dataset keys)
scripts/ableplayer-base.js reads:
letyouTubeId=options.youTubeId??data.youTubeId;
where data = media[0].dataset. But dataset keys are derived from the attribute name — data-youtube-id is dataset.youtubeId (one word, lowercase y, no capital T). data.youTubeId would correspond to a data-you-tube-id attribute, which doesn't exist. Same for youTubeDescId, youTubeSignId (5.0.0 read this from data-youtube-sign-src, so the correct key is youtubeSignSrc), and youTubeNoCookie (data-youtube-nocookie → youtubeNocookie).
Result: even with item 1 patched, every YouTube demo loads with no errors but no video — the instance reports player: 'html5', youTubeId undefined, youTubeNoCookie false, and zero network requests toward the IFrame API. This one is easy to miss precisely because it's silent.
Origin: 2d4a1c2 ("Get data attributes from dataset instead of jQuery object") — $(media).data('youtube-id') resolved the hyphenated name correctly; the dataset reads kept the API's youTube* spelling.
3. Constructor throws for a selector string or bare element
Same commit, same file: let data = media[0].dataset; indexes the constructor argument directly. For a selector string (new AblePlayer('#video1'), used by demos/translations.html) media[0] is the character #; for a bare element it's undefined. Both throw on .dataset. Only a jQuery object works, though all three forms are documented and the constructor's own guard two lines up already uses $(media). (demos/search2.html and demos/translations.html fail on this today.) Fix is one call: $(media)[0].dataset, matching the width reads at lines 330/334 of the same file.
4. syncTrackLanguages throws for any player without a transcript
$transcriptArea is only assigned when a transcript is built, and && evaluates left-to-right, so the .is() call runs before source is examined — including for source === 'init', i.e. normal player construction via initDefaultCaption. Any player with captions but no transcript throws here. Reordering the test (and using the same typeof this.$transcriptArea === 'undefined' idiom refreshControls() already uses at control.js:1618) fixes it. Origin: 05e9a22 ("Update language switching"); the line doesn't exist in 5.0.0.
5. (Smaller, Vimeo) getVimeoId throws on a bare ID string
scripts/vimeo.js:269 runs new URL(url) with only a typeof url === 'number' guard above it. Every caller passes a string read from data-vimeo-id/.attr(), so the documented data-vimeo-id="76979871" markup reaches new URL('76979871') → TypeError: Failed to construct 'URL': Invalid URL. scripts/validate.js:244 already shows the safe pattern (try/catch + base origin). Both Vimeo demos fail on this today.
To Reproduce
Fresh clone of develop; npm ci && npm run build (important — the committed build/ predates these regressions).
Serve the repo root and open demos/youtube1.html with the console open.
See the initSignLanguage TypeError (item 1). Patch item 1 alone and reload: no errors, but also no YouTube iframe and window.YT undefined (item 2). demos/translations.html and demos/vimeo1.html show items 3 and 5.
Measured across all 60 demo pages in headless Chromium (autoplay-policy errors excluded): 17 pages throw on develop; 0 throw with the five fixes applied. The full per-page breakdown: all 6 youtube demos + both vimeo demos + other-noa11y, other-width, search2, translations and 5 others.
Expected behavior
YouTube/Vimeo demos initialize and play as they do on v5.0.0; media elements without <source> children construct normally; all documented constructor argument forms work.
Desktop:
OS: Windows 11 / Linux (CI)
Browser: Chromium 145 (headless and headed) — but all five are environment-independent logic errors.
If it's useful: our fixes are live and testable at https://ableplayer.perkslocker.com/demos/ (our fork's develop plus these guards — every page loads clean there). Say the word and I'll open them as PRs, individually or as one branch, whichever you'd rather review.
These are all straightforward enough that I think a simple PR to resolve them all is pretty reasonable. There's nothing here that would require significant refactoring, and my main concern with combining issues in a PR is ensuring that the PR is still readable.
Thanks for this!
FYI, I never want to guarantee that the develop branch is necessarily functional. The practicality of my available development time is largely that I can dedicate the occasional sprint, but then I have to switch focus to other things, and don't want to need to ensure it's at 100% in between sprints.
@blogcastAI I added a PR to apply fixes to the changes you documented; they are mostly identical to the ones you used, though not 100%. If you have a chance to check them, that would be appreciated; but if not, that's fine! Appreciate the detailed documentation!
Activity
joedolson commentedon Aug 25, 2026
These are all straightforward enough that I think a simple PR to resolve them all is pretty reasonable. There's nothing here that would require significant refactoring, and my main concern with combining issues in a PR is ensuring that the PR is still readable.
Thanks for this!
FYI, I never want to guarantee that the develop branch is necessarily functional. The practicality of my available development time is largely that I can dedicate the occasional sprint, but then I have to switch focus to other things, and don't want to need to ensure it's at 100% in between sprints.
joedolson commentedon Sep 6, 2026
@blogcastAI I added a PR to apply fixes to the changes you documented; they are mostly identical to the ones you used, though not 100%. If you have a chance to check them, that would be appreciated; but if not, that's fine! Appreciate the detailed documentation!
Merge pull request #778 from ableplayer/fix-youtube
joedolson commentedon Sep 13, 2026
Closed with #778