xvai-loi 0.1.136 → 0.1.138

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 +63 -13
package/co.txt CHANGED
@@ -1 +1 @@
1
- xvaiLoi140014
1
+ xvaiLoi140126
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xvai-loi",
3
- "version": "0.1.136",
3
+ "version": "0.1.138",
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
@@ -15015,7 +15015,7 @@ async function ghepKho(canh, kho5) {
15015
15015
  if (!c || !a || +g.diem < 6) continue;
15016
15016
  const loai = String(c.khoa).split(":")[0], web = /^trang web|giao diện/i.test(String(a.mo || ""));
15017
15017
  if (+g.diem < (loai === "trang" || loai === "anh" && web ? 8 : 6)) continue;
15018
- if (a.loai === "video" && loai !== "anh") continue;
15018
+ if (a.loai === "video" && (loai !== "anh" || c.bien)) continue;
15019
15019
  if (loai !== "trang" && da.has(a.id)) continue;
15020
15020
  da.add(a.id);
15021
15021
  kq[c.khoa] = a.id;
@@ -15036,8 +15036,26 @@ async function chuanBiKho(kb, words, bao) {
15036
15036
  const i = thap.indexOf(String(tu2 || "").toLocaleLowerCase("vi"));
15037
15037
  return i < 0 ? String(tu2 || "") : loi2.slice(Math.max(0, i - 70), i + 100);
15038
15038
  };
15039
- const canh = [];
15040
- (kb.canh || []).filter((c) => c && c.tu && (c.kieu === "anh" || c.kieu === "vat")).forEach((c) => canh.push({ khoa: c.kieu + ":" + String(c.tu).toLocaleLowerCase("vi"), y: 'ch\u1EEF kho\xE1 "' + [c.chu, c.chu2].filter(Boolean).join(" ") + '" \xB7 l\u1EDDi: "\u2026' + cau(c.tu) + '\u2026"' }));
15039
+ const canh = [], moc = [];
15040
+ {
15041
+ let o = 0;
15042
+ for (const w of words || []) {
15043
+ moc.push(o);
15044
+ o += String(w && w.text || "").length + 1;
15045
+ }
15046
+ }
15047
+ const giay = (tu2) => {
15048
+ const i = thap.indexOf(String(tu2 || "").toLocaleLowerCase("vi"));
15049
+ if (i < 0) return -1;
15050
+ let j = 0;
15051
+ while (j + 1 < moc.length && moc[j + 1] <= i) j++;
15052
+ return +(words[j] && words[j].t0) || 0;
15053
+ }, het = +(words || [])[(words || []).length - 1]?.t1 || 0;
15054
+ const bien = (tu2) => {
15055
+ const s = giay(tu2);
15056
+ return s >= 0 && (s < 3.5 || s > het - 3);
15057
+ };
15058
+ (kb.canh || []).filter((c) => c && c.tu && (c.kieu === "anh" || c.kieu === "vat")).forEach((c) => canh.push({ khoa: c.kieu + ":" + String(c.tu).toLocaleLowerCase("vi"), bien: bien(c.tu), y: 'ch\u1EEF kho\xE1 "' + [c.chu, c.chu2].filter(Boolean).join(" ") + '" \xB7 l\u1EDDi: "\u2026' + cau(c.tu) + '\u2026"' }));
15041
15059
  (kb.muc || []).forEach((m) => {
15042
15060
  const ten = String(m && m.ten || "").trim();
15043
15061
  if (ten) canh.push({ khoa: "trang:" + ten.toLocaleLowerCase("vi").replace(/[^\p{L}\p{N}]+/gu, ""), y: /SKILL|CÔNG CỤ|CONG CU|TOOL|APP/i.test(String(kb?.nhom || "")) ? 'trang web / giao di\u1EC7n c\u1EE7a c\xF4ng c\u1EE5 "' + ten + '"' + (m.mo ? " (" + m.mo + ")" : "") : '\u1EA3nh minh ho\u1EA1 \xFD "' + ten + '"' });
@@ -15083,7 +15101,7 @@ async function chuanBiKho(kb, words, bao) {
15083
15101
  const k = chuan(String(c.khoa).split(":").slice(1).join(":"));
15084
15102
  if (!k) continue;
15085
15103
  const a = co.find((x) => {
15086
- if (!x.ten || daDung.has(x.id)) return false;
15104
+ if (!x.ten || daDung.has(x.id) || x.loai === "video" && (String(c.khoa).indexOf("anh:") !== 0 || c.bien)) return false;
15087
15105
  const t = chuan(String(x.ten).replace(/\.[a-z0-9]+$/i, "").replace(/^omni-[a-z0-9]+-\d+-/i, ""));
15088
15106
  if (!t) return false;
15089
15107
  return t === k || t.length >= 6 && (k.indexOf(t) >= 0 || t.indexOf(k) >= 0) && Math.min(t.length, k.length) >= 0.6 * Math.max(t.length, k.length) || Math.min(t.length, k.length) >= 8 && lev(t, k) <= Math.max(1, Math.round(0.12 * Math.max(t.length, k.length)));
@@ -15093,7 +15111,7 @@ async function chuanBiKho(kb, words, bao) {
15093
15111
  daDung.add(a.id);
15094
15112
  }
15095
15113
  }
15096
- const gAI = can.some((c) => !gTay[c.khoa]) ? await ghepKho(can.filter((c) => !gTay[c.khoa]), co.filter((x) => x.mo)) : {};
15114
+ const gAI = can.some((c) => !gTay[c.khoa]) ? await ghepKho(can.filter((c) => !gTay[c.khoa]), co.filter((x) => x.mo && !daDung.has(x.id))) : {};
15097
15115
  const g = { ...gAI, ...gTay };
15098
15116
  globalThis.__ghepTay = Object.keys(gTay).length;
15099
15117
  let n = 0;
@@ -15236,6 +15254,17 @@ async function napVideo(b, bao) {
15236
15254
  throw new Error(nap2 === "het" ? "[VD-209c] clip kh\xF4ng n\u1EA1p (tab \u1EA9n?)" : "video h\u1ECFng");
15237
15255
  }
15238
15256
  const dai2 = Math.min(8, v.duration || 4), fps = 10, n = Math.max(1, Math.floor(dai2 * fps)), ds2 = [], han = Date.now() + 6e4;
15257
+ const cv = new OffscreenCanvas(v.videoWidth || 432, v.videoHeight || 768), g = cv.getContext("2d", { willReadFrequently: true });
15258
+ let co = 0, khong = 0;
15259
+ if (!globalThis.__giuDauAI) for (const t of [0.5, dai2 / 2, dai2 - 0.3]) {
15260
+ v.currentTime = Math.max(0, Math.min(dai2 - 0.05, t));
15261
+ if (await choVideo(v, "seeked", 4e3, "napVideo") !== "ok") break;
15262
+ g.drawImage(v, 0, 0);
15263
+ const r = thu(cv);
15264
+ if (r) co++;
15265
+ else if (r === false) khong++;
15266
+ }
15267
+ const dau = co >= 2 || co === 1 && khong === 0;
15239
15268
  for (let i = 0; i < n; i++) {
15240
15269
  if (Date.now() > han) {
15241
15270
  demHetGio("napVideo", "v\xF2ng khung", 6e4);
@@ -15243,12 +15272,16 @@ async function napVideo(b, bao) {
15243
15272
  }
15244
15273
  v.currentTime = Math.min(dai2 - 0.05, i / fps);
15245
15274
  if (await choVideo(v, "seeked", 4e3, "napVideo") !== "ok") break;
15246
- ds2.push(await createImageBitmap(v, { resizeWidth: 432, resizeHeight: 768, resizeQuality: "medium" }));
15275
+ if (dau) {
15276
+ g.drawImage(v, 0, 0);
15277
+ xoaDau(cv, i + 1);
15278
+ }
15279
+ ds2.push(await createImageBitmap(dau ? cv : v, { resizeWidth: 432, resizeHeight: 768, resizeQuality: "medium" }));
15247
15280
  }
15248
15281
  URL.revokeObjectURL(u);
15249
15282
  if (!ds2.length) throw new Error("[VD-209c] clip kh\xF4ng \u0111\u1ECDc \u0111\u01B0\u1EE3c khung n\xE0o");
15250
15283
  bao?.("N\u1EA1p video tr\xE1m " + (ds2.length < n ? ds2.length + "/" : "") + n + " khung");
15251
- return { laVideo: true, width: 432, height: 768, dai: ds2.length < n ? ds2.length / fps : dai2, khung: (t) => ds2[Math.max(0, Math.min(ds2.length - 1, Math.floor(t * fps)))] };
15284
+ return { laVideo: true, goc: b, width: 432, height: 768, dai: ds2.length < n ? ds2.length / fps : dai2, khung: (t) => ds2[Math.max(0, Math.min(ds2.length - 1, Math.floor(t * fps)))] };
15252
15285
  }
15253
15286
 
15254
15287
  // flow-src/engine/omniTram.ts
@@ -15296,7 +15329,7 @@ async function taoTramOmni(canh, o) {
15296
15329
  loi2.push("DA TOI TRAN " + tran + " clip (xvaiOmniDem)");
15297
15330
  break;
15298
15331
  }
15299
- const c = chon[i], de = String(c.en || c.de || ""), prompt = "Vertical 9:16 b-roll clip, " + giay + " seconds, realistic, cinematic, natural motion, no text, no captions, no logos: " + de;
15332
+ const c = chon[i], de = String(c.en || c.de || ""), prompt = "Vertical 9:16 b-roll clip, " + giay + " seconds, one continuous shot with no cuts, realistic, cinematic, natural motion, nobody talks or speaks to the camera, no lip movement, prefer hands, objects, places or people seen from behind or far away, no text, no captions, no logos: " + de;
15300
15333
  o.bao?.("Omni " + (i + 1) + "/" + chon.length + " \xB7 " + de.slice(0, 60));
15301
15334
  try {
15302
15335
  const r = await Flow.generate.video({ prompt, aspectRatio: "9:16", durationSeconds: giay, resolution: "720p", modelDisplayName: model });
@@ -16163,9 +16196,18 @@ var b64 = (bl) => new Promise((r) => {
16163
16196
  f2.readAsDataURL(bl);
16164
16197
  });
16165
16198
  async function taoKeHoach(p, mau2, kb) {
16166
- const anh2 = {};
16199
+ const anh2 = {}, clip = {};
16200
+ let tong = 0;
16167
16201
  for (const [ten, laVideo2] of moTaTaiSan()) {
16168
- if (laVideo2 || /^st3d:/.test(ten)) continue;
16202
+ if (laVideo2) {
16203
+ const v = taiSan(ten);
16204
+ if (v && v.goc && v.goc.size < 8e6 && tong + v.goc.size < 4e7) {
16205
+ clip[ten] = { b64: await b64(v.goc), mime: v.goc.type || "video/mp4" };
16206
+ tong += v.goc.size;
16207
+ }
16208
+ continue;
16209
+ }
16210
+ if (/^st3d:/.test(ten)) continue;
16169
16211
  const im = taiSan(ten);
16170
16212
  if (!im || !im.width) continue;
16171
16213
  try {
@@ -16175,7 +16217,7 @@ async function taoKeHoach(p, mau2, kb) {
16175
16217
  } catch (e) {
16176
16218
  }
16177
16219
  }
16178
- return { pb: PB_KE_HOACH, mau: mau2, van: vanTayNguon(p), luc: Date.now(), kb: JSON.parse(JSON.stringify(kb)), anh: anh2 };
16220
+ return { pb: PB_KE_HOACH, mau: mau2, van: vanTayNguon(p), luc: Date.now(), kb: JSON.parse(JSON.stringify(kb)), anh: anh2, clip };
16179
16221
  }
16180
16222
  async function napKeHoach(k) {
16181
16223
  let n = 0;
@@ -16187,6 +16229,14 @@ async function napKeHoach(k) {
16187
16229
  } catch (e) {
16188
16230
  }
16189
16231
  }
16232
+ for (const [ten, c] of Object.entries(k && k.clip || {})) {
16233
+ if (taiSan(ten)) continue;
16234
+ try {
16235
+ datTaiSan(ten, await napVideo(await (await fetch("data:" + c.mime + ";base64," + c.b64)).blob()));
16236
+ n++;
16237
+ } catch (e) {
16238
+ }
16239
+ }
16190
16240
  return n;
16191
16241
  }
16192
16242
 
@@ -17659,7 +17709,7 @@ function KhoCanhTram({ project, mauId, kichBan, onKichBan, dung }) {
17659
17709
  localStorage.setItem("xvaiNguonAnh", v === "mienphi" ? "mienphi" : "");
17660
17710
  } catch (x) {
17661
17711
  }
17662
- }, className: "bg-transparent text-[11px] ml-1" }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "tay" }, "Ti\u1EBFt ki\u1EC7m: \u1EA3nh AI 0 credit + kho \u1EA3nh t\u1EF1 do"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "mienphi" }, "Mi\u1EC5n ph\xED, nhanh nh\u1EA5t: ch\u1EC9 kho \u1EA3nh t\u1EF1 do"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "flow" }, "Cao c\u1EA5p: th\xEAm clip \u0111\u1ED9ng Omni 4 s (c\xF3 credit, ~6/clip)"))), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("label", { className: nut + " cursor-pointer" }, "\u{1F4C2} T\u1EA3i c\u1EA3 lo\u1EA1t (t\xEAn 01, 02\u2026)", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", accept: "image/*", multiple: true, hidden: true, onChange: (e) => napLoat(e.target.files) })), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("button", { className: nut, onClick: () => chep(ds2.map((r) => String(r.so).padStart(2, "0") + ". " + r.de).join("\n\n")) }, "\u{1F4CB} Ch\xE9p t\u1EA5t c\u1EA3 l\u1EDDi d\u1EB7n"), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[11px] font-bold text-[#F6D178]" }, "\u0110\xE3 c\xF3 ", du, "/", ds2.length, " \u1EA3nh"), dang && /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[11px] text-[#A2B2C9]" }, dang)), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("ol", { className: "text-[11px] text-[#A2B2C9] list-decimal pl-5 space-y-0.5" }, /* @__PURE__ */ shim_react_default.createElement("li", null, "B\u1EA5m \u{1F4CB} ch\xE9p l\u1EDDi d\u1EB7n (t\u1EEBng d\xF2ng ho\u1EB7c t\u1EA5t c\u1EA3)."), /* @__PURE__ */ shim_react_default.createElement("li", null, "D\xE1n v\xE0o Gemini / ChatGPT / Bing Image Creator / Meta AI / Flow, t\u1EA1o \u0111\xFAng t\u1EC9 l\u1EC7 ghi \u1EDF d\xF2ng, t\u1EA3i \u1EA3nh v\u1EC1, \u0111\u1EB7t t\xEAn theo s\u1ED1 (01.png\u2026)."), /* @__PURE__ */ shim_react_default.createElement("li", null, "B\u1EA5m \u{1F4C2} t\u1EA3i c\u1EA3 lo\u1EA1t (ho\u1EB7c n\xFAt t\u1EA3i \u1EDF t\u1EEBng d\xF2ng) \u2192 b\u1EA5m L\xE0m pro. D\xF2ng ch\u01B0a c\xF3 \u1EA3nh tool s\u1EBD t\u1EF1 t\u1EA1o.")), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("div", { className: "max-h-72 overflow-auto space-y-1.5" }, ds2.map((r) => /* @__PURE__ */ shim_react_default.createElement("div", { key: r.ten, className: "flex gap-2 items-start bg-[#0E1E33] rounded-lg p-2" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[12px] font-black text-[#F6D178] w-6" }, String(r.so).padStart(2, "0")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ shim_react_default.createElement("div", { className: "text-[11px] font-bold text-white" }, co[r.ten] ? "\u2705 " : "\u2B1C ", LOAI[r.loai] || r.loai, " \xB7 ", /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "\u201C", r.tu, "\u201D")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "text-[10px] text-[#7F93AE] truncate", title: r.de }, r.de)), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut, onClick: () => chep(r.de) }, "\u{1F4CB}"), /* @__PURE__ */ shim_react_default.createElement("label", { className: nut + " cursor-pointer" }, "\u2B06", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", accept: "image/*", hidden: true, onChange: (e) => nap2(r, e.target.files && e.target.files[0]) }))))));
17712
+ }, className: "bg-transparent text-[11px] ml-1" }, /* @__PURE__ */ shim_react_default.createElement("option", { value: "tay" }, "Ti\u1EBFt ki\u1EC7m: \u1EA3nh AI 0 credit + kho \u1EA3nh t\u1EF1 do"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "mienphi" }, "Mi\u1EC5n ph\xED, nhanh nh\u1EA5t: ch\u1EC9 kho \u1EA3nh t\u1EF1 do"), /* @__PURE__ */ shim_react_default.createElement("option", { value: "flow" }, "Cao c\u1EA5p: th\xEAm clip \u0111\u1ED9ng Omni 4 s (7 credit/clip)"))), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("label", { className: nut + " cursor-pointer" }, "\u{1F4C2} T\u1EA3i c\u1EA3 lo\u1EA1t (t\xEAn 01, 02\u2026)", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", accept: "image/*", multiple: true, hidden: true, onChange: (e) => napLoat(e.target.files) })), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("button", { className: nut, onClick: () => chep(ds2.map((r) => String(r.so).padStart(2, "0") + ". " + r.de).join("\n\n")) }, "\u{1F4CB} Ch\xE9p t\u1EA5t c\u1EA3 l\u1EDDi d\u1EB7n"), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[11px] font-bold text-[#F6D178]" }, "\u0110\xE3 c\xF3 ", du, "/", ds2.length, " \u1EA3nh"), dang && /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[11px] text-[#A2B2C9]" }, dang)), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("ol", { className: "text-[11px] text-[#A2B2C9] list-decimal pl-5 space-y-0.5" }, /* @__PURE__ */ shim_react_default.createElement("li", null, "B\u1EA5m \u{1F4CB} ch\xE9p l\u1EDDi d\u1EB7n (t\u1EEBng d\xF2ng ho\u1EB7c t\u1EA5t c\u1EA3)."), /* @__PURE__ */ shim_react_default.createElement("li", null, "D\xE1n v\xE0o Gemini / ChatGPT / Bing Image Creator / Meta AI / Flow, t\u1EA1o \u0111\xFAng t\u1EC9 l\u1EC7 ghi \u1EDF d\xF2ng, t\u1EA3i \u1EA3nh v\u1EC1, \u0111\u1EB7t t\xEAn theo s\u1ED1 (01.png\u2026)."), /* @__PURE__ */ shim_react_default.createElement("li", null, "B\u1EA5m \u{1F4C2} t\u1EA3i c\u1EA3 lo\u1EA1t (ho\u1EB7c n\xFAt t\u1EA3i \u1EDF t\u1EEBng d\xF2ng) \u2192 b\u1EA5m L\xE0m pro. D\xF2ng ch\u01B0a c\xF3 \u1EA3nh tool s\u1EBD t\u1EF1 t\u1EA1o.")), ds2.length > 0 && /* @__PURE__ */ shim_react_default.createElement("div", { className: "max-h-72 overflow-auto space-y-1.5" }, ds2.map((r) => /* @__PURE__ */ shim_react_default.createElement("div", { key: r.ten, className: "flex gap-2 items-start bg-[#0E1E33] rounded-lg p-2" }, /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[12px] font-black text-[#F6D178] w-6" }, String(r.so).padStart(2, "0")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ shim_react_default.createElement("div", { className: "text-[11px] font-bold text-white" }, co[r.ten] ? "\u2705 " : "\u2B1C ", LOAI[r.loai] || r.loai, " \xB7 ", /* @__PURE__ */ shim_react_default.createElement("span", { className: "text-[#A2B2C9]" }, "\u201C", r.tu, "\u201D")), /* @__PURE__ */ shim_react_default.createElement("div", { className: "text-[10px] text-[#7F93AE] truncate", title: r.de }, r.de)), /* @__PURE__ */ shim_react_default.createElement("button", { className: nut, onClick: () => chep(r.de) }, "\u{1F4CB}"), /* @__PURE__ */ shim_react_default.createElement("label", { className: nut + " cursor-pointer" }, "\u2B06", /* @__PURE__ */ shim_react_default.createElement("input", { type: "file", accept: "image/*", hidden: true, onChange: (e) => nap2(r, e.target.files && e.target.files[0]) }))))));
17663
17713
  }
17664
17714
 
17665
17715
  // flow-src/components/StudioEdit.tsx
@@ -18105,7 +18155,7 @@ function datCauLenh(a) {
18105
18155
  on2 = true;
18106
18156
  window.addEventListener("message", async (ev) => {
18107
18157
  const d = ev.data;
18108
- if (!d || d.xvaiLoi140014 !== true) return;
18158
+ if (!d || d.xvaiLoi140126 !== true) return;
18109
18159
  const o = String(ev.origin || "");
18110
18160
  if (!(o.indexOf("https://flow.google.com") === 0 || o.indexOf("https://labs.google") === 0)) return;
18111
18161
  const tra = (kq) => {