mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-12 15:26:16 -08:00
169 lines
10 KiB
Markdown
169 lines
10 KiB
Markdown
# Chromecast maintenance
|
|
|
|
The factory remains `artplayerPluginChromecast(option)`. Registration is async and
|
|
adds the `chromecast` right control immediately. Its resolved object retains
|
|
`name`, `getCastState()` and `isCasting()`. SDK loading remains lazy on first click.
|
|
The option object stays live: later changes to `url`, `mimeType`, `sdk` and callback
|
|
properties are read at the corresponding operation. Callbacks retain `this === option`.
|
|
The control HTML is captured at registration, as before.
|
|
|
|
## Modules
|
|
|
|
| File | Responsibility |
|
|
| --- | --- |
|
|
| `src/index.ts` | Public factory and historical `.default` factory alias |
|
|
| `src/controller.ts` | One registration's subscriptions, raw session state, click operation, notices and owned control icon |
|
|
| `src/sdk.ts` | Framework readiness, shared in-flight script leases, callback preservation and context configuration |
|
|
| `src/media.ts` | Existing URL/extension MIME rules and SDK media request construction |
|
|
| `src/types.ts` | Narrow internal SDK, event and callback contracts; not the published declaration entrypoint |
|
|
| `src/cast.svg` | Original default Cast artwork imported as inline SVG |
|
|
|
|
Dependencies point from the factory to the controller, then to the SDK loader and
|
|
media builder. The loader and media builder do not receive an ArtPlayer instance.
|
|
Public declarations remain in `types/`. The root and legacy entries retain npm
|
|
1.1.0's required option argument and synchronous name-only factory type, including
|
|
ordinary replacement-function assignment. `/runtime` describes the actual async
|
|
registration and callbacks using the same JavaScript files. Internal option and
|
|
result contracts reference these precise public types to prevent another drift.
|
|
|
|
## Initialization and ownership
|
|
|
|
Each registration has its own session state and subscriptions, even when one
|
|
factory is reused for several players. Unclicked instances do not subscribe to
|
|
the SDK. An initialized instance observes page-wide CastContext events; this is
|
|
the SDK's shared session, not an exclusively owned receiver session.
|
|
|
|
Within a loaded plugin module, controllers share one pending SDK load per window.
|
|
The first pending request's SDK URL wins; another URL can be used on a later retry.
|
|
A complete existing Framework is reused immediately. A partial `chrome.cast`
|
|
object is insufficient readiness and still permits loading the Framework script.
|
|
The original availability callback is invoked with its window receiver and both
|
|
arguments. Its thrown exception still escapes to its caller, while the plugin's
|
|
own subscribers settle independently. Cleanup restores that handler only while
|
|
our handler is still installed, so a later external replacement is preserved.
|
|
|
|
On availability, each subscriber installs its listeners synchronously before its
|
|
loader promise resolves. This preserves the historical boundary where a session
|
|
event immediately following `__onGCastApiAvailable(true)` is observable. One
|
|
subscriber's setup exception rejects that subscriber without stranding the rest.
|
|
The default receiver and ORIGIN_SCOPED policy are configured once per observed
|
|
context. This does not negotiate receiver configuration with unrelated Cast apps.
|
|
|
|
Successful scripts remain on the page. Failed or last-owner-cancelled scripts are
|
|
removed and can be retried. Script `load` may precede Framework availability, so
|
|
incomplete load does not fail immediately; a 30-second readiness timeout settles
|
|
an unavailable Framework even if no error/availability event arrives. The timeout
|
|
is cleared on success, failure and last-owner cancellation. Destroying one player
|
|
releases its lease without interrupting another pending player. Independently
|
|
loaded copies of this plugin do not share their module-local lease registry.
|
|
|
|
## Session operations and failure semantics
|
|
|
|
One player has at most one pending click operation; concurrent clicks receive the
|
|
same promise. After initialization, the controller reads `getCurrentSession()`.
|
|
If absent, it awaits `requestSession()` and reads `getCurrentSession()` again.
|
|
The request's completion value is not a CastSession. No active session after a
|
|
successful request is a connection error. Media URL selection uses the current
|
|
`option.url || art.option.url`; no receiver URL rewriting is performed.
|
|
|
|
The complete media load is awaited. The click promise rejects with the original
|
|
SDK error and reports one stage-specific notice and `onError`. A separate rejection
|
|
observer handles ArtPlayer's DOM dispatcher, which ignores returned click promises;
|
|
programmatic callers still receive the original rejecting promise. Callback
|
|
exceptions retain their normal propagation and are not interpreted as receiver
|
|
success evidence.
|
|
|
|
`getCastState()` retains the last raw SDK SessionState, initially null, and is not
|
|
the normalized callback state. `isCasting()` reflects a retained session reference,
|
|
including one acquired by a successful session request; it does not prove receiver
|
|
playback. `NO_SESSION`, `SESSION_ENDED` and `SESSION_START_FAILED` clear that reference
|
|
and notify disconnected. Initial `NO_SESSION` during SDK setup does not cancel the
|
|
first click before a session operation begins. Ending/terminal events during a
|
|
request or media load, and replacement of the current session, invalidate pending
|
|
work. Late success/rejection is observed without stale media starts or notices.
|
|
|
|
Destroy marks the controller inactive, settles its pending click, releases its
|
|
loader lease, attempts both SDK listener removals and removes its ArtPlayer
|
|
subscription. All cleanup is attempted even when one SDK removal throws; the first
|
|
cleanup error is preserved. Any callback left behind by a broken SDK removal is
|
|
inactive. The plugin never ends a page-shared session. ArtPlayer owns control DOM
|
|
removal; the plugin only updates the icon under the element supplied to its own
|
|
control's `mounted` callback, retaining `.art-icon.art-icon-cast` and the
|
|
red/orange/white states. The actual `Control.add` override returns undefined even
|
|
though the shared component superclass returns an element; never rely on the
|
|
control add return value for DOM ownership. Candidate fixtures replay `mounted`
|
|
and preserve this undefined return so the browser-discovered regression remains
|
|
covered outside the browser too.
|
|
|
|
## Artwork provenance
|
|
|
|
The default SVG now uses original rectangle, circular arc and dot geometry authored
|
|
for this refactor under the repository MIT license. It does not copy the former
|
|
Font Awesome Pro path. `src/cast.svg` is the single artwork source; custom `icon`
|
|
HTML and the existing wrapper hooks remain supported. The previous commercial
|
|
notice/source gap is tracked as VENDOR-10; production bundles must be regenerated
|
|
from this source rather than edited by hand.
|
|
|
|
## Validation and next changes
|
|
|
|
Use the pinned Node and Yarn versions. Scoped commands from the repository root:
|
|
|
|
```sh
|
|
node --test test/chromecast.test.js test/chromecast-failures.test.js test/chromecast-runtime.test.js
|
|
yarn exec tsc -p packages/artplayer-plugin-chromecast/tsconfig.json
|
|
yarn exec eslint packages/artplayer-plugin-chromecast/src test/chromecast-runtime.test.js
|
|
yarn build artplayer-plugin-chromecast
|
|
yarn build:ts artplayer-plugin-chromecast
|
|
node --test refactor/scripts/chromecast-types.test.mjs
|
|
yarn test:chromecast-types-package
|
|
```
|
|
|
|
`ARTPLAYER_CHROMECAST_ARTIFACT` selects a built main or legacy file for the candidate
|
|
tests. `ARTPLAYER_CHROMECAST_ESM_ARTIFACT` selects the native ESM artifact for the
|
|
default-export identity check. Without these variables tests bundle current source
|
|
in memory. Historical tests retain actual frozen npm/source inputs and deliberately
|
|
observe the old defects; candidate tests assert their corrections separately.
|
|
|
|
Change SDK loading in `sdk.ts`, state/cleanup in `controller.ts`, and MIME behavior
|
|
in `media.ts`. Always retain synchronous availability-event coverage, ignored DOM
|
|
promise rejection coverage, multi-player ownership, partial failure cleanup and
|
|
late completion tests when changing those boundaries.
|
|
|
|
Controlled SDK tests and local browser DOM interaction cannot establish real Cast
|
|
receiver playback. PKG-CAST-05 still requires the supported Chrome/HTTPS sender,
|
|
actual receiver, network-reachable media, source changes and disconnection evidence.
|
|
The default SDK URL is mutable; no remote SDK version, physical receiver or Safari
|
|
support is established by this source migration.
|
|
|
|
## Type and module compatibility
|
|
|
|
ADR-027 preserves the latest actual npm declaration, not a claim that all past
|
|
incompatible declarations can coexist. npm 1.0.0 used `export =` and its CommonJS
|
|
module exposed `.default`; npm 1.1.0 uses a default declaration and direct CommonJS
|
|
factory. Both legal JavaScript forms work in the candidate through a writable
|
|
self `.default`. Root types remain a plain factory without that required member.
|
|
|
|
The historical types-first root mapping also retains the latest declaration's
|
|
NodeNext ESM namespace shape and its existing direct-call diagnostic. Its legal
|
|
namespace consumers and full module replacement are tested independently. Choose
|
|
`/runtime` for a directly callable modern ESM default and precise async results;
|
|
its `.d.mts`, `.d.cts` and Node10 `export =` declarations share eight named types.
|
|
The option argument remains required on both type surfaces. Callbacks have the
|
|
live option object as `this`; errors are unknown, raw session state is string or
|
|
null, and `isCasting()` does not establish receiver playback.
|
|
|
|
The installed consumer verifier compares both actual historical tarballs and an
|
|
isolated candidate package, validates individual negative statement diagnostics,
|
|
and checks runtime entry identity. The editor declaration is generated semantically
|
|
from the root declaration. Keep internal `tsconfig.json` and source out of npm packs.
|
|
|
|
## Shared installed browser validation
|
|
|
|
chromecast-lifecycle.spec.js selects the verified installed bundle. It uses a controlled Cast SDK with real core DOM, clicks and local video; receiver discovery, actual Cast SDK and remote playback remain PKG-CAST-05. The artifact map must not be interpreted as physical device acceptance.
|
|
|
|
Use `yarn test:package --browser`, then `yarn test:browser:installed`. The common
|
|
roster in scripts/browser-validation/scope.ts drives both preparation and required
|
|
inputs. Explicit artifact overrides are rejected when an installed map is present;
|
|
missing or stale inputs fail without source fallback. Source mode retains deliberate
|
|
artifact selection. See ../../refactor/changes/2026-09-15-CI-01-asr-cast-installed.md.
|