tav-media
Version:
Cross platform media editing framework
384 lines (383 loc) • 14.2 kB
JavaScript
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;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { tav } from '../tav';
import { Matrix } from '../types/types';
import { Effect } from './tav-effect';
import { allowCallNativeAnytime, updateNative, updateNativeIfEffect } from '../types/tav-object';
/**
* A effect that display PAG file
* @category Effects
*/
export class PAGEffect extends Effect {
constructor() {
super(...arguments);
this.type = 'PAGEffect';
this.scaleMode = 1 /* ScaleMode.Stretch */;
this._clipReplacements = [];
this._textReplacements = [];
this._matrix = new Matrix();
this._timeStretchMode = 0;
}
/**
* Creates a PAG Effect from a PAG asset, return null if the asset does
* not exist or it's not a valid pag asset.
*/
static MakeFromAsset(asset) {
return __awaiter(this, void 0, void 0, function* () {
if (!(asset === null || asset === void 0 ? void 0 : asset.path)) {
return null;
}
const pagEffect = new PAGEffect();
pagEffect.asset = asset;
return pagEffect;
});
}
clone() {
const newEffect = new PAGEffect();
const _a = this, { _nativeObject: _nativeClip, parent, id, nativeInvalidated } = _a, restProperties = __rest(_a, ["_nativeObject", "parent", "id", "nativeInvalidated"]);
Object.assign(newEffect, restProperties);
return newEffect;
}
release() {
var _a;
super.release();
(_a = this.asset) === null || _a === void 0 ? void 0 : _a.release();
this.asset = null;
}
/**
* Add a clip to replace a editable image layer with scale mode.
* @param clip The clip used as an effect input.
* @param scaleMode Set how the clip is scaled to fit the layer.
* @param editableIndex The index of the editable layer in the PAG file.
*/
addInput(clip, scaleMode = 2 /* ScaleMode.LetterBox */, editableIndex = this.clipReplacements.length) {
this._clipReplacements.push({
editableIndex,
scaleMode,
inputIndex: this.inputs.length,
});
// 这里用到了 this.inputs.length 不要与上面代码交换顺序
super.addInput(clip);
}
removeInput(clip) {
const index = this.inputs.indexOf(clip);
if (index >= 0) {
const clipReplacementsIndex = this._clipReplacements.findIndex(r => r.inputIndex === index);
this._clipReplacements.splice(clipReplacementsIndex, 1);
}
super.removeInput(clip);
}
removeAllInputs() {
this._clipReplacements.length = 0;
super.removeAllInputs();
}
/**
* Add a clip to replace a editable image layer with a matrix.
* @param clip The clip used as an effect input.
* @param editableIndex The index of the editable layer in the PAG file.
* @param matrix The matrix used to transform the clip to fit the layer.
*/
addInputMatrix(clip, editableIndex = this.clipReplacements.length, matrix) {
this._clipReplacements.push({
editableIndex,
scaleMode: 0 /* ScaleMode.None */,
inputIndex: this.inputs.length,
matrix,
});
super.addInput(clip);
}
/**
* Set a new matrix to the input clip.
* @param editableIndex The index of the editable layer in the PAG file.
* @param clipIndex The index of the clip in the inputs.
* @param matrix The new matrix.
*/
replaceClipMatrix(editableIndex, clipIndex, matrix) {
this._clipReplacements[clipIndex].matrix = matrix;
if (this._nativeObject) {
const pagEffect = this._nativeObject;
replaceClipMatrix(pagEffect, editableIndex, clipIndex, matrix);
}
else {
this.invalidated();
;
}
}
/**
* Set a new matrix to a existing PAG layer.
* @param layerName The name of the layer in the PAG file.
* @param matrix The new matrix.
*/
replaceLayerMatrix(layerName, matrix) {
if (!this._layerMatrixes) {
this._layerMatrixes = {};
}
this._layerMatrixes[layerName] = matrix;
if (this._nativeObject) {
const pagEffect = this._nativeObject;
pagEffect.replaceLayerMatrix(layerName, matrix.build());
}
else {
this.invalidated();
;
}
}
/**
* Get editable text layers infos.
* @param name The name of the layer. Get all editable texts when the name is empty.
*/
getEditableTextInfo(name) {
if (!this._nativeObject) {
return null;
}
const pagEffect = this._nativeObject;
if (name) {
return pagEffect.getEditableTextInfo_name(name);
}
return pagEffect.getEditableTextInfo();
}
/**
* Get editable image layers infos.
* @param name The name of the layer. Get all editable texts when the name is empty.
*/
getEditableImageInfos(name) {
if (!this._nativeObject) {
return null;
}
const pagEffect = this._nativeObject;
if (name) {
return pagEffect.getEditableImageInfo_name(name);
}
return pagEffect.getEditableImageInfo();
}
createClip() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.asset || !this.asset.path)
return undefined;
if (this._nativeObject)
return this._nativeObject;
const pag = yield tav.PAGEffect.MakeFromPath(this.asset.getPathForPAGEffect());
return pag;
});
}
updateClip(effect) {
const _super = Object.create(null, {
updateClip: { get: () => super.updateClip }
});
var _a;
return __awaiter(this, void 0, void 0, function* () {
yield _super.updateClip.call(this, effect);
const matrix = yield this.matrix.build();
effect.setMatrix(matrix);
if ((_a = this.clipReplacements) === null || _a === void 0 ? void 0 : _a.length) {
this.clipReplacements.forEach((r) => {
if (r.matrix && effect.replaceClipMatrix) {
replaceClipMatrix(effect, r.editableIndex, r.inputIndex, r.matrix);
}
else if (effect.replaceClip) {
effect.replaceClip(r.editableIndex, r.inputIndex, r.scaleMode);
}
});
}
yield this.replaceTexts(effect);
effect.setTimeStretchMode(this._timeStretchMode);
if (this._layerMatrixes) {
Object.keys(this._layerMatrixes).forEach((key) => {
effect.replaceLayerMatrix(key, this._layerMatrixes[key].build());
});
}
});
}
/**
* Get a list of ClipReplacement to replace images in the PAG file,
* The ClipReplacements are added by addInput or addInputMatrix.
*/
get clipReplacements() {
return this._clipReplacements;
}
/**
* Get or set a list of PAGTextReplacement to replace texts in the PAG file
*/
get textReplacements() {
return this._textReplacements;
}
set textReplacements(textReps) {
this._textReplacements = textReps;
this.replaceTexts(this.nativeClip);
}
/**
* Get or set the matrix of this effect.
*/
get matrix() {
return this._matrix;
}
set matrix(matrix) {
this._matrix = matrix;
this.updateMatrix();
}
/**
* The count of replaceable images.
*/
get numImages() {
var _a;
return ((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.numImages()) || 0;
}
/**
* The count of replaceable texts.
*/
get numTexts() {
var _a;
return ((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.numTexts()) || 0;
}
/**
* Get the width of the effect.
*/
get width() {
var _a, _b;
return ((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.width()) || ((_b = this.asset) === null || _b === void 0 ? void 0 : _b.width) || 0;
}
/**
* Get the width of the effect.
*/
get height() {
var _a, _b;
return ((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.height()) || ((_b = this.asset) === null || _b === void 0 ? void 0 : _b.height) || 0;
}
/**
* Get the text data of the specified layer index.
* @param editableIndex The index of the text layer.
*/
getTextAttribute(editableIndex) {
var _a;
return (_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.getTextAttribute(editableIndex);
}
/**
* Get the duration of the PAG file.
*/
get fileDuration() {
var _a;
return ((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.fileDuration()) || 0;
}
/**
* Get or set the time stretch mode of the PAG file.
* PAGEffect will stretch the PAG file to fit the duration of the PAGEffect.
*/
get timeStretchMode() {
var _a;
return ((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.timeStretchMode()) || 0 /* tav.PAGTimeStretchMode.None */;
}
set timeStretchMode(mode) {
var _a, _b;
this._timeStretchMode = mode;
this.invalidated();
;
if (tav.webAssemblyQueue.exec) {
tav.webAssemblyQueue.exec((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.setTimeStretchMode, this.nativeClip, this._timeStretchMode);
}
else {
(_b = this.nativeClip) === null || _b === void 0 ? void 0 : _b.setTimeStretchMode(this._timeStretchMode);
}
}
updateMatrix() {
var _a, _b;
if (!this.nativeClip) {
this.invalidated();
;
return;
}
const nativeMatrix = this.matrix.build();
if (tav.webAssemblyQueue) {
tav.webAssemblyQueue.exec((_a = this.nativeClip) === null || _a === void 0 ? void 0 : _a.setMatrix, this.nativeClip, nativeMatrix);
}
else {
(_b = this.nativeClip) === null || _b === void 0 ? void 0 : _b.setMatrix(nativeMatrix);
}
}
replaceTexts(pagEffect) {
return __awaiter(this, void 0, void 0, function* () {
this.textReplacements.forEach((r) => {
if (typeof r.content === 'string') {
pagEffect.replaceText(r.editableIndex, r.content);
}
else {
pagEffect.replaceText_attribute(r.editableIndex, r.content);
}
});
});
}
}
__decorate([
updateNativeIfEffect
], PAGEffect.prototype, "addInput", null);
__decorate([
updateNativeIfEffect
], PAGEffect.prototype, "removeInput", null);
__decorate([
updateNativeIfEffect
], PAGEffect.prototype, "removeAllInputs", null);
__decorate([
updateNativeIfEffect
], PAGEffect.prototype, "addInputMatrix", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "getEditableTextInfo", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "getEditableImageInfos", null);
__decorate([
updateNative
], PAGEffect.prototype, "textReplacements", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "matrix", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "numImages", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "numTexts", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "getTextAttribute", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "fileDuration", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "timeStretchMode", null);
__decorate([
allowCallNativeAnytime
], PAGEffect.prototype, "replaceTexts", null);
function replaceClipMatrix(effect, editableIndex, inputIndex, matrix) {
const nativeMatrix = matrix.build();
if (tav.webAssemblyQueue.exec) {
tav.webAssemblyQueue.exec(effect.replaceClipMatrix, effect, editableIndex, inputIndex, nativeMatrix);
}
else {
effect.replaceClipMatrix(editableIndex, inputIndex, nativeMatrix);
}
}