Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/v3.32.0 #1296

Merged
merged 34 commits into from
Oct 19, 2023
Merged

Release/v3.32.0 #1296

merged 34 commits into from
Oct 19, 2023

Conversation

peaBerberian
Copy link
Collaborator

Release: v3.32.0

Branch for the incoming 3.32.0 release. We're in the process of testing it.

Those last months focus has mainly shifted into:

  • improving debugging capabilities, issues investigation and platform support
  • ensuring that the future v4 API can be stabilized (we're using it in production right now on some devices) so we finally can make it our official release (we will still support for the v3 for some time) - encouraging more people making the switch
  • Proof-of-Concept of relying on a WebWorker to improve performances in specific cases (low-latency contents, large live contents, resource-constrained devices with rich UI). That huge work ([WIP] [v4] MULTI_THREAD feature relying on a WebWorker #1272) offered great preliminary results, encouraging us to start implementing it, now the implementations works "too well" for some cases, with the worker overwhelming the main thread (and worsening some perf issues) in some specific scenarios.

Consequently this v3 release contains mainly a multitude of small-ish improvements backported when working on those.

The only "real" feature is the new isSpatialAudio property on audio Representations, a nice signalization improvement brought to us by @klatoszewski-oke.

Changelog

Features

Bug fixes

Other improvements

Deprecated

peaBerberian and others added 11 commits May 17, 2023 18:23
Add `trackInfo` property to some `MediaError`
This commit adds the `declareInitSegment` and `freeInitSegment` methods
to the RxPlayer's SegmentBuffer abstractions (which is the part of the
code handling the operations on SourceBuffers, such as pushing media and
init segments).

The short term idea is to improve the handling of initialization
segments in the SegmentBuffer.
Until now, each pushed media segment lead to a check that the
initialization segment it relies on is the same than the last one
pushed. To be able to perform that check, a caller need to communicate
again the initialization segment's data each time a chunk is pushed to
the buffer.

This check can be performed efficiently in most cases because we first
check init segment's data equality by reference, which, by pure luck,
should be equal in most cases in the current code. In cases where it
isn't the same reference however, it can lead to a byte-per-byte check,
which should not be an issue in terms of performance in most cases, but
is still an ugly specificity which could be handled in a more optimal
and understandable way.

This commit now allows the definition of a `initSegmentUniqueId`, an
identifier for initialization segments, on SegmentBuffers.
Any pushed segments can then refer to its associated init segment by
indicating which `initSegmentUniqueId` it is linked to.

The SegmentBuffer will ensure behind the hood that the right
initialization segment is pushed before pushing media segments, like
before, excepted that this can now be done just by comparing this
`initSegmentUniqueId` - it also means that the caller is no more
required to keep in memory the data of the loaded initialization
segment, the `SegmentBuffer` is already doing that.
Previously, the initialization segment's data was kept by the
`RepresentationStream`, the abstraction choosing which segments
to load (which is part of the reasons why the reference mostly never
changed).

The declaration and "freeing" of init segment is done through a
`declareInitSegment`/`freeInitSegment` pair of methods on a
`SegmentBuffer`. This sadly means that memory freeing for the
initialization segment is now manual, whereas we just relied on garbage
collection when the initialization segment was directly used.

---

Though mostly, the long term benefit is to implement the hybrid-worker
mode that we plan to have in the future, where buffering is performed in
a WebWorker (thus improving concurrence with an application, with the
goal of preventing both UI stuttering due to heavy player tasks and
rebuffering due to heavy UI tasks).

In the currently-planned long term worker features we would have thus
the following modes:

  - full worker: where both the rebuffering logic and MSE API are called
    in a WebWorker, allowing to avoid UI and media playback blocking
    each other to some extent

    This however requires the
    [MSE-in-Worker](w3c/media-source#175)
    feature to be available in the browser AND it also implies a more
    complex API, notably some callbacks (`manifestLoader`,
    `segmentLoader` and `representationFilter`) which will have to be
    updated.

  - hybrid mode: The buffering logic is mainly performed in a WebWorker
    but MSE API are still in the main thread. This allows e.g. to not
    fight for CPU with the UI to know which segments to download and to
    avoid blocking the UI when the Manifest is being parsed.

    Though the UI blocking could still mean that a loaded segment is
    waiting to be pushed in that mode.

    Because here MSE APIs may have to be called through `postMessage`-style
    message passing, the previous logic of communicating each time the
    same initialization segment each time a segment was pushed, with no
    mean to just move that data (in JavaScript linguo, to "transfer" it)
    was considerably worst than before.
    Relying on a short identifier instead seems a better solution here.

  - normal mode: The current mode where everything stays in main thread.

However it should be noted that all of this long term objective is still
in an higly experimental phase, and the gains are only theoretical for
now.
This commit performs a small modifications so that the `Stream` module,
when asking for the current content to be "reloaded" (that is: to
replace its MediaSource, generally both for compatibility reasons and to
ensure buffers are flushed), no longer needs to either calculate the
position to reload to nor if it should auto-play after the reload.

This is a simplification of a "reload" event from the point of view of
the `Stream`. A "reload" there now is mostly done "in-place" (with
a possible time offset to apply, e.g. to re-play the last second
after changing the audio track, the `Stream` could be asking for a
`timeOffset` of `-1`) and playback characteristics are mostly kept as
they were before the reload.

The position and playing status is now computed by the
`MediaSourceContentInitializer`, which is the actual module doing the
reloading logic, based on the position and playing status at the time
the reload order was received.

This is important in our current Proof-of-Concept of running the RxPlayer
in a worker: Calculating the current position and playing status was in
the end done synchronously by asking the `HTMLMediaElement` on the page.
In a worker, we do not have access to the `HTMLMediaElement`, thus that
data cannot be accessed synchronously if the module asking for it is
running on the worker (and the `Stream` fully runs in the worker).

By keeping such logic closer to the higher level of the RxPlayer's internal
architecture (closer to the API, further from the core), we greatly
facilitate the possibility of splitting that logic between main thread
(`HTMLMediaElement` management) and worker (`Stream`, `MediaSource`
management when MSE-in-worker is available). The
`MediaSourceContentInitializer` itself is on that matter splitted into two
parts: a part in the main thread, the other in the worker.

Even if that Proof-of-Concept is not actually merged in the future, this
small modification still makes sense, at least to me.
As we're going to probably remove it from the v4 (#1276), it makes sense
to prepare its removal by first deprecating in the v3.
@peaBerberian peaBerberian added this to the 3.32.0 milestone Oct 2, 2023
@peaBerberian peaBerberian force-pushed the release/v3.32.0 branch 2 times, most recently from 50c6243 to 3bd7c72 Compare October 13, 2023 09:30
klatoszewski-oke and others added 14 commits October 13, 2023 11:46
[Proposal] Add `declareInitSegment` method to the SegmentBuffer abstraction
Decide the position and autoplay status of a Reload in the Initializer
Deprecate manifestUpdateUrl loadVideo option in the v3
The `StreamEventsEmitter` is the RxPlayer module storing events found in
the Manifest (for now only DASH' `EventStream` elements) and emitting
`streamEvent`/`streamEventSkip` RxPlayer events when they are encountered.

In the WebWorker work (#1272), I had to refacto the
`StreamEventsEmitter` from being a long-lived function to being a class,
to make it possible to be communicated manifest updates less awkwardly
and more idiomatically, through an `onManifestUpdate` method.

However, I liked the result and find it much more easy to understand
than the previous one, which bears the mark of having been previously
an RxJS-based logic.

This refacto the `StreamEventsEmitter` into a class without adding the
supplementary worker-linked logic handlin manifest updates differently.

Basically, it's just now a class emitting events with `start` and `stop`
methods.
Bring multiple feature switching improvements
In #1287, I deprecated the `NATIVE_TEXT_BUFFER` and `HTML_TEXT_BUFFER`
as they already are automatically included when importing one of the
corresponding text track parsers (so there's no point to have a separate
import here, it can just be lazily added on any of those parser's
injection to the RxPlayer).

Yet I forgot that the exact same situation was there for the
`IMAGE_BUFFER` (and even completely forgot to re-document image-related
features). This is now done.
@peaBerberian peaBerberian merged commit b1e7a6d into master Oct 19, 2023
1 of 3 checks passed
@peaBerberian peaBerberian deleted the release/v3.32.0 branch February 7, 2024 16:32
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