UNPKG

tav-media

Version:

Cross platform media editing framework

228 lines (227 loc) 7.99 kB
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()); }); }; import { tav } from '../tav'; import { MovieClip } from './tav-movie-clip'; import { FakeClip } from './tav-fake-clip'; import { updateNativeIfEffect } from '../types/tav-object'; /** * An object that combines and arranges clips into a single composite clip that you can play or * process. * @category Clips */ export class Composition extends MovieClip { constructor() { super(...arguments); this.type = 'Composition'; this.clips = []; this.fakeClips = []; this.lastNoticeUpdateFakeClip = null; this._width = 1; this._widthInvalid = true; this._height = 1; this._heightInvalid = true; } /** * Create a new composition with specified size. * @param width The width of the composition. * @param height The height of the composition. * @param contentStartTime The start time of the content of this composition. * @param contentDuration The duration of the content of this composition. */ static Make(width, height, contentStartTime, contentDuration) { return __awaiter(this, void 0, void 0, function* () { const comp = new Composition(); comp.width = width; comp.height = height; comp.contentStartTime = contentStartTime; comp.contentDuration = contentDuration; return comp; }); } /** * Adds a clip to this composition. */ addClip(clip) { if (clip) { // convert to composition to call protected method and vars const child = clip; child.removeFromParent(); child.attachToParent(this); this.clips.push(child); return; } console.warn('composition must add with a clip, but now is', clip); } /** * Removes a clip from this composition. * @param clip */ removeClip(clip) { // convert to composition to call protected method and vars const child = clip; const index = this.clips.indexOf(child); if (index >= 0) { child.detachFromParent(); this.clips.splice(index, 1); } } hasChildClip(clip) { return this.clips.indexOf(clip) >= 0; } /** * Removes all clips from this composition. */ removeAllClips() { this.clips.forEach((clip) => { // convert to composition to call protected method and vars const child = clip; child.detachFromParent(); }); this.clips.length = 0; } /** * Get all chid clips */ getAllClips() { return this.clips.concat(); } /** * Make fakeClip from this composition, * used to reference a snapshot of this composition in other effects */ MakeFakeClip() { const fakeClip = new FakeClip(); fakeClip.ontology = this; this.fakeClips.push(fakeClip); return fakeClip; } /** * whether this composition has a fakeClip child that need rebuild * @ignore */ hasFakeClipNativeInvalidated() { for (const clip of this.clips) { if (clip.hasFakeClipNativeInvalidated()) { return true; } } return false; } /** * whether fake clips of this composition to rebuild * @ignore */ noticeFakeClipsUpdate(noticeClip) { if (noticeClip) { this.lastNoticeUpdateFakeClip = noticeClip; return; } const needNotice = this.fakeClips.filter(clip => clip !== this.lastNoticeUpdateFakeClip); needNotice.forEach(clip => clip.setNativeInvalidated()); } /** * remove one fake clip from this composition's fake clips * @ignore */ removeFakeClip(fakeClip) { this.fakeClips.splice(this.fakeClips.indexOf(fakeClip), 1); } /** * Release this composition and all clips of this composition. */ release() { super.release(); this.clips.forEach(clip => clip.release()); } createClip() { return __awaiter(this, void 0, void 0, function* () { const existing = this._nativeObject; if (existing && !this._contentTimeInvalid && !this._heightInvalid && !this._widthInvalid) { return existing; } const composition = tav.Composition.Make(this.width, this.height, this.contentStartTime || 0, this.contentDuration || this.duration); composition.clips = []; this._contentTimeInvalid = false; this._heightInvalid = false; this._widthInvalid = false; return composition; }); } updateClip(composition) { const _super = Object.create(null, { updateClip: { get: () => super.updateClip } }); var _a; return __awaiter(this, void 0, void 0, function* () { yield _super.updateClip.call(this, composition); composition.removeAllClips(); // eslint-disable-next-line no-param-reassign composition.clips = []; for (const clip of this.clips) { const nativeClip = yield clip.build(); if (nativeClip) { (_a = composition.clips) === null || _a === void 0 ? void 0 : _a.push(nativeClip); composition.addClip(nativeClip); } else { console.error(`Found unsupported clip with type: ${clip.type}, id: ${clip.id}`); } } this.noticeFakeClipsUpdate(); this.lastNoticeUpdateFakeClip = null; }); } get width() { return this._width; } set width(w) { if (w === this._width) return; if (w < 0) { console.error('The width must be greater than or equal to 0.'); w = 0; } this._width = w; this._widthInvalid = true; this.invalidated(); } get height() { return this._height; } set height(h) { if (h === this._height) return; if (h < 0) { console.error('The height must be greater than or equal to 0.'); h = 0; } this._height = h; this._heightInvalid = true; this.invalidated(); } } __decorate([ updateNativeIfEffect ], Composition.prototype, "addClip", null); __decorate([ updateNativeIfEffect ], Composition.prototype, "removeClip", null); __decorate([ updateNativeIfEffect ], Composition.prototype, "removeAllClips", null);