@pictx/gemini-veo-watermark-remover 0.2.3 → 0.2.4
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/browser.js +140 -26
- package/dist/browser.js.map +3 -3
- package/dist/cli.js +136 -27
- package/dist/cli.js.map +4 -4
- package/dist/index.js +136 -27
- package/dist/index.js.map +4 -4
- package/dist/node.js +136 -27
- package/dist/node.js.map +3 -3
- package/package.json +4 -2
package/dist/browser.js
CHANGED
|
@@ -272,6 +272,79 @@ var init_frameProcessor = __esm({
|
|
|
272
272
|
}
|
|
273
273
|
});
|
|
274
274
|
|
|
275
|
+
// src/video/codecDescription.js
|
|
276
|
+
function buildAvcDecoderConfigurationRecord(avcC) {
|
|
277
|
+
const spsList = avcC.SPS ?? [];
|
|
278
|
+
const ppsList = avcC.PPS ?? [];
|
|
279
|
+
let size = 7;
|
|
280
|
+
for (const sps of spsList) {
|
|
281
|
+
size += 2 + getNaluByteLength(sps);
|
|
282
|
+
}
|
|
283
|
+
size += 1;
|
|
284
|
+
for (const pps of ppsList) {
|
|
285
|
+
size += 2 + getNaluByteLength(pps);
|
|
286
|
+
}
|
|
287
|
+
if (avcC.ext?.length) {
|
|
288
|
+
size += avcC.ext.length;
|
|
289
|
+
}
|
|
290
|
+
const buffer = new Uint8Array(size);
|
|
291
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
292
|
+
let offset = 0;
|
|
293
|
+
buffer[offset++] = avcC.configurationVersion;
|
|
294
|
+
buffer[offset++] = avcC.AVCProfileIndication;
|
|
295
|
+
buffer[offset++] = avcC.profile_compatibility;
|
|
296
|
+
buffer[offset++] = avcC.AVCLevelIndication;
|
|
297
|
+
buffer[offset++] = (avcC.lengthSizeMinusOne & 3) + (63 << 2);
|
|
298
|
+
buffer[offset++] = spsList.length + (7 << 5);
|
|
299
|
+
for (const sps of spsList) {
|
|
300
|
+
const nalu = getNaluBytes(sps);
|
|
301
|
+
view.setUint16(offset, nalu.length);
|
|
302
|
+
offset += 2;
|
|
303
|
+
buffer.set(nalu, offset);
|
|
304
|
+
offset += nalu.length;
|
|
305
|
+
}
|
|
306
|
+
buffer[offset++] = ppsList.length;
|
|
307
|
+
for (const pps of ppsList) {
|
|
308
|
+
const nalu = getNaluBytes(pps);
|
|
309
|
+
view.setUint16(offset, nalu.length);
|
|
310
|
+
offset += 2;
|
|
311
|
+
buffer.set(nalu, offset);
|
|
312
|
+
offset += nalu.length;
|
|
313
|
+
}
|
|
314
|
+
if (avcC.ext?.length) {
|
|
315
|
+
buffer.set(avcC.ext, offset);
|
|
316
|
+
}
|
|
317
|
+
return buffer;
|
|
318
|
+
}
|
|
319
|
+
function extractCodecDescription(mp4, trackId) {
|
|
320
|
+
const trak = mp4.getTrackById(trackId);
|
|
321
|
+
const entries = trak?.mdia?.minf?.stbl?.stsd?.entries ?? [];
|
|
322
|
+
for (const entry of entries) {
|
|
323
|
+
if (entry.avcC) {
|
|
324
|
+
return buildAvcDecoderConfigurationRecord(entry.avcC);
|
|
325
|
+
}
|
|
326
|
+
if (entry.hvcC) {
|
|
327
|
+
throw new Error("HEVC (hvcC) WebCodecs decoding is not implemented yet.");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
throw new Error("Codec description box (avcC or hvcC) not found for video track.");
|
|
331
|
+
}
|
|
332
|
+
function getNaluBytes(entry) {
|
|
333
|
+
if (entry?.nalu instanceof Uint8Array) return entry.nalu;
|
|
334
|
+
if (entry instanceof Uint8Array) return entry;
|
|
335
|
+
throw new Error("Invalid SPS/PPS entry in avcC box.");
|
|
336
|
+
}
|
|
337
|
+
function getNaluByteLength(entry) {
|
|
338
|
+
if (entry?.nalu instanceof Uint8Array) return entry.nalu.length;
|
|
339
|
+
if (typeof entry?.length === "number") return entry.length;
|
|
340
|
+
if (entry instanceof Uint8Array) return entry.length;
|
|
341
|
+
throw new Error("Invalid SPS/PPS entry in avcC box.");
|
|
342
|
+
}
|
|
343
|
+
var init_codecDescription = __esm({
|
|
344
|
+
"src/video/codecDescription.js"() {
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
275
348
|
// src/video/videoDecoder.base.js
|
|
276
349
|
var VideoDecoderBase;
|
|
277
350
|
var init_videoDecoder_base = __esm({
|
|
@@ -296,6 +369,7 @@ var init_videoDecoder_base = __esm({
|
|
|
296
369
|
var WebCodecsDecoder;
|
|
297
370
|
var init_videoDecoder_webcodecs = __esm({
|
|
298
371
|
"src/video/videoDecoder.webcodecs.js"() {
|
|
372
|
+
init_codecDescription();
|
|
299
373
|
init_videoDecoder_base();
|
|
300
374
|
WebCodecsDecoder = class extends VideoDecoderBase {
|
|
301
375
|
#videoInfo = null;
|
|
@@ -321,6 +395,15 @@ var init_videoDecoder_webcodecs = __esm({
|
|
|
321
395
|
if (!videoTrack) {
|
|
322
396
|
throw new Error("No video track found");
|
|
323
397
|
}
|
|
398
|
+
this.#videoMp4 = createFile();
|
|
399
|
+
await new Promise((resolve, reject) => {
|
|
400
|
+
this.#videoMp4.onReady = resolve;
|
|
401
|
+
this.#videoMp4.onError = reject;
|
|
402
|
+
const buffer = this.#sourceBuffer.slice(0);
|
|
403
|
+
buffer.fileStart = 0;
|
|
404
|
+
this.#videoMp4.appendBuffer(buffer);
|
|
405
|
+
this.#videoMp4.flush();
|
|
406
|
+
});
|
|
324
407
|
this.#videoInfo = {
|
|
325
408
|
width: videoTrack.video.width,
|
|
326
409
|
height: videoTrack.video.height,
|
|
@@ -328,21 +411,13 @@ var init_videoDecoder_webcodecs = __esm({
|
|
|
328
411
|
duration: videoTrack.duration / videoTrack.timescale,
|
|
329
412
|
fps: videoTrack.nb_samples / (videoTrack.duration / videoTrack.timescale),
|
|
330
413
|
codec: videoTrack.codec,
|
|
331
|
-
videoTrackId: videoTrack.id
|
|
414
|
+
videoTrackId: videoTrack.id,
|
|
415
|
+
description: extractCodecDescription(this.#videoMp4, videoTrack.id)
|
|
332
416
|
};
|
|
333
417
|
const audioTrack = info.audioTracks?.[0] ?? null;
|
|
334
418
|
if (audioTrack) {
|
|
335
419
|
this.#audioData = await this.#readTrackSamples(createFile, audioTrack);
|
|
336
420
|
}
|
|
337
|
-
this.#videoMp4 = createFile();
|
|
338
|
-
await new Promise((resolve, reject) => {
|
|
339
|
-
this.#videoMp4.onReady = resolve;
|
|
340
|
-
this.#videoMp4.onError = reject;
|
|
341
|
-
const buffer = this.#sourceBuffer.slice(0);
|
|
342
|
-
buffer.fileStart = 0;
|
|
343
|
-
this.#videoMp4.appendBuffer(buffer);
|
|
344
|
-
this.#videoMp4.flush();
|
|
345
|
-
});
|
|
346
421
|
return this.#videoInfo;
|
|
347
422
|
}
|
|
348
423
|
/**
|
|
@@ -389,10 +464,13 @@ var init_videoDecoder_webcodecs = __esm({
|
|
|
389
464
|
if (!this.#videoMp4 || !this.#videoInfo) {
|
|
390
465
|
throw new Error("Call open() first");
|
|
391
466
|
}
|
|
392
|
-
const { width, height, videoTrackId } = this.#videoInfo;
|
|
467
|
+
const { width, height, videoTrackId, frameCount } = this.#videoInfo;
|
|
393
468
|
const pendingFrames = [];
|
|
394
469
|
let resolveNext = null;
|
|
395
470
|
let done = false;
|
|
471
|
+
let extractionDone = false;
|
|
472
|
+
let flushed = false;
|
|
473
|
+
let samplesSubmitted = 0;
|
|
396
474
|
const decoder = new VideoDecoder({
|
|
397
475
|
output: (frame) => {
|
|
398
476
|
const canvas = new OffscreenCanvas(width, height);
|
|
@@ -416,12 +494,18 @@ var init_videoDecoder_webcodecs = __esm({
|
|
|
416
494
|
error: (e) => {
|
|
417
495
|
console.error("Decoder error:", e);
|
|
418
496
|
done = true;
|
|
497
|
+
if (resolveNext) {
|
|
498
|
+
const r = resolveNext;
|
|
499
|
+
resolveNext = null;
|
|
500
|
+
r(null);
|
|
501
|
+
}
|
|
419
502
|
}
|
|
420
503
|
});
|
|
421
504
|
decoder.configure({
|
|
422
505
|
codec: this.#videoInfo.codec,
|
|
423
506
|
codedWidth: width,
|
|
424
|
-
codedHeight: height
|
|
507
|
+
codedHeight: height,
|
|
508
|
+
description: this.#videoInfo.description
|
|
425
509
|
});
|
|
426
510
|
this.#videoMp4.onSamples = (_trackId, _user, trackSamples) => {
|
|
427
511
|
for (const sample of trackSamples) {
|
|
@@ -432,6 +516,15 @@ var init_videoDecoder_webcodecs = __esm({
|
|
|
432
516
|
data: sample.data
|
|
433
517
|
});
|
|
434
518
|
decoder.decode(chunk);
|
|
519
|
+
samplesSubmitted++;
|
|
520
|
+
}
|
|
521
|
+
if (samplesSubmitted >= frameCount) {
|
|
522
|
+
extractionDone = true;
|
|
523
|
+
if (resolveNext && pendingFrames.length === 0 && decoder.decodeQueueSize === 0) {
|
|
524
|
+
const r = resolveNext;
|
|
525
|
+
resolveNext = null;
|
|
526
|
+
r(null);
|
|
527
|
+
}
|
|
435
528
|
}
|
|
436
529
|
};
|
|
437
530
|
this.#videoMp4.setExtractionOptions(videoTrackId);
|
|
@@ -439,18 +532,24 @@ var init_videoDecoder_webcodecs = __esm({
|
|
|
439
532
|
while (!done) {
|
|
440
533
|
if (pendingFrames.length > 0) {
|
|
441
534
|
yield pendingFrames.shift();
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (extractionDone && decoder.decodeQueueSize === 0) {
|
|
538
|
+
if (!flushed) {
|
|
539
|
+
await decoder.flush();
|
|
540
|
+
flushed = true;
|
|
541
|
+
if (pendingFrames.length > 0) {
|
|
542
|
+
continue;
|
|
450
543
|
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
544
|
+
}
|
|
545
|
+
done = true;
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
const frame = await new Promise((resolve) => {
|
|
549
|
+
resolveNext = resolve;
|
|
550
|
+
});
|
|
551
|
+
if (frame) {
|
|
552
|
+
yield frame;
|
|
454
553
|
}
|
|
455
554
|
}
|
|
456
555
|
decoder.close();
|
|
@@ -511,7 +610,8 @@ var init_videoEncoder_webcodecs = __esm({
|
|
|
511
610
|
width: config.width,
|
|
512
611
|
height: config.height
|
|
513
612
|
},
|
|
514
|
-
fastStart: "in-memory"
|
|
613
|
+
fastStart: "in-memory",
|
|
614
|
+
firstTimestampBehavior: "offset"
|
|
515
615
|
};
|
|
516
616
|
if (config.audio) {
|
|
517
617
|
muxerConfig.audio = {
|
|
@@ -534,7 +634,14 @@ var init_videoEncoder_webcodecs = __esm({
|
|
|
534
634
|
width: config.width,
|
|
535
635
|
height: config.height,
|
|
536
636
|
bitrate: config.bitrate || 5e6,
|
|
537
|
-
framerate: config.fps
|
|
637
|
+
framerate: config.fps,
|
|
638
|
+
avc: { format: "avc" },
|
|
639
|
+
colorSpace: {
|
|
640
|
+
primaries: "bt709",
|
|
641
|
+
transfer: "bt709",
|
|
642
|
+
matrix: "bt709",
|
|
643
|
+
fullRange: false
|
|
644
|
+
}
|
|
538
645
|
});
|
|
539
646
|
this._target = target;
|
|
540
647
|
}
|
|
@@ -543,7 +650,13 @@ var init_videoEncoder_webcodecs = __esm({
|
|
|
543
650
|
format: "RGBA",
|
|
544
651
|
codedWidth: imageData.width,
|
|
545
652
|
codedHeight: imageData.height,
|
|
546
|
-
timestamp
|
|
653
|
+
timestamp,
|
|
654
|
+
colorSpace: {
|
|
655
|
+
primaries: "bt709",
|
|
656
|
+
transfer: "bt709",
|
|
657
|
+
matrix: "bt709",
|
|
658
|
+
fullRange: true
|
|
659
|
+
}
|
|
547
660
|
});
|
|
548
661
|
const isKey = this.#frameCount % 30 === 0;
|
|
549
662
|
this.#encoder.encode(frame, { keyFrame: isKey });
|
|
@@ -594,6 +707,7 @@ async function processVideo(input, options = {}) {
|
|
|
594
707
|
height: videoInfo.height,
|
|
595
708
|
fps: videoInfo.fps,
|
|
596
709
|
bitrate: bitrate || 5e6,
|
|
710
|
+
codec: videoInfo.codec,
|
|
597
711
|
audio: audioData ? {
|
|
598
712
|
codec: audioData.codec,
|
|
599
713
|
sampleRate: audioData.sampleRate,
|