diff --git a/packages/core/src/textures/resources/VideoResource.js b/packages/core/src/textures/resources/VideoResource.js index 6f869d2..6eaafd1 100644 --- a/packages/core/src/textures/resources/VideoResource.js +++ b/packages/core/src/textures/resources/VideoResource.js @@ -10,6 +10,8 @@ * @param {object} [options] - Options to use * @param {boolean} [options.autoLoad=true] - Start loading the video immediately * @param {boolean} [options.autoPlay=true] - Start playing video immediately + * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video. + * Leave at 0 to update at every render. * @param {boolean} [options.crossorigin=true] - Load image using cross origin */ export default class VideoResource extends BaseImageResource @@ -60,6 +62,8 @@ this._autoUpdate = true; this._isAutoUpdating = false; + this._updateFPS = options.updateFPS || 0; + this._msToNextUpdate = 0; /** * When set to true will automatically play videos used by this texture once @@ -94,6 +98,33 @@ } } + /** + * Trigger updating of the texture + * + * @param {number} deltaTime - time delta since last tick + */ + update(deltaTime) + { + if (!this.destroyed) + { + // account for if video has had its playbackRate changed + const elapsedMS = Ticker.shared.elapsedMS * this.source.playbackRate; + + this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS); + if (!this._updateFPS || this._msToNextUpdate <= 0) + { + super.update(deltaTime); + this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0; + } + } + } + + /** + * Start preloading the video resource. + * + * @protected + * @return {Promise} Handle the validate event + */ load() { if (this._load) @@ -280,6 +311,25 @@ } /** + * How many times a second to update the texture from the video. Leave at 0 to update at every render. + * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient. + * + * @member {number} + */ + get updateFPS() + { + return this._updateFPS; + } + + set updateFPS(value) // eslint-disable-line require-jsdoc + { + if (value !== this._updateFPS) + { + this._updateFPS = value; + } + } + + /** * Used to auto-detect the type of resource. * * @static diff --git a/packages/core/src/textures/resources/VideoResource.js b/packages/core/src/textures/resources/VideoResource.js index 6f869d2..6eaafd1 100644 --- a/packages/core/src/textures/resources/VideoResource.js +++ b/packages/core/src/textures/resources/VideoResource.js @@ -10,6 +10,8 @@ * @param {object} [options] - Options to use * @param {boolean} [options.autoLoad=true] - Start loading the video immediately * @param {boolean} [options.autoPlay=true] - Start playing video immediately + * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video. + * Leave at 0 to update at every render. * @param {boolean} [options.crossorigin=true] - Load image using cross origin */ export default class VideoResource extends BaseImageResource @@ -60,6 +62,8 @@ this._autoUpdate = true; this._isAutoUpdating = false; + this._updateFPS = options.updateFPS || 0; + this._msToNextUpdate = 0; /** * When set to true will automatically play videos used by this texture once @@ -94,6 +98,33 @@ } } + /** + * Trigger updating of the texture + * + * @param {number} deltaTime - time delta since last tick + */ + update(deltaTime) + { + if (!this.destroyed) + { + // account for if video has had its playbackRate changed + const elapsedMS = Ticker.shared.elapsedMS * this.source.playbackRate; + + this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS); + if (!this._updateFPS || this._msToNextUpdate <= 0) + { + super.update(deltaTime); + this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0; + } + } + } + + /** + * Start preloading the video resource. + * + * @protected + * @return {Promise} Handle the validate event + */ load() { if (this._load) @@ -280,6 +311,25 @@ } /** + * How many times a second to update the texture from the video. Leave at 0 to update at every render. + * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient. + * + * @member {number} + */ + get updateFPS() + { + return this._updateFPS; + } + + set updateFPS(value) // eslint-disable-line require-jsdoc + { + if (value !== this._updateFPS) + { + this._updateFPS = value; + } + } + + /** * Used to auto-detect the type of resource. * * @static diff --git a/packages/core/src/textures/resources/autoDetectResource.js b/packages/core/src/textures/resources/autoDetectResource.js index 48fa8e0..a081b69 100644 --- a/packages/core/src/textures/resources/autoDetectResource.js +++ b/packages/core/src/textures/resources/autoDetectResource.js @@ -52,6 +52,9 @@ * @param {number} [options.scale=1] - SVG source scale * @param {boolean} [options.createBitmap=true] - Image option to create Bitmap object * @param {boolean} [options.crossorigin=true] - Image and Video option to set crossOrigin + * @param {boolean} [options.autoPlay=true] - Video option to start playing video immediately + * @param {number} [options.updateFPS=0] - Video option to update how many times a second the + * texture should be updated from the video. Leave at 0 to update at every render * @return {PIXI.resources.Resource} The created resource. */ export function autoDetectResource(source, options) diff --git a/packages/core/src/textures/resources/VideoResource.js b/packages/core/src/textures/resources/VideoResource.js index 6f869d2..6eaafd1 100644 --- a/packages/core/src/textures/resources/VideoResource.js +++ b/packages/core/src/textures/resources/VideoResource.js @@ -10,6 +10,8 @@ * @param {object} [options] - Options to use * @param {boolean} [options.autoLoad=true] - Start loading the video immediately * @param {boolean} [options.autoPlay=true] - Start playing video immediately + * @param {number} [options.updateFPS=0] - How many times a second to update the texture from the video. + * Leave at 0 to update at every render. * @param {boolean} [options.crossorigin=true] - Load image using cross origin */ export default class VideoResource extends BaseImageResource @@ -60,6 +62,8 @@ this._autoUpdate = true; this._isAutoUpdating = false; + this._updateFPS = options.updateFPS || 0; + this._msToNextUpdate = 0; /** * When set to true will automatically play videos used by this texture once @@ -94,6 +98,33 @@ } } + /** + * Trigger updating of the texture + * + * @param {number} deltaTime - time delta since last tick + */ + update(deltaTime) + { + if (!this.destroyed) + { + // account for if video has had its playbackRate changed + const elapsedMS = Ticker.shared.elapsedMS * this.source.playbackRate; + + this._msToNextUpdate = Math.floor(this._msToNextUpdate - elapsedMS); + if (!this._updateFPS || this._msToNextUpdate <= 0) + { + super.update(deltaTime); + this._msToNextUpdate = this._updateFPS ? Math.floor(1000 / this._updateFPS) : 0; + } + } + } + + /** + * Start preloading the video resource. + * + * @protected + * @return {Promise} Handle the validate event + */ load() { if (this._load) @@ -280,6 +311,25 @@ } /** + * How many times a second to update the texture from the video. Leave at 0 to update at every render. + * A lower fps can help performance, as updating the texture at 60fps on a 30ps video may not be efficient. + * + * @member {number} + */ + get updateFPS() + { + return this._updateFPS; + } + + set updateFPS(value) // eslint-disable-line require-jsdoc + { + if (value !== this._updateFPS) + { + this._updateFPS = value; + } + } + + /** * Used to auto-detect the type of resource. * * @static diff --git a/packages/core/src/textures/resources/autoDetectResource.js b/packages/core/src/textures/resources/autoDetectResource.js index 48fa8e0..a081b69 100644 --- a/packages/core/src/textures/resources/autoDetectResource.js +++ b/packages/core/src/textures/resources/autoDetectResource.js @@ -52,6 +52,9 @@ * @param {number} [options.scale=1] - SVG source scale * @param {boolean} [options.createBitmap=true] - Image option to create Bitmap object * @param {boolean} [options.crossorigin=true] - Image and Video option to set crossOrigin + * @param {boolean} [options.autoPlay=true] - Video option to start playing video immediately + * @param {number} [options.updateFPS=0] - Video option to update how many times a second the + * texture should be updated from the video. Leave at 0 to update at every render * @return {PIXI.resources.Resource} The created resource. */ export function autoDetectResource(source, options) diff --git a/packages/core/test/VideoResource.js b/packages/core/test/VideoResource.js index f765b33..aa40a30 100644 --- a/packages/core/test/VideoResource.js +++ b/packages/core/test/VideoResource.js @@ -61,5 +61,23 @@ resource.destroy(); }); + + it('should respect the updateFPS settings property and getter / setter', function () + { + const resource = new VideoResource(this.videoUrl, { + autoLoad: false, + autoPlay: false, + updateFPS: 30, + }); + + return resource.load().then((res) => + { + expect(res).to.equal(resource); + expect(res.updateFPS).to.equal(30); + res.updateFPS = 20; + expect(res.updateFPS).to.equal(20); + resource.destroy(); + }); + }); });