Skip to content

Commit 71e7cf6

Browse files
committed
migrated composition and encoder to scene graph
1 parent b3f2342 commit 71e7cf6

File tree

4 files changed

+24
-34
lines changed

4 files changed

+24
-34
lines changed

src/composition/composition.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,29 @@ describe('The composition', () => {
9090
});
9191

9292
it('should append new tracks', () => {
93+
expect(composition.stage.children.length).toBe(0);
9394
const video = composition.createTrack('video');
9495

9596
expect(video instanceof VideoTrack).toBe(true);
97+
expect(composition.stage.children.length).toBe(1);
9698
expect(composition.tracks.length).toBe(1);
9799

98100
const image = composition.createTrack('image').layer('bottom');
99101
expect(image instanceof ImageTrack).toBe(true);
102+
expect(composition.stage.children.length).toBe(2);
100103
expect(composition.tracks.length).toBe(2);
101104
expect(composition.tracks.at(-1) instanceof ImageTrack).toBe(true);
102105

103106
const text = composition.createTrack('text').layer('top');
104107
expect(text instanceof TextTrack).toBe(true);
108+
expect(composition.stage.children.length).toBe(3);
105109
expect(composition.tracks.length).toBe(3);
106110
expect(composition.tracks[0] instanceof TextTrack).toBe(true);
107111
expect(composition.tracks[1] instanceof VideoTrack).toBe(true);
108112

109113
const audio = composition.createTrack('audio').layer(1);
110114
expect(audio instanceof AudioTrack).toBe(true);
115+
expect(composition.stage.children.length).toBe(4);
111116
expect(composition.tracks.length).toBe(4);
112117
expect(composition.tracks[1] instanceof AudioTrack).toBe(true);
113118
});

src/composition/composition.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@
55
* Public License, v. 2.0 that can be found in the LICENSE file.
66
*/
77

8-
import { autoDetectRenderer } from 'pixi.js';
8+
import { autoDetectRenderer, Container } from 'pixi.js';
99
import { framesToMillis, Timestamp, FPS_DEFAULT } from '../models';
1010
import { MediaClip } from '../clips';
1111
import { Serializer } from '../services';
1212
import { TrackDeserializer } from '../tracks';
13-
import { clear } from '../utils/pixi';
1413
import { isClass } from '../utils';
1514
import { EventEmitterMixin } from '../mixins';
1615
import { BaseError } from '../errors';
@@ -35,6 +34,11 @@ export class Composition extends EventEmitterMixin<CompositionEvents, typeof Ser
3534
*/
3635
public renderer?: Renderer;
3736

37+
/**
38+
* The root container of the composition
39+
*/
40+
public stage = new Container();
41+
3842
/**
3943
* Settings of the composition
4044
*/
@@ -95,7 +99,7 @@ export class Composition extends EventEmitterMixin<CompositionEvents, typeof Ser
9599
this.on('frame', this.computeFrame.bind(this));
96100
this.on('error', this.computeFrame.bind(this));
97101

98-
autoDetectRenderer({ ...this.settings, clearBeforeRender: false, preference: backend })
102+
autoDetectRenderer({ ...this.settings, preference: backend })
99103
.then(renderer => {
100104
this.renderer = renderer;
101105
this.trigger('init', undefined);
@@ -196,6 +200,7 @@ export class Composition extends EventEmitterMixin<CompositionEvents, typeof Ser
196200

197201
track.connect(this);
198202

203+
this.stage.addChild(track.view);
199204
this.tracks.unshift(track);
200205

201206
track.on('*', this.updateDuration.bind(this));
@@ -301,13 +306,13 @@ export class Composition extends EventEmitterMixin<CompositionEvents, typeof Ser
301306
*/
302307
public computeFrame(): void {
303308
if (!this.renderer) return;
304-
305-
clear(this.renderer, this.context);
306-
307-
for (let i = this.tracks.length - 1; i >= 0; i--) {
308-
this.tracks[i].render(this.renderer, Timestamp.fromFrames(this.frame));
309+
310+
for (let i = 0; i < this.tracks.length; i++) {
311+
this.tracks[i].update(Timestamp.fromFrames(this.frame));
309312
}
310313

314+
this.renderer.render(this.stage);
315+
this.context?.clearRect(0, 0, this.settings.width, this.settings.height);
311316
this.context?.drawImage(this.renderer.canvas, 0, 0);
312317

313318
this.trigger('currentframe', this.frame);
@@ -372,7 +377,7 @@ export class Composition extends EventEmitterMixin<CompositionEvents, typeof Ser
372377
await track.seek(Timestamp.fromFrames(this.frame));
373378
}
374379

375-
this.timerCallback();
380+
this.ticker();
376381
this.trigger('play', this.frame);
377382
}
378383

@@ -456,7 +461,7 @@ export class Composition extends EventEmitterMixin<CompositionEvents, typeof Ser
456461
);
457462
}
458463

459-
private async timerCallback() {
464+
private async ticker() {
460465
const interval = 1000 / FPS_DEFAULT;
461466

462467
let then = performance.now();

src/encoders/webcodecs.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { audioClipFilter, createStreamTarget } from './webcodecs.utils';
1111
import { FPS_DEFAULT, Timestamp } from '../models';
1212
import { getRenderEventDetail } from './utils';
1313
import { EventEmitter } from '../services';
14-
import { clear } from '../utils/pixi';
1514
import * as utils from '../utils';
1615

1716
import type { StreamTarget } from 'mp4-muxer';
@@ -83,12 +82,12 @@ export class WebcodecsEncoder extends EventEmitter<EncoderEvents>() implements R
8382
});
8483
}
8584

86-
clear(renderer);
87-
88-
for (let i = tracks.length - 1; i >= 0; i--) {
89-
await tracks[i].render(renderer, Timestamp.fromFrames(frame, this.fps));
85+
for (let i = 0; i < tracks.length; i++) {
86+
await tracks[i].update(Timestamp.fromFrames(frame, this.fps));
9087
}
9188

89+
renderer.render(this.composition.stage);
90+
9291
const videoFrame = new VideoFrame(renderer.canvas, {
9392
timestamp: Math.floor((frame / this.fps) * 1e6),
9493
duration: Math.floor(1e6 / this.fps),

src/utils/pixi.ts

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)