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