@geekapps/silo-elements-nextjs 0.3.1 → 0.3.3

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.
@@ -391,9 +391,54 @@ function ImageUploader({
391
391
  ] })
392
392
  ] });
393
393
  }
394
- var CODECS = [
395
- { value: "h264", label: "H.264 (NVENC)", hint: "Compatibilidade m\xE1xima \u2014 GPU accelerated" },
396
- { value: "h265", label: "H.265 (NVENC)", hint: "Melhor compress\xE3o \u2014 GPU accelerated" }
394
+ var VIDEO_CODECS = [
395
+ {
396
+ value: "h264",
397
+ label: "H.264",
398
+ description: "Compatibilidade universal \u2014 funciona em todos os players, browsers e Smart TVs."
399
+ },
400
+ {
401
+ value: "h265",
402
+ label: "H.265",
403
+ description: "50% menor que H.264 com a mesma qualidade. Requer player moderno."
404
+ },
405
+ {
406
+ value: "av1",
407
+ label: "AV1",
408
+ description: "M\xE1xima efici\xEAncia \u2014 at\xE9 50% menor que H.265. Chrome 70+, Firefox 67+, Safari 17+.",
409
+ warning: "N\xE3o suportado em iPhones antigos (iOS < 16) e Smart TVs antigas."
410
+ }
411
+ ];
412
+ var AUDIO_SIMPLE = [
413
+ {
414
+ value: "passthrough",
415
+ label: "Preservar original",
416
+ badge: "Recomendado",
417
+ description: "Copia o \xE1udio sem reencodar quando compat\xEDvel com HLS (AAC, AC3, E-AC3). Converte para AAC est\xE9reo como fallback."
418
+ },
419
+ {
420
+ value: "aac",
421
+ label: "AAC",
422
+ description: "Compatibilidade m\xE1xima. Funciona em todos os players e dispositivos."
423
+ },
424
+ {
425
+ value: "opus",
426
+ label: "Opus",
427
+ description: "Melhor efici\xEAncia que AAC. Suportado em Chrome, Firefox e Android. N\xE3o suportado em Safari/iOS."
428
+ }
429
+ ];
430
+ var AUDIO_ADVANCED_CODEC = [
431
+ { value: "passthrough", label: "Original", description: "Passthrough quando HLS-compat\xEDvel, AAC como fallback." },
432
+ { value: "aac", label: "AAC", description: "Compatibilidade m\xE1xima." },
433
+ { value: "opus", label: "Opus", description: "Melhor efici\xEAncia que AAC. Chrome/Firefox/Android." },
434
+ { value: "ac3", label: "AC3", description: "Dolby Digital. Compat\xEDvel com HLS e home theaters." },
435
+ { value: "eac3", label: "E-AC3", description: "Dolby Digital Plus. Suporta Atmos. Netflix, Disney+, Apple TV+." }
436
+ ];
437
+ var AUDIO_CHANNELS = [
438
+ { value: "original", label: "Original", description: "Mant\xE9m os canais do arquivo fonte." },
439
+ { value: "stereo", label: "Est\xE9reo", description: "2.0 \u2014 compat\xEDvel com todos os dispositivos." },
440
+ { value: "5.1", label: "5.1", description: "Surround 5.1." },
441
+ { value: "7.1", label: "7.1", description: "Surround 7.1." }
397
442
  ];
398
443
  var RESOLUTIONS = ["144", "240", "360", "480", "720", "1080", "1440", "2160"];
399
444
  var RESOLUTION_LABELS = {
@@ -407,19 +452,40 @@ var RESOLUTION_LABELS = {
407
452
  "2160": "4K"
408
453
  };
409
454
  function optBtnStyle(active) {
410
- return active ? { border: "1px solid #6366f1", background: "#6366f1", color: "#fff", padding: "4px 10px", borderRadius: 6, fontSize: 12, fontWeight: 600, cursor: "pointer", minWidth: 36 } : { border: "1px solid rgba(255,255,255,0.2)", background: "rgba(255,255,255,0.06)", color: "rgba(255,255,255,0.8)", padding: "4px 10px", borderRadius: 6, fontSize: 12, fontWeight: 600, cursor: "pointer", minWidth: 36 };
455
+ return active ? { border: "1px solid #6366f1", background: "#6366f1", color: "#fff", padding: "4px 10px", borderRadius: 6, fontSize: 12, fontWeight: 600, cursor: "pointer" } : { border: "1px solid rgba(255,255,255,0.2)", background: "rgba(255,255,255,0.06)", color: "rgba(255,255,255,0.8)", padding: "4px 10px", borderRadius: 6, fontSize: 12, fontWeight: 600, cursor: "pointer" };
456
+ }
457
+ function SectionLabel({ children }) {
458
+ return /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 6, color: "rgba(255,255,255,0.35)" }, children });
411
459
  }
