@editframe/assets 0.20.4-beta.0 → 0.23.6-beta.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/Probe.d.ts +1 -1
- package/dist/Probe.js +16 -24
- package/dist/VideoRenderOptions.d.ts +3 -0
- package/dist/VideoRenderOptions.js +1 -0
- package/dist/generateFragmentIndex.js +20 -42
- package/dist/generateSingleTrack.js +3 -4
- package/dist/idempotentTask.js +2 -2
- package/dist/md5.js +1 -2
- package/dist/tasks/cacheImage.js +1 -1
- package/dist/tasks/findOrCreateCaptions.js +3 -3
- package/dist/tasks/generateTrack.js +2 -4
- package/dist/tasks/generateTrackFragmentIndex.js +2 -4
- package/package.json +2 -1
- package/types.json +1 -1
package/dist/Probe.d.ts
CHANGED
|
@@ -1149,7 +1149,7 @@ declare abstract class ProbeBase {
|
|
|
1149
1149
|
get ffmpegAudioOutputOptions(): string[];
|
|
1150
1150
|
get ffmpegVideoOutputOptions(): string[];
|
|
1151
1151
|
protected constructor(absolutePath: string);
|
|
1152
|
-
createConformingReadstream(): Readable;
|
|
1152
|
+
createConformingReadstream(): Readable | import('fs').ReadStream;
|
|
1153
1153
|
createTrackReadstream(trackIndex: number): Readable;
|
|
1154
1154
|
}
|
|
1155
1155
|
export declare class Probe extends ProbeBase {
|
package/dist/Probe.js
CHANGED
|
@@ -4,8 +4,8 @@ import { promisify } from "node:util";
|
|
|
4
4
|
import { createReadStream } from "node:fs";
|
|
5
5
|
import * as z$1 from "zod";
|
|
6
6
|
import debug from "debug";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
var execPromise = promisify(exec);
|
|
8
|
+
var log = debug("ef:assets:probe");
|
|
9
9
|
const AudioStreamSchema = z$1.object({
|
|
10
10
|
index: z$1.number(),
|
|
11
11
|
codec_name: z$1.string(),
|
|
@@ -52,7 +52,7 @@ const VideoStreamSchema = z$1.object({
|
|
|
52
52
|
bit_rate: z$1.string().optional(),
|
|
53
53
|
disposition: z$1.record(z$1.unknown())
|
|
54
54
|
});
|
|
55
|
-
|
|
55
|
+
var ProbeFormatSchema = z$1.object({
|
|
56
56
|
filename: z$1.string(),
|
|
57
57
|
nb_streams: z$1.number(),
|
|
58
58
|
nb_programs: z$1.number(),
|
|
@@ -71,12 +71,12 @@ const DataStreamSchema = z$1.object({
|
|
|
71
71
|
duration_ts: z$1.number().optional(),
|
|
72
72
|
start_pts: z$1.number().optional()
|
|
73
73
|
});
|
|
74
|
-
|
|
74
|
+
var StreamSchema = z$1.discriminatedUnion("codec_type", [
|
|
75
75
|
AudioStreamSchema,
|
|
76
76
|
VideoStreamSchema,
|
|
77
77
|
DataStreamSchema
|
|
78
78
|
]);
|
|
79
|
-
|
|
79
|
+
var PacketSchema = z$1.object({
|
|
80
80
|
stream_index: z$1.number(),
|
|
81
81
|
pts: z$1.number(),
|
|
82
82
|
pts_time: z$1.coerce.number(),
|
|
@@ -86,18 +86,17 @@ const PacketSchema = z$1.object({
|
|
|
86
86
|
pos: z$1.coerce.number().optional(),
|
|
87
87
|
flags: z$1.string().optional()
|
|
88
88
|
});
|
|
89
|
-
|
|
89
|
+
var ProbeSchema = z$1.object({
|
|
90
90
|
streams: z$1.array(StreamSchema),
|
|
91
91
|
format: ProbeFormatSchema
|
|
92
92
|
});
|
|
93
|
-
|
|
93
|
+
var PacketProbeSchema = z$1.object({
|
|
94
94
|
packets: z$1.array(PacketSchema),
|
|
95
95
|
format: ProbeFormatSchema,
|
|
96
96
|
streams: z$1.array(StreamSchema)
|
|
97
97
|
});
|
|
98
|
-
|
|
98
|
+
var buildProbeArgs = (options) => {
|
|
99
99
|
const streamEntries = "stream=index,codec_name,codec_long_name,codec_type,codec_tag_string,codec_tag,profile,level,width,height,coded_width,coded_height,r_frame_rate,avg_frame_rate,time_base,start_pts,start_time,duration_ts,duration,bit_rate,sample_fmt,sample_rate,channels,channel_layout,bits_per_sample,initial_padding,disposition";
|
|
100
|
-
const packetEntries = "packet=stream_index,pts,pts_time,dts,dts_time,duration,pos,flags";
|
|
101
100
|
return [
|
|
102
101
|
"-v",
|
|
103
102
|
"error",
|
|
@@ -105,7 +104,7 @@ const buildProbeArgs = (options) => {
|
|
|
105
104
|
"-show_streams",
|
|
106
105
|
"-of",
|
|
107
106
|
"json",
|
|
108
|
-
...options.showPackets ? ["-show_entries", `${streamEntries}
|
|
107
|
+
...options.showPackets ? ["-show_entries", `${streamEntries}:packet=stream_index,pts,pts_time,dts,dts_time,duration,pos,flags`] : ["-show_entries", streamEntries]
|
|
109
108
|
];
|
|
110
109
|
};
|
|
111
110
|
var FFProbeRunner = class {
|
|
@@ -149,7 +148,7 @@ var FFProbeRunner = class {
|
|
|
149
148
|
});
|
|
150
149
|
stream.pipe(probe.stdin);
|
|
151
150
|
try {
|
|
152
|
-
|
|
151
|
+
return await Promise.race([new Promise((resolve, reject) => {
|
|
153
152
|
probe.stdout.on("end", () => {
|
|
154
153
|
try {
|
|
155
154
|
const buffer = Buffer.concat(chunks).toString("utf8");
|
|
@@ -159,7 +158,6 @@ var FFProbeRunner = class {
|
|
|
159
158
|
}
|
|
160
159
|
});
|
|
161
160
|
}), processExit]);
|
|
162
|
-
return json;
|
|
163
161
|
} finally {
|
|
164
162
|
stream.unpipe(probe.stdin);
|
|
165
163
|
probe.stdin.end();
|
|
@@ -375,12 +373,10 @@ var ProbeBase = class {
|
|
|
375
373
|
};
|
|
376
374
|
var Probe = class Probe extends ProbeBase {
|
|
377
375
|
static async probePath(absolutePath) {
|
|
378
|
-
|
|
379
|
-
return new Probe(absolutePath, json);
|
|
376
|
+
return new Probe(absolutePath, await FFProbeRunner.probePath(absolutePath, false));
|
|
380
377
|
}
|
|
381
378
|
static async probeStream(stream) {
|
|
382
|
-
|
|
383
|
-
return new Probe("pipe:0", json);
|
|
379
|
+
return new Probe("pipe:0", await FFProbeRunner.probeStream(stream, false));
|
|
384
380
|
}
|
|
385
381
|
constructor(absolutePath, rawData) {
|
|
386
382
|
super(absolutePath);
|
|
@@ -389,12 +385,10 @@ var Probe = class Probe extends ProbeBase {
|
|
|
389
385
|
};
|
|
390
386
|
var PacketProbe = class PacketProbe extends ProbeBase {
|
|
391
387
|
static async probePath(absolutePath) {
|
|
392
|
-
|
|
393
|
-
return new PacketProbe(absolutePath, json);
|
|
388
|
+
return new PacketProbe(absolutePath, await FFProbeRunner.probePath(absolutePath, true));
|
|
394
389
|
}
|
|
395
390
|
static async probeStream(stream) {
|
|
396
|
-
|
|
397
|
-
return new PacketProbe("pipe:0", json);
|
|
391
|
+
return new PacketProbe("pipe:0", await FFProbeRunner.probeStream(stream, true));
|
|
398
392
|
}
|
|
399
393
|
constructor(absolutePath, rawData) {
|
|
400
394
|
super(absolutePath);
|
|
@@ -412,15 +406,13 @@ var PacketProbe = class PacketProbe extends ProbeBase {
|
|
|
412
406
|
const videoStream = this.videoStreams[0];
|
|
413
407
|
if (!videoStream) return [];
|
|
414
408
|
const videoPackets = this.packets.filter((packet) => packet.stream_index === videoStream.index);
|
|
415
|
-
const
|
|
416
|
-
const [num, den] = frameRate.split("/").map(Number);
|
|
409
|
+
const [num, den] = videoStream.r_frame_rate.split("/").map(Number);
|
|
417
410
|
if (!num || !den) return [];
|
|
418
411
|
const packetDuration = den / num;
|
|
419
412
|
if (videoPackets.length === 0) return [];
|
|
420
413
|
const ptsTimes = videoPackets.map((p) => p.pts_time);
|
|
421
414
|
const minPts = Math.min(...ptsTimes);
|
|
422
|
-
const
|
|
423
|
-
const totalDuration = maxPts - minPts + packetDuration;
|
|
415
|
+
const totalDuration = Math.max(...ptsTimes) - minPts + packetDuration;
|
|
424
416
|
return truncateDecimal(Math.round(totalDuration * 1e4) / 1e4, 5);
|
|
425
417
|
}
|
|
426
418
|
};
|
|
@@ -3,6 +3,7 @@ export declare const VideoRenderOptions: z.ZodObject<{
|
|
|
3
3
|
mode: z.ZodEnum<["canvas", "screenshot"]>;
|
|
4
4
|
strategy: z.ZodEnum<["v1", "v2"]>;
|
|
5
5
|
showFrameBox: z.ZodOptional<z.ZodBoolean>;
|
|
6
|
+
enableTracing: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
6
7
|
encoderOptions: z.ZodObject<{
|
|
7
8
|
sequenceNumber: z.ZodNumber;
|
|
8
9
|
keyframeIntervalMs: z.ZodNumber;
|
|
@@ -155,6 +156,7 @@ export declare const VideoRenderOptions: z.ZodObject<{
|
|
|
155
156
|
};
|
|
156
157
|
fetchHost: string;
|
|
157
158
|
showFrameBox?: boolean | undefined;
|
|
159
|
+
enableTracing?: boolean | undefined;
|
|
158
160
|
}, {
|
|
159
161
|
mode: "canvas" | "screenshot";
|
|
160
162
|
strategy: "v1" | "v2";
|
|
@@ -186,5 +188,6 @@ export declare const VideoRenderOptions: z.ZodObject<{
|
|
|
186
188
|
};
|
|
187
189
|
fetchHost: string;
|
|
188
190
|
showFrameBox?: boolean | undefined;
|
|
191
|
+
enableTracing?: boolean | undefined;
|
|
189
192
|
}>;
|
|
190
193
|
export type VideoRenderOptions = z.infer<typeof VideoRenderOptions>;
|
|
@@ -3,6 +3,7 @@ const VideoRenderOptions = z.object({
|
|
|
3
3
|
mode: z.enum(["canvas", "screenshot"]),
|
|
4
4
|
strategy: z.enum(["v1", "v2"]),
|
|
5
5
|
showFrameBox: z.boolean().optional(),
|
|
6
|
+
enableTracing: z.boolean().default(false).optional(),
|
|
6
7
|
encoderOptions: z.object({
|
|
7
8
|
sequenceNumber: z.number(),
|
|
8
9
|
keyframeIntervalMs: z.number(),
|
|
@@ -2,27 +2,20 @@ import { PacketProbe } from "./Probe.js";
|
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
import { Readable, Transform, Writable } from "node:stream";
|
|
4
4
|
import { pipeline } from "node:stream/promises";
|
|
5
|
-
|
|
5
|
+
var log = debug("ef:generateFragmentIndex");
|
|
6
6
|
function constructH264CodecString(codecTagString, profile, level) {
|
|
7
7
|
if (codecTagString !== "avc1" || !profile || level === void 0) return codecTagString;
|
|
8
|
-
const
|
|
8
|
+
const profileIdc = {
|
|
9
9
|
"Baseline": 66,
|
|
10
10
|
"Main": 77,
|
|
11
11
|
"High": 100,
|
|
12
12
|
"High 10": 110,
|
|
13
13
|
"High 422": 122,
|
|
14
14
|
"High 444": 244
|
|
15
|
-
};
|
|
16
|
-
const profileIdc = profileMap[profile];
|
|
15
|
+
}[profile];
|
|
17
16
|
if (!profileIdc) return codecTagString;
|
|
18
|
-
|
|
19
|
-
const constraintFlags = "00";
|
|
20
|
-
const levelHex = level.toString(16).padStart(2, "0");
|
|
21
|
-
return `${codecTagString}.${profileHex}${constraintFlags}${levelHex}`;
|
|
17
|
+
return `${codecTagString}.${profileIdc.toString(16).padStart(2, "0")}00${level.toString(16).padStart(2, "0")}`;
|
|
22
18
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Streaming MP4 box parser that detects box boundaries without loading entire file into memory
|
|
25
|
-
*/
|
|
26
19
|
var StreamingBoxParser = class extends Transform {
|
|
27
20
|
constructor() {
|
|
28
21
|
super({ objectMode: false });
|
|
@@ -112,12 +105,11 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
112
105
|
const parser = new StreamingBoxParser();
|
|
113
106
|
const chunks = [];
|
|
114
107
|
let totalSize = 0;
|
|
115
|
-
|
|
108
|
+
await pipeline(inputStream, parser, new Writable({ write(chunk, _encoding, callback) {
|
|
116
109
|
chunks.push(chunk);
|
|
117
110
|
totalSize += chunk.length;
|
|
118
111
|
callback();
|
|
119
|
-
} });
|
|
120
|
-
await pipeline(inputStream, parser, dest);
|
|
112
|
+
} }));
|
|
121
113
|
const fragments = parser.getFragments();
|
|
122
114
|
if (totalSize === 0) return {};
|
|
123
115
|
const completeData = Buffer.concat(chunks);
|
|
@@ -140,8 +132,7 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
140
132
|
const fragmentStart = fragment.offset;
|
|
141
133
|
const fragmentEnd = fragment.offset + fragment.size;
|
|
142
134
|
const videoPackets = probe.packets.filter((packet) => {
|
|
143
|
-
|
|
144
|
-
return stream?.codec_type === "video" && packet.pos !== void 0 && packet.pos >= fragmentStart && packet.pos < fragmentEnd;
|
|
135
|
+
return videoStreams.find((s) => s.index === packet.stream_index)?.codec_type === "video" && packet.pos !== void 0 && packet.pos >= fragmentStart && packet.pos < fragmentEnd;
|
|
145
136
|
}).map((packet) => ({
|
|
146
137
|
pts: packet.pts,
|
|
147
138
|
dts: packet.dts,
|
|
@@ -149,8 +140,7 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
149
140
|
isKeyframe: packet.flags?.includes("K") ?? false
|
|
150
141
|
}));
|
|
151
142
|
const audioPackets = probe.packets.filter((packet) => {
|
|
152
|
-
|
|
153
|
-
return stream?.codec_type === "audio" && packet.pos !== void 0 && packet.pos >= fragmentStart && packet.pos < fragmentEnd;
|
|
143
|
+
return audioStreams.find((s) => s.index === packet.stream_index)?.codec_type === "audio" && packet.pos !== void 0 && packet.pos >= fragmentStart && packet.pos < fragmentEnd;
|
|
154
144
|
}).map((packet) => ({
|
|
155
145
|
pts: packet.pts,
|
|
156
146
|
dts: packet.dts,
|
|
@@ -196,20 +186,15 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
196
186
|
const keyframe = videoPackets.find((p) => p.isKeyframe) || firstPacket;
|
|
197
187
|
const segmentCts = Math.round(keyframe.pts * timescale / timebase.den);
|
|
198
188
|
const segmentDts = Math.round(keyframe.dts * timescale / timebase.den);
|
|
199
|
-
const
|
|
200
|
-
const nextKeyframe = nextFragmentData?.videoPackets.find((p) => p.isKeyframe);
|
|
189
|
+
const nextKeyframe = fragmentTimingData[fragmentData.fragmentIndex + 1]?.videoPackets.find((p) => p.isKeyframe);
|
|
201
190
|
let segmentDuration;
|
|
202
|
-
if (nextKeyframe)
|
|
203
|
-
|
|
204
|
-
segmentDuration = nextSegmentCts - segmentCts;
|
|
205
|
-
} else {
|
|
191
|
+
if (nextKeyframe) segmentDuration = Math.round(nextKeyframe.pts * timescale / timebase.den) - segmentCts;
|
|
192
|
+
else {
|
|
206
193
|
const allVideoPackets$1 = probe.packets.filter((p) => {
|
|
207
|
-
|
|
208
|
-
return stream?.codec_type === "video";
|
|
194
|
+
return videoStreams.find((s) => s.index === p.stream_index)?.codec_type === "video";
|
|
209
195
|
}).sort((a, b) => a.pts - b.pts);
|
|
210
196
|
const lastPacket = allVideoPackets$1[allVideoPackets$1.length - 1];
|
|
211
|
-
|
|
212
|
-
segmentDuration = streamEnd - segmentCts;
|
|
197
|
+
segmentDuration = Math.round((lastPacket.pts + (lastPacket.duration || 0)) * timescale / timebase.den) - segmentCts;
|
|
213
198
|
}
|
|
214
199
|
segments.push({
|
|
215
200
|
cts: segmentCts,
|
|
@@ -224,8 +209,7 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
224
209
|
const firstPacket = totalVideoPackets[0];
|
|
225
210
|
const lastPacket = totalVideoPackets[totalVideoPackets.length - 1];
|
|
226
211
|
const firstPts = Math.round(firstPacket.pts * timescale / timebase.den);
|
|
227
|
-
|
|
228
|
-
totalDuration = lastPts - firstPts;
|
|
212
|
+
totalDuration = Math.round(lastPacket.pts * timescale / timebase.den) - firstPts;
|
|
229
213
|
}
|
|
230
214
|
const finalTrackId = trackIdMapping?.[videoStream.index] ?? videoStream.index + 1;
|
|
231
215
|
trackIndexes[finalTrackId] = {
|
|
@@ -247,8 +231,7 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
247
231
|
}
|
|
248
232
|
for (const audioStream of audioStreams) {
|
|
249
233
|
const segments = [];
|
|
250
|
-
const
|
|
251
|
-
const totalSampleCount = totalAudioPackets.length;
|
|
234
|
+
const totalSampleCount = probe.packets.filter((p) => p.stream_index === audioStream.index).length;
|
|
252
235
|
const timebase = probe.audioTimebase;
|
|
253
236
|
if (!timebase) {
|
|
254
237
|
console.warn("No timebase found for audio stream");
|
|
@@ -274,20 +257,15 @@ const generateFragmentIndex = async (inputStream, startTimeOffsetMs, trackIdMapp
|
|
|
274
257
|
const firstPacket = audioPackets[0];
|
|
275
258
|
const segmentCts = Math.round(firstPacket.pts * timescale / timebase.den);
|
|
276
259
|
const segmentDts = Math.round(firstPacket.dts * timescale / timebase.den);
|
|
277
|
-
const
|
|
278
|
-
const nextFirstPacket = nextFragmentData?.audioPackets[0];
|
|
260
|
+
const nextFirstPacket = fragmentTimingData[fragmentData.fragmentIndex + 1]?.audioPackets[0];
|
|
279
261
|
let segmentDuration;
|
|
280
|
-
if (nextFirstPacket)
|
|
281
|
-
|
|
282
|
-
segmentDuration = nextSegmentCts - segmentCts;
|
|
283
|
-
} else {
|
|
262
|
+
if (nextFirstPacket) segmentDuration = Math.round(nextFirstPacket.pts * timescale / timebase.den) - segmentCts;
|
|
263
|
+
else {
|
|
284
264
|
const allAudioPackets$1 = probe.packets.filter((p) => {
|
|
285
|
-
|
|
286
|
-
return stream?.codec_type === "audio";
|
|
265
|
+
return audioStreams.find((s) => s.index === p.stream_index)?.codec_type === "audio";
|
|
287
266
|
}).sort((a, b) => a.pts - b.pts);
|
|
288
267
|
const lastPacket = allAudioPackets$1[allAudioPackets$1.length - 1];
|
|
289
|
-
|
|
290
|
-
segmentDuration = streamEnd - segmentCts;
|
|
268
|
+
segmentDuration = Math.round((lastPacket.pts + (lastPacket.duration || 0)) * timescale / timebase.den) - segmentCts;
|
|
291
269
|
}
|
|
292
270
|
segments.push({
|
|
293
271
|
cts: segmentCts,
|
|
@@ -4,7 +4,7 @@ import { idempotentTask } from "./idempotentTask.js";
|
|
|
4
4
|
import debug from "debug";
|
|
5
5
|
import { PassThrough } from "node:stream";
|
|
6
6
|
import { basename } from "node:path";
|
|
7
|
-
|
|
7
|
+
var log = debug("ef:generateSingleTrack");
|
|
8
8
|
const generateSingleTrackFromPath = async (absolutePath, trackId) => {
|
|
9
9
|
log(`Generating track ${trackId} for ${absolutePath}`);
|
|
10
10
|
const probe = await Probe.probePath(absolutePath);
|
|
@@ -23,8 +23,7 @@ const generateSingleTrackFromPath = async (absolutePath, trackId) => {
|
|
|
23
23
|
outputStream.destroy(error);
|
|
24
24
|
indexStream.destroy(error);
|
|
25
25
|
});
|
|
26
|
-
const
|
|
27
|
-
const fragmentIndexPromise = generateFragmentIndex(indexStream, void 0, trackIdMapping);
|
|
26
|
+
const fragmentIndexPromise = generateFragmentIndex(indexStream, void 0, { 1: trackId });
|
|
28
27
|
fragmentIndexPromise.then(() => {
|
|
29
28
|
if (sourceStreamEnded) outputStream.end();
|
|
30
29
|
else trackStream.once("end", () => {
|
|
@@ -38,7 +37,7 @@ const generateSingleTrackFromPath = async (absolutePath, trackId) => {
|
|
|
38
37
|
fragmentIndex: fragmentIndexPromise
|
|
39
38
|
};
|
|
40
39
|
};
|
|
41
|
-
|
|
40
|
+
idempotentTask({
|
|
42
41
|
label: "track-single",
|
|
43
42
|
filename: (absolutePath, trackId) => `${basename(absolutePath)}.track-${trackId}.mp4`,
|
|
44
43
|
runner: async (absolutePath, trackId) => {
|
package/dist/idempotentTask.js
CHANGED
|
@@ -43,7 +43,7 @@ const idempotentTask = ({ label, filename, runner }) => {
|
|
|
43
43
|
await new Promise((resolve, reject) => {
|
|
44
44
|
readable.on("error", reject);
|
|
45
45
|
writeStream.on("error", reject);
|
|
46
|
-
writeStream.on("finish", resolve);
|
|
46
|
+
writeStream.on("finish", () => resolve());
|
|
47
47
|
});
|
|
48
48
|
const { rename } = await import("node:fs/promises");
|
|
49
49
|
await rename(tempPath, downloadCachePath);
|
|
@@ -91,7 +91,7 @@ const idempotentTask = ({ label, filename, runner }) => {
|
|
|
91
91
|
await new Promise((resolve, reject) => {
|
|
92
92
|
result.on("error", reject);
|
|
93
93
|
writeStream.on("error", reject);
|
|
94
|
-
writeStream.on("finish", resolve);
|
|
94
|
+
writeStream.on("finish", () => resolve());
|
|
95
95
|
});
|
|
96
96
|
const { rename } = await import("node:fs/promises");
|
|
97
97
|
await rename(tempPath, cachePath);
|
package/dist/md5.js
CHANGED
|
@@ -23,8 +23,7 @@ async function md5Directory(directory, spinner) {
|
|
|
23
23
|
return addDashesToUUID(hash.digest("hex"));
|
|
24
24
|
}
|
|
25
25
|
async function md5FilePath(filePath) {
|
|
26
|
-
|
|
27
|
-
return md5ReadStream(readStream);
|
|
26
|
+
return md5ReadStream(createReadStream(filePath));
|
|
28
27
|
}
|
|
29
28
|
function md5ReadStream(readStream) {
|
|
30
29
|
return new Promise((resolve, reject) => {
|
package/dist/tasks/cacheImage.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { idempotentTask } from "../idempotentTask.js";
|
|
2
2
|
import { createReadStream } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
|
|
4
|
+
var cacheImageTask = idempotentTask({
|
|
5
5
|
label: "image",
|
|
6
6
|
filename: (absolutePath) => path.basename(absolutePath),
|
|
7
7
|
runner: async (absolutePath) => {
|
|
@@ -3,15 +3,15 @@ import { exec } from "node:child_process";
|
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
import debug from "debug";
|
|
5
5
|
import { basename } from "node:path";
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
var execPromise = promisify(exec);
|
|
7
|
+
var log = debug("ef:generateCaptions");
|
|
8
8
|
const generateCaptionDataFromPath = async (absolutePath) => {
|
|
9
9
|
const command = `whisper_timestamped --language en --efficient --output_format vtt ${absolutePath}`;
|
|
10
10
|
log(`Running command: ${command}`);
|
|
11
11
|
const { stdout } = await execPromise(command);
|
|
12
12
|
return stdout;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
var generateCaptionDataTask = idempotentTask({
|
|
15
15
|
label: "captions",
|
|
16
16
|
filename: (absolutePath) => `${basename(absolutePath)}.captions.json`,
|
|
17
17
|
runner: generateCaptionDataFromPath
|
|
@@ -3,10 +3,8 @@ import { generateSingleTrackFromPath } from "../generateSingleTrack.js";
|
|
|
3
3
|
import debug from "debug";
|
|
4
4
|
import { basename } from "node:path";
|
|
5
5
|
const generateTrackFromPath = async (absolutePath, trackId) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const result = await generateSingleTrackFromPath(absolutePath, trackId);
|
|
9
|
-
return result.stream;
|
|
6
|
+
debug("ef:generateTrackFragment")(`Generating track ${trackId} for ${absolutePath}`);
|
|
7
|
+
return (await generateSingleTrackFromPath(absolutePath, trackId)).stream;
|
|
10
8
|
};
|
|
11
9
|
const generateTrackTask = idempotentTask({
|
|
12
10
|
label: "track",
|
|
@@ -24,14 +24,12 @@ const generateTrackFragmentIndexFromPath = async (absolutePath) => {
|
|
|
24
24
|
if (stream.codec_type !== "audio" && stream.codec_type !== "video") continue;
|
|
25
25
|
const trackId = streamIndex + 1;
|
|
26
26
|
log(`Processing track ${trackId} (${stream.codec_type})`);
|
|
27
|
-
const
|
|
28
|
-
const trackIdMapping = { 0: trackId };
|
|
29
|
-
const singleTrackIndexes = await generateFragmentIndex(trackStream, startTimeOffsetMs, trackIdMapping);
|
|
27
|
+
const singleTrackIndexes = await generateFragmentIndex(probe.createTrackReadstream(streamIndex), startTimeOffsetMs, { 0: trackId });
|
|
30
28
|
Object.assign(trackFragmentIndexes, singleTrackIndexes);
|
|
31
29
|
}
|
|
32
30
|
return trackFragmentIndexes;
|
|
33
31
|
};
|
|
34
|
-
|
|
32
|
+
var generateTrackFragmentIndexTask = idempotentTask({
|
|
35
33
|
label: "trackFragmentIndex",
|
|
36
34
|
filename: (absolutePath) => `${basename(absolutePath)}.tracks.json`,
|
|
37
35
|
runner: async (absolutePath) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/assets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.6-beta.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"author": "",
|
|
26
26
|
"license": "UNLICENSED",
|
|
27
27
|
"dependencies": {
|
|
28
|
+
"@lit/context": "^1.1.6",
|
|
28
29
|
"debug": "^4.3.5",
|
|
29
30
|
"mediabunny": "^1.5.0",
|
|
30
31
|
"ora": "^8.0.1",
|