Ensure generated bundles contain a single license header instead of
repeating the same notice across bundled modules.
Normalize all copyright years to 2016 and remove
duplicate license headers from generated bundles.
This reduces the final bundle size while preserving license information
in the distributed artifacts.
Improve readability and separate responsibilities. Use Intl.DisplayNames
when available and fallback to mozilla.LanguageMapping otherwise.
Note: this is in preparation for addressing
https://github.com/shaka-project/shaka-player/issues/9694
---------
Co-authored-by: Matthias Van Parijs <matvp91@gmail.com>
Region elements were cached by an ID that omitted regionAnchorX and
regionAnchorY, causing regions that shared the same viewport anchor but
differed in region anchor to reuse a previously cached DOM element
positioned incorrectly. Include both region anchor values in the
generated ID so each unique anchor combination gets its own element.
Issue: https://github.com/shaka-project/shaka-player/issues/2583
Closes#10042
Adds a `textDisplayer.suspendRenderingWhenHidden` config flag that gates
the IntersectionObserver-based render suspension introduced in #9545.
- Defaults to `true` (existing behavior preserved for browsers/desktop).
- Defaults to `false` on TV devices (detected via
`shaka.device.DeviceFactory.getDevice().getDeviceType() ===
DeviceType.TV`).
Some TV browsers (e.g. older Tizen WebKit) misreport
`IntersectionObserver` visibility for transformed/absolute-positioned
player containers, leading to permanently suspended caption rendering.
Disabling suspension on TVs sidesteps the platform bug at the cost of
running one DOM update per `captionsUpdatePeriod` (default 0.25s) while
the player is off-screen.
Externs updated at `externs/shaka/player.js`. When the flag is `false`,
`applyVisibility_` short-circuits to "always visible" so the IO observer
can never suspend rendering.
---------
Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
For HLS CMAF streams with WebVTT subtitles with large timestamps, the
rollover wrapping prevents the cues from being shown at the correct
time.
By adding a check to only do the wrapping for MPEG-TS streams this
problem is eliminated.
fixes#10020
There are platforms (some WebKit STBs) where IntersectionObserver
doesn't work well with fullscreen.
Managing multiple videos on screen. Detecting which one opens in PiP and
Fullscreen.
This PR:
- replaces `splice` with an index variable to avoid array shifts on every cue parse
- replaces `slice(1).join('\n')` with a manual loop to eliminate two intermediate allocations per cue
- hoists inline regex literals to static class constants, fixing unreliable literal caching in older Chromium version (helps TV devices and Xbox)
This PR changes the way that timestamp offsets are stored in the media
source engine. Instead of a single value, it now has a map of values.
For DASH, it should contain a single value, which is the last timestamp
offset available. For HLS, it'll keep track of the timestamp offsets per
discontinuity sequence. If content is appended and we don't yet have a
timestamp offset for that discontinuity sequence number, it'll defer
creating the cues until the timestamp offset is set, otherwise, the
times for the cues may not be correct.
Fixes#9470
UITextDisplayer was triggering:
"ResizeObserver loop completed with undelivered notifications"
This happened because updateCaptions_() mutates the DOM inside the
ResizeObserver callback, which can cause synchronous layout feedback
loops.
This change:
- Observes videoContainer_ instead of textContainer_
- Defers updateCaptions_() using requestAnimationFrame
- Coalesces multiple resize events using a pendingResize_ flag
- Ensures updates only run when captions are visible
This prevents layout feedback loops while preserving correct caption
re-rendering behavior.
Fixes https://github.com/shaka-project/shaka-player/issues/9721
Added polyfills for `Map.getOrInsert()` and
`Map.getOrInsertComputed()` from the TC39 upsert proposal and refactor
the codebase to use them.
These methods replace the common "check if key exists, then set default"
pattern with a single atomic operation. This improves code readability
and eliminates redundant map lookups throughout the player.
---------
Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
TextEngine was storing closed captions and releasing them only on
teardown. This might be a potential memory leak for long running
sessions.
This PR addresses it by removing cached captions along with removed
segments. Furthermore, it adds some more tweaks and improvements, such
as:
- simplify CEA cache structure, from `Map<string, Map<string,
Array<Cue>>>` to `Map<string, Array<Cue>>`
- adjust TextEngine buffered ranges with cached cues values
Make cloning buffers (or not) explicit in readBytes.
When we use a range of bytes temporarily for further parsing, we pass
clone=false and get a view on the existing memory buffer. When we want
to store the range of bytes, we pass clone=true and avoid holding a
reference to an entire segment in memory.
The call for the EMSG parser in MediaSourceEngine had an explicit clone,
but now uses the new clone parameter. This is not a functional change,
though.
The only readBytes call that changed in this audit was in the UI seek
bar.
The rest all appear to be values for temporary usage, and so are not
being cloned.
The new `clone` parameter will require future callers of `readBytes()`
to think about their purpose and make a choice.
The goal is to simplify and abstract feature logic detection. Currently
lots of places depend on various calls to `shaka.util.Platform` and
mainteinance of this is hard & not easy to read.
By introducing device API ideally rest of the player logic would look
into device features instead of directly checking platform. Additionally
we can more easily cache needed values, so we won't have to parse user
agent several times anymore.
---------
Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>