412
- function Toggle({ checked, onToggle, label }) {
413
- return /* @__PURE__ */ jsxs("div", { style: { display: "inline-flex", alignItems: "center", gap: 8, cursor: "pointer", userSelect: "none" }, onClick: onToggle, children: [
414
- /* @__PURE__ */ jsx("span", { style: { position: "relative", display: "inline-block", width: 32, height: 18, borderRadius: 9, flexShrink: 0, cursor: "pointer", background: checked ? "#6366f1" : "rgba(255,255,255,0.15)", transition: "background 150ms" }, children: /* @__PURE__ */ jsx("span", { style: { position: "absolute", top: 2, left: checked ? 16 : 2, width: 14, height: 14, borderRadius: "50%", background: "#fff", boxShadow: "0 1px 3px rgba(0,0,0,.3)", transition: "left 150ms" } }) }),
415
- /* @__PURE__ */ jsx("span", { style: { fontSize: 12, fontWeight: 500, color: "rgba(255,255,255,0.85)" }, children: label })
460
+ function Hint({ children }) {
461
+ return /* @__PURE__ */ jsx("p", { style: { marginTop: 5, fontSize: 11, color: "rgba(255,255,255,0.4)", lineHeight: 1.5 }, children });
462
+ }
463
+ function Warning({ children }) {
464
+ return /* @__PURE__ */ jsx("div", { style: { marginTop: 5, display: "flex", gap: 5, background: "rgba(251,191,36,0.08)", border: "1px solid rgba(251,191,36,0.2)", borderRadius: 6, padding: "5px 8px" }, children: /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, color: "#fbbf24", lineHeight: 1.5 }, children: [
465
+ "\u26A0 ",
466
+ children
467
+ ] }) });
468
+ }
469
+ function Toggle({ checked, onToggle, label, hint }) {
470
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: 8, cursor: "pointer", userSelect: "none" }, onClick: onToggle, children: [
471
+ /* @__PURE__ */ jsx("span", { style: { position: "relative", display: "inline-block", width: 32, height: 18, borderRadius: 9, flexShrink: 0, marginTop: 1, background: checked ? "#6366f1" : "rgba(255,255,255,0.15)", transition: "background 150ms" }, children: /* @__PURE__ */ jsx("span", { style: { position: "absolute", top: 2, left: checked ? 16 : 2, width: 14, height: 14, borderRadius: "50%", background: "#fff", boxShadow: "0 1px 3px rgba(0,0,0,.3)", transition: "left 150ms" } }) }),
472
+ /* @__PURE__ */ jsxs("div", { children: [
473
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, fontWeight: 500, color: "rgba(255,255,255,0.85)" }, children: label }),
474
+ hint && /* @__PURE__ */ jsx("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.4)", marginTop: 1, lineHeight: 1.4 }, children: hint })
475
+ ] })
416
476
  ] });
417
477
  }
418
478
  function VideoOptions({ value, onChange, style }) {
479
+ const [advanced, setAdvanced] = useState(false);
419
480
  const codec = value.codec ?? "h264";
420
481
  const transcoding = value.transcoding ?? "auto";
421
482
  const isAuto = transcoding === "auto";
422
483
  const selectedRes = isAuto ? [] : transcoding;
484
+ const audioCodec = value.audioCodec ?? "passthrough";
485
+ const audioChannels = value.audioChannels ?? "original";
486
+ const preserveAtmos = value.preserveAtmos ?? true;
487
+ const hdrMode = value.hdr ?? "preserve";
488
+ const selectedVideoCodec = VIDEO_CODECS.find((c) => c.value === codec);
423
489
  function toggleRes(r) {
424
490
  if (isAuto) {
425
491
  onChange({ ...value, transcoding: [r] });
@@ -428,49 +494,132 @@ function VideoOptions({ value, onChange, style }) {
428
494
  const next = selectedRes.includes(r) ? selectedRes.filter((x) => x !== r) : [...selectedRes, r];
429
495
  onChange({ ...value, transcoding: next.length === 0 ? "auto" : next });
430
496
  }
431
- function toggleFeature(key) {
432
- onChange({ ...value, [key]: !value[key] });
433
- }
434
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", style, children: [
497
+ const showAtmosOption = audioCodec === "eac3" || audioCodec === "passthrough";
498
+ const showAtmosWarning = audioCodec === "aac" || audioCodec === "opus" || audioCodec === "ac3";
499
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", style, children: [
435
500
  /* @__PURE__ */ jsxs("div", { children: [
436
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 6, color: "rgba(255,255,255,0.4)" }, children: "Codec" }),
437
- /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 flex-wrap", children: CODECS.map((c) => /* @__PURE__ */ jsx(
501
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Codec de v\xEDdeo" }),
502
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 flex-wrap", children: VIDEO_CODECS.map((c) => /* @__PURE__ */ jsx(
438
503
  "button",
439
504
  {
440
505
  type: "button",
441
- title: c.hint,
442
506
  onClick: () => onChange({ ...value, codec: c.value }),
443
507
  style: optBtnStyle(codec === c.value),
444
508
  children: c.label
445
509
  },
446
510
  c.value
447
- )) })
511
+ )) }),
512
+ selectedVideoCodec && /* @__PURE__ */ jsx(Hint, { children: selectedVideoCodec.description }),
513
+ selectedVideoCodec?.warning && /* @__PURE__ */ jsx(Warning, { children: selectedVideoCodec.warning })
448
514
  ] }),
