{"version":3,"file":"VideoResource.mjs","sources":["../../../src/textures/resources/VideoResource.ts"],"sourcesContent":["import { Ticker } from '@pixi/ticker';\nimport { BaseImageResource } from './BaseImageResource';\n\nimport type { Dict } from '@pixi/utils';\n\nexport interface IVideoResourceOptions\n{\n    autoLoad?: boolean;\n    autoPlay?: boolean;\n    updateFPS?: number;\n    crossorigin?: boolean | string;\n    loop?: boolean;\n    muted?: boolean;\n    playsinline?: boolean;\n}\n\nexport interface IVideoResourceOptionsElement\n{\n    src: string;\n    mime: string;\n}\n\n/**\n * Resource type for {@link HTMLVideoElement}.\n * @memberof PIXI\n */\nexport class VideoResource extends BaseImageResource\n{\n    /** Override the source to be the video element. */\n    public source: HTMLVideoElement;\n\n    /**\n     * `true` to use Ticker.shared to auto update the base texture.\n     * @default true\n     */\n    protected _autoUpdate: boolean;\n\n    /**\n     * `true` if the instance is currently connected to PIXI.Ticker.shared to auto update the base texture.\n     * @default false\n     */\n    protected _isConnectedToTicker: boolean;\n    protected _updateFPS: number;\n    protected _msToNextUpdate: number;\n\n    private _videoFrameRequestCallbackHandle: number | null;\n\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    /**\n     * Promise when loading.\n     * @default null\n     */\n    private _load: Promise<this>;\n\n    /** Callback when completed with load. */\n    private _resolve: (value?: this | PromiseLike<this>) => void;\n    private _reject: (error: ErrorEvent) => void;\n\n    /**\n     * @param {HTMLVideoElement|object|string|Array<string|object>} source - Video element to use.\n     * @param {object} [options] - Options to use\n     * @param {boolean} [options.autoLoad=true] - Start loading the video immediately\n     * @param {boolean} [options.autoPlay=true] - Start playing video immediately\n     * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video.\n     * Leave at 0 to update at every render.\n     * @param {boolean} [options.crossorigin=true] - Load image using cross origin\n     * @param {boolean} [options.loop=false] - Loops the video\n     * @param {boolean} [options.muted=false] - Mutes the video audio, useful for autoplay\n     * @param {boolean} [options.playsinline=true] - Prevents opening the video on mobile devices\n     */\n    constructor(\n        source?: HTMLVideoElement | Array<string | IVideoResourceOptionsElement> | string, options?: IVideoResourceOptions\n    )\n    {\n        options = options || {};\n\n        if (!(source instanceof HTMLVideoElement))\n        {\n            const videoElement = document.createElement('video');\n\n            // workaround for https://github.com/pixijs/pixijs/issues/5996\n            if (options.autoLoad !== false)\n            {\n                videoElement.setAttribute('preload', 'auto');\n            }\n\n            if (options.playsinline !== false)\n            {\n                videoElement.setAttribute('webkit-playsinline', '');\n                videoElement.setAttribute('playsinline', '');\n            }\n\n            if (options.muted === true)\n            {\n                // For some reason we need to set both muted flags for chrome to autoplay\n                // https://stackoverflow.com/a/51189390\n\n                videoElement.setAttribute('muted', '');\n                videoElement.muted = true;\n            }\n\n            if (options.loop === true)\n            {\n                videoElement.setAttribute('loop', '');\n            }\n\n            if (options.autoPlay !== false)\n            {\n                videoElement.setAttribute('autoplay', '');\n            }\n\n            if (typeof source === 'string')\n            {\n                source = [source];\n            }\n\n            const firstSrc = (source[0] as IVideoResourceOptionsElement).src || source[0] as string;\n\n            BaseImageResource.crossOrigin(videoElement, firstSrc, options.crossorigin);\n\n            // array of objects or strings\n            for (let i = 0; i < source.length; ++i)\n            {\n                const sourceElement = document.createElement('source');\n\n                let { src, mime } = source[i] as IVideoResourceOptionsElement;\n\n                src = src || source[i] as string;\n\n                if (src.startsWith('data:'))\n                {\n                    mime = src.slice(5, src.indexOf(';'));\n                }\n                else if (!src.startsWith('blob:'))\n                {\n                    const baseSrc = src.split('?').shift().toLowerCase();\n                    const ext = baseSrc.slice(baseSrc.lastIndexOf('.') + 1);\n\n                    mime = mime || VideoResource.MIME_TYPES[ext] || `video/${ext}`;\n                }\n\n                sourceElement.src = src;\n\n                if (mime)\n                {\n                    sourceElement.type = mime;\n                }\n\n                videoElement.appendChild(sourceElement);\n            }\n\n            // Override the source\n            source = videoElement;\n        }\n\n        super(source);\n\n        this.noSubImage = true;\n\n        this._autoUpdate = true;\n        this._isConnectedToTicker = false;\n\n        this._updateFPS = options.updateFPS || 0;\n        this._msToNextUpdate = 0;\n        this.autoPlay = options.autoPlay !== false;\n\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._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            this.load();\n        }\n    }\n\n    /**\n     * Trigger updating of the texture.\n     * @param _deltaTime - time delta since last tick\n     */\n    update(_deltaTime = 0): void\n    {\n        if (!this.destroyed)\n        {\n            if (this._updateFPS)\n            {\n                // account for if video has had its playbackRate changed\n                const elapsedMS = Ticker.shared.elapsedMS * (this.source as HTMLVideoElement).playbackRate;\n\n                this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS);\n            }\n\n            if (!this._updateFPS || this._msToNextUpdate <= 0)\n            {\n                super.update(/* deltaTime*/);\n                this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0;\n            }\n        }\n    }\n\n    private _videoFrameRequestCallback(): void\n    {\n        this.update();\n\n        if (!this.destroyed)\n        {\n            this._videoFrameRequestCallbackHandle = (this.source as any).requestVideoFrameCallback(\n                this._videoFrameRequestCallback);\n        }\n        else\n        {\n            this._videoFrameRequestCallbackHandle = null;\n        }\n    }\n\n    /**\n     * Start preloading the video resource.\n     * @returns {Promise<void>} Handle the validate event\n     */\n    load(): Promise<this>\n    {\n        if (this._load)\n        {\n            return this._load;\n        }\n\n        const source = this.source as HTMLVideoElement;\n\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        source.addEventListener('play', this._onPlayStart);\n        source.addEventListener('pause', this._onPlayStop);\n        source.addEventListener('seeked', this._onSeeked);\n\n        if (!this._isSourceReady())\n        {\n            source.addEventListener('canplay', this._onCanPlay);\n            source.addEventListener('canplaythrough', this._onCanPlay);\n            source.addEventListener('error', this._onError, true);\n        }\n        else\n        {\n            this._onCanPlay();\n        }\n\n        this._load = new Promise((resolve, reject): void =>\n        {\n            if (this.valid)\n            {\n                resolve(this);\n            }\n            else\n            {\n                this._resolve = resolve;\n                this._reject = reject;\n\n                source.load();\n            }\n        });\n\n        return this._load;\n    }\n\n    /**\n     * Handle video error events.\n     * @param event\n     */\n    private _onError(event: ErrorEvent): void\n    {\n        (this.source as HTMLVideoElement).removeEventListener('error', this._onError, true);\n        this.onError.emit(event);\n\n        if (this._reject)\n        {\n            this._reject(event);\n            this._reject = null;\n            this._resolve = null;\n        }\n    }\n\n    /**\n     * Returns true if the underlying source is playing.\n     * @returns - True if playing.\n     */\n    private _isSourcePlaying(): boolean\n    {\n        const source = this.source as HTMLVideoElement;\n\n        return (!source.paused && !source.ended);\n    }\n\n    /**\n     * Returns true if the underlying source is ready for playing.\n     * @returns - True if ready.\n     */\n    private _isSourceReady(): boolean\n    {\n        const source = this.source as HTMLVideoElement;\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        // Just in case the video has not received its can play even yet..\n        if (!this.valid)\n        {\n            this._onCanPlay();\n        }\n\n        this._configureAutoUpdate();\n    }\n\n    /** Fired when a pause event is triggered, stops the update loop. */\n    private _onPlayStop(): void\n    {\n        this._configureAutoUpdate();\n    }\n\n    /** Fired when the video is completed seeking to the current playback position. */\n    private _onSeeked(): void\n    {\n        if (this._autoUpdate && !this._isSourcePlaying())\n        {\n            this._msToNextUpdate = 0;\n            this.update();\n            this._msToNextUpdate = 0;\n        }\n    }\n\n    /** Fired when the video is loaded and ready to play. */\n    private _onCanPlay(): void\n    {\n        const source = this.source as HTMLVideoElement;\n\n        source.removeEventListener('canplay', this._onCanPlay);\n        source.removeEventListener('canplaythrough', this._onCanPlay);\n\n        const valid = this.valid;\n\n        this._msToNextUpdate = 0;\n        this.update();\n        this._msToNextUpdate = 0;\n\n        // prevent multiple loaded dispatches..\n        if (!valid && this._resolve)\n        {\n            this._resolve(this);\n            this._resolve = null;\n            this._reject = null;\n        }\n\n        if (this._isSourcePlaying())\n        {\n            this._onPlayStart();\n        }\n        else if (this.autoPlay)\n        {\n            source.play();\n        }\n    }\n\n    /** Destroys this texture. */\n    dispose(): void\n    {\n        this._configureAutoUpdate();\n\n        const source = this.source as HTMLVideoElement;\n\n        if (source)\n        {\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._onCanPlay);\n            source.removeEventListener('error', this._onError, true);\n            source.pause();\n            source.src = '';\n            source.load();\n        }\n        super.dispose();\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. 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    private _configureAutoUpdate(): void\n    {\n        if (this._autoUpdate && this._isSourcePlaying())\n        {\n            if (!this._updateFPS && (this.source as any).requestVideoFrameCallback)\n            {\n                if (this._isConnectedToTicker)\n                {\n                    Ticker.shared.remove(this.update, this);\n                    this._isConnectedToTicker = false;\n                    this._msToNextUpdate = 0;\n                }\n\n                if (this._videoFrameRequestCallbackHandle === null)\n                {\n                    this._videoFrameRequestCallbackHandle = (this.source as any).requestVideoFrameCallback(\n                        this._videoFrameRequestCallback);\n                }\n            }\n            else\n            {\n                if (this._videoFrameRequestCallbackHandle !== null)\n                {\n                    (this.source as any).cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle);\n                    this._videoFrameRequestCallbackHandle = null;\n                }\n\n                if (!this._isConnectedToTicker)\n                {\n                    Ticker.shared.add(this.update, this);\n                    this._isConnectedToTicker = true;\n                    this._msToNextUpdate = 0;\n                }\n            }\n        }\n        else\n        {\n            if (this._videoFrameRequestCallbackHandle !== null)\n            {\n                (this.source as any).cancelVideoFrameCallback(this._videoFrameRequestCallbackHandle);\n                this._videoFrameRequestCallbackHandle = null;\n            }\n\n            if (this._isConnectedToTicker)\n            {\n                Ticker.shared.remove(this.update, this);\n                this._isConnectedToTicker = false;\n                this._msToNextUpdate = 0;\n            }\n        }\n    }\n\n    /**\n     * Used to auto-detect the type of resource.\n     * @param {*} source - The source object\n     * @param {string} extension - The extension of source, if set\n     * @returns {boolean} `true` if video source\n     */\n    static test(source: unknown, extension?: string): source is HTMLVideoElement\n    {\n        return (globalThis.HTMLVideoElement && source instanceof HTMLVideoElement)\n            || VideoResource.TYPES.includes(extension);\n    }\n\n    /**\n     * List of common video file extensions supported by VideoResource.\n     * @readonly\n     */\n    static TYPES: Array<string> = ['mp4', 'm4v', 'webm', 'ogg', 'ogv', 'h264', 'avi', 'mov'];\n\n    /**\n     * Map of video MIME types that can't be directly derived from file extensions.\n     * @readonly\n     */\n    static MIME_TYPES: Dict<string> = {\n        ogv: 'video/ogg',\n        mov: 'video/quicktime',\n        m4v: 'video/mp4',\n    };\n}\n"],"names":["_VideoResource"],"mappings":"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"}