Skip to content

Commit 96eb5bf

Browse files
authored
Merge pull request #22 from diffusionstudio/konstantin/fix/large-video-handling
Konstantin/fix/large video handling
2 parents 9a501fe + 65af040 commit 96eb5bf

File tree

11 files changed

+44
-30
lines changed

11 files changed

+44
-30
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@diffusionstudio/core",
33
"private": false,
4-
"version": "1.0.0-rc.8",
4+
"version": "1.0.0",
55
"type": "module",
66
"description": "Build bleeding edge video processing applications",
77
"files": [

src/clips/video/buffer.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ describe('FrameBuffer', () => {
2727

2828
frameBuffer.enqueue(mockVideoFrame);
2929

30-
expect(frameBuffer['buffer'].length).toBe(1);
31-
expect(frameBuffer['buffer'][0]).toBe(mockVideoFrame);
30+
expect(frameBuffer.frames.length).toBe(1);
31+
expect(frameBuffer.frames[0]).toBe(mockVideoFrame);
3232
expect(mockOnEnqueue).toHaveBeenCalled();
3333
});
3434

@@ -44,7 +44,7 @@ describe('FrameBuffer', () => {
4444

4545
expect(dequeuedFrame1).toBe(frame1);
4646
expect(dequeuedFrame2).toBe(frame2);
47-
expect(frameBuffer['buffer'].length).toBe(0);
47+
expect(frameBuffer.frames.length).toBe(0);
4848
});
4949

5050
it('should wait for a frame to be enqueued if buffer is empty and state is active', async () => {

src/clips/video/buffer.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@
66
*/
77

88
export class FrameBuffer {
9-
private buffer: Array<VideoFrame> = [];
10-
private state: 'active' | 'closed' = 'active';
9+
public frames: Array<VideoFrame> = [];
10+
public state: 'active' | 'closed' = 'active';
1111

1212
public onenqueue?: () => void;
1313
public onclose?: () => void;
1414

1515
public enqueue(data: VideoFrame) {
16-
this.buffer.unshift(data);
16+
this.frames.unshift(data);
1717
this.onenqueue?.();
1818
}
1919

2020
public async dequeue() {
21-
if (this.buffer.length == 0 && this.state == 'active') {
21+
if (this.frames.length == 0 && this.state == 'active') {
2222
await this.waitFor(20e3);
2323
}
2424

25-
if (this.buffer.length == 0 && this.state == 'closed') {
25+
if (this.frames.length == 0 && this.state == 'closed') {
2626
return;
2727
}
2828

29-
return this.buffer.pop();
29+
return this.frames.pop();
3030
}
3131

3232
public close() {
@@ -35,7 +35,7 @@ export class FrameBuffer {
3535
}
3636

3737
public terminate() {
38-
for (const frame of this.buffer) {
38+
for (const frame of this.frames) {
3939
frame.close();
4040
}
4141
}

src/clips/video/video.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@ describe('The Video Clip', () => {
264264
const composition = new Composition();
265265
await composition.add(clip);
266266

267+
composition.computeFrame();
268+
269+
expect(clip.track?.view.children.length).toBe(1);
270+
267271
const buffer = new FrameBuffer();
268272

269273
Object.defineProperty(buffer, 'onenqueue', {
@@ -274,8 +278,13 @@ describe('The Video Clip', () => {
274278
const decodeSpy = vi.spyOn(clip, 'decodeVideo').mockReturnValueOnce(buffer);
275279
composition.state = 'RENDER';
276280

277-
await clip.seek(new Timestamp());
281+
await composition.seek(0);
282+
283+
expect(clip.track?.view.children.length).toBe(0);
284+
285+
await composition.computeFrame();
278286

287+
expect(clip.track?.view.children.length).toBe(1);
279288
expect(decodeSpy).toBeCalledTimes(1);
280289
expect(seekFn.mock.calls[0][0]).toBe(0);
281290
});

src/clips/video/video.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ export class VideoClip extends VisualMixin(MediaClip<VideoClipProps>) {
110110
await this.seek(Timestamp.fromFrames(frame));
111111
}
112112

113+
public enter() {
114+
super.enter();
115+
if (this.track?.composition?.rendering && this.buffer?.state != 'active') {
116+
this.decodeVideo();
117+
}
118+
}
119+
113120
@visualize
114121
@textureSwap
115122
public update(_: Timestamp): void | Promise<void> {
@@ -139,17 +146,6 @@ export class VideoClip extends VisualMixin(MediaClip<VideoClipProps>) {
139146
return clip;
140147
}
141148

142-
public async seek(time: Timestamp): Promise<void> {
143-
if (this.track?.composition?.rendering) {
144-
const buffer = await this.decodeVideo();
145-
return new Promise<void>((resolve) => {
146-
buffer.onenqueue = () => resolve();
147-
});
148-
}
149-
150-
return super.seek(time);
151-
}
152-
153149
private async decodeVideo() {
154150
this.buffer = new FrameBuffer();
155151
this.worker = new DecodeWorker();

src/encoders/encoder.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ describe('The Encoder', () => {
4949
await encoder.render();
5050

5151
expect(pauseSpy).toBeCalledTimes(1);
52-
// before and after
53-
expect(seekSpy).toBeCalledTimes(2);
52+
expect(seekSpy).toBeCalledTimes(1);
5453
});
5554

5655
it('should not render when the composition renderer is not defined', async () => {

src/encoders/encoder.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ export class Encoder extends WebcodecsVideoEncoder {
9696
this.composition.state = 'IDLE';
9797
this.composition.renderer.resolution = 1;
9898
this.composition.fps = FPS_DEFAULT;
99-
this.composition.seek(0);
10099
}
101100
}
102101

src/models/transcript.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import type { Captions } from '../types';
1717
import type { Serializer } from '../services';
1818

1919
export class Transcript implements Serializer {
20-
public readonly id = crypto.randomUUID();
20+
public id = crypto.randomUUID();
2121
public language: Language = Language.en;
2222
public groups: WordGroup[] = [];
2323

src/services/serializer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export class Serializer {
44
/**
55
* Unique identifier of the object
66
*/
7-
public readonly id = crypto.randomUUID();
7+
public id = crypto.randomUUID();
88

99
toJSON(): any {
1010
const obj: any = {};

0 commit comments

Comments
 (0)