Commit Graph

2690 Commits

Author SHA1 Message Date
Álvaro Velad Galván e59b8b40a7 feat(HLS): Add chapter images (#9738)
Spec:
https://developer.apple.com/documentation/http-live-streaming/providing-javascript-object-notation-json-chapters
2026-02-20 15:04:12 +01:00
Álvaro Velad Galván 88c65c6bbf chore: Reduce the internal complexity of the chapters (#9737)
Instead of saving chapter titles as a URL, they are now saved as a
metadata section that can be expanded in the future.
2026-02-20 11:38:33 +01:00
Andy(김규회) c7368024ae feat: Select default track by a list of preferences (#9542)
I went ahead and implemented the full structured preference system that
was discussed in
https://github.com/shaka-project/shaka-player/issues/1591.
Instead of just expanding languages to arrays, I replaced all 14
individual preference fields with 3 structured arrays:

```tsx
  preferredAudio (language, role, label, channelCount, codec, spatialAudio)
  preferredText (language, role, format, forced)
  preferredVideo (label, role, codec, hdrLevel, layout)
```

Each array entry works as an AND filter - so you can say things like "I
want Korean with 5.1 surround, but if not available, English is fine
too":

```tsx
player.configure('preferredAudio', [
  {language: 'ko', channelCount: 6},
  {language: 'ko'},
  {language: 'en'},
]);
```

<img width="1728" height="965" alt="image"
src="https://github.com/user-attachments/assets/7b088150-139b-475e-bdba-5bc77dd4e524"
/>

**Config** - Replaced the 14 individual fields with 3 arrays of typed
preference objects (AudioPreference, TextPreference, VideoPreference).
The old fields still work at runtime with a deprecation warning, so
existing apps won't break immediately.

**Demo** - The demo config UI now shows inline expandable preference
lists instead of flat text inputs. You can add/remove entries and
configure each field per entry. URL hash serialization was updated to
use JSON format, with legacy param fallbacks preserved.
2026-02-20 10:12:08 +01:00
Álvaro Velad Galván ab09d4dcd7 fix: Do not update the player position with negative playback rates if the video is paused (#9732) 2026-02-20 10:01:37 +01:00
Álvaro Velad Galván 992f2158e5 chore: Remove shaka.media.IClosedCaptionParser interface (#9731) 2026-02-20 09:58:09 +01:00
Álvaro Velad Galván 6826ffa311 feat(CEA): Implement raw CEA-608 packet extraction (#9730)
This format is generated by Apple's HLS tools.
2026-02-19 11:45:18 +01:00
Álvaro Velad Galván 56ac70d44a perf(S2T): Improve SpeechToText code (#9718)
Avoid race conditions when using Translator API.
Avoid unnecessary DOM mutations.
Separate responsibilities in the code.
2026-02-17 10:07:29 +01:00
Álvaro Velad Galván 943a5f5e97 feat(HLS): Add CAN-SKIP-DATERANGES support (#9679)
Co-authored-by: Theodore Abshire <TheodoreAbshire@Gmail.com>
2026-02-09 09:47:00 +01:00
Álvaro Velad Galván ebcf0feb98 fix: Correctly destroy enqueue blocking operations (#9677)
Fixes https://github.com/shaka-project/shaka-player/issues/9639
2026-02-06 11:27:38 +01:00
Álvaro Velad Galván 4082ed75ee feat(DASH): Add support for SegmentTimeline@Pattern (#9669)
Close https://github.com/shaka-project/shaka-player/issues/9659
2026-02-06 07:31:49 +01:00
Álvaro Velad Galván a10287e3f0 feat!: Require apps to call updateStartTime instead of setting media element currentTime directly during startup (#9668)
This change is feat! because it no longer allows modifying the
`currentTime` of the mediaElement in the streaming event. With this
change, only `updateStartTime` can be called to update the time, and the
user should always use the `canupdatestarttime` event instead of
`streaming` event when they need it.

Fixes https://github.com/shaka-project/shaka-player/issues/9661
2026-02-05 20:26:33 +01:00
Andy(김규회) d98169bc25 feat(EME): Add retryLicensing() and failureCallback for manual license retry (#9638)
So basically, when a license request fails (eg. network Error, server
down whatever), apps can now retry from scratch by calling
`player.retryLicensing()`. This was tricky to implement because of EME
spec limitations: `generateRequest()` can only be called once per
session. So if it fails, it would be stuck.

So I close the old session and create a brand new one with the same
`initData`

> Will Video element throw an error during this process?

we were worried that closing the session would leave the video without
keys for a brief moment, potentially triggering errors. But in practice,
the transition is fast enough( I added a 0.1s delay for CDM clean up)
and the video element handles it gracefully

> Will new encrypted event fire? If not, will it limit this feature?

The encrypted event only fires when the browser first encounters
encrypted content. When we close and recreate a session, the content is
already loaded, so no new event

Solutions: In `CreateSession()` metadata store `initData` and
`initDataType` in the session metadata when the session is first
created. So when `retryLicensing()`is called, we just grab the stored
data and pass it to `generateRequest()` on the new session. No need to
wait for an `encrypted` event at all.

---------

Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
Co-authored-by: Wojciech Tyczyński <tykus160@gmail.com>
2026-02-05 14:12:30 +01:00
Álvaro Velad Galván c200219fa2 test: Fix UI tests on SmartTVs (#9660)
Tests fixed:

```
  UI Customization
    ✗ big buttons only created when configured [Safari 3.0 (Tizen 3.0)]
	Error: Expected 1 to be 0.
	    at <Jasmine>
	    at Function.confirmElementMissing (test/test/util/ui_utils.js:70:29 <- test/test/util/ui_utils.js:139:31)
	    at _callee6$ (test/ui/ui_customization_unit.js:86:13 <- test/ui/ui_customization_unit.js:152:21)
	    at tryCatch (node_modules/@babel/polyfill/dist/polyfill.js:6473:40)
  UI
    controls
      controls-button-panel
        ✗ has default elements [Safari 3.0 (Tizen 3.0)]
	Error: Expected 1 to be 0.
	    at <Jasmine>
	    at Function.confirmElementMissing (test/test/util/ui_utils.js:70:29 <- test/test/util/ui_utils.js:139:31)
	    at _callee15$ (test/ui/ui_unit.js:425:19 <- test/ui/ui_unit.js:506:27)
	    at tryCatch (node_modules/@babel/polyfill/dist/polyfill.js:6473:40)

```
2026-02-05 07:09:13 +01:00
Álvaro Velad Galván 514246c8de feat(UI)!: Remove airplay button (#9654)
`airplay` button uses WebKit's proprietary API. In newer versions, this
has been replaced by the RemotePlayback API, which is available in
`remote` button.

More info: https://caniuse.com/mdn-api_remoteplayback

---------

Co-authored-by: Theodore Abshire <TheodoreAbshire@Gmail.com>
2026-02-04 11:28:17 +01:00
Álvaro Velad Galván bd167c3744 feat: Add listenMulti and listenOnceMulti to shaka.util.EventManager (#9652)
Co-authored-by: Wojciech Tyczyński <tykus160@gmail.com>
2026-02-03 21:49:35 +01:00
Álvaro Velad Galván 3fd73ce941 feat(UI)!: Add bigButtons config and remove addBigPlayButton config (#9636)
- The following buttons are registered: play_pause, mute, fullscreen,
rewind, fast_forward, picture_in_picture, remote, loop, skip_next,
skip_previous
- SmallPlayButton and BigPlayButton are removed
- The following buttons are used by default on mobile: skip_previous,
play_pause, skip_next
2026-02-02 09:56:43 +01:00
Álvaro Velad Galván 0c0c2ffe29 feat(UI)!: Enable customContextMenu by default on desktop browsers (#9635)
statistics and ad_statistics are added by default to context menu only
on debug builds
2026-01-30 12:03:26 +01:00
Álvaro Velad Galván 6fc70622eb chore: Change frameRate from string to number in shaka.media.SegmentUtils.BasicInfo (#9627)
Related to https://github.com/shaka-project/shaka-player/pull/9626
2026-01-29 17:13:20 +01:00
Álvaro Velad Galván afd24224ce feat(SRT): Improve SRT to WebVTT conversion and color handling (#9624)
- Full SRT → WebVTT conversion now supports timestamps, alignment,
position, and basic styles (bold, italic, underline).
- Added proper handling for <font color="..."> tags:
  - Converts known colors to WebVTT <c.color> classes.
  - Safely removes unknown colors without leaving orphaned </c> tags.
- Supports Aegisub cues ({\anX} → line & align, {\pos(x,y)} → position &
line).
- Normalizes timestamps (MM:SS,mmm → 00:MM:SS.mmm) for WebVTT
compliance.
2026-01-29 12:39:38 +01:00
Álvaro Velad Galván 1debeb8640 feat: Derive frameRate from fMP4 samples and improve MP4 parsing in SegmentUtils (#9626)
- Calculate frameRate using tfhd/trun in fMP4
- Concatenate initData and media data for parsing
- Deduplicate PSSH boxes across initData and segments
2026-01-29 11:51:26 +01:00
Álvaro Velad Galván 7a171c6217 chore(Queue): Improve the QueueManager code (#9620) 2026-01-29 09:50:09 +01:00
Álvaro Velad Galván eefc8c2726 fix(Ads): Handle bad HTTP status errors as specified, play main content (#9612)
Fixes https://github.com/shaka-project/shaka-player/issues/9607

More info:
https://mailarchive.ietf.org/arch/msg/hls-interest/ev-q7Q7sH5ADz4NgKxqSeCnE2IQ/
2026-01-28 11:20:44 +01:00
Álvaro Velad Galván a9df794849 fix(MSF): Do not re-encapsulate Shaka errors (#9613) 2026-01-27 14:05:13 +01:00
Álvaro Velad Galván 1904341bde test: Load experimental build on tests (#9610) 2026-01-27 10:30:58 +01:00
Álvaro Velad Galván 71af24f82b feat: Only disallow SourceBuffer.changeType on PlayReady when using Edge browser (#9603)
More info in
https://chromium-review.googlesource.com/c/chromium/src/+/4577759 and
https://issues.chromium.org/issues/40261162

According to the source code and empirical testing, SMOOTH is supported
with clear content and Widevine, but not with PlayReady.
2026-01-26 12:12:53 +01:00
Andy(김규회) eac68c7ea0 feat(EME): Add manual and automatic license renewal API (#9589)
Widevine's CDM handles renewal automatically, but FairPlay and PlayReady
require manual
`session.update()` calls to renew licenses before they expire.
Previously, developers had to access internal APIs like
`getDrmEngine().activeSessions_` which only works in debug builds - not
ideal for production use.
Based on the discussion in #9505, this PR implements both Option A and
Option C:
**Option A - Manual renewal API:**
```js
player.renewLicense(); // all sessions
player.renewLicense(sessionId); // specific session
 ``` 
  **Option C - Automatic renewal with config:**
```js
player.configure({
drm: {
renewalIntervalSec: 600
}
});
player.addEventListener('licenserenewal', (event) => {
console.log('License renewed:', event.newSessionMetadata,
event.oldSessionMetadata);
  });
```
This way, developers can choose automatic renewal, manual control, or
both depending on their use case.
Under the hood, FairPlay sends a 'renew' message via session.update(),
while PlayReady re-creates the session. Widevine just dispatches the
event since the CDM already handles everything.
2026-01-26 11:49:26 +01:00
Wojciech Tyczyński 482117f6c8 fix(ContentWorkarounds): Insert PSSH boxes for fake init encryption (#9600)
Related to #8048

Some platforms (i.e. NOS STB) are not able to play encrypted content
without PSSH boxes in init segments. This PR addresses it by adding PSSH
boxes with actual data if we have it.
2026-01-26 10:15:39 +01:00
Wojciech Tyczyński 5c05132772 feat!: Use shared logic for MediaError details (#9594) 2026-01-22 20:50:32 +01:00
Álvaro Velad Galván 55b0681151 feat: Add getMimeType method to shaka.Player (#9592) 2026-01-22 14:28:06 +01:00
Álvaro Velad Galván 4c945af650 feat(MSF): Add support for custom namespaces via config (#9586) 2026-01-22 14:00:12 +01:00
Álvaro Velad Galván eda2429b7c feat: Allow detect Fairplay on shaka.media.SegmentUtils (#9585) 2026-01-22 09:45:11 +01:00
Álvaro Velad Galván 5ee77799f5 chore: Remove unused code (#9584) 2026-01-21 14:08:36 +01:00
Álvaro Velad Galván dbfe560b66 fix(Ads): Fix send _HLS_primary_id on HLS interstitials (#9581)
See:
https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#appendix-D.4
In particular:
> Clients that cannot set the X-PLAYBACK-SESSION-ID request header
   SHOULD create a globally-unique value for every primary playback
   session, and provide this value as an _HLS_primary_id query parameter
   on both the request for the primary asset and interstitial requests
   made on behalf of that asset.
2026-01-21 12:27:53 +01:00
Álvaro Velad Galván 33cf09ce0d fix(HLS): Fix support DATERANGE from 1970-01-01T00:00:00.000Z (#9580) 2026-01-20 20:57:46 +01:00
Woody Hill 66b0c74a01 fix: parseHDLR for Apple QuickTime hdlr box compatibility (#9577)
Apple QuickTime places a manufacturer field ('appl') immediately after
the handler type ('soun'), causing readTerminatedString() to incorrectly
read 'sounappl' instead of 'soun'. This breaks Opus fMP4 audio playback
for content packaged with Apple tools.

Replace null-terminated string parsing with fixed-length byte reading to
extract exactly 4 bytes for the handler type.

Closes #9576

---------

Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
2026-01-20 12:59:31 +01:00
Álvaro Velad Galván c4a506a83b feat(HLS): Detect new chapter streams added after initial load (#9573)
Co-authored-by: Theodore Abshire <TheodoreAbshire@Gmail.com>
2026-01-20 11:02:28 +01:00
Álvaro Velad Galván cafab9a8c6 test: Check live update of chapters in HLS (#9564) 2026-01-15 14:58:55 +01:00
Álvaro Velad Galván e5d9471fa5 feat(HLS): Add AES-256-GCM support (#9562)
More info in:
https://datatracker.ietf.org/doc/draft-pantos-hls-rfc8216bis/19/ and
https://mailarchive.ietf.org/arch/msg/hls-interest/85CoeMS9O2zRoMff_Xx_WgCukJg/
2026-01-15 14:18:02 +01:00
Álvaro Velad Galván aaecc079be fix(TTML): Fix MP4 TTML Parser producing invalid image subtitles (#9559)
Fixes https://github.com/shaka-project/shaka-player/issues/9557
2026-01-14 12:01:02 +01:00
Álvaro Velad Galván ef361ed039 feat: Add MoQT draft-14 + WARP/MSF draft-1 experimental support (#9409)
Spec: https://datatracker.ietf.org/doc/draft-ietf-moq-transport/14/
Spec: https://datatracker.ietf.org/doc/draft-ietf-moq-warp/01/

Note: this is experimental and not included in the default builds

---------

Co-authored-by: Wojciech Tyczyński <tykus160@gmail.com>
2026-01-14 09:27:10 +01:00
Álvaro Velad Galván f9f9977673 test: Disable mp4 muxed test on Tizen 3 (#9550) 2026-01-08 12:16:27 +01:00
Álvaro Velad Galván 5b473c8d54 test: Fix override TextDecoder on tests (#9549) 2026-01-08 11:44:12 +01:00
Andy(김규회) 2bfb798465 feat(EME): Implement MediaKeySessionClosedReason handling (#9540)
When a MediaKeySession is closed by the CDM, the engine now utilizes the
MediaKeySessionClosedReason to determine the appropriate recovery path.
For critical reasons like hardware-context-reset, the engine
automatically recreates the session using its original initialization
data. We also addressed a race condition where keystatuseschange events
arriving for already-closed sessions would cause an engine crash.

This implementation is specific to the new EME closed promise resolution
logic and handles CDM-initiated closures. It ensures robustness on
platforms where hardware events, such as device sleep or GPU switches,
would otherwise lead to permanent playback failure.

Correctly handling these closure reasons prevents orphaned sessions and
allows playback to resume seamlessly after a hardware reset. The
additional safety check in the key status path ensures that asynchronous
notifications from the CDM do not interfere with the engine's session
management.

---------

Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
2026-01-05 15:04:43 +01:00
Álvaro Velad Galván c4de8f1f53 fix: Fix alignItems usage on old devices (#9544)
start/end are supported from Chromium 93+ (see:
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/align-items).
2026-01-05 15:04:13 +01:00
Gary Katsevman 2d23ea456a fix: don't clear text displayer cache for vtt if we're clearing cea cache (#9538)
an issue we found as part of making the fix for #9470 and also
separately.
2025-12-23 15:43:33 +01:00
Wojciech Tyczyński b733fe26fb fix(Thumbnails): Fix thumbnails precision issues (#9536)
Fixes 2 issues around thumbnails:
- adjusts position calculation within grid to take rounding errors into
account. Lack of that caused duplicated thumbnails sometimes
- removes thumbnails that are outside of reference window (i.e. outside
of period) which may happen if grid is partially fulfilled
2025-12-23 15:43:17 +01:00
Álvaro Velad Galván 909655f4eb feat: Add configurationchanged event (#9531) 2025-12-19 16:35:35 +01:00
Álvaro Velad Galván c6e6082bc2 feat: Allow override subtitle position (#9522)
Close https://github.com/shaka-project/shaka-player/issues/9521

---------

Co-authored-by: Wojciech Tyczyński <tykus160@gmail.com>
2025-12-19 13:38:33 +01:00
Álvaro Velad Galván 2d02ae3f6d feat(UI): Allow all items registered in overflow to be in the context menu (#9527) 2025-12-19 09:23:07 +01:00
Álvaro Velad Galván 691e7b5aa7 fix(HLS): Fix label name for audio-only content without EXT-X-MEDIA (#9520)
Fixes https://github.com/shaka-project/shaka-player/issues/9519
2025-12-18 13:25:47 +01:00