@revideo/2d 0.4.7-test.1023 → 0.4.7
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/editor/index.js +151 -380
- package/editor/index.js.map +1 -1
- package/lib/code/CodeCursor.d.ts +74 -74
- package/lib/code/CodeDiffer.d.ts +16 -21
- package/lib/code/CodeDiffer.js +41 -39
- package/lib/code/CodeFragment.d.ts +8 -16
- package/lib/code/CodeFragment.js +36 -36
- package/lib/code/CodeHighlighter.d.ts +59 -59
- package/lib/code/CodeHighlighter.js +1 -1
- package/lib/code/CodeMetrics.d.ts +8 -12
- package/lib/code/CodeMetrics.js +24 -26
- package/lib/code/CodeRange.d.ts +5 -21
- package/lib/code/CodeRange.js +124 -131
- package/lib/code/CodeScope.d.ts +8 -18
- package/lib/code/CodeSelection.d.ts +4 -9
- package/lib/code/CodeSelection.js +8 -8
- package/lib/code/CodeSignal.d.ts +47 -74
- package/lib/code/CodeTokenizer.d.ts +1 -1
- package/lib/code/CodeTokenizer.js +41 -41
- package/lib/code/DefaultHighlightStyle.d.ts +2 -2
- package/lib/code/DefaultHighlightStyle.js +96 -96
- package/lib/code/LezerHighlighter.d.ts +19 -21
- package/lib/code/diff.d.ts +9 -12
- package/lib/code/diff.js +205 -218
- package/lib/code/extractRange.d.ts +4 -7
- package/lib/code/extractRange.js +71 -79
- package/lib/code/index.d.ts +1 -1
- package/lib/code/index.js +1 -1
- package/lib/components/Audio.d.ts +11 -11
- package/lib/components/Bezier.d.ts +18 -18
- package/lib/components/Circle.d.ts +90 -95
- package/lib/components/Code.d.ts +211 -244
- package/lib/components/CodeBlock.d.ts +1 -1
- package/lib/components/CubicBezier.d.ts +36 -36
- package/lib/components/Curve.d.ts +198 -208
- package/lib/components/Grid.d.ts +42 -47
- package/lib/components/Icon.d.ts +50 -55
- package/lib/components/Img.d.ts +79 -86
- package/lib/components/Knot.d.ts +78 -97
- package/lib/components/Latex.d.ts +12 -12
- package/lib/components/Layout.d.ts +413 -455
- package/lib/components/Line.d.ts +49 -61
- package/lib/components/Media.d.ts +37 -37
- package/lib/components/Media.d.ts.map +1 -1
- package/lib/components/Media.js +6 -1
- package/lib/components/Node.d.ts +1 -1
- package/lib/components/Path.d.ts +1 -1
- package/lib/components/Polygon.d.ts +55 -60
- package/lib/components/QuadBezier.d.ts +29 -29
- package/lib/components/Ray.d.ts +28 -28
- package/lib/components/Rect.d.ts +108 -115
- package/lib/components/SVG.d.ts +1 -1
- package/lib/components/Shape.d.ts +1 -1
- package/lib/components/Spline.d.ts +40 -46
- package/lib/components/Txt.d.ts +44 -55
- package/lib/components/TxtLeaf.d.ts +16 -20
- package/lib/components/Video.d.ts +1 -0
- package/lib/components/Video.d.ts.map +1 -1
- package/lib/components/Video.js +7 -2
- package/lib/components/View2D.d.ts +22 -22
- package/lib/components/index.d.ts +1 -1
- package/lib/components/types.d.ts +9 -22
- package/lib/curves/ArcSegment.d.ts +24 -36
- package/lib/curves/CircleSegment.d.ts +16 -26
- package/lib/curves/CubicBezierSegment.d.ts +13 -18
- package/lib/curves/CurveDrawingInfo.d.ts +9 -9
- package/lib/curves/CurvePoint.d.ts +13 -13
- package/lib/curves/CurveProfile.d.ts +5 -5
- package/lib/curves/CurveProfile.js +1 -1
- package/lib/curves/KnotInfo.d.ts +8 -8
- package/lib/curves/LineSegment.d.ts +14 -19
- package/lib/curves/Polynomial.d.ts +110 -110
- package/lib/curves/Polynomial2D.d.ts +20 -20
- package/lib/curves/PolynomialSegment.d.ts +37 -42
- package/lib/curves/QuadBezierSegment.d.ts +12 -12
- package/lib/curves/Segment.d.ts +7 -12
- package/lib/curves/UniformPolynomialCurveSampler.d.ts +34 -34
- package/lib/curves/createCurveProfileLerp.d.ts +6 -17
- package/lib/curves/getBezierSplineProfile.d.ts +4 -8
- package/lib/curves/getCircleProfile.d.ts +4 -10
- package/lib/curves/getPathProfile.d.ts +2 -2
- package/lib/curves/getPointAtDistance.d.ts +4 -7
- package/lib/curves/getPolylineProfile.d.ts +4 -8
- package/lib/curves/getRectProfile.d.ts +4 -9
- package/lib/curves/index.d.ts +1 -1
- package/lib/curves/index.js +1 -1
- package/lib/decorators/canvasStyleSignal.d.ts +3 -3
- package/lib/decorators/colorSignal.d.ts +1 -1
- package/lib/decorators/compound.d.ts +2 -4
- package/lib/decorators/computed.d.ts +1 -1
- package/lib/decorators/defaultStyle.d.ts +2 -5
- package/lib/decorators/filtersSignal.d.ts +8 -28
- package/lib/decorators/index.d.ts +1 -1
- package/lib/decorators/index.js +1 -1
- package/lib/decorators/initializers.d.ts +2 -5
- package/lib/decorators/initializers.js +19 -18
- package/lib/decorators/nodeName.d.ts +1 -1
- package/lib/decorators/nodeName.js +4 -4
- package/lib/decorators/signal.d.ts +20 -40
- package/lib/decorators/spacingSignal.d.ts +1 -1
- package/lib/decorators/vector2Signal.d.ts +7 -13
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/jsx-dev-runtime.d.ts +3 -3
- package/lib/jsx-dev-runtime.js +3 -3
- package/lib/jsx-runtime.d.ts +9 -19
- package/lib/jsx-runtime.js +18 -18
- package/lib/partials/Filter.d.ts +16 -24
- package/lib/partials/Gradient.d.ts +24 -30
- package/lib/partials/Pattern.d.ts +9 -14
- package/lib/partials/ShaderConfig.d.ts +74 -81
- package/lib/partials/index.d.ts +1 -1
- package/lib/partials/index.js +1 -1
- package/lib/partials/types.d.ts +6 -19
- package/lib/scenes/Scene2D.d.ts +23 -42
- package/lib/scenes/index.d.ts +1 -1
- package/lib/scenes/index.js +1 -1
- package/lib/scenes/makeScene2D.d.ts +5 -7
- package/lib/scenes/useScene2D.d.ts +2 -2
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/utils/diff.d.ts +18 -25
- package/lib/utils/diff.js +87 -84
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +1 -1
- package/lib/utils/is.d.ts +2 -4
- package/lib/utils/is.js +2 -2
- package/lib/utils/makeSignalExtensions.d.ts +4 -11
- package/lib/utils/video/mp4-parser-manager.d.ts +1 -0
- package/lib/utils/video/mp4-parser-manager.d.ts.map +1 -1
- package/lib/utils/video/mp4-parser-manager.js +21 -4
- package/lib/utils/video/parser/index.d.ts +2 -0
- package/lib/utils/video/parser/index.d.ts.map +1 -0
- package/lib/utils/video/parser/index.js +2 -0
- package/lib/utils/video/parser/parser.d.ts +21 -0
- package/lib/utils/video/parser/parser.d.ts.map +1 -0
- package/lib/utils/video/parser/parser.js +168 -0
- package/lib/utils/video/parser/sampler.d.ts +16 -0
- package/lib/utils/video/parser/sampler.d.ts.map +1 -0
- package/lib/utils/video/parser/sampler.js +56 -0
- package/lib/utils/video/parser/segment.d.ts +44 -0
- package/lib/utils/video/parser/segment.d.ts.map +1 -0
- package/lib/utils/video/parser/segment.js +161 -0
- package/lib/utils/video/parser/sink.d.ts +9 -0
- package/lib/utils/video/parser/sink.d.ts.map +1 -0
- package/lib/utils/video/parser/sink.js +22 -0
- package/lib/utils/video/parser/utils.d.ts +10 -0
- package/lib/utils/video/parser/utils.d.ts.map +1 -0
- package/lib/utils/video/parser/utils.js +22 -0
- package/package.json +5 -5
- package/src/lib/components/Media.ts +6 -0
- package/src/lib/components/Video.ts +7 -1
- package/src/lib/utils/video/mp4-parser-manager.ts +24 -5
- package/src/lib/utils/video/parser/index.ts +1 -0
- package/src/lib/utils/video/parser/parser.ts +256 -0
- package/src/lib/utils/video/parser/sampler.ts +72 -0
- package/src/lib/utils/video/parser/segment.ts +211 -0
- package/src/lib/utils/video/parser/sink.ts +29 -0
- package/src/lib/utils/video/parser/utils.ts +31 -0
- package/lib/components/HlsVideo.d.ts +0 -62
- package/lib/components/HlsVideo.d.ts.map +0 -1
- package/lib/components/HlsVideo.js +0 -169
- package/lib/tsconfig.tsbuildinfo +0 -1
- package/lib/utils/video/mp4-parser.d.ts +0 -63
- package/lib/utils/video/mp4-parser.d.ts.map +0 -1
- package/lib/utils/video/mp4-parser.js +0 -264
- package/src/lib/utils/video/mp4-parser.ts +0 -340
package/lib/utils/diff.js
CHANGED
|
@@ -1,94 +1,97 @@
|
|
|
1
1
|
function getIdMap(list) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
const map = new Map();
|
|
3
|
+
let before = undefined;
|
|
4
|
+
for (const [index, current] of list.entries()) {
|
|
5
|
+
const currentArray = map.get(current.id) ?? [];
|
|
6
|
+
if (!map.has(current.id)) {
|
|
7
|
+
map.set(current.id, currentArray);
|
|
8
|
+
}
|
|
9
|
+
currentArray.push({
|
|
10
|
+
before,
|
|
11
|
+
current,
|
|
12
|
+
beforeIdIndex: before ? map.get(before.id).length - 1 : -1,
|
|
13
|
+
currentIndex: index,
|
|
14
|
+
});
|
|
15
|
+
before = current;
|
|
8
16
|
}
|
|
9
|
-
|
|
10
|
-
before,
|
|
11
|
-
current,
|
|
12
|
-
beforeIdIndex: before ? map.get(before.id).length - 1 : -1,
|
|
13
|
-
currentIndex: index,
|
|
14
|
-
});
|
|
15
|
-
before = current;
|
|
16
|
-
}
|
|
17
|
-
return map;
|
|
17
|
+
return map;
|
|
18
18
|
}
|
|
19
19
|
export function getTransformDiff(from, to) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
20
|
+
const diff = {
|
|
21
|
+
inserted: [],
|
|
22
|
+
deleted: [],
|
|
23
|
+
transformed: [],
|
|
24
|
+
};
|
|
25
|
+
const fromMap = getIdMap(from);
|
|
26
|
+
const toMap = getIdMap(to);
|
|
27
|
+
for (const [key, fromItem] of fromMap.entries()) {
|
|
28
|
+
const toItem = toMap.get(key);
|
|
29
|
+
if (toItem) {
|
|
30
|
+
toMap.delete(key);
|
|
31
|
+
for (let i = 0; i < Math.max(fromItem.length, toItem.length); i++) {
|
|
32
|
+
const insert = i >= fromItem.length;
|
|
33
|
+
const remove = i >= toItem.length;
|
|
34
|
+
const fromNode = !insert ? fromItem[i] : fromItem[fromItem.length - 1];
|
|
35
|
+
const toNode = !remove ? toItem[i] : toItem[toItem.length - 1];
|
|
36
|
+
diff.transformed.push({
|
|
37
|
+
insert,
|
|
38
|
+
remove,
|
|
39
|
+
from: fromNode,
|
|
40
|
+
to: toNode,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
for (const node of fromItem) {
|
|
46
|
+
diff.deleted.push(node);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
47
49
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
for (const toItem of toMap.values()) {
|
|
51
|
+
for (const node of toItem) {
|
|
52
|
+
diff.inserted.push(node);
|
|
53
|
+
}
|
|
52
54
|
}
|
|
53
|
-
|
|
54
|
-
return diff;
|
|
55
|
+
return diff;
|
|
55
56
|
}
|
|
56
57
|
export function applyTransformDiff(current, diff, cloner) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
for (const item of diff.transformed) {
|
|
77
|
-
if (!item.insert) continue;
|
|
78
|
-
const from = item.from;
|
|
79
|
-
item.from = {
|
|
80
|
-
...item.to,
|
|
81
|
-
current: cloner(from.current),
|
|
58
|
+
function insert(item) {
|
|
59
|
+
let idIndex = -1;
|
|
60
|
+
const index = item.before
|
|
61
|
+
? current.findIndex(({ id }) => {
|
|
62
|
+
if (id === item.before?.id) {
|
|
63
|
+
idIndex++;
|
|
64
|
+
if (idIndex === item.beforeIdIndex)
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
})
|
|
69
|
+
: 0;
|
|
70
|
+
current.splice(index + 1, 0, item.current);
|
|
71
|
+
}
|
|
72
|
+
const result = {
|
|
73
|
+
inserted: diff.inserted.map(item => ({
|
|
74
|
+
item,
|
|
75
|
+
order: item.currentIndex,
|
|
76
|
+
})),
|
|
82
77
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
78
|
+
for (const item of diff.transformed) {
|
|
79
|
+
if (!item.insert)
|
|
80
|
+
continue;
|
|
81
|
+
const from = item.from;
|
|
82
|
+
item.from = {
|
|
83
|
+
...item.to,
|
|
84
|
+
current: cloner(from.current),
|
|
85
|
+
};
|
|
86
|
+
result.inserted.push({
|
|
87
|
+
item: item.from,
|
|
88
|
+
order: item.to.currentIndex,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
result.inserted.sort((a, b) => a.order - b.order);
|
|
92
|
+
for (const item of result.inserted) {
|
|
93
|
+
insert(item.item);
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
93
96
|
}
|
|
94
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdXRpbHMvZGlmZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFpQ0EsU0FBUyxRQUFRLENBQW1CLElBQVM7SUFDM0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUM7SUFDdEQsSUFBSSxNQUFNLEdBQWtCLFNBQVMsQ0FBQztJQUN0QyxLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7UUFDOUMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3pCLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsWUFBWSxDQUFDLElBQUksQ0FBQztZQUNoQixNQUFNO1lBQ04sT0FBTztZQUNQLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzRCxZQUFZLEVBQUUsS0FBSztTQUNwQixDQUFDLENBQUM7UUFDSCxNQUFNLEdBQUcsT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLElBQVMsRUFDVCxFQUFPO0lBRVAsTUFBTSxJQUFJLEdBQXFCO1FBQzdCLFFBQVEsRUFBRSxFQUFFO1FBQ1osT0FBTyxFQUFFLEVBQUU7UUFDWCxXQUFXLEVBQUUsRUFBRTtLQUNo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
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdXRpbHMvZGlmZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFpQ0EsU0FBUyxRQUFRLENBQW1CLElBQVM7SUFDM0MsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUM7SUFDdEQsSUFBSSxNQUFNLEdBQWtCLFNBQVMsQ0FBQztJQUN0QyxLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7UUFDOUMsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3pCLEdBQUcsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsWUFBWSxDQUFDLElBQUksQ0FBQztZQUNoQixNQUFNO1lBQ04sT0FBTztZQUNQLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzRCxZQUFZLEVBQUUsS0FBSztTQUNwQixDQUFDLENBQUM7UUFDSCxNQUFNLEdBQUcsT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLElBQVMsRUFDVCxFQUFPO0lBRVAsTUFBTSxJQUFJLEdBQXFCO1FBQzdCLFFBQVEsRUFBRSxFQUFFO1FBQ1osT0FBTyxFQUFFLEVBQUU7UUFDWCxXQUFXLEVBQUUsRUFBRTtLQUNo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
|
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export * from './CanvasUtils';
|
|
2
2
|
export * from './is';
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsTUFBTSxDQUFDIn0=
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsTUFBTSxDQUFDIn0=
|
package/lib/utils/is.d.ts
CHANGED
|
@@ -4,7 +4,5 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @param klass - The class to check against.
|
|
6
6
|
*/
|
|
7
|
-
export declare function is<T>(
|
|
8
|
-
|
|
9
|
-
): (object: any) => object is T;
|
|
10
|
-
//# sourceMappingURL=is.d.ts.map
|
|
7
|
+
export declare function is<T>(klass: new (...args: any[]) => T): (object: any) => object is T;
|
|
8
|
+
//# sourceMappingURL=is.d.ts.map
|
package/lib/utils/is.js
CHANGED
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* @param klass - The class to check against.
|
|
6
6
|
*/
|
|
7
7
|
export function is(klass) {
|
|
8
|
-
|
|
8
|
+
return (object) => object instanceof klass;
|
|
9
9
|
}
|
|
10
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzL2lzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLEVBQUUsQ0FDaEIsS0FBZ0M7SUFFaEMsT0FBTyxDQUFDLE1BQU0sRUFBZSxFQUFFLENBQUMsTUFBTSxZQUFZLEtBQUssQ0FBQztBQUMxRCxDQUFDIn0=
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3V0aWxzL2lzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLEVBQUUsQ0FDaEIsS0FBZ0M7SUFFaEMsT0FBTyxDQUFDLE1BQU0sRUFBZSxFQUFFLENBQUMsTUFBTSxZQUFZLEtBQUssQ0FBQztBQUMxRCxDQUFDIn0=
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {SignalExtensions} from '@revideo/core';
|
|
2
|
-
import {PropertyMetadata} from '../decorators';
|
|
3
|
-
export declare function makeSignalExtensions<
|
|
4
|
-
|
|
5
|
-
TValue extends TSetterValue,
|
|
6
|
-
>(
|
|
7
|
-
meta?: Partial<PropertyMetadata<TValue>>,
|
|
8
|
-
owner?: any,
|
|
9
|
-
name?: string,
|
|
10
|
-
): Partial<SignalExtensions<TSetterValue, TValue>>;
|
|
11
|
-
//# sourceMappingURL=makeSignalExtensions.d.ts.map
|
|
1
|
+
import { SignalExtensions } from '@revideo/core';
|
|
2
|
+
import { PropertyMetadata } from '../decorators';
|
|
3
|
+
export declare function makeSignalExtensions<TSetterValue, TValue extends TSetterValue>(meta?: Partial<PropertyMetadata<TValue>>, owner?: any, name?: string): Partial<SignalExtensions<TSetterValue, TValue>>;
|
|
4
|
+
//# sourceMappingURL=makeSignalExtensions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mp4-parser-manager.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/video/mp4-parser-manager.ts"],"names":[],"mappings":"AAKA,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"mp4-parser-manager.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/video/mp4-parser-manager.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,iBAO/D;AAED,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,uBAqDZ"}
|
|
@@ -1,14 +1,31 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Mp4Parser } from './parser';
|
|
2
2
|
// List of VideoFrameExtractors
|
|
3
3
|
const videoFrameExtractors = new Map();
|
|
4
|
+
export async function dropExtractor(id, filePath) {
|
|
5
|
+
const extractorId = filePath + '-' + id;
|
|
6
|
+
const extractor = videoFrameExtractors.get(extractorId);
|
|
7
|
+
if (extractor) {
|
|
8
|
+
extractor.close();
|
|
9
|
+
videoFrameExtractors.delete(extractorId);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
4
12
|
export async function getFrame(id, filePath, time, fps) {
|
|
5
13
|
// Check if we already have a VideoFrameExtractor for this video
|
|
6
14
|
const extractorId = filePath + '-' + id;
|
|
7
15
|
let extractor = videoFrameExtractors.get(extractorId);
|
|
8
16
|
const frameDuration = 1 / fps;
|
|
17
|
+
/**
|
|
18
|
+
* Sometimes, HTMLVideoElement.duration is not accurate, which can lead to the
|
|
19
|
+
* requested time being greater than the duration.
|
|
20
|
+
* To prevent this, we clamp the time to the duration reported by the extractor.
|
|
21
|
+
*/
|
|
22
|
+
const duration = extractor?.getDuration();
|
|
23
|
+
if (duration && time > duration) {
|
|
24
|
+
time = duration;
|
|
25
|
+
}
|
|
9
26
|
const isOldFrame = extractor && Math.abs(time - extractor.getLastTime()) < frameDuration / 2;
|
|
10
27
|
// If time has not changed, return the last frame
|
|
11
|
-
if (isOldFrame) {
|
|
28
|
+
if (extractor && isOldFrame) {
|
|
12
29
|
const lastFrame = extractor.getLastFrame();
|
|
13
30
|
if (!lastFrame) {
|
|
14
31
|
throw new Error('No last frame');
|
|
@@ -28,11 +45,11 @@ export async function getFrame(id, filePath, time, fps) {
|
|
|
28
45
|
extractor = undefined;
|
|
29
46
|
}
|
|
30
47
|
if (!extractor) {
|
|
31
|
-
extractor = new
|
|
48
|
+
extractor = new Mp4Parser(filePath, fps, time);
|
|
32
49
|
await extractor.start();
|
|
33
50
|
videoFrameExtractors.set(extractorId, extractor);
|
|
34
51
|
}
|
|
35
52
|
// Go to the frame that is closest to the requested time
|
|
36
53
|
return extractor.getNextFrame();
|
|
37
54
|
}
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXA0LXBhcnNlci1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi91dGlscy92aWRlby9tcDQtcGFyc2VyLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUVuQywrQkFBK0I7QUFDL0IsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztBQUUxRCxNQUFNLENBQUMsS0FBSyxVQUFVLGFBQWEsQ0FBQyxFQUFVLEVBQUUsUUFBZ0I7SUFDOUQsTUFBTSxXQUFXLEdBQUcsUUFBUSxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7SUFDeEMsTUFBTSxTQUFTLEdBQUcsb0JBQW9CLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3hELElBQUksU0FBUyxFQUFFLENBQUM7UUFDZCxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsb0JBQW9CLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzNDLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRLENBQzVCLEVBQVUsRUFDVixRQUFnQixFQUNoQixJQUFZLEVBQ1osR0FBVztJQUVYLGdFQUFnRTtJQUNoRSxNQUFNLFdBQVcsR0FBRyxRQUFRLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUN4QyxJQUFJLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFdEQsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUU5Qjs7OztPQUlHO0lBQ0gsTUFBTSxRQUFRLEdBQUcsU0FBUyxFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQzFDLElBQUksUUFBUSxJQUFJLElBQUksR0FBRyxRQUFRLEVBQUUsQ0FBQztRQUNoQyxJQUFJLEdBQUcsUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FDZCxTQUFTLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDLEdBQUcsYUFBYSxHQUFHLENBQUMsQ0FBQztJQUU1RSxpREFBaUQ7SUFDakQsSUFBSSxTQUFTLElBQUksVUFBVSxFQUFFLENBQUM7UUFDNUIsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzNDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUVELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFRCxrRUFBa0U7SUFDbEUsSUFBSSxTQUFTLElBQUksSUFBSSxHQUFHLGFBQWEsR0FBRyxTQUFTLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUM1RCxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEIsb0JBQW9CLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3pDLFNBQVMsR0FBRyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELHFFQUFxRTtJQUNyRSxJQUFJLFNBQVMsSUFBSSxJQUFJLEdBQUcsU0FBUyxDQUFDLE9BQU8sRUFBRSxHQUFHLGFBQWEsRUFBRSxDQUFDO1FBQzVELFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQixvQkFBb0IsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekMsU0FBUyxHQUFHLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRUQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2YsU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDL0MsTUFBTSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEIsb0JBQW9CLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsd0RBQXdEO0lBQ3hELE9BQU8sU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ2xDLENBQUMifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/video/parser/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from './parser';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3V0aWxzL3ZpZGVvL3BhcnNlci9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLFVBQVUsQ0FBQyJ9
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class Mp4Parser {
|
|
2
|
+
private uri;
|
|
3
|
+
private file;
|
|
4
|
+
private edits;
|
|
5
|
+
private decoderConfig?;
|
|
6
|
+
private startTime;
|
|
7
|
+
private targetFps;
|
|
8
|
+
private nextSegment;
|
|
9
|
+
private sampler?;
|
|
10
|
+
constructor(uri: string, targetFps: number, startTime: number);
|
|
11
|
+
start(): Promise<void>;
|
|
12
|
+
getNextFrame(): Promise<VideoFrame>;
|
|
13
|
+
private getSecondDurationOfSegment;
|
|
14
|
+
getDuration(): number;
|
|
15
|
+
private getTimeSubtractingFrames;
|
|
16
|
+
getTime(): number;
|
|
17
|
+
getLastTime(): number;
|
|
18
|
+
getLastFrame(): VideoFrame | undefined;
|
|
19
|
+
close(): void;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/video/parser/parser.ts"],"names":[],"mappings":"AAiGA,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAAM;IAClB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAqB;IAE3C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,OAAO,CAAC,CAAe;gBAEZ,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAMvD,KAAK;IAOL,YAAY;IAqFzB,OAAO,CAAC,0BAA0B;IAO3B,WAAW;IAOlB,OAAO,CAAC,wBAAwB;IAiBzB,OAAO;IAIP,WAAW;IAIX,YAAY;IAIZ,KAAK;CAKb"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { createFile } from 'mp4box';
|
|
2
|
+
import { FrameSampler } from './sampler';
|
|
3
|
+
import { Segment } from './segment';
|
|
4
|
+
import { MP4FileSink } from './sink';
|
|
5
|
+
import { description, mp4BoxEditToEdit } from './utils';
|
|
6
|
+
/**
|
|
7
|
+
* Loads the file at the given URI until it finds the moov box.
|
|
8
|
+
* Once found, it calls `setConfig` with the video configuration.
|
|
9
|
+
* @param uri - The URI of the video file.
|
|
10
|
+
* @param setConfig - Callback to set the video configuration.
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
async function getFileInfo(uri) {
|
|
14
|
+
return new Promise((res, rej) => {
|
|
15
|
+
const file = createFile();
|
|
16
|
+
let found = false;
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
file.onReady = (info) => {
|
|
19
|
+
found = true;
|
|
20
|
+
controller.abort();
|
|
21
|
+
const track = info.videoTracks[0];
|
|
22
|
+
const config = {
|
|
23
|
+
// Browser doesn't support parsing full vp8 codec (eg: `vp08.00.41.08`),
|
|
24
|
+
// they only support `vp8`.
|
|
25
|
+
codec: track.codec.startsWith('vp08') ? 'vp8' : track.codec,
|
|
26
|
+
codedHeight: track.video.height,
|
|
27
|
+
codedWidth: track.video.width,
|
|
28
|
+
description: description(file, track),
|
|
29
|
+
};
|
|
30
|
+
const defaultEdit = {
|
|
31
|
+
mediaTime: 0,
|
|
32
|
+
segmentDuration: track.duration,
|
|
33
|
+
mediaRateInteger: 1,
|
|
34
|
+
mediaRateFraction: 0,
|
|
35
|
+
};
|
|
36
|
+
const editsFromVideo = track.edits?.map((edit) => mp4BoxEditToEdit(edit));
|
|
37
|
+
// If there are no entries, use the default edit
|
|
38
|
+
const editsWithoutFps = editsFromVideo?.length
|
|
39
|
+
? editsFromVideo
|
|
40
|
+
: [defaultEdit];
|
|
41
|
+
// Calculate FPS for each segment
|
|
42
|
+
const edits = editsWithoutFps.map(edit => {
|
|
43
|
+
const trackDurationInSec = track.duration / track.timescale;
|
|
44
|
+
const segmentDurationInSec = edit.segmentDuration / track.movie_timescale;
|
|
45
|
+
const segmentFrames = track.nb_samples * (segmentDurationInSec / trackDurationInSec);
|
|
46
|
+
const mediaRate = edit.mediaRateInteger + edit.mediaRateFraction / 0xffff;
|
|
47
|
+
const fps = (segmentFrames / segmentDurationInSec) * mediaRate;
|
|
48
|
+
return { ...edit, fps };
|
|
49
|
+
});
|
|
50
|
+
file.setExtractionOptions(track.id);
|
|
51
|
+
file.start();
|
|
52
|
+
res({ file, edits, config });
|
|
53
|
+
};
|
|
54
|
+
return fetch(uri, { signal: controller.signal }).then(async (response) => {
|
|
55
|
+
if (!response.body) {
|
|
56
|
+
throw new Error('Response body is null');
|
|
57
|
+
}
|
|
58
|
+
const reader = response.body.getReader();
|
|
59
|
+
const sink = new MP4FileSink(file, () => { });
|
|
60
|
+
while (!found) {
|
|
61
|
+
await reader.read().then(({ done, value }) => {
|
|
62
|
+
if (done) {
|
|
63
|
+
file.flush();
|
|
64
|
+
controller.abort();
|
|
65
|
+
rej('Could not find moov');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
sink.write(value);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
export class Mp4Parser {
|
|
75
|
+
constructor(uri, targetFps, startTime) {
|
|
76
|
+
this.edits = [];
|
|
77
|
+
this.nextSegment = 0;
|
|
78
|
+
this.uri = uri;
|
|
79
|
+
this.targetFps = targetFps;
|
|
80
|
+
this.startTime = startTime;
|
|
81
|
+
}
|
|
82
|
+
async start() {
|
|
83
|
+
const { file, edits, config } = await getFileInfo(this.uri);
|
|
84
|
+
this.file = file;
|
|
85
|
+
this.edits = edits;
|
|
86
|
+
this.decoderConfig = config;
|
|
87
|
+
}
|
|
88
|
+
async getNextFrame() {
|
|
89
|
+
// Start the first segment
|
|
90
|
+
if (!this.sampler) {
|
|
91
|
+
// Skip segments until the start time
|
|
92
|
+
let startTimeWithinSegment = this.startTime;
|
|
93
|
+
while (this.nextSegment < this.edits.length) {
|
|
94
|
+
const segmentDurationInSeconds = this.getSecondDurationOfSegment(this.edits[this.nextSegment]);
|
|
95
|
+
if (startTimeWithinSegment < segmentDurationInSeconds) {
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
startTimeWithinSegment -= segmentDurationInSeconds;
|
|
99
|
+
this.nextSegment++;
|
|
100
|
+
}
|
|
101
|
+
// The timestamp is outside of the video
|
|
102
|
+
if (this.nextSegment >= this.edits.length) {
|
|
103
|
+
throw new Error(`Timestamp ${this.startTime} is outside of the video, max timestamp is ${this.getDuration()}`);
|
|
104
|
+
}
|
|
105
|
+
const segment = new Segment(this.uri, this.file, this.edits, this.nextSegment, startTimeWithinSegment);
|
|
106
|
+
await segment.start(this.decoderConfig);
|
|
107
|
+
this.sampler = new FrameSampler(segment, this.edits[this.nextSegment].fps, this.targetFps, 0);
|
|
108
|
+
this.nextSegment++;
|
|
109
|
+
}
|
|
110
|
+
// Try to get the next frame
|
|
111
|
+
let frame = await this.sampler.getNextFrame();
|
|
112
|
+
// If there are no more frames in the current segment, start the next segment
|
|
113
|
+
while (!frame && this.nextSegment < this.edits.length) {
|
|
114
|
+
this.sampler.getSegment().close();
|
|
115
|
+
this.sampler.getLastFrame()?.close();
|
|
116
|
+
const segment = new Segment(this.uri, this.file, this.edits, this.nextSegment, 0);
|
|
117
|
+
await segment.start(this.decoderConfig);
|
|
118
|
+
this.sampler = new FrameSampler(segment, this.edits[this.nextSegment].fps, this.targetFps, this.sampler.getSum());
|
|
119
|
+
this.nextSegment++;
|
|
120
|
+
frame = await this.sampler.getNextFrame();
|
|
121
|
+
}
|
|
122
|
+
// If there are no more frames, return the last frame
|
|
123
|
+
if (!frame) {
|
|
124
|
+
frame = this.sampler.getLastFrame();
|
|
125
|
+
// We can close the segment
|
|
126
|
+
this.sampler.getSegment().close();
|
|
127
|
+
// If we still don't have a frame, throw an error
|
|
128
|
+
if (!frame) {
|
|
129
|
+
throw new Error('There are no frames in the video.');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return frame;
|
|
133
|
+
}
|
|
134
|
+
getSecondDurationOfSegment(edit) {
|
|
135
|
+
const mediaRate = edit.mediaRateInteger + edit.mediaRateFraction / 0xffff;
|
|
136
|
+
const duration = edit.segmentDuration / this.file.getInfo().videoTracks[0].movie_timescale;
|
|
137
|
+
return duration / mediaRate;
|
|
138
|
+
}
|
|
139
|
+
getDuration() {
|
|
140
|
+
return this.edits.reduce((acc, edit) => acc + this.getSecondDurationOfSegment(edit), 0);
|
|
141
|
+
}
|
|
142
|
+
getTimeSubtractingFrames(frames) {
|
|
143
|
+
const durationOfPastSegmentsInSeconds = this.edits
|
|
144
|
+
.slice(0, this.nextSegment - 1)
|
|
145
|
+
.reduce((acc, edit) => acc + this.getSecondDurationOfSegment(edit), 0);
|
|
146
|
+
if (!this.sampler) {
|
|
147
|
+
throw new Error('No current segment');
|
|
148
|
+
}
|
|
149
|
+
const currentSegmentStartTime = this.sampler.getSegment().getStartTime();
|
|
150
|
+
const samplerTime = this.sampler.getTime(frames);
|
|
151
|
+
return (durationOfPastSegmentsInSeconds + currentSegmentStartTime + samplerTime);
|
|
152
|
+
}
|
|
153
|
+
getTime() {
|
|
154
|
+
return this.getTimeSubtractingFrames(0);
|
|
155
|
+
}
|
|
156
|
+
getLastTime() {
|
|
157
|
+
return this.getTimeSubtractingFrames(1);
|
|
158
|
+
}
|
|
159
|
+
getLastFrame() {
|
|
160
|
+
return this.sampler?.getLastFrame();
|
|
161
|
+
}
|
|
162
|
+
close() {
|
|
163
|
+
this.sampler?.getSegment().close();
|
|
164
|
+
this.sampler?.getLastFrame()?.close();
|
|
165
|
+
this.file.flush();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi91dGlscy92aWRlby9wYXJzZXIvcGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDbEMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUN2QyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFDbkMsT0FBTyxFQUFPLFdBQVcsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLFNBQVMsQ0FBQztBQUU1RDs7Ozs7O0dBTUc7QUFDSCxLQUFLLFVBQVUsV0FBVyxDQUFDLEdBQVc7SUFDcEMsT0FBTyxJQUFJLE9BQU8sQ0FJZixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtRQUNkLE1BQU0sSUFBSSxHQUFHLFVBQVUsRUFBRSxDQUFDO1FBQzFCLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNsQixNQUFNLFVBQVUsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBRXpDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxJQUFTLEVBQUUsRUFBRTtZQUMzQixLQUFLLEdBQUcsSUFBSSxDQUFDO1lBQ2IsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRW5CLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFbEMsTUFBTSxNQUFNLEdBQUc7Z0JBQ2Isd0VBQXdFO2dCQUN4RSwyQkFBMkI7Z0JBQzNCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSztnQkFDM0QsV0FBVyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFDL0IsVUFBVSxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSztnQkFDN0IsV0FBVyxFQUFFLFdBQVcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDO2FBQ3RDLENBQUM7WUFFRixNQUFNLFdBQVcsR0FBc0I7Z0JBQ3JDLFNBQVMsRUFBRSxDQUFDO2dCQUNaLGVBQWUsRUFBRSxLQUFLLENBQUMsUUFBUTtnQkFDL0IsZ0JBQWdCLEVBQUUsQ0FBQztnQkFDbkIsaUJBQWlCLEVBQUUsQ0FBQzthQUNyQixDQUFDO1lBRUYsTUFBTSxjQUFjLEdBQXdCLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUMxRCxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQ3RDLENBQUM7WUFFRixnREFBZ0Q7WUFDaEQsTUFBTSxlQUFlLEdBQUcsY0FBYyxFQUFFLE1BQU07Z0JBQzVDLENBQUMsQ0FBQyxjQUFjO2dCQUNoQixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUVsQixpQ0FBaUM7WUFDakMsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDdkMsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7Z0JBQzVELE1BQU0sb0JBQW9CLEdBQ3hCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQztnQkFDL0MsTUFBTSxhQUFhLEdBQ2pCLEtBQUssQ0FBQyxVQUFVLEdBQUcsQ0FBQyxvQkFBb0IsR0FBRyxrQkFBa0IsQ0FBQyxDQUFDO2dCQUNqRSxNQUFNLFNBQVMsR0FDYixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztnQkFDMUQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxhQUFhLEdBQUcsb0JBQW9CLENBQUMsR0FBRyxTQUFTLENBQUM7Z0JBQy9ELE9BQU8sRUFBQyxHQUFHLElBQUksRUFBRSxHQUFHLEVBQUMsQ0FBQztZQUN4QixDQUFDLENBQUMsQ0FBQztZQUVILElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDcEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRWIsR0FBRyxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUMsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQztRQUVGLE9BQU8sS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxFQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFDLFFBQVEsRUFBQyxFQUFFO1lBQ25FLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztZQUMzQyxDQUFDO1lBRUQsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN6QyxNQUFNLElBQUksR0FBRyxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUM7WUFFN0MsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNkLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxFQUFFLEVBQUU7b0JBQ3pDLElBQUksSUFBSSxFQUFFLENBQUM7d0JBQ1QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUNiLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQzt3QkFDbkIsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7d0JBQzNCLE9BQU87b0JBQ1QsQ0FBQztvQkFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNwQixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELE1BQU0sT0FBTyxTQUFTO0lBWXBCLFlBQW1CLEdBQVcsRUFBRSxTQUFpQixFQUFFLFNBQWlCO1FBVDVELFVBQUssR0FBVyxFQUFFLENBQUM7UUFNbkIsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFJdEIsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDZixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztRQUMzQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztJQUM3QixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUs7UUFDaEIsTUFBTSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDLEdBQUcsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFDO0lBQzlCLENBQUM7SUFFTSxLQUFLLENBQUMsWUFBWTtRQUN2QiwwQkFBMEI7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixxQ0FBcUM7WUFDckMsSUFBSSxzQkFBc0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQzVDLE9BQU8sSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUM1QyxNQUFNLHdCQUF3QixHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FDOUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQzdCLENBQUM7Z0JBQ0YsSUFBSSxzQkFBc0IsR0FBRyx3QkFBd0IsRUFBRSxDQUFDO29CQUN0RCxNQUFNO2dCQUNSLENBQUM7Z0JBRUQsc0JBQXNCLElBQUksd0JBQXdCLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixDQUFDO1lBRUQsd0NBQXdDO1lBQ3hDLElBQUksSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUMxQyxNQUFNLElBQUksS0FBSyxDQUNiLGFBQWEsSUFBSSxDQUFDLFNBQVMsOENBQThDLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUM5RixDQUFDO1lBQ0osQ0FBQztZQUVELE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUN6QixJQUFJLENBQUMsR0FBRyxFQUNSLElBQUksQ0FBQyxJQUFJLEVBQ1QsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsV0FBVyxFQUNoQixzQkFBc0IsQ0FDdkIsQ0FBQztZQUNGLE1BQU0sT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYyxDQUFDLENBQUM7WUFFekMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksQ0FDN0IsT0FBTyxFQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEdBQUcsRUFDaEMsSUFBSSxDQUFDLFNBQVMsRUFDZCxDQUFDLENBQ0YsQ0FBQztZQUNGLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixDQUFDO1FBRUQsNEJBQTRCO1FBQzVCLElBQUksS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUU5Qyw2RUFBNkU7UUFDN0UsT0FBTyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ3JDLE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUN6QixJQUFJLENBQUMsR0FBRyxFQUNSLElBQUksQ0FBQyxJQUFJLEVBQ1QsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsV0FBVyxFQUNoQixDQUFDLENBQ0YsQ0FBQztZQUNGLE1BQU0sT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYyxDQUFDLENBQUM7WUFFekMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLFlBQVksQ0FDN0IsT0FBTyxFQUNQLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEdBQUcsRUFDaEMsSUFBSSxDQUFDLFNBQVMsRUFDZCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUN0QixDQUFDO1lBQ0YsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBRW5CLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDNUMsQ0FBQztRQUVELHFEQUFxRDtRQUNyRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUVwQywyQkFBMkI7WUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUVsQyxpREFBaUQ7WUFDakQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztZQUN2RCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVPLDBCQUEwQixDQUFDLElBQVU7UUFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUM7UUFDMUUsTUFBTSxRQUFRLEdBQ1osSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUM7UUFDNUUsT0FBTyxRQUFRLEdBQUcsU0FBUyxDQUFDO0lBQzlCLENBQUM7SUFFTSxXQUFXO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQ3RCLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsRUFDMUQsQ0FBQyxDQUNGLENBQUM7SUFDSixDQUFDO0lBRU8sd0JBQXdCLENBQUMsTUFBYztRQUM3QyxNQUFNLCtCQUErQixHQUFHLElBQUksQ0FBQyxLQUFLO2FBQy9DLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7YUFDOUIsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV6RSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN4QyxDQUFDO1FBRUQsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3pFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWpELE9BQU8sQ0FDTCwrQkFBK0IsR0FBRyx1QkFBdUIsR0FBRyxXQUFXLENBQ3hFLENBQUM7SUFDSixDQUFDO0lBRU0sT0FBTztRQUNaLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFTSxXQUFXO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFTSxZQUFZO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRU0sS0FBSztRQUNWLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkMsSUFBSSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3BCLENBQUM7Q0FDRiJ9
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Segment } from './segment';
|
|
2
|
+
export declare class FrameSampler {
|
|
3
|
+
private segment;
|
|
4
|
+
private sourceFps;
|
|
5
|
+
private targetFps;
|
|
6
|
+
private sum;
|
|
7
|
+
private framesRequested;
|
|
8
|
+
private lastFrame?;
|
|
9
|
+
constructor(segment: Segment, sourceFps: number, targetFps: number, sum?: number);
|
|
10
|
+
getNextFrame(): Promise<VideoFrame | undefined>;
|
|
11
|
+
getLastFrame(): VideoFrame | undefined;
|
|
12
|
+
getSum(): number;
|
|
13
|
+
getSegment(): Segment;
|
|
14
|
+
getTime(framesToSubtract: number): number;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=sampler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sampler.d.ts","sourceRoot":"","sources":["../../../../src/lib/utils/video/parser/sampler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAElC,qBAAa,YAAY;IAKrB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,GAAG;IAPb,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,SAAS,CAAC,CAAa;gBAGrB,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAU;IAGZ,YAAY;IA2ClB,YAAY;IAIZ,MAAM;IAIN,UAAU;IAIV,OAAO,CAAC,gBAAgB,EAAE,MAAM;CAGxC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export class FrameSampler {
|
|
2
|
+
constructor(segment, sourceFps, targetFps, sum = 0) {
|
|
3
|
+
this.segment = segment;
|
|
4
|
+
this.sourceFps = sourceFps;
|
|
5
|
+
this.targetFps = targetFps;
|
|
6
|
+
this.sum = sum;
|
|
7
|
+
this.framesRequested = 0;
|
|
8
|
+
}
|
|
9
|
+
async getNextFrame() {
|
|
10
|
+
const samplingRate = this.sourceFps / this.targetFps;
|
|
11
|
+
this.sum += samplingRate;
|
|
12
|
+
this.framesRequested += 1;
|
|
13
|
+
// Return last frame if we haven't progressed enough to get a new frame.
|
|
14
|
+
if (this.sum < 1 && this.lastFrame) {
|
|
15
|
+
return this.lastFrame;
|
|
16
|
+
}
|
|
17
|
+
// Burn frames if we have too many.
|
|
18
|
+
while (this.sum >= 2) {
|
|
19
|
+
// Burn frame
|
|
20
|
+
const frame = await this.segment.getNextFrame();
|
|
21
|
+
// If there are no more frames, return
|
|
22
|
+
if (!frame) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
frame.close();
|
|
26
|
+
this.sum -= 1;
|
|
27
|
+
}
|
|
28
|
+
// Get a new frame.
|
|
29
|
+
if (this.sum >= 1 || !this.lastFrame) {
|
|
30
|
+
this.sum -= 1;
|
|
31
|
+
const frame = await this.segment.getNextFrame();
|
|
32
|
+
// If there are no more frames, return
|
|
33
|
+
if (!frame) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.lastFrame?.close();
|
|
37
|
+
this.lastFrame = frame;
|
|
38
|
+
return frame;
|
|
39
|
+
}
|
|
40
|
+
// One of the three if statements above is always true.
|
|
41
|
+
throw new Error('Unreachable code');
|
|
42
|
+
}
|
|
43
|
+
getLastFrame() {
|
|
44
|
+
return this.lastFrame;
|
|
45
|
+
}
|
|
46
|
+
getSum() {
|
|
47
|
+
return this.sum;
|
|
48
|
+
}
|
|
49
|
+
getSegment() {
|
|
50
|
+
return this.segment;
|
|
51
|
+
}
|
|
52
|
+
getTime(framesToSubtract) {
|
|
53
|
+
return (this.framesRequested - framesToSubtract) / this.targetFps;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FtcGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvdXRpbHMvdmlkZW8vcGFyc2VyL3NhbXBsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLFlBQVk7SUFJdkIsWUFDVSxPQUFnQixFQUNoQixTQUFpQixFQUNqQixTQUFpQixFQUNqQixNQUFjLENBQUM7UUFIZixZQUFPLEdBQVAsT0FBTyxDQUFTO1FBQ2hCLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFDakIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUNqQixRQUFHLEdBQUgsR0FBRyxDQUFZO1FBUGpCLG9CQUFlLEdBQUcsQ0FBQyxDQUFDO0lBUXpCLENBQUM7SUFFRyxLQUFLLENBQUMsWUFBWTtRQUN2QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDckQsSUFBSSxDQUFDLEdBQUcsSUFBSSxZQUFZLENBQUM7UUFDekIsSUFBSSxDQUFDLGVBQWUsSUFBSSxDQUFDLENBQUM7UUFFMUIsd0VBQXdFO1FBQ3hFLElBQUksSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25DLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUN4QixDQUFDO1FBRUQsbUNBQW1DO1FBQ25DLE9BQU8sSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNyQixhQUFhO1lBQ2IsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRWhELHNDQUFzQztZQUN0QyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ1gsT0FBTztZQUNULENBQUM7WUFFRCxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDZCxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQztRQUNoQixDQUFDO1FBRUQsbUJBQW1CO1FBQ25CLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDZCxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFaEQsc0NBQXNDO1lBQ3RDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7WUFDdkIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsdURBQXVEO1FBQ3ZELE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRU0sWUFBWTtRQUNqQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVNLE1BQU07UUFDWCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDbEIsQ0FBQztJQUVNLFVBQVU7UUFDZixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVNLE9BQU8sQ0FBQyxnQkFBd0I7UUFDckMsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3BFLENBQUM7Q0FDRiJ9
|