This PR reduces allocation pressure in MP4 segment generation by writing
mdat data directly into the final segment buffer - this avoids one full
media-payload copy per segment
In `H264.getVideoSamples()` `lastVideoSample.data` is initialized with
an empty `Uint8Array` which is always replaced before the sample is
pushed into the `videoSamples` array, so to avoid creating a new empty
placeholder `Uint8Array` for each sample, the empty `Uint8Array` can be
created once and then use to initialize all `lastVideoSample` objects in
that segment.
`TSParser.parsePES_` had a similar placeholder empty `Uint8Array` issue,
which I was able to resolve by creating the PES object in the return
statement instead of upfront, that way it can be initialized with the
final data, avoiding the placeholder.
While yes empty Uint8Arrays definitely need less memory than larger
ones, it is still better to not create 100+ unnecessary objects in rapid
succession which then need to be cleaned up by the garbage collector
later on.
This PR replaces a full-config deep-clone in Player.getBufferFullness()
with a direct read, removing a per-timeupdate allocation for playback
sessions that have liveSync configured, or `vodDynamicPlaybackRate`
This improves TS h265, TS AC-3, TS EC-3, raw AC-3 and raw EC-3 as the
transmuxer calls `parseFrame` for each frame in the payload passed to
the `transmux` method, for LOC h265 this is marginally worse as it only
calls `parseFrame` once per `transmux` call.
We recorded a h264 + opus video and audio stream with chrome
mediarecorder api.
From debug mode, I noticed that transmuxed opus chunk was 3x shorter
than video, but ffmpeg showed that they should be about the same.
It turns out the duration is not set correctly. Before the fix, repeated
seeking will eventually get stuck. After this fix, I can verify that
seeking no longer is stuck.
Co-authored-by: Claude <noreply@anthropic.com>
---------
Co-authored-by: Álvaro Velad Galván <ladvan91@hotmail.com>
This PR reduces steady-state work during HLS live/DVR playlist refreshes
by avoiding already known segments' re-construction. Before this, on a
live playlist update, the parser would still call
createSegmentReference_() for every segment, though only the newly
appended tail was actually merged into the segment index.
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
This PR removes slice for a simpler truncation - especially good for
`merge` because we just truncate from the back. No need for allocation
for none of them anyway so this is an easy win
This PR extends work from #5061 to DASH SegmentTemplate@duration streams
by lazily creating fixed-duration segment references instead of building
the full index up front during manifest parsing
`Mp4Generator.box()` merges all arguments into one `Uint8Array`, so
arrays of `Uint8Arrays` can be spread directly into the
`Mp4Generator.box()` calls instead of doing the extra step of merging
them into a single `Uint8Array` first. I also included a drive-by change
to simplify `array.push(...[x, y])` into `array.push(x, y)` in the
`segmentData` method.
This PR replaces more linear scans with binary search in more segment
lookup methods - optimization is aimed at long DVR livestreams on
low-end TV devices
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
```js
player.addTextTrackAsync("...", "en", "subtitles");
const textTracks = player.getTextTracks();
// Text tracks has a length of 1, but immediately selecting it would fail.
player.selectTextTrack(textTracks[0]);
```
Text track preference runs after we manually selected a text track, in
`src=` we'd wait for `loadeddata` before figuring out which initial text
track should be selected. The fix is to bail out when we already have a
text track active when trying to select an initial text track.
Technically the spec does not impose a maximum limit, but browsers do
not reliably support playback rates above 16x. For rates greater than
16x, we fall back to the trick-play mechanism used for negative playback
rates.
#9416 introduced case insensitive matching for ManifestParser detection.
To add a feature parity, the same should be added for src= detection.
Lack of it may cause issues with proper detection of native playback
capabilities and accidental preference of MSE over src=.
Logic has been shifted - now passed MIME type is lowercased by default
in `load()` and `preload()` methods. If MIME type is not present,
`NetworkingUtils.getMimeType()` guarantees to return lowercase variant.
HLS SUPPLEMENTAL-CODECS (e.g. Dolby Vision dvh1) creates duplicate
variant tags with different codecs but the same media playlist URI. Due
to lazy-loading, only one variant gets its drmInfos populated via
createSegmentIndex(). The other variant remains with empty drmInfos and
is treated as unencrypted by getDecodingConfigs_().
In the preferredKeySystems loop, the filter rejected these unencrypted
configs (undefined !== preferredKeySystem), leaving the variant with no
decodingInfo and causing it to be dropped.
Fix: allow unencrypted configs (!keySystem) to pass through, matching
the pattern already used in the second (fallback) loop.
Propagating drmInfos in HLS parser would be more correct but is complex
because stream duplication happens at the tag level with separate cache
keys (URI + codecs) in createStreamInfoFromVariantTags_.