"use strict";
cc._RF.push(module, '5bcb2O7tHNFYKddKtn7YOjW', 'CCMVideo');
// lib/CCMVideo/CCMVideo.ts

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CCMVideo = exports.EventType = void 0;
var CCMVideoAssembler_1 = require("./CCMVideoAssembler");
var EventType;
(function (EventType) {
    EventType[EventType["PREPARING"] = 1] = "PREPARING";
    EventType[EventType["LOADED"] = 2] = "LOADED";
    EventType[EventType["READY"] = 3] = "READY";
    EventType[EventType["COMPLETED"] = 4] = "COMPLETED";
    EventType[EventType["ERROR"] = 5] = "ERROR";
    EventType[EventType["PLAYING"] = 6] = "PLAYING";
    EventType[EventType["PAUSED"] = 7] = "PAUSED";
    EventType[EventType["STOPPED"] = 8] = "STOPPED";
    EventType[EventType["BUFFER_START"] = 9] = "BUFFER_START";
    EventType[EventType["BUFFER_UPDATE"] = 10] = "BUFFER_UPDATE";
    EventType[EventType["BUFFER_END"] = 11] = "BUFFER_END";
})(EventType = exports.EventType || (exports.EventType = {}));
;
var VideoState;
(function (VideoState) {
    VideoState[VideoState["ERROR"] = -1] = "ERROR";
    VideoState[VideoState["IDLE"] = 0] = "IDLE";
    VideoState[VideoState["PREPARING"] = 1] = "PREPARING";
    VideoState[VideoState["PREPARED"] = 2] = "PREPARED";
    VideoState[VideoState["PLAYING"] = 3] = "PLAYING";
    VideoState[VideoState["PAUSED"] = 4] = "PAUSED";
    VideoState[VideoState["COMPLETED"] = 5] = "COMPLETED";
})(VideoState || (VideoState = {}));
;
var ReadyState;
(function (ReadyState) {
    ReadyState[ReadyState["HAVE_NOTHING"] = 0] = "HAVE_NOTHING";
    ReadyState[ReadyState["HAVE_METADATA"] = 1] = "HAVE_METADATA";
    ReadyState[ReadyState["HAVE_CURRENT_DATA"] = 2] = "HAVE_CURRENT_DATA";
    ReadyState[ReadyState["HAVE_FUTURE_DATA"] = 3] = "HAVE_FUTURE_DATA";
    ReadyState[ReadyState["HAVE_ENOUGH_DATA"] = 4] = "HAVE_ENOUGH_DATA";
})(ReadyState || (ReadyState = {}));
;
var PixelFormat;
(function (PixelFormat) {
    PixelFormat[PixelFormat["NONE"] = -1] = "NONE";
    PixelFormat[PixelFormat["I420"] = 0] = "I420";
    PixelFormat[PixelFormat["RGB"] = 2] = "RGB";
    PixelFormat[PixelFormat["NV12"] = 23] = "NV12";
    PixelFormat[PixelFormat["NV21"] = 24] = "NV21";
    PixelFormat[PixelFormat["RGBA"] = 26] = "RGBA";
})(PixelFormat || (PixelFormat = {}));
;
var _a = cc._decorator, ccclass = _a.ccclass, property = _a.property;
var gfx = cc.gfx;
var CCMVideo = /** @class */ (function (_super) {
    __extends(CCMVideo, _super);
    function CCMVideo() {
        var _this = _super.call(this) || this;
        _this.source = null;
        _this.seekTime = 0;
        _this.nativeDuration = 0;
        _this.nativeWidth = 0;
        _this.nativeHeight = 0;
        _this.currentState = VideoState.IDLE;
        _this.targetState = VideoState.IDLE;
        _this.pixelFormat = PixelFormat.RGBA;
        _this.impl = null;
        _this.textures = [];
        _this.loaded = false;
        _this.isBuffering = false;
        _this.inBackground = false;
        _this.lastPlayState = false;
        // rgb material
        _this.rgb = null;
        // rgb material
        _this.rgba = null;
        // i420 material
        _this.i420 = null;
        // nv12 material
        _this.nv12 = null;
        // nv21 material
        _this.nv21 = null;
        // loop property
        _this.loop = false;
        // video event handler for editor
        _this.videoPlayerEvent = [];
        _this.initialize();
        return _this;
    }
    Object.defineProperty(CCMVideo.prototype, "materials", {
        // hide materials property of base class
        get: function () {
            return this['_materials'];
        },
        set: function (val) {
            this['_materials'] = val;
            // @ts-ignore
            this._activateMaterial();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(CCMVideo.prototype, "clip", {
        // video resource
        get: function () {
            return this.source;
        },
        set: function (value) {
            this.source = value;
            this.updateVideoSource();
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(CCMVideo.prototype, "currentTime", {
        // current position of the video which is playing
        get: function () {
            if (!this.impl)
                return 0;
            if (this.isInPlaybackState()) {
                if (CC_JSB) {
                    return this.impl.currentTime();
                }
                else {
                    return this.impl.currentTime;
                }
            }
            else {
                return this.seekTime;
            }
        },
        // seek to position
        set: function (value) {
            if (!this.impl)
                return;
            if (this.isInPlaybackState()) {
                if (CC_JSB) {
                    this.impl.seek(value);
                }
                else {
                    this.impl.currentTime = value;
                }
            }
            else {
                this.seekTime = value;
            }
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(CCMVideo.prototype, "duration", {
        // duration of the video
        get: function () {
            if (!this.impl)
                return 0;
            if (this.nativeDuration > 0)
                return this.nativeDuration;
            if (CC_JSB) {
                this.nativeDuration = this.impl.duration();
            }
            else {
                var duration = this.impl.duration;
                this.nativeDuration = isNaN(duration) ? 0 : duration;
            }
            return this.nativeDuration;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(CCMVideo.prototype, "width", {
        get: function () {
            if (!this.isInPlaybackState())
                return 0;
            if (this.nativeWidth > 0)
                return this.nativeWidth;
            if (CC_JSB) {
                this.nativeWidth = this.impl.width();
            }
            else {
                var width = this.impl.videoWidth;
                this.nativeWidth = isNaN(width) ? 0 : width;
            }
            return this.nativeWidth;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(CCMVideo.prototype, "height", {
        get: function () {
            if (!this.isInPlaybackState())
                return 0;
            if (this.nativeHeight > 0)
                return this.nativeHeight;
            if (CC_JSB) {
                this.nativeHeight = this.impl.height();
            }
            else {
                var height = this.impl.videoHeight;
                this.nativeHeight = isNaN(height) ? 0 : height;
            }
            return this.nativeHeight;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(CCMVideo.prototype, "bufferPercentage", {
        // not accurate because native event is async, larger than actual percentage.
        get: function () {
            if (!this.impl)
                return 0;
            if (CC_JSB) {
                return this.impl.bufferPercentage();
            }
            else {
                return 0;
            }
        },
        enumerable: false,
        configurable: true
    });
    /**
     * override private method __preload
     */
    CCMVideo.prototype.__preload = function () {
        this.initializeMaterials();
        // @ts-ignore
        _super.prototype.__preload.call(this);
    };
    // must be called before super.__preload()
    CCMVideo.prototype.initializeMaterials = function () {
        this['_materials'] = [this.rgba];
    };
    /**
     * override private method _updateMaterial for set material properties
     */
    CCMVideo.prototype._updateMaterial = function () {
        var _this = this;
        var material = this.getMaterial(0);
        if (material) {
            material.setProperty('texture0', { getImpl: function () { return _this.textures[0]; } });
            switch (this.pixelFormat) {
                case PixelFormat.I420:
                    material.setProperty('texture2', { getImpl: function () { return _this.textures[2]; } });
                // fall through
                case PixelFormat.NV12:
                case PixelFormat.NV21:
                    material.setProperty('texture1', { getImpl: function () { return _this.textures[1]; } });
                    break;
            }
        }
        // @ts-ignore
        this.markForRender(true);
    };
    /**
     * update pixel format for android, ios, web platform, support yuv render
     */
    CCMVideo.prototype.updatePixelFormat = function () {
        var pixelFormat = CC_JSB ? this.impl.pixelFormat() : PixelFormat.RGB;
        if (this.pixelFormat == pixelFormat)
            return;
        this.pixelFormat = pixelFormat;
        switch (pixelFormat) {
            case PixelFormat.RGB:
                this.materials = [this.rgb];
                break;
            case PixelFormat.RGBA:
                this.materials = [this.rgba];
                break;
            case PixelFormat.I420:
                this.materials = [this.i420];
                break;
            case PixelFormat.NV12:
                this.materials = [this.nv12];
                break;
            case PixelFormat.NV21:
                this.materials = [this.nv21];
                break;
        }
    };
    /**
     * override private method _resetAssembler for customize video assembler
     */
    CCMVideo.prototype._resetAssembler = function () {
        // @ts-ignore
        this.setVertsDirty();
        this['_assembler'] = new CCMVideoAssembler_1.CCMVideoAssembler();
        this['_assembler'].init(this);
    };
    /**
     * initialize native video player, register video event handler
     */
    CCMVideo.prototype.initializeNative = function () {
        var _this = this;
        this.impl = new gfx.Video();
        this.textures = this.impl.getTextures();
        this.impl.addEventListener('loaded', function () { return _this.onMetaLoaded(); });
        this.impl.addEventListener('ready', function () { return _this.onReadyToPlay(); });
        this.impl.addEventListener('completed', function () { return _this.onCompleted(); });
        this.impl.addEventListener('error', function () { return _this.onError(); });
        this.impl.addEventListener('buffer_start', function () { return _this.onBufferStart(); });
        this.impl.addEventListener('buffer_update', function () { return _this.onBufferUpdate(); });
        this.impl.addEventListener('buffer_end', function () { return _this.onBufferEnd(); });
    };
    /**
     * initialize browser player, register video event handler
     */
    CCMVideo.prototype.initializeBrowser = function () {
        var _this = this;
        this.impl = document.createElement('video');
        this.impl.crossOrigin = 'anonymous';
        this.impl.autoplay = false;
        this.impl.loop = false;
        this.impl.muted = false;
        this.textures = [
            // @ts-ignore
            new cc.renderer.Texture2D(cc.renderer.device, {
                wrapS: gfx.WRAP_CLAMP,
                wrapT: gfx.WRAP_CLAMP,
                genMipmaps: false,
                premultiplyAlpha: false,
                flipY: false,
                format: gfx.TEXTURE_FMT_RGBA8
            })
        ];
        this.impl.addEventListener('loadedmetadata', function () { return _this.onMetaLoaded(); });
        this.impl.addEventListener('ended', function () { return _this.onCompleted(); });
        this.loaded = false;
        var onCanPlay = function () {
            if (_this.loaded || _this.currentState == VideoState.PLAYING)
                return;
            if (_this.impl.readyState === ReadyState.HAVE_ENOUGH_DATA ||
                _this.impl.readyState === ReadyState.HAVE_METADATA) {
                _this.impl.currentTime = 0;
                _this.loaded = true;
                _this.onReadyToPlay();
            }
        };
        this.impl.addEventListener('canplay', onCanPlay);
        this.impl.addEventListener('canplaythrough', onCanPlay);
        this.impl.addEventListener('suspend', onCanPlay);
        // @ts-ignore
        var gl = cc.renderer.device._gl;
        this.update = function (dt) {
            if (_this.isInPlaybackState()) {
                gl.bindTexture(gl.TEXTURE_2D, _this.textures[0]._glID);
                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, _this.impl);
                // @ts-ignore
                cc.renderer.device._restoreTexture(0);
            }
        };
    };
    /**
     * initialize video player
     */
    CCMVideo.prototype.initialize = function () {
        if (CC_JSB) {
            this.initializeNative();
        }
        else {
            this.initializeBrowser();
        }
    };
    CCMVideo.prototype.onLoad = function () {
        if (this.impl) {
            this.updateVideoSource();
        }
    };
    /**
     * register game show and hide event handler
     */
    CCMVideo.prototype.onEnable = function () {
        _super.prototype.onEnable.call(this);
        cc.game.on(cc.game.EVENT_SHOW, this.onShow, this);
        cc.game.on(cc.game.EVENT_HIDE, this.onHide, this);
    };
    // unregister game show and hide event handler
    CCMVideo.prototype.onDisable = function () {
        _super.prototype.onDisable.call(this);
        cc.game.off(cc.game.EVENT_SHOW, this.onShow, this);
        cc.game.off(cc.game.EVENT_HIDE, this.onHide, this);
        this.stop();
    };
    CCMVideo.prototype.onShow = function () {
        if (!this.inBackground)
            return;
        this.inBackground = false;
        if (this.lastPlayState)
            this.resume();
    };
    CCMVideo.prototype.onHide = function () {
        if (this.inBackground)
            return;
        this.inBackground = true;
        this.lastPlayState = this.isPlaying();
        if (this.lastPlayState)
            this.pause();
    };
    CCMVideo.prototype._onPreDestroy = function () {
        if (this.impl) {
            if (CC_JSB)
                this.impl.destroy();
            this.impl = undefined;
        }
        // @ts-ignore
        _super.prototype._onPreDestroy.call(this);
    };
    /**
     * update video data source
     */
    CCMVideo.prototype.updateVideoSource = function () {
        this.seekTime = 0;
        this.nativeDuration = 0;
        this.nativeWidth = 0;
        this.nativeHeight = 0;
        this.currentState = VideoState.PREPARING;
        this.targetState = VideoState.PREPARING;
        var url = '';
        if (this.source) {
            if (typeof this.source == 'string') {
                url = this.source;
            }
            else {
                url = this.source.nativeUrl;
            }
        }
        if (url && cc.loader.md5Pipe) {
            url = cc.loader.md5Pipe.transformURL(url);
        }
        if (CC_JSB) {
            this.impl.stop();
            this.impl.setURL(url);
            this.impl.prepare();
        }
        else {
            this.loaded = false;
            this.impl.pause();
            this.impl.src = url;
        }
        this.node.emit('preparing', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.PREPARING);
    };
    CCMVideo.prototype.onReadyToPlay = function () {
        this.updatePixelFormat();
        this.currentState = VideoState.PREPARED;
        if (this.seekTime > 0.1) {
            this.currentTime = this.seekTime;
        }
        this.node.emit('ready', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.READY);
        this.targetState == VideoState.PLAYING && this.play();
    };
    CCMVideo.prototype.onMetaLoaded = function () {
        this.node.emit('loaded', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.LOADED);
    };
    CCMVideo.prototype.onBufferStart = function () {
        this.isBuffering = true;
        this.node.emit('buffer_start', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.BUFFER_START);
    };
    CCMVideo.prototype.onBufferUpdate = function () {
        this.node.emit('buffer_update', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.BUFFER_UPDATE);
    };
    CCMVideo.prototype.onBufferEnd = function () {
        this.isBuffering = false;
        this.node.emit('buffer_end', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.BUFFER_END);
    };
    CCMVideo.prototype.onCompleted = function () {
        if (this.loop) {
            if (this.currentState == VideoState.PLAYING) {
                this.currentTime = 0;
                this.impl.play();
            }
        }
        else {
            this.currentState = VideoState.COMPLETED;
            this.targetState = VideoState.COMPLETED;
            this.node.emit('completed', this);
            cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.COMPLETED);
        }
    };
    CCMVideo.prototype.onError = function () {
        this.currentState = VideoState.ERROR;
        this.targetState = VideoState.ERROR;
        this.node.emit('error', this);
        cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.ERROR);
    };
    CCMVideo.prototype.play = function () {
        if (this.isInPlaybackState()) {
            if (this.currentState == VideoState.COMPLETED) {
                this.currentTime = 0;
            }
            if (this.currentState != VideoState.PLAYING) {
                this.impl.play();
                this.node.emit('playing', this);
                this.currentState = VideoState.PLAYING;
                this.targetState = VideoState.PLAYING;
                cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.PLAYING);
            }
        }
        else {
            this.targetState = VideoState.PLAYING;
        }
    };
    CCMVideo.prototype.resume = function () {
        if (this.isInPlaybackState() && this.currentState != VideoState.PLAYING) {
            if (CC_JSB) {
                this.impl.resume();
            }
            else {
                this.impl.play();
            }
            this.node.emit('playing', this);
            this.currentState = VideoState.PLAYING;
            this.targetState = VideoState.PLAYING;
            cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.PLAYING);
        }
        else {
            this.targetState = VideoState.PLAYING;
        }
    };
    CCMVideo.prototype.pause = function () {
        if (this.isInPlaybackState() && this.currentState != VideoState.PAUSED) {
            this.impl.pause();
            this.node.emit('paused', this);
            this.currentState = VideoState.PAUSED;
            this.targetState = VideoState.PAUSED;
            cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.PAUSED);
        }
        else {
            this.targetState = VideoState.PAUSED;
        }
    };
    CCMVideo.prototype.stop = function () {
        this.seekTime = 0;
        if (this.isInPlaybackState() && this.currentState != VideoState.IDLE) {
            if (CC_JSB) {
                this.impl.stop();
            }
            else {
                this.impl.pause();
                this.impl.currentTime = 0;
            }
            this.node.emit('stopped', this);
            this.currentState = VideoState.IDLE;
            this.targetState = VideoState.IDLE;
            cc.Component.EventHandler.emitEvents(this.videoPlayerEvent, this, EventType.STOPPED);
        }
        else {
            this.targetState = VideoState.IDLE;
        }
    };
    CCMVideo.prototype.clear = function () {
    };
    CCMVideo.prototype.isPlaying = function () {
        return this.currentState == VideoState.PLAYING || this.targetState == VideoState.PLAYING;
    };
    CCMVideo.prototype.isInPlaybackState = function () {
        return !!this.impl && this.currentState != VideoState.IDLE && this.currentState != VideoState.PREPARING && this.currentState != VideoState.ERROR;
    };
    __decorate([
        property({
            type: [cc.Material],
            visible: false,
            override: true,
        })
    ], CCMVideo.prototype, "materials", null);
    __decorate([
        property(cc.Material)
    ], CCMVideo.prototype, "rgb", void 0);
    __decorate([
        property(cc.Material)
    ], CCMVideo.prototype, "rgba", void 0);
    __decorate([
        property(cc.Material)
    ], CCMVideo.prototype, "i420", void 0);
    __decorate([
        property(cc.Material)
    ], CCMVideo.prototype, "nv12", void 0);
    __decorate([
        property(cc.Material)
    ], CCMVideo.prototype, "nv21", void 0);
    __decorate([
        property
    ], CCMVideo.prototype, "loop", void 0);
    __decorate([
        property([cc.Component.EventHandler])
    ], CCMVideo.prototype, "videoPlayerEvent", void 0);
    CCMVideo = __decorate([
        ccclass
    ], CCMVideo);
    return CCMVideo;
}(cc.RenderComponent));
exports.CCMVideo = CCMVideo;

cc._RF.pop();