@pixerate/editor-react 0.57.0 → 0.58.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.
|
@@ -485,6 +485,7 @@ function VideoTimeline({ controller, pxPerSecond, onPxPerSecondChange, editable
|
|
|
485
485
|
}
|
|
486
486
|
|
|
487
487
|
// src/video-editor/ClipInspector.tsx
|
|
488
|
+
import { useState as useState3 } from "react";
|
|
488
489
|
import {
|
|
489
490
|
findVideoClip,
|
|
490
491
|
formatVideoSeconds as formatVideoSeconds2,
|
|
@@ -493,7 +494,8 @@ import {
|
|
|
493
494
|
normalizeVideoGrade,
|
|
494
495
|
VIDEO_GRADE_CONTROLS,
|
|
495
496
|
VIDEO_GRADE_PRESET_NAMES,
|
|
496
|
-
|
|
497
|
+
videoGradeLook,
|
|
498
|
+
videoLutEdits,
|
|
497
499
|
VIDEO_BLEND_MODE_LABELS,
|
|
498
500
|
VIDEO_BLEND_MODES,
|
|
499
501
|
VIDEO_FADE_CURVE_LABELS,
|
|
@@ -538,6 +540,59 @@ function Commit({
|
|
|
538
540
|
);
|
|
539
541
|
return /* @__PURE__ */ jsx5("input", { className: field, ...rest, defaultValue: value, onKeyDown: (e) => e.key === "Enter" && e.currentTarget.blur(), onBlur: (e) => commit(e.currentTarget.value) }, value);
|
|
540
542
|
}
|
|
543
|
+
function LutControls({ controller, clip, disabled }) {
|
|
544
|
+
const [message, setMessage] = useState3(null);
|
|
545
|
+
const lut = clip.grade?.lut;
|
|
546
|
+
const apply = (setting, label) => {
|
|
547
|
+
const r = controller.apply(videoLutEdits(controller.getProject(), [clip.id], setting), label);
|
|
548
|
+
setMessage(r.ok ? null : r.error);
|
|
549
|
+
};
|
|
550
|
+
const choose = async (src) => {
|
|
551
|
+
if (!src) return lut && apply(null, "Remove LUT");
|
|
552
|
+
try {
|
|
553
|
+
const table = await controller.luts.load(src);
|
|
554
|
+
apply({ src, ...lut?.strength !== void 0 ? { strength: lut.strength } : {}, ...table.title ? { name: table.title } : {} }, "Apply LUT");
|
|
555
|
+
} catch (e) {
|
|
556
|
+
setMessage(e instanceof Error ? e.message : String(e));
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
const readFile = async (file) => {
|
|
560
|
+
if (!file) return;
|
|
561
|
+
try {
|
|
562
|
+
const table = controller.luts.set(file.name, await file.text());
|
|
563
|
+
apply({ src: file.name, ...lut?.strength !== void 0 ? { strength: lut.strength } : {}, ...table.title ? { name: table.title } : {} }, "Apply LUT");
|
|
564
|
+
} catch (e) {
|
|
565
|
+
setMessage(`${file.name}: ${e instanceof Error ? e.message : String(e)}`);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
569
|
+
/* @__PURE__ */ jsx5(Row, { label: "LUT", name: "grade.lut", children: /* @__PURE__ */ jsxs4("div", { className: "flex min-w-0 gap-1", children: [
|
|
570
|
+
/* @__PURE__ */ jsx5(Commit, { value: lut?.src ?? "", placeholder: "look.cube", "aria-label": "LUT file", disabled, onCommit: (raw) => void choose(raw.trim()) }),
|
|
571
|
+
/* @__PURE__ */ jsxs4("label", { className: `${btn2} cursor-pointer whitespace-nowrap`, title: "Load a .cube file", children: [
|
|
572
|
+
"Load",
|
|
573
|
+
/* @__PURE__ */ jsx5("input", { type: "file", accept: ".cube", className: "sr-only", disabled, "aria-label": "Load a .cube LUT", onChange: (e) => void readFile(e.currentTarget.files?.[0]) })
|
|
574
|
+
] }),
|
|
575
|
+
lut && /* @__PURE__ */ jsx5("button", { type: "button", className: btn2, disabled, "aria-label": "Remove LUT", onClick: () => apply(null, "Remove LUT"), children: "\u2715" })
|
|
576
|
+
] }) }),
|
|
577
|
+
lut && /* @__PURE__ */ jsx5(Row, { label: "LUT strength", name: "grade.lut.strength", children: /* @__PURE__ */ jsx5(
|
|
578
|
+
Commit,
|
|
579
|
+
{
|
|
580
|
+
type: "number",
|
|
581
|
+
min: 0,
|
|
582
|
+
max: 1,
|
|
583
|
+
step: 0.05,
|
|
584
|
+
value: String(lut.strength ?? 1),
|
|
585
|
+
"aria-label": "LUT strength",
|
|
586
|
+
disabled,
|
|
587
|
+
onCommit: (raw) => {
|
|
588
|
+
const n = Number(raw);
|
|
589
|
+
if (raw.trim() && Number.isFinite(n)) apply(n > 0 ? { ...lut, strength: Math.min(1, n) } : null, n > 0 ? "Change LUT strength" : "Remove LUT");
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
) }),
|
|
593
|
+
message && /* @__PURE__ */ jsx5("p", { className: "text-xs text-red-500", role: "alert", "data-lut-error": "", children: message })
|
|
594
|
+
] });
|
|
595
|
+
}
|
|
541
596
|
function Row({ label, name, children }) {
|
|
542
597
|
return /* @__PURE__ */ jsxs4("label", { className: "grid grid-cols-[5.5rem_minmax(0,1fr)] items-center gap-2 text-xs", "data-field": name, children: [
|
|
543
598
|
/* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: label }),
|
|
@@ -630,7 +685,7 @@ function ClipInspector({ controller, className = "" }) {
|
|
|
630
685
|
disabled,
|
|
631
686
|
"aria-label": "Apply a look",
|
|
632
687
|
onChange: (e) => {
|
|
633
|
-
const grade =
|
|
688
|
+
const grade = videoGradeLook(clip.grade, e.target.value);
|
|
634
689
|
if (grade) controller.apply({ op: "update_clip", clip: clip.id, set: { grade } }, `Apply ${e.target.value} look`);
|
|
635
690
|
},
|
|
636
691
|
children: [
|
|
@@ -657,7 +712,8 @@ function ClipInspector({ controller, className = "" }) {
|
|
|
657
712
|
set("grade", grade, `Change ${c.label.toLowerCase()}`);
|
|
658
713
|
}
|
|
659
714
|
}
|
|
660
|
-
) }, c.key))
|
|
715
|
+
) }, c.key)),
|
|
716
|
+
/* @__PURE__ */ jsx5(LutControls, { controller, clip, disabled })
|
|
661
717
|
] }),
|
|
662
718
|
at.track.kind === "video" && ["animateIn", "animateOut"].map((key) => /* @__PURE__ */ jsx5(Row, { label: key === "animateIn" ? "Animate in" : "Animate out", name: key, children: /* @__PURE__ */ jsxs4(
|
|
663
719
|
"select",
|
|
@@ -788,7 +844,7 @@ function ClipInspector({ controller, className = "" }) {
|
|
|
788
844
|
}
|
|
789
845
|
|
|
790
846
|
// src/video-editor/MediaBin.tsx
|
|
791
|
-
import { useState as
|
|
847
|
+
import { useState as useState4 } from "react";
|
|
792
848
|
import {
|
|
793
849
|
formatVideoSeconds as formatVideoSeconds3,
|
|
794
850
|
probeVideoMedia,
|
|
@@ -800,11 +856,11 @@ var btn3 = "rounded border border-border px-2 py-0.5 text-xs disabled:opacity-40
|
|
|
800
856
|
function MediaBin({ controller, editable = true, fileToUrl, probe = probeVideoMedia, className = "" }) {
|
|
801
857
|
const { project, readOnly } = useVideoEditorState(controller);
|
|
802
858
|
const canEdit = editable && !readOnly;
|
|
803
|
-
const [url, setUrl] =
|
|
804
|
-
const [urlKind, setUrlKind] =
|
|
805
|
-
const [busy, setBusy] =
|
|
806
|
-
const [problem, setProblem] =
|
|
807
|
-
const [over, setOver] =
|
|
859
|
+
const [url, setUrl] = useState4("");
|
|
860
|
+
const [urlKind, setUrlKind] = useState4("");
|
|
861
|
+
const [busy, setBusy] = useState4(0);
|
|
862
|
+
const [problem, setProblem] = useState4(null);
|
|
863
|
+
const [over, setOver] = useState4(false);
|
|
808
864
|
const addSource = async (src, kind, name) => {
|
|
809
865
|
setBusy((n) => n + 1);
|
|
810
866
|
try {
|
|
@@ -939,7 +995,7 @@ function MediaBin({ controller, editable = true, fileToUrl, probe = probeVideoMe
|
|
|
939
995
|
}
|
|
940
996
|
|
|
941
997
|
// src/video-editor/TranscriptPanel.tsx
|
|
942
|
-
import
|
|
998
|
+
import React6, { useMemo as useMemo3, useState as useState5 } from "react";
|
|
943
999
|
import {
|
|
944
1000
|
findVideoFillers,
|
|
945
1001
|
findVideoTranscriptPauses,
|
|
@@ -955,9 +1011,9 @@ function TranscriptPanel({ controller, track, editable = true, className = "" })
|
|
|
955
1011
|
const state = useVideoEditorState(controller);
|
|
956
1012
|
const { project, time, readOnly } = state;
|
|
957
1013
|
const canEdit = editable && !readOnly;
|
|
958
|
-
const [anchor, setAnchor] =
|
|
959
|
-
const [focus, setFocus] =
|
|
960
|
-
const [message, setMessage] =
|
|
1014
|
+
const [anchor, setAnchor] = useState5(null);
|
|
1015
|
+
const [focus, setFocus] = useState5(null);
|
|
1016
|
+
const [message, setMessage] = useState5(null);
|
|
961
1017
|
const words = useMemo3(() => {
|
|
962
1018
|
try {
|
|
963
1019
|
return videoTimelineTranscript(project, { track });
|
|
@@ -1002,7 +1058,7 @@ function TranscriptPanel({ controller, track, editable = true, className = "" })
|
|
|
1002
1058
|
},
|
|
1003
1059
|
children: words.map((w, i) => {
|
|
1004
1060
|
const inSelection = selected !== null && i >= selected[0] && i <= selected[1];
|
|
1005
|
-
return /* @__PURE__ */ jsxs6(
|
|
1061
|
+
return /* @__PURE__ */ jsxs6(React6.Fragment, { children: [
|
|
1006
1062
|
/* @__PURE__ */ jsx7(
|
|
1007
1063
|
"span",
|
|
1008
1064
|
{
|