Skip to content

fix: don't undo Video.js source fallback on media error - #1093

Merged
tsi merged 1 commit into
masterfrom
fix/hevc-h264-fallback
Oct 1, 2026
Merged

tsi merged 1 commit into
masterfrom
fix/hevc-h264-fallback

Conversation

@tsi

@tsi tsi commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

With sourceTypes: ['hls/h265', 'hls/h264'], browsers that cannot decode HEVC (Windows Edge/Firefox without GPU HEVC support) ended in error 6 "No supported media sources" instead of playing the h264 fallback. Video.js already retries the next source when one fails before playback; our handleCldError ran on the same error event, reloaded the full source list with h265 first, and undid that fallback.

The regression was introduced in #880, which started calling player.error({ code: 4 }) for every fatal hls.js error. Before that, the fatal error only fired an error event without setting a player error, so handleCldError never ran and the Video.js retry handled the fallback alone (this is why v2.1.1 works and v4.1.2 does not).

Changes

  • Defer handleCldError by one tick and only run it if Video.js did not already clear the error. Video.js's retry clears it synchronously inside the same error dispatch, so when it fires we skip our recovery and let the next source load. When nothing is left to retry (single source, or all sources failed), the error is still set after the tick and handleCldError runs exactly as before.
  • Add test/unit/source-fallback.test.js covering both branches of the deferred check.

Related

How to Test

npm run test:unit

Manual check on a browser without HEVC decoding (Windows Edge/Firefox), or on any browser by stubbing MediaSource.isTypeSupported to return false for hvc1/hev1 before the player loads (the stacked follow-up branch has a page that does this via ?simulateNoHevc=true):

  • sourceTypes: ['hls/h265', 'hls/h264'] with sourceTransformation { 'hls/h265': [{ streaming_profile: 'full_hd_h265' }], 'hls/h264': [{ streaming_profile: 'full_hd' }] }, public ID dog on the demo cloud.
  • Expected: h265 errors once (manifestIncompatibleCodecsError), h264 loads and plays, player.videojs.error() stays null, no TypeError ... reading 'videoSources' in the console.
  • On v4.1.2 the same setup reloads h265, logs the TypeError, and ends in error 6 or stalls.
  • ['hls/h264'] only, and a run on a browser with HEVC support, play as before.

The error display that #880 added is preserved. With sourceTypes: ['hls'] and a transformation that sp_auto rejects (for example { aspect_ratio: '9:16', crop: 'fill' }), the manifest request returns 400 and the player still shows "Video cannot be played- sp_auto transformation is not allowed (aspect_ratio is not supported)" with statusCode: 400, identical to v4.1.2.

Notes

  • Verified in a Chromium build with simulated codec support. The real Windows Edge/Firefox decode failure is not covered locally; the ticket's log shows it fails before playing, which is the window where Video.js's retry is still armed, so the same path applies. Please confirm on BrowserStack before release.
  • The customer's videoSources TypeError no longer occurs with this fix, since it was caused by the mid-load source swap. A defensive source?. guard in the cldsourcechanged listener is in the stacked follow-up branch rather than here.
  • After a later mid-stream error, handleCldError still retries the failed h265 first. Follow-up: skip the source that just failed.

@tsi
tsi requested a review from a team as a code owner October 1, 2026 08:00
@netlify

netlify Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for cld-video-player ready!

Name Link
🔨 Latest commit f8d8783
🔍 Latest deploy log https://app.netlify.com/projects/cld-video-player/deploys/6abe1d9d5247a00008782886
😎 Deploy Preview https://deploy-preview-1093--cld-video-player.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for cld-vp-esm-pages ready!

Name Link
🔨 Latest commit f8d8783
🔍 Latest deploy log https://app.netlify.com/projects/cld-vp-esm-pages/deploys/6abe1d9d29cfd9000803c35c
😎 Deploy Preview https://deploy-preview-1093--cld-vp-esm-pages.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Video.js retries the next source on error before playback. handleCldError
ran on the same error and reloaded the full source list, putting the
failed source (e.g. hls/h265 on browsers without HEVC) back first and
ending in error 6. Only recover when Video.js didn't clear the error.
@tsi
tsi force-pushed the fix/hevc-h264-fallback branch from 1cc746c to f8d8783 Compare October 1, 2026 08:45
@tsi
tsi merged commit d3ae070 into master Oct 1, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants