Newer
Older
pixi.js / src / core / textures / VideoTexture.js
@Chad Engler Chad Engler on 28 Dec 2014 4 KB initial move to new module folders
var BaseTexture = require('./BaseTexture'),
    Texture = require('./Texture'),
    utils = require('../utils');

/**
 * A texture of a [playing] Video.
 *
 * See the ["deus" demo](http://www.goodboydigital.com/pixijs/examples/deus/).
 *
 * @class
 * @extends BaseTexture
 * @namespace PIXI
 * @param source {HTMLVideoElement}
 * @param [scaleMode] {number} See {@link scaleModes} for possible values
 */
function VideoTexture(source, scaleMode) {
    if (!source){
        throw new Error('No video source element specified.');
    }

    // hook in here to check if video is already available.
    // BaseTexture looks for a source.complete boolean, plus width & height.

    if ((source.readyState === source.HAVE_ENOUGH_DATA || source.readyState === source.HAVE_FUTURE_DATA) && source.width && source.height) {
        source.complete = true;
    }

    BaseTexture.call(this, source, scaleMode);

    this.autoUpdate = false;
    this.updateBound = this._onUpdate.bind(this);

    if (!source.complete) {
        this._onCanPlay = this.onCanPlay.bind(this);

        source.addEventListener('canplay', this._onCanPlay);
        source.addEventListener('canplaythrough', this._onCanPlay);

        // started playing..
        source.addEventListener('play', this.onPlayStart.bind(this));
        source.addEventListener('pause', this.onPlayStop.bind(this));
    }
}

VideoTexture.prototype = Object.create(BaseTexture.prototype);
VideoTexture.prototype.constructor = VideoTexture;
module.exports = VideoTexture;

VideoTexture.prototype._onUpdate = function () {
    if (this.autoUpdate) {
        window.requestAnimationFrame(this.updateBound);
        this.dirty();
    }
};

VideoTexture.prototype.onPlayStart = function () {
    if (!this.autoUpdate) {
        window.requestAnimationFrame(this.updateBound);
        this.autoUpdate = true;
    }
};

VideoTexture.prototype.onPlayStop = function () {
    this.autoUpdate = false;
};

VideoTexture.prototype.onCanPlay = function () {
    if (event.type === 'canplaythrough') {
        this.hasLoaded  = true;


        if (this.source) {
            this.source.removeEventListener('canplay', this._onCanPlay);
            this.source.removeEventListener('canplaythrough', this._onCanPlay);

            this.width      = this.source.videoWidth;
            this.height     = this.source.videoHeight;

            // prevent multiple loaded dispatches..
            if (!this.__loaded){
                this.__loaded = true;
                this.dispatchEvent({ type: 'loaded', content: this });
            }
        }
    }
};

VideoTexture.prototype.destroy = function () {
    if (this.source && this.source._pixiId) {
        utils.BaseTextureCache[ this.source._pixiId ] = null;
        delete utils.BaseTextureCache[ this.source._pixiId ];

        this.source._pixiId = null;
        delete this.source._pixiId;
    }

    BaseTexture.prototype.destroy.call(this);
};

/**
 * Mimic Pixi BaseTexture.from.... method.
 *
 * @static
 * @param video {HTMLVideoElement}
 * @param scaleMode {number} See {{#crossLink "PIXI/scaleModes:property"}}scaleModes{{/crossLink}} for possible values
 * @return {VideoTexture}
 */
VideoTexture.baseTextureFromVideo = function (video, scaleMode) {
    if (!video._pixiId) {
        video._pixiId = 'video_' + utils.TextureCacheIdGenerator++;
    }

    var baseTexture = utils.BaseTextureCache[ video._pixiId ];

    if (!baseTexture) {
        baseTexture = new VideoTexture(video, scaleMode);
        utils.BaseTextureCache[ video._pixiId ] = baseTexture;
    }

    return baseTexture;
};

/**
 * Mimic Pixi BaseTexture.from.... method.
 *
 * @static
 * @param video {HTMLVideoElement}
 * @param scaleMode {number} See {{#crossLink "PIXI/scaleModes:property"}}scaleModes{{/crossLink}} for possible values
 * @return {Texture} A Texture, but not a VideoTexture.
 */
VideoTexture.textureFromVideo = function (video, scaleMode) {
    var baseTexture = VideoTexture.baseTextureFromVideo(video, scaleMode);
    return new Texture(baseTexture);
};

/**
 * Mimic Pixi BaseTexture.from.... method.
 *
 * @static
 * @param videoSrc {string} The URL for the video.
 * @param scaleMode {number} See {{#crossLink "PIXI/scaleModes:property"}}scaleModes{{/crossLink}} for possible values
 * @return {VideoTexture}
 */
VideoTexture.fromUrl = function (videoSrc, scaleMode) {
    var video = document.createElement('video');
    video.src = videoSrc;
    video.autoPlay = true;
    video.play();
    return VideoTexture.textureFromVideo(video, scaleMode);
};