UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 28 kB
{"version":3,"file":"VideoSource.mjs","sources":["../../../../../../src/rendering/renderers/shared/texture/sources/VideoSource.ts"],"sourcesContent":["// VideoSource.ts\n\nimport { ExtensionType } from '../../../../../extensions/Extensions';\nimport { Ticker } from '../../../../../ticker/Ticker';\nimport { detectVideoAlphaMode } from '../../../../../utils/browser/detectVideoAlphaMode';\nimport { TextureSource } from './TextureSource';\n\nimport type { ExtensionMetadata } from '../../../../../extensions/Extensions';\nimport type { Dict } from '../../../../../utils/types';\nimport type { ALPHA_MODES } from '../const';\nimport type { TextureSourceOptions } from './TextureSource';\n\n/**\n * The type of resource used for video textures.\n * This is typically an HTMLVideoElement.\n * @category rendering\n * @advanced\n */\nexport type VideoResource = HTMLVideoElement;\n\n/**\n * Options for video sources.\n * @category rendering\n * @advanced\n */\nexport interface VideoSourceOptions extends TextureSourceOptions<VideoResource>\n{\n /** If true, the video will start loading immediately. */\n autoLoad?: boolean;\n /** If true, the video will start playing as soon as it is loaded. */\n autoPlay?: boolean;\n /** The number of times a second to update the texture from the video. Leave at 0 to update at every render. */\n updateFPS?: number;\n /** If true, the video will be loaded with the `crossorigin` attribute. */\n crossorigin?: boolean | string;\n /** If true, the video will loop when it ends. */\n loop?: boolean;\n /** If true, the video will be muted. */\n muted?: boolean;\n /** If true, the video will play inline. */\n playsinline?: boolean;\n /** If true, the video will be preloaded. */\n preload?: boolean;\n /** The time in milliseconds to wait for the video to preload before timing out. */\n preloadTimeoutMs?: number;\n /** The alpha mode of the video. */\n alphaMode?: ALPHA_MODES;\n}\n\n/**\n * A texture source that uses a video as its resource.\n * It automatically resizes the texture based on the video dimensions.\n * It also provides methods to control playback and handle video events.\n * This class supports automatic loading, playback, and frame updates.\n * It can also handle cross-origin videos and provides options for looping, muting, and inline playback.\n * @category rendering\n * @advanced\n */\nexport class VideoSource extends TextureSource<VideoResource>\n{\n public static extension: ExtensionMetadata = ExtensionType.TextureSource;\n\n /** The default options for video sources. */\n public static defaultOptions: VideoSourceOptions = {\n ...TextureSource.defaultOptions,\n /** If true, the video will start loading immediately. */\n autoLoad: true,\n /** If true, the video will start playing as soon as it is loaded. */\n autoPlay: true,\n /** The number of times a second to update the texture from the video. Leave at 0 to update at every render. */\n updateFPS: 0,\n /** If true, the video will be loaded with the `crossorigin` attribute. */\n crossorigin: true,\n /** If true, the video will loop when it ends. */\n loop: false,\n /** If true, the video will be muted. */\n muted: true,\n /** If true, the video will play inline. */\n playsinline: true,\n /** If true, the video will be preloaded. */\n preload: false,\n };\n\n // Public\n /** Whether or not the video is ready to play. */\n public isReady = false;\n /** The upload method for this texture. */\n public uploadMethodId = 'video';\n\n // Protected\n /**\n * When set to true will automatically play videos used by this texture once\n * they are loaded. If false, it will not modify the playing state.\n * @default true\n */\n protected autoPlay: boolean;\n\n // Private\n /**\n * `true` to use Ticker.shared to auto update the base texture.\n * @default true\n */\n private _autoUpdate: boolean;\n\n /**\n * `true` if the instance is currently connected to Ticker.shared to auto update the base texture.\n * @default false\n */\n private _isConnectedToTicker: boolean;\n\n /**\n * Promise when loading.\n * @default null\n */\n private _load: Promise<this>;\n\n private _msToNextUpdate: number;\n private _preloadTimeout: number;\n\n /** Callback when completed with load. */\n private _resolve: (value?: this | PromiseLike<this>) => void;\n private _reject: (error: ErrorEvent) => void;\n\n private _updateFPS: number;\n private _videoFrameRequestCallbackHandle: number | null;\n\n constructor(\n options: VideoSourceOptions\n )\n {\n super(options);\n\n // Merge provided options with default ones\n options = {\n ...VideoSource.defaultOptions,\n ...options\n };\n\n this._autoUpdate = true;\n this._isConnectedToTicker = false;\n this._updateFPS = options.updateFPS || 0;\n this._msToNextUpdate = 0;\n this.autoPlay = options.autoPlay !== false;\n this.alphaMode = options.alphaMode ?? 'premultiply-alpha-on-upload';\n\n // Binding for frame updates\n this._videoFrameRequestCallback = this._videoFrameRequestCallback.bind(this);\n this._videoFrameRequestCallbackHandle = null;\n\n this._load = null;\n this._resolve = null;\n this._reject = null;\n\n // Bind for listeners\n this._onCanPlay = this._onCanPlay.bind(this);\n this._onCanPlayThrough = this._onCanPlayThrough.bind(this);\n this._onError = this._onError.bind(this);\n this._onPlayStart = this._onPlayStart.bind(this);\n this._onPlayStop = this._onPlayStop.bind(this);\n this._onSeeked = this._onSeeked.bind(this);\n\n if (options.autoLoad !== false)\n {\n void this.load();\n }\n }\n\n /** Update the video frame if the source is not destroyed and meets certain conditions. */\n protected updateFrame(): void\n {\n if (this.destroyed)\n {\n return;\n }\n\n if (this._updateFPS)\n {\n // Account for if video has had its playbackRate changed\n const elapsedMS = Ticker.shared.elapsedMS * this.resource.playbackRate;\n\n this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS);\n }\n\n if (!this._updateFPS || this._msToNextUpdate <= 0)\n {\n this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0;\n }\n\n if (this.isValid)\n {\n this.update();\n }\n }\n\n /** Callback to update the video frame and potentially request the next frame update. */\n private _videoFrameRequestCallback(): void\n {\n this.updateFrame();\n\n if (this.destroyed)\n {\n this._videoFrameRequestCallbackHandle = null;\n }\n else\n {\n this._videoFrameRequestCallbackHandle = this.resource.requestVideoFrameCallback(\n this._videoFrameRequestCallback\n );\n }\n }\n\n /**\n * Checks if the resource has valid dimensions.\n * @returns {boolean} True if width and height are set, otherwise false.\n */\n public get isValid(): boolean\n {\n return !!this.resource.videoWidth && !!this.resource.videoHeight;\n }\n\n /**\n * Start preloading the video resource.\n * @returns {Promise<this>} Handle the validate event\n */\n public async load(): Promise<this>\n {\n if (this._load)\n {\n return this._load;\n }\n\n const source = this.resource;\n const options = this.options as VideoSourceOptions;\n\n // Check if source data is enough and set it to complete if needed\n if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA)\n && source.width && source.height)\n {\n (source as any).complete = true;\n }\n\n // Add event listeners related to playback and seeking\n source.addEventListener('play', this._onPlayStart);\n source.addEventListener('pause', this._onPlayStop);\n source.addEventListener('seeked', this._onSeeked);\n\n // Add or handle source readiness event listeners\n if (!this._isSourceReady())\n {\n if (!options.preload)\n {\n // since this event fires early, only bind if not waiting for a preload event\n source.addEventListener('canplay', this._onCanPlay);\n }\n source.addEventListener('canplaythrough', this._onCanPlayThrough);\n source.addEventListener('error', this._onError, true);\n }\n else\n {\n // Source is already ready, so handle it immediately\n this._mediaReady();\n }\n\n this.alphaMode = await detectVideoAlphaMode();\n\n // Create and return the loading promise\n this._load = new Promise((resolve, reject): void =>\n {\n if (this.isValid)\n {\n resolve(this);\n }\n else\n {\n this._resolve = resolve;\n this._reject = reject;\n\n if (options.preloadTimeoutMs !== undefined)\n {\n this._preloadTimeout = setTimeout(() =>\n {\n this._onError(new ErrorEvent(`Preload exceeded timeout of ${options.preloadTimeoutMs}ms`));\n }) as unknown as number;\n }\n source.load();\n }\n });\n\n return this._load;\n }\n\n /**\n * Handle video error events.\n * @param event - The error event\n */\n private _onError(event: ErrorEvent): void\n {\n this.resource.removeEventListener('error', this._onError, true);\n this.emit('error', event);\n\n if (this._reject)\n {\n this._reject(event);\n this._reject = null;\n this._resolve = null;\n }\n }\n\n /**\n * Checks if the underlying source is playing.\n * @returns True if playing.\n */\n private _isSourcePlaying(): boolean\n {\n const source = this.resource;\n\n return (!source.paused && !source.ended);\n }\n\n /**\n * Checks if the underlying source is ready for playing.\n * @returns True if ready.\n */\n private _isSourceReady(): boolean\n {\n const source = this.resource;\n\n return source.readyState > 2;\n }\n\n /** Runs the update loop when the video is ready to play. */\n private _onPlayStart(): void\n {\n // Handle edge case where video might not have received its \"can play\" event yet\n if (!this.isValid)\n {\n this._mediaReady();\n }\n\n this._configureAutoUpdate();\n }\n\n /** Stops the update loop when a pause event is triggered. */\n private _onPlayStop(): void\n {\n this._configureAutoUpdate();\n }\n\n /** Handles behavior when the video completes seeking to the current playback position. */\n private _onSeeked(): void\n {\n if (this._autoUpdate && !this._isSourcePlaying())\n {\n this._msToNextUpdate = 0;\n this.updateFrame();\n this._msToNextUpdate = 0;\n }\n }\n\n private _onCanPlay(): void\n {\n const source = this.resource;\n\n // Remove event listeners\n source.removeEventListener('canplay', this._onCanPlay);\n\n this._mediaReady();\n }\n\n private _onCanPlayThrough(): void\n {\n const source = this.resource;\n\n // Remove event listeners\n source.removeEventListener('canplaythrough', this._onCanPlay);\n\n if (this._preloadTimeout)\n {\n clearTimeout(this._preloadTimeout);\n this._preloadTimeout = undefined;\n }\n\n this._mediaReady();\n }\n\n /** Fired when the video is loaded and ready to play. */\n private _mediaReady(): void\n {\n const source = this.resource;\n\n if (this.isValid)\n {\n this.isReady = true;\n this.resize(source.videoWidth, source.videoHeight);\n }\n\n // Reset update timers and perform a frame update\n this._msToNextUpdate = 0;\n this.updateFrame();\n this._msToNextUpdate = 0;\n\n // Resolve the loading promise if it exists\n if (this._resolve)\n {\n this._resolve(this);\n this._resolve = null;\n this._reject = null;\n }\n\n // Handle play behavior based on current source status\n if (this._isSourcePlaying())\n {\n this._onPlayStart();\n }\n else if (this.autoPlay)\n {\n void this.resource.play();\n }\n }\n\n /** Cleans up resources and event listeners associated with this texture. */\n public destroy()\n {\n this._configureAutoUpdate();\n\n const source = this.resource;\n\n if (source)\n {\n // Remove event listeners\n source.removeEventListener('play', this._onPlayStart);\n source.removeEventListener('pause', this._onPlayStop);\n source.removeEventListener('seeked', this._onSeeked);\n source.removeEventListener('canplay', this._onCanPlay);\n source.removeEventListener('canplaythrough', this._onCanPlayThrough);\n source.removeEventListener('error', this._onError, true);\n\n // Clear the video source and pause\n source.pause();\n source.src = '';\n source.load();\n }\n\n super.destroy();\n }\n\n /** Should the base texture automatically update itself, set to true by default. */\n get autoUpdate(): boolean\n {\n return this._autoUpdate;\n }\n\n set autoUpdate(value: boolean)\n {\n if (value !== this._autoUpdate)\n {\n this._autoUpdate = value;\n this._configureAutoUpdate();\n }\n }\n\n /**\n * How many times a second to update the texture from the video.\n * Leave at 0 to update at every render.\n * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient.\n */\n get updateFPS(): number\n {\n return this._updateFPS;\n }\n\n set updateFPS(value: number)\n {\n if (value !== this._updateFPS)\n {\n this._updateFPS = value;\n this._configureAutoUpdate();\n }\n }\n\n /**\n * Configures the updating mechanism based on the current state and settings.\n *\n * This method decides between using the browser's native video frame callback or a custom ticker\n * for updating the video frame. It ensures optimal performance and responsiveness\n * based on the video's state, playback status, and the desired frames-per-second setting.\n *\n * - If `_autoUpdate` is enabled and the video source is playing:\n * - It will prefer the native video frame callback if available and no specific FPS is set.\n * - Otherwise, it will use a custom ticker for manual updates.\n * - If `_autoUpdate` is disabled or the video isn't playing, any active update mechanisms are halted.\n */\n private _configureAutoUpdate(): void\n {\n // Check if automatic updating is enabled and if the source is currently playing\n if (this._autoUpdate && this._isSourcePlaying())\n {\n // Determine if we should use the browser's native video frame callback (generally for better performance)\n if (!this._updateFPS && this.resource.requestVideoFrameCallback)\n {\n // If connected to a custom ticker, remove the update frame function from it\n if (this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.updateFrame, this);\n this._isConnectedToTicker = false;\n // Reset the time until the next update\n this._msToNextUpdate = 0;\n }\n\n // Check if we haven't already requested a video frame callback, and if not, request one\n if (this._videoFrameRequestCallbackHandle === null)\n {\n this._videoFrameRequestCallbackHandle = this.resource.requestVideoFrameCallback(\n this._videoFrameRequestCallback\n );\n }\n }\n else\n {\n // If a video frame request callback exists, cancel it, as we are switching to manual ticker-based updates\n if (this._videoFrameRequestCallbackHandle !== null)\n {\n this.resource.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle);\n this._videoFrameRequestCallbackHandle = null;\n }\n\n // If not connected to the custom ticker, add the update frame function to it\n if (!this._isConnectedToTicker)\n {\n Ticker.shared.add(this.updateFrame, this);\n this._isConnectedToTicker = true;\n // Reset the time until the next update\n this._msToNextUpdate = 0;\n }\n }\n }\n else\n {\n // If automatic updating is disabled or the source isn't playing, perform cleanup\n\n // Cancel any existing video frame callback request\n if (this._videoFrameRequestCallbackHandle !== null)\n {\n this.resource.cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle);\n this._videoFrameRequestCallbackHandle = null;\n }\n\n // Remove the update frame function from the custom ticker\n if (this._isConnectedToTicker)\n {\n Ticker.shared.remove(this.updateFrame, this);\n this._isConnectedToTicker = false;\n // Reset the time until the next update\n this._msToNextUpdate = 0;\n }\n }\n }\n\n /**\n * Map of video MIME types that can't be directly derived from file extensions.\n * @readonly\n */\n public static MIME_TYPES: Dict<string>\n = {\n ogv: 'video/ogg',\n mov: 'video/quicktime',\n m4v: 'video/mp4',\n };\n\n public static test(resource: any): resource is VideoResource\n {\n return (globalThis.HTMLVideoElement && resource instanceof HTMLVideoElement);\n }\n}\n"],"names":[],"mappings":"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"}