449
515
  /* @__PURE__ */ jsxs("div", { children: [
450
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 6, color: "rgba(255,255,255,0.4)" }, children: "Resolu\xE7\xF5es" }),
516
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Resolu\xE7\xF5es" }),
451
517
  /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 flex-wrap", children: [
452
518
  /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onChange({ ...value, transcoding: "auto" }), style: optBtnStyle(isAuto), children: "Auto" }),
453
- RESOLUTIONS.map((r) => /* @__PURE__ */ jsx(
519
+ RESOLUTIONS.map((r) => /* @__PURE__ */ jsx("button", { type: "button", onClick: () => toggleRes(r), style: optBtnStyle(!isAuto && selectedRes.includes(r)), children: RESOLUTION_LABELS[r] }, r))
520
+ ] }),
521
+ isAuto && /* @__PURE__ */ jsx(Hint, { children: "Gera todas as resolu\xE7\xF5es at\xE9 a resolu\xE7\xE3o original do v\xEDdeo." })
522
+ ] }),
523
+ !advanced && /* @__PURE__ */ jsxs(Fragment, { children: [
524
+ /* @__PURE__ */ jsxs("div", { children: [
525
+ /* @__PURE__ */ jsx(SectionLabel, { children: "\xC1udio" }),
526
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 flex-wrap", children: AUDIO_SIMPLE.map((a) => /* @__PURE__ */ jsxs(
454
527
  "button",
455
528
  {
456
529
  type: "button",
457
- onClick: () => toggleRes(r),
458
- style: optBtnStyle(!isAuto && selectedRes.includes(r)),
459
- children: RESOLUTION_LABELS[r]
530
+ onClick: () => onChange({ ...value, audioCodec: a.value }),
531
+ style: optBtnStyle(audioCodec === a.value),
532
+ children: [
533
+ a.label,
534
+ "badge" in a && a.badge ? /* @__PURE__ */ jsx("span", { style: { marginLeft: 5, fontSize: 9, fontWeight: 700, background: "rgba(255,255,255,0.15)", borderRadius: 4, padding: "1px 4px", verticalAlign: "middle" }, children: a.badge }) : null
535
+ ]
460
536
  },
461
- r
462
- ))
537
+ a.value
538
+ )) }),
539
+ /* @__PURE__ */ jsx(Hint, { children: AUDIO_SIMPLE.find((a) => a.value === audioCodec)?.description })
540
+ ] }),
541
+ /* @__PURE__ */ jsxs("div", { children: [
542
+ /* @__PURE__ */ jsx(SectionLabel, { children: "HDR" }),
543
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ jsx(
544
+ Toggle,
545
+ {
546
+ checked: hdrMode === "preserve",
547
+ onToggle: () => onChange({ ...value, hdr: hdrMode === "preserve" ? "sdr" : "preserve" }),
548
+ label: "Preservar HDR",
549
+ hint: "Mant\xE9m HDR10, HDR10+, HLG e Dolby Vision quando o codec de sa\xEDda suporta (H.265 e AV1). Ignorado para H.264."
550
+ }
551
+ ) })
552
+ ] })
553
+ ] }),
554
+ advanced && /* @__PURE__ */ jsxs(Fragment, { children: [
555
+ /* @__PURE__ */ jsxs("div", { children: [
556
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Codec de \xE1udio" }),
557
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 flex-wrap", children: AUDIO_ADVANCED_CODEC.map((a) => /* @__PURE__ */ jsx(
558
+ "button",
559
+ {
560
+ type: "button",
561
+ onClick: () => onChange({ ...value, audioCodec: a.value }),
562
+ style: optBtnStyle(audioCodec === a.value),
563
+ children: a.label
564
+ },
565
+ a.value
566
+ )) }),
567
+ /* @__PURE__ */ jsx(Hint, { children: AUDIO_ADVANCED_CODEC.find((a) => a.value === audioCodec)?.description }),
568
+ showAtmosWarning && /* @__PURE__ */ jsx(Warning, { children: "Este codec n\xE3o preserva Dolby Atmos. Use E-AC3 ou Original para manter Atmos." })
569
+ ] }),
570
+ /* @__PURE__ */ jsxs("div", { children: [
571
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Canais" }),
572
+ /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 flex-wrap", children: AUDIO_CHANNELS.map((c) => /* @__PURE__ */ jsx(
573
+ "button",
574
+ {
575
+ type: "button",
576
+ onClick: () => onChange({ ...value, audioChannels: c.value }),
577
+ style: optBtnStyle(audioChannels === c.value),
578
+ children: c.label
579
+ },
580
+ c.value
581
+ )) }),
582
+ /* @__PURE__ */ jsx(Hint, { children: AUDIO_CHANNELS.find((c) => c.value === audioChannels)?.description })
583
+ ] }),
584
+ showAtmosOption && /* @__PURE__ */ jsxs("div", { children: [
585
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Atmos" }),
586
+ /* @__PURE__ */ jsx(
587
+ Toggle,
588
+ {
589
+ checked: preserveAtmos,
590
+ onToggle: () => onChange({ ...value, preserveAtmos: !preserveAtmos }),
591
+ label: "Preservar Dolby Atmos quando dispon\xEDvel",
592
+ hint: "Mant\xE9m os metadados Atmos no E-AC3 de sa\xEDda. Efetivo somente com codec E-AC3 ou Original."
593
+ }
594
+ )
595
+ ] }),
596
+ /* @__PURE__ */ jsxs("div", { children: [
597
+ /* @__PURE__ */ jsx(SectionLabel, { children: "HDR" }),
598
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 flex-wrap", children: [
599
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onChange({ ...value, hdr: "preserve" }), style: optBtnStyle(hdrMode === "preserve"), children: "Preservar HDR" }),
600
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onChange({ ...value, hdr: "sdr" }), style: optBtnStyle(hdrMode === "sdr"), children: "Converter para SDR" })
601
+ ] }),
602
+ /* @__PURE__ */ jsx(Hint, { children: hdrMode === "preserve" ? "HDR10, HDR10+, HLG e Dolby Vision s\xE3o preservados com H.265 e AV1. H.264 ignora HDR." : "Tonemapping para SDR \u2014 compat\xEDvel com todos os displays." })
463
603
  ] })
