xvai-loi 0.1.64 → 0.1.65

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.
Files changed (3) hide show
  1. package/co.txt +1 -1
  2. package/package.json +1 -1
  3. package/xvai-loi.js +86 -12
package/co.txt CHANGED
@@ -1 +1 @@
1
- xvaiLoi111325
1
+ xvaiLoi111348
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xvai-loi",
3
- "version": "0.1.64",
3
+ "version": "0.1.65",
4
4
  "description": "Loi dung video (Edit Video Tu Dong) nap vao tool Google Flow qua o cam engine/oCam.ts",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
package/xvai-loi.js CHANGED
@@ -1462,9 +1462,83 @@ function sampleFromLandmarks(t, lm) {
1462
1462
  const eyeY = ((lm[33]?.y ?? face.y) + (lm[263]?.y ?? face.y)) / 2;
1463
1463
  return { t, face, headTop, chin, mouth: bounds(lm, LIPS), eyeY, confidence: 1 };
1464
1464
  }
1465
+ var SEG = "https://storage.googleapis.com/mediapipe-models/image_segmenter/selfie_segmenter/float16/latest/selfie_segmenter.tflite";
1466
+ var segP = null;
1467
+ function napSeg() {
1468
+ if (!segP) segP = (async () => {
1469
+ const imp = new Function("u", "return import(u)"), mod = await imp(CDN + "/vision_bundle.mjs"), v = await mod.FilesetResolver.forVisionTasks(CDN + "/wasm");
1470
+ return mod.ImageSegmenter.createFromOptions(v, { baseOptions: { modelAssetPath: SEG, delegate: "CPU" }, runningMode: "IMAGE", outputConfidenceMasks: true, outputCategoryMask: false });
1471
+ })().catch(() => null);
1472
+ return segP;
1473
+ }
1474
+ function luoiNguoi(seg2, canvas) {
1475
+ let r = null;
1476
+ try {
1477
+ r = seg2.segment(canvas);
1478
+ } catch (e) {
1479
+ return null;
1480
+ }
1481
+ const m = r && r.confidenceMasks && r.confidenceMasks[0];
1482
+ if (!m) return null;
1483
+ const f2 = m.getAsFloat32Array(), mw = m.width, mh = m.height, g = new Uint8Array(36 * 64);
1484
+ for (let y = 0; y < 64; y++) for (let x = 0; x < 36; x++) {
1485
+ let s = 0, n = 0;
1486
+ for (let yy = Math.floor(y * mh / 64); yy < Math.floor((y + 1) * mh / 64); yy++) for (let xx = Math.floor(x * mw / 36); xx < Math.floor((x + 1) * mw / 36); xx++) {
1487
+ s += f2[yy * mw + xx];
1488
+ n++;
1489
+ }
1490
+ g[y * 36 + x] = n && s / n > 0.5 ? 1 : 0;
1491
+ }
1492
+ try {
1493
+ r.close && r.close();
1494
+ } catch (e) {
1495
+ }
1496
+ return g;
1497
+ }
1465
1498
  async function detectOnCanvas(landmarker, canvas, t) {
1466
1499
  const res = landmarker.detect(canvas);
1467
- return sampleFromLandmarks(t, res && res.faceLandmarks && res.faceLandmarks[0]);
1500
+ let s = sampleFromLandmarks(t, res && res.faceLandmarks && res.faceLandmarks[0]);
1501
+ const seg2 = await napSeg(), g = seg2 ? luoiNguoi(seg2, canvas) : null, W4 = canvas.width, H2 = canvas.height;
1502
+ if (!s.face && g) {
1503
+ let r0 = -1;
1504
+ for (let y = 0; y < 64 && r0 < 0; y++) for (let x = 0; x < 36; x++) if (g[y * 36 + x]) {
1505
+ r0 = y;
1506
+ break;
1507
+ }
1508
+ if (r0 >= 0) {
1509
+ let c0 = 36, c1 = -1, sx = 0, n = 0;
1510
+ for (let y = r0; y < Math.min(64, r0 + 6); y++) for (let x = 0; x < 36; x++) if (g[y * 36 + x]) {
1511
+ c0 = Math.min(c0, x);
1512
+ c1 = Math.max(c1, x);
1513
+ sx += x;
1514
+ n++;
1515
+ }
1516
+ const cx = (sx / Math.max(1, n) + 0.5) / 36, cy = (r0 + 4) / 64, sz = Math.max(0.16 * H2, (c1 - c0 + 1) / 36 * W4 * 2.2), x0 = Math.max(0, cx * W4 - sz / 2), y0 = Math.max(0, cy * H2 - sz / 2), cw = Math.min(W4, x0 + sz) - x0, ch = Math.min(H2, y0 + sz) - y0;
1517
+ if (cw > 8 && ch > 8) {
1518
+ const cv = document.createElement("canvas");
1519
+ cv.width = 480;
1520
+ cv.height = Math.max(2, Math.round(480 * ch / cw));
1521
+ cv.getContext("2d").drawImage(canvas, x0, y0, cw, ch, 0, 0, cv.width, cv.height);
1522
+ const r22 = landmarker.detect(cv), p = r22 && r22.faceLandmarks && r22.faceLandmarks[0];
1523
+ if (p) {
1524
+ s = sampleFromLandmarks(t, p.map((q) => ({ x: (x0 + q.x * cw) / W4, y: (y0 + q.y * ch) / H2 })));
1525
+ s.haiTang = 1;
1526
+ }
1527
+ }
1528
+ }
1529
+ }
1530
+ if (s.face) {
1531
+ let dinh = -1;
1532
+ if (g) {
1533
+ const c0 = Math.floor(s.face.x * 36), c1 = Math.max(c0 + 1, Math.floor((s.face.x + s.face.w) * 36));
1534
+ for (let y = 0; y < 64 && dinh < 0; y++) for (let x = c0; x < c1; x++) if (g[y * 36 + x]) {
1535
+ dinh = y / 64;
1536
+ break;
1537
+ }
1538
+ }
1539
+ s.headTop = dinh >= 0 && dinh < s.face.y + 0.02 ? dinh : Math.max(0, s.face.y - s.face.h * 0.35);
1540
+ }
1541
+ return s;
1468
1542
  }
