@revideo/2d 0.4.2 → 0.4.3-alpha.1002
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/editor/editor/tsconfig.build.tsbuildinfo +1 -1
- package/lib/components/Video.d.ts +11 -12
- package/lib/components/Video.d.ts.map +1 -1
- package/lib/components/Video.js +41 -53
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/utils/video/ffmpeg-client.d.ts +7 -0
- package/lib/utils/video/ffmpeg-client.d.ts.map +1 -0
- package/lib/utils/video/ffmpeg-client.js +45 -0
- package/lib/utils/video/mp4-parser-manager.d.ts +2 -0
- package/lib/utils/video/mp4-parser-manager.d.ts.map +1 -0
- package/lib/utils/video/mp4-parser-manager.js +38 -0
- package/lib/utils/video/mp4-parser.d.ts +63 -0
- package/lib/utils/video/mp4-parser.d.ts.map +1 -0
- package/lib/utils/video/mp4-parser.js +264 -0
- package/package.json +6 -5
- package/src/lib/components/Video.ts +62 -83
- package/src/lib/utils/video/declarations.d.ts +1 -0
- package/src/lib/utils/video/ffmpeg-client.ts +64 -0
- package/src/lib/utils/video/mp4-parser-manager.ts +53 -0
- package/src/lib/utils/video/mp4-parser.ts +340 -0
package/lib/components/Video.js
CHANGED
|
@@ -8,57 +8,17 @@ var Video_1;
|
|
|
8
8
|
import { BBox, DependencyContext, PlaybackState, viaProxy, } from '@revideo/core';
|
|
9
9
|
import { computed, initial, nodeName, signal } from '../decorators';
|
|
10
10
|
import { drawImage } from '../utils';
|
|
11
|
+
import { ImageCommunication } from '../utils/video/ffmpeg-client';
|
|
12
|
+
import { getFrame } from '../utils/video/mp4-parser-manager';
|
|
11
13
|
import { Media } from './Media';
|
|
12
|
-
class ImageCommunication {
|
|
13
|
-
constructor() {
|
|
14
|
-
this.nextFrameHandlers = [];
|
|
15
|
-
if (!import.meta.hot) {
|
|
16
|
-
throw new Error('FfmpegVideoFrame can only be used with HMR.');
|
|
17
|
-
}
|
|
18
|
-
import.meta.hot.on('revideo:ffmpeg-video-frame-res', this.handler.bind(this));
|
|
19
|
-
}
|
|
20
|
-
handler(event) {
|
|
21
|
-
const handlers = this.nextFrameHandlers;
|
|
22
|
-
this.nextFrameHandlers = [];
|
|
23
|
-
for (const handler of handlers) {
|
|
24
|
-
handler(event);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
async getFrame(id, src, time, duration, fps, png) {
|
|
28
|
-
return new Promise((resolve, reject) => {
|
|
29
|
-
if (!import.meta.hot) {
|
|
30
|
-
reject('FfmpegVideoFrame can only be used with HMR.');
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
function handler(event) {
|
|
34
|
-
const image = new Image();
|
|
35
|
-
const uint8Array = new Uint8Array(event.data.frame.data);
|
|
36
|
-
const type = png ? 'image/png' : 'image/jpeg';
|
|
37
|
-
const blob = new Blob([uint8Array], { type });
|
|
38
|
-
const url = URL.createObjectURL(blob);
|
|
39
|
-
image.src = url;
|
|
40
|
-
image.onload = () => {
|
|
41
|
-
resolve(image);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
this.nextFrameHandlers.push(handler);
|
|
45
|
-
import.meta.hot.send('revideo:ffmpeg-video-frame', {
|
|
46
|
-
data: {
|
|
47
|
-
id: id,
|
|
48
|
-
filePath: src,
|
|
49
|
-
startTime: time,
|
|
50
|
-
duration,
|
|
51
|
-
fps,
|
|
52
|
-
png,
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
14
|
let Video = Video_1 = class Video extends Media {
|
|
59
15
|
constructor(props) {
|
|
60
16
|
super(props);
|
|
61
17
|
this.lastFrame = null;
|
|
18
|
+
// If the file is not mp4, warn.
|
|
19
|
+
if (!this.fullSource().endsWith('.mp4')) {
|
|
20
|
+
console.warn(`WARNING: Video source is not an MP4 file. This may significantly slow down rendering: ${this.fullSource()}`);
|
|
21
|
+
}
|
|
62
22
|
}
|
|
63
23
|
desiredSize() {
|
|
64
24
|
const custom = super.desiredSize();
|
|
@@ -145,7 +105,17 @@ let Video = Video_1 = class Video extends Media {
|
|
|
145
105
|
}
|
|
146
106
|
return video;
|
|
147
107
|
}
|
|
148
|
-
async
|
|
108
|
+
async webcodecSeekedVideo() {
|
|
109
|
+
const video = this.video();
|
|
110
|
+
const time = this.clampTime(this.time());
|
|
111
|
+
video.playbackRate = this.playbackRate();
|
|
112
|
+
if (this.lastFrame && this.lastTime === time) {
|
|
113
|
+
return this.lastFrame;
|
|
114
|
+
}
|
|
115
|
+
const fps = this.view().fps() / this.playbackRate();
|
|
116
|
+
return getFrame(this.key, video.src, time, fps);
|
|
117
|
+
}
|
|
118
|
+
async ffmpegSeekedVideo() {
|
|
149
119
|
const video = this.video();
|
|
150
120
|
const time = this.clampTime(this.time());
|
|
151
121
|
const duration = this.getDuration();
|
|
@@ -157,19 +127,37 @@ let Video = Video_1 = class Video extends Media {
|
|
|
157
127
|
if (!Video_1.imageCommunication) {
|
|
158
128
|
throw new Error('ServerSeekedVideo can only be used with HMR.');
|
|
159
129
|
}
|
|
160
|
-
const frame = await Video_1.imageCommunication.getFrame(this.key, video.src, time, duration, fps
|
|
130
|
+
const frame = await Video_1.imageCommunication.getFrame(this.key, video.src, time, duration, fps);
|
|
161
131
|
this.lastFrame = frame;
|
|
162
132
|
this.lastTime = time;
|
|
163
133
|
return frame;
|
|
164
134
|
}
|
|
165
135
|
async seekFunction() {
|
|
166
136
|
const playbackState = this.view().playbackState();
|
|
137
|
+
// During playback
|
|
167
138
|
if (playbackState === PlaybackState.Playing ||
|
|
168
139
|
playbackState === PlaybackState.Presenting) {
|
|
169
140
|
return this.fastSeekedVideo();
|
|
170
141
|
}
|
|
171
|
-
if (playbackState === PlaybackState.
|
|
172
|
-
return this.
|
|
142
|
+
if (playbackState === PlaybackState.Paused) {
|
|
143
|
+
return this.seekedVideo();
|
|
144
|
+
}
|
|
145
|
+
// During rendering, if set explicitly
|
|
146
|
+
if (this.decoder() === 'slow') {
|
|
147
|
+
return this.seekedVideo();
|
|
148
|
+
}
|
|
149
|
+
if (this.decoder() === 'ffmpeg') {
|
|
150
|
+
return this.ffmpegSeekedVideo();
|
|
151
|
+
}
|
|
152
|
+
if (this.decoder() === 'web') {
|
|
153
|
+
return this.webcodecSeekedVideo();
|
|
154
|
+
}
|
|
155
|
+
// If not set explicitly, use file extension to determine decoder
|
|
156
|
+
if (this.src().endsWith('.mp4')) {
|
|
157
|
+
return this.webcodecSeekedVideo();
|
|
158
|
+
}
|
|
159
|
+
if (this.src().endsWith('.webm')) {
|
|
160
|
+
return this.ffmpegSeekedVideo();
|
|
173
161
|
}
|
|
174
162
|
return this.seekedVideo();
|
|
175
163
|
}
|
|
@@ -212,9 +200,9 @@ __decorate([
|
|
|
212
200
|
signal()
|
|
213
201
|
], Video.prototype, "smoothing", void 0);
|
|
214
202
|
__decorate([
|
|
215
|
-
initial(
|
|
203
|
+
initial(null),
|
|
216
204
|
signal()
|
|
217
|
-
], Video.prototype, "
|
|
205
|
+
], Video.prototype, "decoder", void 0);
|
|
218
206
|
__decorate([
|
|
219
207
|
computed()
|
|
220
208
|
], Video.prototype, "video", null);
|
|
@@ -228,4 +216,4 @@ Video = Video_1 = __decorate([
|
|
|
228
216
|
nodeName('Video')
|
|
229
217
|
], Video);
|
|
230
218
|
export { Video };
|
|
231
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
219
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVmlkZW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvVmlkZW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE9BQU8sRUFDTCxJQUFJLEVBQ0osaUJBQWlCLEVBQ2pCLGFBQWEsRUFJYixRQUFRLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUVsRSxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ25DLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBQ2hFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUMzRCxPQUFPLEVBQUMsS0FBSyxFQUFhLE1BQU0sU0FBUyxDQUFDO0FBa0JuQyxJQUFNLEtBQUssYUFBWCxNQUFNLEtBQU0sU0FBUSxLQUFLO0lBOEM5QixZQUFtQixLQUFpQjtRQUNsQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUF5SEwsY0FBUyxHQUE0QixJQUFJLENBQUM7UUF2SGxELGdDQUFnQztRQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU8sQ0FBQyxJQUFJLENBQ1YseUZBQXlGLElBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUM3RyxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFa0IsV0FBVztRQUM1QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkMsSUFBSSxNQUFNLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzNDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFL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
|