464
604
  ] }),
465
605
  /* @__PURE__ */ jsxs("div", { children: [
466
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 8, color: "var(--silo-text-muted)" }, children: "Recursos" }),
467
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
468
- /* @__PURE__ */ jsx(Toggle, { checked: value.thumbnails ?? true, onToggle: () => toggleFeature("thumbnails"), label: "Gerar thumbnails" }),
469
- /* @__PURE__ */ jsx(Toggle, { checked: value.storyboard ?? false, onToggle: () => toggleFeature("storyboard"), label: "Gerar storyboard" }),
470
- /* @__PURE__ */ jsx(Toggle, { checked: value.autoCaptions ?? false, onToggle: () => toggleFeature("autoCaptions"), label: "Legendas autom\xE1ticas (IA)" }),
471
- /* @__PURE__ */ jsx(Toggle, { checked: value.separateAudio ?? false, onToggle: () => toggleFeature("separateAudio"), label: "Separar faixa de \xE1udio" })
606
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Recursos" }),
607
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2.5", children: [
608
+ /* @__PURE__ */ jsx(Toggle, { checked: value.thumbnails ?? true, onToggle: () => onChange({ ...value, thumbnails: !(value.thumbnails ?? true) }), label: "Gerar thumbnails" }),
609
+ /* @__PURE__ */ jsx(Toggle, { checked: value.storyboard ?? false, onToggle: () => onChange({ ...value, storyboard: !value.storyboard }), label: "Gerar storyboard" }),
610
+ /* @__PURE__ */ jsx(Toggle, { checked: value.autoCaptions ?? false, onToggle: () => onChange({ ...value, autoCaptions: !value.autoCaptions }), label: "Legendas autom\xE1ticas (IA)" }),
611
+ /* @__PURE__ */ jsx(Toggle, { checked: value.separateAudio ?? false, onToggle: () => onChange({ ...value, separateAudio: !value.separateAudio }), label: "Separar faixa de \xE1udio" })
472
612
  ] })
473
- ] })
613
+ ] }),
614
+ /* @__PURE__ */ jsx(
615
+ "button",
616
+ {
617
+ type: "button",
618
+ onClick: () => setAdvanced((v) => !v),
619
+ style: { alignSelf: "flex-start", fontSize: 11, color: "rgba(255,255,255,0.35)", background: "none", border: "none", cursor: "pointer", padding: 0, textDecoration: "underline", textUnderlineOffset: 3 },
620
+ children: advanced ? "\u2190 Modo simples" : "Op\xE7\xF5es avan\xE7adas \u2192"
621
+ }
622
+ )
474
623
  ] });
475
624
  }
476
625
  var DEFAULT_VIDEO_OPTS = {