UNPKG

@ktt45678/vidstack

Version:

UI component library for building high-quality, accessible video and audio experiences on the web.

143 lines (139 loc) 4.37 kB
import { IS_CHROME } from './vidstack-Dv-j8Hw0.js'; import { loadScript } from './vidstack-DPeH8lGJ.js'; import '@floating-ui/dom'; import { peek } from './vidstack-41uXLVgN.js'; import './vidstack-BI9udY6A.js'; import 'media-captions'; function getCastFrameworkURL() { return "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"; } function hasLoadedCastFramework() { return !!window.cast?.framework; } function isCastAvailable() { return !!window.chrome?.cast?.isAvailable; } function isCastConnected() { return getCastContext().getCastState() === cast.framework.CastState.CONNECTED; } function getCastContext() { return window.cast.framework.CastContext.getInstance(); } function getCastSession() { return getCastContext().getCurrentSession(); } function getDefaultCastOptions() { return { language: "en-US", autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED, receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, resumeSavedSession: true, androidReceiverCompatible: true }; } function getCastErrorMessage(code) { const defaultMessage = `Google Cast Error Code: ${code}`; return defaultMessage; } class GoogleCastLoader { constructor() { this.name = "google-cast"; } /** * @see {@link https://developers.google.com/cast/docs/reference/web_sender/cast.framework.CastContext} */ get cast() { return getCastContext(); } mediaType() { return "video"; } canPlay(src) { return IS_CHROME; } async prompt(ctx) { let loadEvent, openEvent, errorEvent; try { loadEvent = await this._loadCastFramework(ctx); if (!this._player) { this._player = new cast.framework.RemotePlayer(); new cast.framework.RemotePlayerController(this._player); } openEvent = ctx.player.createEvent("google-cast-prompt-open", { trigger: loadEvent }); ctx.player.dispatchEvent(openEvent); this._notifyRemoteStateChange(ctx, "connecting", openEvent); await this._showPrompt(peek(ctx.$props.googleCast)); ctx.$state.remotePlaybackInfo.set({ deviceName: getCastSession()?.getCastDevice().friendlyName }); if (isCastConnected()) this._notifyRemoteStateChange(ctx, "connected", openEvent); } catch (code) { const error = code instanceof Error ? code : this._createError( (code + "").toUpperCase(), "Prompt failed." ); errorEvent = ctx.player.createEvent("google-cast-prompt-error", { detail: error, trigger: openEvent ?? loadEvent, cancelable: true }); ctx.player.dispatch(errorEvent); this._notifyRemoteStateChange( ctx, isCastConnected() ? "connected" : "disconnected", errorEvent ); throw error; } finally { ctx.player.dispatch("google-cast-prompt-close", { trigger: errorEvent ?? openEvent ?? loadEvent }); } } async load(ctx) { { throw Error("[vidstack] can not load google cast provider server-side"); } } async _loadCastFramework(ctx) { if (hasLoadedCastFramework()) return; const loadStartEvent = ctx.player.createEvent("google-cast-load-start"); ctx.player.dispatch(loadStartEvent); await loadScript(getCastFrameworkURL()); await customElements.whenDefined("google-cast-launcher"); const loadedEvent = ctx.player.createEvent("google-cast-loaded", { trigger: loadStartEvent }); ctx.player.dispatch(loadedEvent); if (!isCastAvailable()) { throw this._createError("CAST_NOT_AVAILABLE", "Google Cast not available on this platform."); } return loadedEvent; } async _showPrompt(options) { this._setOptions(options); const errorCode = await this.cast.requestSession(); if (errorCode) { throw this._createError( errorCode.toUpperCase(), getCastErrorMessage(errorCode) ); } } _setOptions(options) { this.cast?.setOptions({ ...getDefaultCastOptions(), ...options }); } _notifyRemoteStateChange(ctx, state, trigger) { const detail = { type: "google-cast", state }; ctx.delegate._notify("remote-playback-change", detail, trigger); } _createError(code, message) { const error = Error(message); error.code = code; return error; } } export { GoogleCastLoader };