@lumen5/framefusion 1.0.8 → 1.1.0
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/dist/framefusion.cjs +1 -1
- package/dist/framefusion.cjs.map +1 -1
- package/dist/framefusion.d.ts +2 -1
- package/dist/framefusion.es.js +221 -179
- package/dist/framefusion.es.js.map +1 -1
- package/dist/framefusion.js +2 -1
- package/dist/framefusion.js.map +1 -1
- package/dist/src/DownloadVideoURL.js +4 -3
- package/dist/src/DownloadVideoURL.js.map +1 -1
- package/dist/src/backends/beamcoder.js +9 -6
- package/dist/src/backends/beamcoder.js.map +1 -1
- package/dist/src/cachedVideoDownloader.d.ts +11 -0
- package/dist/src/cachedVideoDownloader.js +54 -0
- package/dist/src/cachedVideoDownloader.js.map +1 -0
- package/package.json +2 -2
package/dist/framefusion.es.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
var
|
|
2
|
-
if (!
|
|
1
|
+
var I = (a, i, t) => {
|
|
2
|
+
if (!i.has(a))
|
|
3
3
|
throw TypeError("Cannot " + t);
|
|
4
4
|
};
|
|
5
|
-
var e = (
|
|
6
|
-
if (
|
|
5
|
+
var e = (a, i, t) => (I(a, i, "read from private field"), t ? t.call(a) : i.get(a)), c = (a, i, t) => {
|
|
6
|
+
if (i.has(a))
|
|
7
7
|
throw TypeError("Cannot add the same private member more than once");
|
|
8
|
-
|
|
9
|
-
},
|
|
10
|
-
set _(
|
|
11
|
-
a
|
|
8
|
+
i instanceof WeakSet ? i.add(a) : i.set(a, t);
|
|
9
|
+
}, o = (a, i, t, s) => (I(a, i, "write to private field"), s ? s.call(a, t) : i.set(a, t), t), v = (a, i, t, s) => ({
|
|
10
|
+
set _(r) {
|
|
11
|
+
o(a, i, r, t);
|
|
12
12
|
},
|
|
13
13
|
get _() {
|
|
14
|
-
return e(
|
|
15
|
-
}
|
|
16
|
-
}),
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
class
|
|
24
|
-
static async create(
|
|
14
|
+
return e(a, i, s);
|
|
15
|
+
}
|
|
16
|
+
}), L = (a, i, t) => (I(a, i, "access private method"), t);
|
|
17
|
+
import b from "@lumen5/beamcoder";
|
|
18
|
+
import H from "path";
|
|
19
|
+
import O from "node:https";
|
|
20
|
+
import z from "http";
|
|
21
|
+
import G from "tmp";
|
|
22
|
+
import X from "fs-extra";
|
|
23
|
+
class K {
|
|
24
|
+
static async create(i) {
|
|
25
25
|
throw new Error("Not implemented");
|
|
26
26
|
}
|
|
27
27
|
async init({
|
|
28
|
-
inputFileOrUrl:
|
|
28
|
+
inputFileOrUrl: i,
|
|
29
29
|
outputFile: t,
|
|
30
|
-
threadCount:
|
|
31
|
-
endTime:
|
|
32
|
-
interpolateFps:
|
|
33
|
-
interpolateMode:
|
|
30
|
+
threadCount: s = 8,
|
|
31
|
+
endTime: r,
|
|
32
|
+
interpolateFps: n,
|
|
33
|
+
interpolateMode: h
|
|
34
34
|
}) {
|
|
35
35
|
throw new Error("Not implemented");
|
|
36
36
|
}
|
|
@@ -43,29 +43,29 @@ class G {
|
|
|
43
43
|
get height() {
|
|
44
44
|
throw new Error("Not implemented");
|
|
45
45
|
}
|
|
46
|
-
async seekToPTS(
|
|
46
|
+
async seekToPTS(i) {
|
|
47
47
|
throw new Error("Not implemented");
|
|
48
48
|
}
|
|
49
|
-
async getFrameAtTime(
|
|
49
|
+
async getFrameAtTime(i) {
|
|
50
50
|
throw new Error("Not implemented");
|
|
51
51
|
}
|
|
52
|
-
async getImageDataAtTime(
|
|
52
|
+
async getImageDataAtTime(i) {
|
|
53
53
|
throw new Error("Not implemented");
|
|
54
54
|
}
|
|
55
|
-
async getFrameAtPts(
|
|
55
|
+
async getFrameAtPts(i) {
|
|
56
56
|
throw new Error("Not implemented");
|
|
57
57
|
}
|
|
58
|
-
async seekToTime(
|
|
58
|
+
async seekToTime(i) {
|
|
59
59
|
throw new Error("Not implemented");
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
62
|
* Convert a PTS (based on timebase) to PTS (in seconds)
|
|
63
63
|
*/
|
|
64
|
-
ptsToTime(
|
|
64
|
+
ptsToTime(i) {
|
|
65
65
|
throw new Error("Not implemented");
|
|
66
66
|
}
|
|
67
67
|
async readFrames({
|
|
68
|
-
onFrameAvailable:
|
|
68
|
+
onFrameAvailable: i,
|
|
69
69
|
flush: t = !0
|
|
70
70
|
} = {
|
|
71
71
|
flush: !0,
|
|
@@ -77,136 +77,137 @@ class G {
|
|
|
77
77
|
throw new Error("Not implemented");
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
class
|
|
80
|
+
class Y extends Error {
|
|
81
81
|
}
|
|
82
|
-
var
|
|
83
|
-
class
|
|
84
|
-
constructor(
|
|
82
|
+
var P, N, F, _;
|
|
83
|
+
class q {
|
|
84
|
+
constructor(i) {
|
|
85
|
+
c(this, P, void 0);
|
|
86
|
+
c(this, N, void 0);
|
|
85
87
|
c(this, F, void 0);
|
|
86
|
-
c(this,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
c(this, _, void 0);
|
|
89
|
+
o(this, P, i);
|
|
90
|
+
const t = H.extname(i);
|
|
91
|
+
o(this, _, G.fileSync({ postfix: t })), o(this, F, e(this, _).name);
|
|
90
92
|
}
|
|
91
93
|
/**
|
|
92
94
|
* returns the filepath of the downloaded file. If the file has not been downloaded yet, it will be undefined
|
|
93
95
|
*/
|
|
94
96
|
get filepath() {
|
|
95
|
-
return e(this,
|
|
97
|
+
return e(this, F);
|
|
96
98
|
}
|
|
97
99
|
/**
|
|
98
100
|
* Downloads the file from the given URL. The file will be downloaded to a temporary file.
|
|
99
101
|
*/
|
|
100
102
|
async download() {
|
|
101
|
-
await new Promise((
|
|
102
|
-
const
|
|
103
|
-
a(this, v, O.fileSync({ postfix: o }));
|
|
103
|
+
await new Promise((i, t) => {
|
|
104
|
+
const s = e(this, P);
|
|
104
105
|
try {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
if (!
|
|
109
|
-
const
|
|
110
|
-
t(
|
|
106
|
+
const r = s.startsWith("https://") ? O : z;
|
|
107
|
+
o(this, N, r.get(s, (n) => {
|
|
108
|
+
const h = n.headers["content-type"];
|
|
109
|
+
if (!h.includes("video")) {
|
|
110
|
+
const m = new Error(`Source ${s}, returned unsupported content type ${h}`);
|
|
111
|
+
t(m);
|
|
111
112
|
return;
|
|
112
113
|
}
|
|
113
|
-
const
|
|
114
|
-
n.pipe(
|
|
115
|
-
|
|
116
|
-
}),
|
|
117
|
-
t(
|
|
114
|
+
const u = X.createWriteStream(e(this, _).name);
|
|
115
|
+
n.pipe(u), u.on("finish", () => {
|
|
116
|
+
u.close(), o(this, F, e(this, _).name), i();
|
|
117
|
+
}), u.on("error", (m) => {
|
|
118
|
+
t(m);
|
|
118
119
|
});
|
|
119
|
-
})), e(this,
|
|
120
|
-
n instanceof
|
|
120
|
+
})), e(this, N).on("error", (n) => {
|
|
121
|
+
n instanceof Y || t(n);
|
|
121
122
|
});
|
|
122
|
-
} catch (
|
|
123
|
-
t(
|
|
123
|
+
} catch (r) {
|
|
124
|
+
t(r);
|
|
124
125
|
}
|
|
125
126
|
});
|
|
126
127
|
}
|
|
127
128
|
clear() {
|
|
128
|
-
e(this,
|
|
129
|
+
e(this, _) && e(this, _).removeCallback(), e(this, P) && o(this, P, void 0), e(this, N) && o(this, N, null), e(this, F) && o(this, F, void 0);
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
demuxer:
|
|
134
|
-
streamIndex:
|
|
132
|
+
P = new WeakMap(), N = new WeakMap(), F = new WeakMap(), _ = new WeakMap();
|
|
133
|
+
const M = 4, Z = ({
|
|
134
|
+
demuxer: a,
|
|
135
|
+
streamIndex: i,
|
|
135
136
|
threadCount: t
|
|
136
137
|
}) => {
|
|
137
|
-
const
|
|
138
|
-
width:
|
|
139
|
-
height:
|
|
140
|
-
pix_fmt:
|
|
138
|
+
const s = {
|
|
139
|
+
width: a.streams[i].codecpar.width,
|
|
140
|
+
height: a.streams[i].codecpar.height,
|
|
141
|
+
pix_fmt: a.streams[i].codecpar.format,
|
|
141
142
|
thread_count: t
|
|
142
143
|
};
|
|
143
|
-
return
|
|
144
|
-
...
|
|
144
|
+
return a.streams[i].codecpar.name === "vp8" ? b.decoder({
|
|
145
|
+
...s,
|
|
145
146
|
name: "libvpx"
|
|
146
|
-
}) :
|
|
147
|
-
...
|
|
147
|
+
}) : a.streams[i].codecpar.name === "vp9" ? b.decoder({
|
|
148
|
+
...s,
|
|
148
149
|
name: "libvpx-vp9"
|
|
149
|
-
}) :
|
|
150
|
-
...
|
|
151
|
-
demuxer:
|
|
152
|
-
stream_index:
|
|
150
|
+
}) : b.decoder({
|
|
151
|
+
...s,
|
|
152
|
+
demuxer: a,
|
|
153
|
+
stream_index: i
|
|
153
154
|
});
|
|
154
|
-
},
|
|
155
|
-
stream:
|
|
156
|
-
outputPixelFormat:
|
|
155
|
+
}, J = async ({
|
|
156
|
+
stream: a,
|
|
157
|
+
outputPixelFormat: i,
|
|
157
158
|
interpolateFps: t,
|
|
158
|
-
interpolateMode:
|
|
159
|
+
interpolateMode: s = "fast"
|
|
159
160
|
}) => {
|
|
160
|
-
if (!
|
|
161
|
+
if (!a.codecpar.format)
|
|
161
162
|
return null;
|
|
162
|
-
let
|
|
163
|
+
let r = [`[in0:v]format=${a.codecpar.format}`];
|
|
163
164
|
if (t)
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
else if (
|
|
167
|
-
|
|
165
|
+
if (s === "high-quality")
|
|
166
|
+
r = [...r, `minterpolate=fps=${t}`];
|
|
167
|
+
else if (s === "fast")
|
|
168
|
+
r = [...r, `fps=${t}`];
|
|
168
169
|
else
|
|
169
|
-
throw new Error(`Unexpected interpolation mode: ${
|
|
170
|
-
const
|
|
171
|
-
return
|
|
170
|
+
throw new Error(`Unexpected interpolation mode: ${s}`);
|
|
171
|
+
const n = r.join(", ") + "[out0:v]";
|
|
172
|
+
return b.filterer({
|
|
172
173
|
filterType: "video",
|
|
173
174
|
inputParams: [
|
|
174
175
|
{
|
|
175
176
|
name: "in0:v",
|
|
176
|
-
width:
|
|
177
|
-
height:
|
|
178
|
-
pixelFormat:
|
|
179
|
-
timeBase:
|
|
180
|
-
pixelAspect:
|
|
177
|
+
width: a.codecpar.width,
|
|
178
|
+
height: a.codecpar.height,
|
|
179
|
+
pixelFormat: a.codecpar.format,
|
|
180
|
+
timeBase: a.time_base,
|
|
181
|
+
pixelAspect: a.sample_aspect_ratio
|
|
181
182
|
}
|
|
182
183
|
],
|
|
183
184
|
outputParams: [
|
|
184
185
|
{
|
|
185
186
|
name: "out0:v",
|
|
186
|
-
pixelFormat:
|
|
187
|
+
pixelFormat: i
|
|
187
188
|
}
|
|
188
189
|
],
|
|
189
|
-
filterSpec:
|
|
190
|
+
filterSpec: n
|
|
190
191
|
});
|
|
191
|
-
},
|
|
192
|
-
var
|
|
193
|
-
const $ = class extends
|
|
192
|
+
}, V = "video", Q = "rgba", U = 5;
|
|
193
|
+
var l, d, C, w, y, E, T, R, p, x, k, S, B;
|
|
194
|
+
const $ = class extends K {
|
|
194
195
|
constructor() {
|
|
195
196
|
super(...arguments);
|
|
196
|
-
c(this,
|
|
197
|
+
c(this, S);
|
|
197
198
|
/**
|
|
198
199
|
* The demuxer reads the file and outputs packet streams
|
|
199
200
|
*/
|
|
200
|
-
c(this,
|
|
201
|
+
c(this, l, null);
|
|
201
202
|
/**
|
|
202
203
|
* The decoder reads packets and can output raw frame data
|
|
203
204
|
*/
|
|
204
|
-
c(this,
|
|
205
|
+
c(this, d, null);
|
|
205
206
|
/**
|
|
206
207
|
* Packets can be filtered to change colorspace, fps and add various effects. If there are no colorspace changes or
|
|
207
208
|
* filters, filter might not be necessary.
|
|
208
209
|
*/
|
|
209
|
-
c(this,
|
|
210
|
+
c(this, C, null);
|
|
210
211
|
/**
|
|
211
212
|
* This is where we store filtered frames from each previously processed packet.
|
|
212
213
|
* We keep these in chronological order. We hang on to them for two reasons:
|
|
@@ -219,7 +220,7 @@ const $ = class extends G {
|
|
|
219
220
|
* This contains the last raw frames we read from the demuxer. We use it as a starting point for each new query. We
|
|
220
221
|
* do this ensure we don't skip any frames.
|
|
221
222
|
*/
|
|
222
|
-
c(this,
|
|
223
|
+
c(this, y, []);
|
|
223
224
|
/**
|
|
224
225
|
* This contains the last packet we read from the demuxer. We use it as a starting point for each new query. We do
|
|
225
226
|
* this ensure we don't skip any frames.
|
|
@@ -229,7 +230,7 @@ const $ = class extends G {
|
|
|
229
230
|
* The last target presentation timestamp (PTS) we requested. If we never requested a time(stamp) then this
|
|
230
231
|
* value is null
|
|
231
232
|
*/
|
|
232
|
-
c(this,
|
|
233
|
+
c(this, T, null);
|
|
233
234
|
/**
|
|
234
235
|
* The number of threads to use for decoding
|
|
235
236
|
*/
|
|
@@ -237,12 +238,12 @@ const $ = class extends G {
|
|
|
237
238
|
/**
|
|
238
239
|
* The index of the video stream in the demuxer
|
|
239
240
|
*/
|
|
240
|
-
c(this,
|
|
241
|
+
c(this, p, 0);
|
|
241
242
|
/**
|
|
242
243
|
* The number of packets we've read from the demuxer to complete the frame query
|
|
243
244
|
* @private
|
|
244
245
|
*/
|
|
245
|
-
c(this,
|
|
246
|
+
c(this, x, 0);
|
|
246
247
|
/**
|
|
247
248
|
* The number of times we've recursively read packets from the demuxer to complete the frame query
|
|
248
249
|
* @private
|
|
@@ -254,82 +255,82 @@ const $ = class extends G {
|
|
|
254
255
|
* Use and await this method to generate an extractor.
|
|
255
256
|
*/
|
|
256
257
|
static async create(t) {
|
|
257
|
-
const
|
|
258
|
-
return await
|
|
258
|
+
const s = new $();
|
|
259
|
+
return await s.init(t), s;
|
|
259
260
|
}
|
|
260
261
|
async init({
|
|
261
262
|
inputFileOrUrl: t,
|
|
262
|
-
threadCount:
|
|
263
|
+
threadCount: s = 8
|
|
263
264
|
}) {
|
|
264
|
-
if (
|
|
265
|
-
const
|
|
266
|
-
await
|
|
265
|
+
if (o(this, R, s), t.startsWith("http")) {
|
|
266
|
+
const r = new q(t);
|
|
267
|
+
await r.download(), t = r.filepath;
|
|
267
268
|
}
|
|
268
|
-
if (t.startsWith("file:") || (t = "file:" + t),
|
|
269
|
-
throw new Error(`File has no ${
|
|
270
|
-
|
|
271
|
-
stream: e(this,
|
|
272
|
-
outputPixelFormat:
|
|
269
|
+
if (t.startsWith("file:") || (t = "file:" + t), o(this, l, await b.demuxer(t)), o(this, p, e(this, l).streams.findIndex((r) => r.codecpar.codec_type === V)), e(this, p) === -1)
|
|
270
|
+
throw new Error(`File has no ${V} stream!`);
|
|
271
|
+
o(this, C, await J({
|
|
272
|
+
stream: e(this, l).streams[e(this, p)],
|
|
273
|
+
outputPixelFormat: Q
|
|
273
274
|
}));
|
|
274
275
|
}
|
|
275
276
|
/**
|
|
276
277
|
* This is the duration of the first video stream in the file expressed in seconds.
|
|
277
278
|
*/
|
|
278
279
|
get duration() {
|
|
279
|
-
const t = e(this,
|
|
280
|
-
return t.duration !== null ? this.ptsToTime(t.duration) : this.ptsToTime(e(this,
|
|
280
|
+
const t = e(this, l).streams[e(this, p)];
|
|
281
|
+
return t.duration !== null ? this.ptsToTime(t.duration) : this.ptsToTime(e(this, l).duration) / 1e3;
|
|
281
282
|
}
|
|
282
283
|
/**
|
|
283
284
|
* Width in pixels
|
|
284
285
|
*/
|
|
285
286
|
get width() {
|
|
286
|
-
return e(this,
|
|
287
|
+
return e(this, l).streams[e(this, p)].codecpar.width;
|
|
287
288
|
}
|
|
288
289
|
/**
|
|
289
290
|
* Height in pixels
|
|
290
291
|
*/
|
|
291
292
|
get height() {
|
|
292
|
-
return e(this,
|
|
293
|
+
return e(this, l).streams[e(this, p)].codecpar.height;
|
|
293
294
|
}
|
|
294
295
|
/**
|
|
295
296
|
* Get the beamcoder Frame for a given time in seconds
|
|
296
297
|
* @param targetTime
|
|
297
298
|
*/
|
|
298
299
|
async getFrameAtTime(t) {
|
|
299
|
-
const
|
|
300
|
-
return this._getFrameAtPts(
|
|
300
|
+
const s = Math.round(this._timeToPTS(t));
|
|
301
|
+
return this._getFrameAtPts(s);
|
|
301
302
|
}
|
|
302
303
|
/**
|
|
303
304
|
* Get imageData for a given time in seconds
|
|
304
305
|
* @param targetTime
|
|
305
306
|
*/
|
|
306
|
-
async getImageDataAtTime(t,
|
|
307
|
-
const
|
|
308
|
-
if (!
|
|
307
|
+
async getImageDataAtTime(t, s) {
|
|
308
|
+
const r = Math.round(this._timeToPTS(t)), n = await this._getFrameAtPts(r);
|
|
309
|
+
if (!n)
|
|
309
310
|
return null;
|
|
310
|
-
let
|
|
311
|
-
return
|
|
312
|
-
data:
|
|
313
|
-
width:
|
|
314
|
-
height:
|
|
311
|
+
let h = s;
|
|
312
|
+
return s || (h = new Uint8ClampedArray(n.width * n.height * M)), this._setFrameDataToImageData(n, h), {
|
|
313
|
+
data: h,
|
|
314
|
+
width: n.width,
|
|
315
|
+
height: n.height
|
|
315
316
|
};
|
|
316
317
|
}
|
|
317
318
|
/**
|
|
318
319
|
* Get the presentation timestamp (PTS) for a given time in seconds
|
|
319
320
|
*/
|
|
320
321
|
_timeToPTS(t) {
|
|
321
|
-
const
|
|
322
|
-
return t *
|
|
322
|
+
const s = e(this, l).streams[e(this, p)].time_base;
|
|
323
|
+
return t * s[1] / s[0];
|
|
323
324
|
}
|
|
324
325
|
/**
|
|
325
326
|
* Get the time in seconds from a given presentation timestamp (PTS)
|
|
326
327
|
*/
|
|
327
328
|
ptsToTime(t) {
|
|
328
|
-
const
|
|
329
|
-
return t *
|
|
329
|
+
const s = e(this, l).streams[e(this, p)].time_base;
|
|
330
|
+
return t * s[0] / s[1];
|
|
330
331
|
}
|
|
331
332
|
get packetReadCount() {
|
|
332
|
-
return e(this,
|
|
333
|
+
return e(this, x);
|
|
333
334
|
}
|
|
334
335
|
/**
|
|
335
336
|
* Get the frame at the given presentation timestamp (PTS)
|
|
@@ -338,44 +339,44 @@ const $ = class extends G {
|
|
|
338
339
|
* the targetPTS. We use it to further move away from the requested PTS to find a frame. The allows use to read
|
|
339
340
|
* additional packets and find a frame that is closer to the targetPTS.
|
|
340
341
|
*/
|
|
341
|
-
async _getFrameAtPts(t,
|
|
342
|
-
|
|
343
|
-
const
|
|
344
|
-
(e(this,
|
|
342
|
+
async _getFrameAtPts(t, s = 0) {
|
|
343
|
+
o(this, x, 0);
|
|
344
|
+
const r = 3, n = e(this, w).flat().some((g) => this.ptsToTime(Math.abs(t - g.pts)) < r);
|
|
345
|
+
(e(this, T) === null || e(this, T) > t || !n) && (await e(this, l).seek({
|
|
345
346
|
stream_index: 0,
|
|
346
347
|
// even though we specify the stream index, it still seeks all streams
|
|
347
|
-
timestamp: t +
|
|
348
|
+
timestamp: t + s,
|
|
348
349
|
any: !1
|
|
349
|
-
}), await
|
|
350
|
-
let
|
|
350
|
+
}), await L(this, S, B).call(this), o(this, E, null), o(this, y, []), o(this, T, t), o(this, w, []));
|
|
351
|
+
let h = null, u = -1, m = null;
|
|
351
352
|
if (e(this, w).length > 0) {
|
|
352
|
-
const
|
|
353
|
-
if (
|
|
354
|
-
const f = e(this, w).flat().find((
|
|
355
|
-
if (
|
|
356
|
-
return
|
|
353
|
+
const g = e(this, w).flat().find((f) => f.pts <= t);
|
|
354
|
+
if (g) {
|
|
355
|
+
const f = e(this, w).flat().find((D) => D.pts > g.pts);
|
|
356
|
+
if (u = g.pts, m = g, f && f.pts > t || u === t)
|
|
357
|
+
return o(this, T, t), m;
|
|
357
358
|
}
|
|
358
359
|
}
|
|
359
|
-
for (!e(this, E) && e(this,
|
|
360
|
-
if (e(this,
|
|
361
|
-
|
|
362
|
-
const f =
|
|
360
|
+
for (!e(this, E) && e(this, y).length === 0 && ({ packet: v(this, E)._, frames: v(this, y)._ } = await this._getNextPacketAndDecodeFrames(), v(this, x)._++); (e(this, E) || e(this, y).length !== 0) && u < t; ) {
|
|
361
|
+
if (e(this, y).length !== 0) {
|
|
362
|
+
h = (await e(this, C).filter([{ name: "in0:v", frames: e(this, y) }])).flatMap((D) => D.frames);
|
|
363
|
+
const f = e(this, x) === 1 && h[0].pts > t ? h[0] : h.reverse().find((D) => D.pts <= t);
|
|
363
364
|
if (!f)
|
|
364
|
-
return
|
|
365
|
-
if (e(this, w).unshift(
|
|
366
|
-
|
|
365
|
+
return m;
|
|
366
|
+
if (e(this, w).unshift(h), e(this, w).length > 2 && e(this, w).pop(), u = f == null ? void 0 : f.pts, !m || u <= t)
|
|
367
|
+
o(this, T, t), m = f;
|
|
367
368
|
else
|
|
368
369
|
break;
|
|
369
370
|
}
|
|
370
|
-
({ packet:
|
|
371
|
+
({ packet: v(this, E)._, frames: v(this, y)._ } = await this._getNextPacketAndDecodeFrames()), v(this, x)._++;
|
|
371
372
|
}
|
|
372
|
-
if (!
|
|
373
|
-
if (
|
|
373
|
+
if (!m) {
|
|
374
|
+
if (U < e(this, k))
|
|
374
375
|
throw Error("No matching frame found");
|
|
375
|
-
const
|
|
376
|
-
|
|
376
|
+
const g = 0.1, f = this._timeToPTS(g);
|
|
377
|
+
v(this, k)._++, m = await this._getFrameAtPts(t, s - f), m && o(this, k, 0);
|
|
377
378
|
}
|
|
378
|
-
return
|
|
379
|
+
return m;
|
|
379
380
|
}
|
|
380
381
|
/**
|
|
381
382
|
* Get the next packet from the video stream and decode it into frames. Each frame has a presentation time stamp
|
|
@@ -384,38 +385,79 @@ const $ = class extends G {
|
|
|
384
385
|
*/
|
|
385
386
|
async _getNextPacketAndDecodeFrames() {
|
|
386
387
|
const t = await this._getNextVideoStreamPacket();
|
|
387
|
-
let
|
|
388
|
-
t !== null && e(this,
|
|
389
|
-
let
|
|
390
|
-
return
|
|
388
|
+
let s = null;
|
|
389
|
+
t !== null && e(this, d) ? s = await e(this, d).decode(t) : e(this, d) && (s = await e(this, d).flush(), o(this, d, null));
|
|
390
|
+
let r = [];
|
|
391
|
+
return s && s.frames.length !== 0 && (r = s.frames), { packet: t, frames: r };
|
|
391
392
|
}
|
|
392
393
|
async _getNextVideoStreamPacket() {
|
|
393
|
-
let t = await e(this,
|
|
394
|
-
for (; t && t.stream_index !== e(this,
|
|
395
|
-
if (t = await e(this,
|
|
394
|
+
let t = await e(this, l).read();
|
|
395
|
+
for (; t && t.stream_index !== e(this, p); )
|
|
396
|
+
if (t = await e(this, l).read(), t === null)
|
|
396
397
|
return null;
|
|
397
398
|
return t;
|
|
398
399
|
}
|
|
399
|
-
_setFrameDataToImageData(t,
|
|
400
|
-
const
|
|
401
|
-
for (let
|
|
402
|
-
const
|
|
403
|
-
|
|
400
|
+
_setFrameDataToImageData(t, s) {
|
|
401
|
+
const r = t.linesize, n = t.data[0];
|
|
402
|
+
for (let h = 0; h < t.height; h++) {
|
|
403
|
+
const u = h * r, m = u + t.width * M, g = n.subarray(u, m), f = h * t.width * M;
|
|
404
|
+
s.set(g, f);
|
|
404
405
|
}
|
|
405
406
|
}
|
|
406
407
|
async dispose() {
|
|
407
|
-
e(this,
|
|
408
|
+
e(this, d) && (await e(this, d).flush(), o(this, d, null)), e(this, l).forceClose(), o(this, C, null), o(this, w, void 0), o(this, y, []), o(this, E, null), o(this, T, null), o(this, p, 0);
|
|
408
409
|
}
|
|
409
410
|
};
|
|
410
411
|
let W = $;
|
|
411
|
-
|
|
412
|
-
e(this,
|
|
413
|
-
demuxer: e(this,
|
|
414
|
-
streamIndex: e(this,
|
|
412
|
+
l = new WeakMap(), d = new WeakMap(), C = new WeakMap(), w = new WeakMap(), y = new WeakMap(), E = new WeakMap(), T = new WeakMap(), R = new WeakMap(), p = new WeakMap(), x = new WeakMap(), k = new WeakMap(), S = new WeakSet(), B = async function() {
|
|
413
|
+
e(this, d) && (await e(this, d).flush(), o(this, d, null)), o(this, d, Z({
|
|
414
|
+
demuxer: e(this, l),
|
|
415
|
+
streamIndex: e(this, p),
|
|
415
416
|
threadCount: e(this, R)
|
|
416
417
|
}));
|
|
417
418
|
};
|
|
419
|
+
var A;
|
|
420
|
+
class ot {
|
|
421
|
+
constructor() {
|
|
422
|
+
c(this, A, /* @__PURE__ */ new Map());
|
|
423
|
+
}
|
|
424
|
+
get(i) {
|
|
425
|
+
const t = this;
|
|
426
|
+
let s;
|
|
427
|
+
return {
|
|
428
|
+
url: i,
|
|
429
|
+
get filepath() {
|
|
430
|
+
return s;
|
|
431
|
+
},
|
|
432
|
+
async download() {
|
|
433
|
+
let r = e(t, A).get(i);
|
|
434
|
+
if (r)
|
|
435
|
+
r.refCount += 1, r.downloadPromise && await r.downloadPromise;
|
|
436
|
+
else {
|
|
437
|
+
const n = new q(i), h = n.download();
|
|
438
|
+
r = {
|
|
439
|
+
downloader: n,
|
|
440
|
+
refCount: 1,
|
|
441
|
+
downloadPromise: h
|
|
442
|
+
}, e(t, A).set(i, r);
|
|
443
|
+
try {
|
|
444
|
+
await h;
|
|
445
|
+
} finally {
|
|
446
|
+
r.downloadPromise = void 0;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
s = e(t, A).get(i).downloader.filepath;
|
|
450
|
+
},
|
|
451
|
+
destroy() {
|
|
452
|
+
const r = e(t, A).get(i);
|
|
453
|
+
r && (r.refCount -= 1, r.refCount <= 0 && (r.downloader.clear(), e(t, A).delete(i)), s = void 0);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
A = new WeakMap();
|
|
418
459
|
export {
|
|
419
|
-
W as BeamcoderExtractor
|
|
460
|
+
W as BeamcoderExtractor,
|
|
461
|
+
ot as CachedVideoDownloader
|
|
420
462
|
};
|
|
421
463
|
//# sourceMappingURL=framefusion.es.js.map
|