1469
1543
  async function analyzeFaceMap(src, step = 0.5, cancel = () => false, onStatus = () => {
1470
1544
  }, maxSide = 480) {
@@ -1533,7 +1607,7 @@ async function analyzeFaceMap(src, step = 0.5, cancel = () => false, onStatus =
1533
1607
  video.onseeked = null;
1534
1608
  video.src = "";
1535
1609
  video.load();
1536
- return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20" };
1610
+ return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+mat2" };
1537
1611
  }
1538
1612
  async function faceMapWC(src, step, cancel, onStatus, maxSide, landmarker, t0) {
1539
1613
  onStatus("Nh\u1EADn m\u1EB7t (gi\u1EA3i m\xE3 WebCodecs)\u2026");
@@ -1560,7 +1634,7 @@ async function faceMapWC(src, step, cancel, onStatus, maxSide, landmarker, t0) {
1560
1634
  samples.push(await detectOnCanvas(landmarker, canvas, t));
1561
1635
  if (samples.length % 10 === 0) onStatus("Nh\u1EADn m\u1EB7t " + Math.round(t) + "/" + Math.round(dur) + " s");
1562
1636
  }
1563
- return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+webcodecs" };
1637
+ return { step, width: vw, height: vh, samples, ms: Math.round(performance.now() - t0), engine: "mediapipe-face-landmarker-0.10.20+webcodecs+mat2" };
1564
1638
  }
1565
1639
  function faceMapSummary(map) {
1566
1640
  const n = map.samples.length, hit2 = map.samples.filter((s) => s.face).length;
@@ -10001,7 +10075,7 @@ function thuLuoi(L, t) {
10001
10075
  }
10002
10076
  return o;
10003
10077
  }
10004
- function luoiNguoi(p, key) {
10078
+ function luoiNguoi2(p, key) {
10005
10079
  if (!p || !key) return null;
10006
10080
  key = key._goc || key;
10007
10081
  if (luoiCache.has(key)) return luoiCache.get(key);
@@ -10050,7 +10124,7 @@ function datChuNhan(g, W4, H2, F, giant, chu22, pxG, pxC, kieuG, maxW, tren = 0.
10050
10124
  return r;
10051
10125
  };
10052
10126
  {
10053
- const L = luoiNguoi(pN, khoaC);
10127
+ const L = luoiNguoi2(pN, khoaC);
10054
10128
  if (L && F) {
10055
10129
  let dinhM = null;
10056
10130
  {
@@ -10368,7 +10442,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10368
10442
  const kS = 1;
10369
10443
  let p = (d.bo === "depth" || d.bo === "cut" && !d.anNguoi) && nen2 ? nguoi(nen2, W4, H2) : null;
10370
10444
  if (p && d.bo === "cut" && F) {
10371
- const L0 = luoiNguoi(p, d);
10445
+ const L0 = luoiNguoi2(p, d);
10372
10446
  if (L0) {
10373
10447
  const c0 = Math.max(0, Math.floor(F[0] * 36)), c1 = Math.min(35, Math.ceil(F[2] * 36)), r0 = Math.max(0, Math.floor(F[1] * 64)), r1 = Math.min(63, Math.ceil(F[3] * 64));
10374
10448
  let n = 0, t = 0;
@@ -10388,7 +10462,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10388
10462
  const F7 = phongDinh(F || hopNguoi(p, d), d.z || d.phong || 1);
10389
10463
  if (F7) {
10390
10464
  const t7 = datChuNhan(g, W4, H2, F7, d.giant, String(d.giant || "").indexOf(String.fromCharCode(10)) >= 0 ? "" : d.chu2 || "", 165 * (d.coChu || 1) * H2 / 1920, 96 * H2 / 1920, "giant", 0.76 * W4, d.thanh ? 0.1 : 0.075, p, d, true);
10391
- const L7 = luoiNguoi(p, d);
10465
+ const L7 = luoiNguoi2(p, d);
10392
10466
  let day7 = 0;
10393
10467
  if (L7) for (let i = 60 * 36; i < 64 * 36; i++) day7 += L7[i];
10394
10468
  if (t7 && day7 >= 4 && (t7.vung === "het-cho" || t7.pxG < 0.6 * 165 * (d.coChu || 1) * H2 / 1920)) d = { ...d, _goc: d._goc || d, bo: "cut" };
@@ -10644,7 +10718,7 @@ dangKy("cmNen", (g, d, tuoi, W4, H2, nen2, _s, dai2) => {
10644
10718
  if (d.ui) theUI(g, d.ui, tuoi, W4, H2, 1);
10645
10719
  if (d.hang) {
10646
10720
  let yh = d.so ? 0.23 : 0.17, kh = 1;
10647
- const L2 = luoiNguoi(p || (nen2 ? nguoi(nen2, W4, H2) : null), d), F2 = F || (nen2 ? dauCanh(d, nen2, W4, H2) : null);
10721
+ const L2 = luoiNguoi2(p || (nen2 ? nguoi(nen2, W4, H2) : null), d), F2 = F || (nen2 ? dauCanh(d, nen2, W4, H2) : null);
10648
10722
  if (L2 && F2) {
10649
10723
  const tt = d.bo === "cut" && p ? THU_HANG : 1, Lt = tt < 1 ? thuLuoi(L2, tt) : L2, Ft = tt < 1 ? [0.5 + tt * (F2[0] - 0.5), 1 - tt * (1 - F2[1]), 0.5 + tt * (F2[2] - 0.5), 1 - tt * (1 - F2[3])] : F2;
10650
10724
  const nr = Math.ceil(d.hang.length / (d.hang.length > 3 ? 2 : 1)), hb2 = nr * 0.078, c = datKhoiChu({ luoi: Lt, mat: [Ft[0], Ft[1] + 0.25 * (Ft[3] - Ft[1]), Ft[2], Ft[3]], dinh: Ft[1], cam: Ft[3] }, { h: hb2, w: d.hang.length > 3 ? 0.87 : 0.7 }, false, false, void 0, false, W4 / H2, [[0, 0, 1, d.so ? 0.21 : 0.17]]);
@@ -16517,7 +16591,7 @@ var ProEditPanel = (props) => {
16517
16591
  try {
16518
16592
  const heard = await heardWithRetry(cancelled);
16519
16593
  if (cancelled()) return;
16520
- let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) ? prior.faceMap : null;
16594
+ let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) && /mat2/.test(String(prior.faceMap.engine || "")) ? prior.faceMap : null;
16521
16595
  if (!faceMap) try {
16522
16596
  const raw = atob(currentScene.videoBase64), bytes = new Uint8Array(raw.length);
16523
16597
  for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
@@ -16594,7 +16668,7 @@ var ProEditPanel = (props) => {
16594
16668
  if (!d) {
16595
16669
  const heard = await heardWithRetry(cancelled);
16596
16670
  if (cancelled()) return;
16597
- let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) ? prior.faceMap : null;
16671
+ let faceMap = prior && prior.fingerprint === heard.fingerprint && prior.faceMap && Array.isArray(prior.faceMap.samples) && /mat2/.test(String(prior.faceMap.engine || "")) ? prior.faceMap : null;
16598
16672
  if (!faceMap) try {
16599
16673
  const raw = atob(currentScene.videoBase64), bytes = new Uint8Array(raw.length);
16600
16674
  for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
@@ -20536,7 +20610,7 @@ async function napLoi(d) {
20536
20610
  return "LOI: " + String(e && e.message || e).slice(0, 300);
20537
20611
  }
20538
20612
  }
20539
- var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.63/nap.js";
20613
+ var LOI_URL = "https://cdn.jsdelivr.net/npm/xvai-loi@0.1.64/nap.js";
20540
20614
  var TRONG_LOI = !!globalThis.__xvaiReact;
20541
20615
  try {
20542
20616
  if (!TRONG_LOI) setTimeout(() => {
@@ -20566,7 +20640,7 @@ function datCauLenh(a) {
20566
20640
  on2 = true;
20567
20641
  window.addEventListener("message", async (ev) => {
20568
20642
  const d = ev.data;
20569
- if (!d || d.xvaiLoi111325 !== true) return;
20643
+ if (!d || d.xvaiLoi111348 !== true) return;
20570
20644
  const o = String(ev.origin || "");
20571
20645
  if (!(o.indexOf("https://flow.google.com") === 0 || o.indexOf("https://labs.google") === 0)) return;
20572
20646
  const tra = (kq) => {