@pixerate/editor 0.76.0 → 0.77.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.
|
@@ -775,6 +775,13 @@ function placeVideoRect(frame, size, fit = "contain", transform = {}) {
|
|
|
775
775
|
const cy = frame.height / 2 + (_nullishCoalesce(_optionalChain([transform, 'optionalAccess', _11 => _11.y]), () => ( 0)));
|
|
776
776
|
return { x: cx - w / 2, y: cy - h / 2, width: w, height: h };
|
|
777
777
|
}
|
|
778
|
+
function videoTextStyle(clip) {
|
|
779
|
+
return { text: clip.text, color: _nullishCoalesce(clip.color, () => ( "#ffffff")), fontSize: _nullishCoalesce(clip.fontSize, () => ( 64)), fontFamily: _nullishCoalesce(clip.fontFamily, () => ( "sans-serif")), fontWeight: _nullishCoalesce(clip.fontWeight, () => ( 700)), ...clip.background ? { background: clip.background } : {} };
|
|
780
|
+
}
|
|
781
|
+
function videoTitleFrame(project, clip) {
|
|
782
|
+
const layer = { clip: clip.id, track: "", type: "text", opacity: 1, rect: placeVideoRect(project, project, "fill", clip.transform), rotation: _nullishCoalesce(_optionalChain([clip, 'access', _12 => _12.transform, 'optionalAccess', _13 => _13.rotation]), () => ( 0)), text: videoTextStyle(clip) };
|
|
783
|
+
return { time: clip.start, width: project.width, height: project.height, background: "rgba(0,0,0,0)", layers: [layer], audio: [] };
|
|
784
|
+
}
|
|
778
785
|
var clamp01 = (v) => Math.min(1, Math.max(0, v));
|
|
779
786
|
function fadeGain(clip, time) {
|
|
780
787
|
let g = 1;
|
|
@@ -788,7 +795,7 @@ function activeOnTrack(track, time) {
|
|
|
788
795
|
const before = clip.transition ? videoClipBefore(track, clip) : null;
|
|
789
796
|
const lead = before ? clip.transition.duration / 2 : 0;
|
|
790
797
|
const next = videoClipAfter(track, clip);
|
|
791
|
-
const tail = _optionalChain([next, 'optionalAccess',
|
|
798
|
+
const tail = _optionalChain([next, 'optionalAccess', _14 => _14.transition]) ? next.transition.duration / 2 : 0;
|
|
792
799
|
if (time < clip.start - lead || time >= videoClipEnd(clip) + tail) continue;
|
|
793
800
|
const a = { clip };
|
|
794
801
|
if (lead && time < clip.start + lead) a.incoming = { progress: clamp01((time - (clip.start - lead)) / (2 * lead)), type: clip.transition.type, transition: clip.transition };
|
|
@@ -805,8 +812,8 @@ function videoFrameAt(project, time) {
|
|
|
805
812
|
for (let ti = project.tracks.length - 1; ti >= 0; ti--) {
|
|
806
813
|
const track = project.tracks[ti];
|
|
807
814
|
for (const { clip, incoming, outgoing } of activeOnTrack(track, time)) {
|
|
808
|
-
if (_optionalChain([incoming, 'optionalAccess',
|
|
809
|
-
if (_optionalChain([outgoing, 'optionalAccess',
|
|
815
|
+
if (_optionalChain([incoming, 'optionalAccess', _15 => _15.type]) === "dip" && incoming.progress < 0.5) continue;
|
|
816
|
+
if (_optionalChain([outgoing, 'optionalAccess', _16 => _16.type]) === "dip" && outgoing.progress >= 0.5) continue;
|
|
810
817
|
const fade = fadeGain(clip, Math.min(Math.max(time, clip.start), videoClipEnd(clip)));
|
|
811
818
|
const level = (t, into) => t.type === "dip" ? Math.abs(1 - 2 * t.progress) : into ? t.progress : 1 - t.progress;
|
|
812
819
|
const mix = (incoming ? level(incoming, true) : 1) * (outgoing ? level(outgoing, false) : 1);
|
|
@@ -827,14 +834,14 @@ function videoFrameAt(project, time) {
|
|
|
827
834
|
else if (incoming.type === "wipe") wipe = { direction: _nullishCoalesce(incoming.transition.direction, () => ( "right")), progress: incoming.progress };
|
|
828
835
|
else dip = { color: _nullishCoalesce(incoming.transition.color, () => ( "#000000")), opacity: (1 - incoming.progress) * 2 };
|
|
829
836
|
}
|
|
830
|
-
if (_optionalChain([outgoing, 'optionalAccess',
|
|
837
|
+
if (_optionalChain([outgoing, 'optionalAccess', _17 => _17.type]) === "dip") dip = { color: _nullishCoalesce(outgoing.next.transition.color, () => ( "#000000")), opacity: outgoing.progress * 2 };
|
|
831
838
|
const size = clip.type === "media" ? { width: _nullishCoalesce(asset.width, () => ( project.width)), height: _nullishCoalesce(asset.height, () => ( project.height)) } : { width: project.width, height: project.height };
|
|
832
839
|
const fit = _nullishCoalesce(clip.fit, () => ( (clip.type === "media" ? "contain" : "fill")));
|
|
833
840
|
const rect = clip.type === "text" ? placeVideoRect(project, size, "fill", clip.transform) : placeVideoRect(project, size, fit, clip.transform);
|
|
834
|
-
const layer = { clip: clip.id, track: track.id, type: clip.type, opacity: clamp01(opacity), rect, rotation: _nullishCoalesce(_optionalChain([clip, 'access',
|
|
841
|
+
const layer = { clip: clip.id, track: track.id, type: clip.type, opacity: clamp01(opacity), rect, rotation: _nullishCoalesce(_optionalChain([clip, 'access', _18 => _18.transform, 'optionalAccess', _19 => _19.rotation]), () => ( 0)) };
|
|
835
842
|
if (wipe) layer.wipe = wipe;
|
|
836
843
|
if (clip.type === "media") Object.assign(layer, { asset: asset.id, assetKind: asset.kind, src: asset.src, sourceTime });
|
|
837
|
-
if (clip.type === "text") layer.text =
|
|
844
|
+
if (clip.type === "text") layer.text = videoTextStyle(clip);
|
|
838
845
|
if (clip.type === "color") layer.color = clip.color;
|
|
839
846
|
if (layer.opacity > 0) layers.push(layer);
|
|
840
847
|
if (dip && dip.opacity > 0) layers.push({ clip: `transition:${incoming ? clip.id : outgoing.next.id}`, track: track.id, type: "color", color: dip.color, opacity: clamp01(dip.opacity), rect: { x: 0, y: 0, width: project.width, height: project.height }, rotation: 0 });
|
|
@@ -976,7 +983,7 @@ function drawVideoFrame(ctx, frame, sourceFor, scale = 1) {
|
|
|
976
983
|
}
|
|
977
984
|
|
|
978
985
|
// src/video-editor/export.ts
|
|
979
|
-
var reelName = (asset) => (_nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess',
|
|
986
|
+
var reelName = (asset) => (_nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess', _20 => _20.name]), () => ( _optionalChain([asset, 'optionalAccess', _21 => _21.id]))), () => ( "AX"))).replace(/\.[a-z0-9]+$/i, "").replace(/[^A-Za-z0-9]/g, "").toUpperCase().slice(0, 8) || "AX";
|
|
980
987
|
function toVideoEdl(project, options = {}) {
|
|
981
988
|
const track = options.track !== void 0 ? project.tracks.find((t) => t.id === options.track) : [...project.tracks].reverse().find((t) => t.kind === "video");
|
|
982
989
|
if (!track) throw new Error(options.track !== void 0 ? `There is no track "${options.track}".` : "The project has no video track.");
|
|
@@ -1009,7 +1016,7 @@ function toVideoEdl(project, options = {}) {
|
|
|
1009
1016
|
lines.push(row(n2, reel, `${t.type === "wipe" ? "W001" : "D"} ${frames}`, sourceAt(clip, recIn), sourceAt(clip, recOut), recIn, recOut));
|
|
1010
1017
|
} else lines.push(row(n2, reel, "C", sourceAt(clip, recIn), sourceAt(clip, recOut), recIn, recOut));
|
|
1011
1018
|
if (clip.type === "media" && videoClipSpeed(clip) !== 1) lines.push(`M2 ${reel.padEnd(8)} ${(videoClipSpeed(clip) * fps).toFixed(1).padStart(6)} ${tc(sourceAt(clip, recIn))}`);
|
|
1012
|
-
if (clip.type === "media") lines.push(`* FROM CLIP NAME: ${_nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess',
|
|
1019
|
+
if (clip.type === "media") lines.push(`* FROM CLIP NAME: ${_nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess', _22 => _22.name]), () => ( _optionalChain([asset, 'optionalAccess', _23 => _23.src]))), () => ( clip.asset))}`);
|
|
1013
1020
|
if (clip.type === "text") lines.push(`* TITLE: ${clip.text.replace(/\n/g, " ")}`);
|
|
1014
1021
|
if (clip.type === "color") lines.push(`* COLOR: ${clip.color}`);
|
|
1015
1022
|
lines.push("");
|
|
@@ -1052,6 +1059,7 @@ function toVideoFfmpeg(project, options = {}) {
|
|
|
1052
1059
|
const graph = [`color=c=${color(_nullishCoalesce(project.background, () => ( "#000000")))}:s=${W}x${H}:r=${fps}:d=${sec(D)},format=yuva420p[base]`];
|
|
1053
1060
|
const audio = [];
|
|
1054
1061
|
let cur = "base";
|
|
1062
|
+
let usesDrawtext = false;
|
|
1055
1063
|
let k = 0;
|
|
1056
1064
|
const input = (clip, asset, lead, tail) => {
|
|
1057
1065
|
const speed = videoClipSpeed(clip);
|
|
@@ -1083,7 +1091,7 @@ function toVideoFfmpeg(project, options = {}) {
|
|
|
1083
1091
|
if (lead) chain2.push(`afade=t=in:st=0:d=${sec(2 * lead)}`);
|
|
1084
1092
|
if (tail) chain2.push(`afade=t=out:st=${sec(span - 2 * tail)}:d=${sec(2 * tail)}`);
|
|
1085
1093
|
if (before2 && clip.transition.type === "dip") chain2.push(`afade=t=in:st=0:d=${sec(clip.transition.duration / 2)}`);
|
|
1086
|
-
const after = sortedVideoClips(track).find((c) => c !== clip && Math.abs(c.start - end) < 0.5 && _optionalChain([c, 'access',
|
|
1094
|
+
const after = sortedVideoClips(track).find((c) => c !== clip && Math.abs(c.start - end) < 0.5 && _optionalChain([c, 'access', _24 => _24.transition, 'optionalAccess', _25 => _25.type]) === "dip");
|
|
1087
1095
|
if (after) chain2.push(`afade=t=out:st=${sec(span - after.transition.duration / 2)}:d=${sec(after.transition.duration / 2)}`);
|
|
1088
1096
|
if (clip.fadeIn) chain2.push(`afade=t=in:st=${sec(lead)}:d=${sec(clip.fadeIn)}`);
|
|
1089
1097
|
if (clip.fadeOut) chain2.push(`afade=t=out:st=${sec(lead + clip.duration - clip.fadeOut)}:d=${sec(clip.fadeOut)}`);
|
|
@@ -1094,15 +1102,19 @@ function toVideoFfmpeg(project, options = {}) {
|
|
|
1094
1102
|
if (track.kind !== "video" || track.hidden) continue;
|
|
1095
1103
|
const enable = `enable='between(t,${sec(t0)},${sec(t0 + span)})'`;
|
|
1096
1104
|
const next = `v${k++}`;
|
|
1097
|
-
if (clip.type === "text") {
|
|
1105
|
+
if (clip.type === "text" && options.titleImage) {
|
|
1106
|
+
inputs.push(["-loop", "1", "-framerate", String(fps), "-t", sec(span), "-i", options.titleImage(clip, { width: project.width, height: project.height })]);
|
|
1107
|
+
index = inputs.length - 1;
|
|
1108
|
+
} else if (clip.type === "text") {
|
|
1109
|
+
usesDrawtext = true;
|
|
1098
1110
|
const op = _nullishCoalesce(clip.opacity, () => ( 1));
|
|
1099
1111
|
const alpha = [String(op), clip.fadeIn ? `min(1,(t-${sec(clip.start)})/${sec(clip.fadeIn)})` : "", clip.fadeOut ? `min(1,(${sec(end)}-t)/${sec(clip.fadeOut)})` : ""].filter(Boolean).join("*");
|
|
1100
|
-
const x = _nullishCoalesce(_optionalChain([clip, 'access',
|
|
1101
|
-
const y = _nullishCoalesce(_optionalChain([clip, 'access',
|
|
1112
|
+
const x = _nullishCoalesce(_optionalChain([clip, 'access', _26 => _26.transform, 'optionalAccess', _27 => _27.x]), () => ( 0));
|
|
1113
|
+
const y = _nullishCoalesce(_optionalChain([clip, 'access', _28 => _28.transform, 'optionalAccess', _29 => _29.y]), () => ( 0));
|
|
1102
1114
|
const opts = [
|
|
1103
1115
|
`text=${ffmpegFilterValue(clip.text)}`,
|
|
1104
1116
|
options.fontFile ? `fontfile=${ffmpegFilterValue(options.fontFile)}` : `font=${ffmpegFilterValue(_nullishCoalesce(clip.fontFamily, () => ( "sans-serif")))}`,
|
|
1105
|
-
`fontsize=${Math.round((_nullishCoalesce(clip.fontSize, () => ( 64))) * (_nullishCoalesce(_optionalChain([clip, 'access',
|
|
1117
|
+
`fontsize=${Math.round((_nullishCoalesce(clip.fontSize, () => ( 64))) * (_nullishCoalesce(_optionalChain([clip, 'access', _30 => _30.transform, 'optionalAccess', _31 => _31.scale]), () => ( 1))))}`,
|
|
1106
1118
|
`fontcolor=${color(_nullishCoalesce(clip.color, () => ( "#ffffff")))}`,
|
|
1107
1119
|
`x=(w-text_w)/2+${x}`,
|
|
1108
1120
|
`y=(h-text_h)/2+${y}`,
|
|
@@ -1110,13 +1122,13 @@ function toVideoFfmpeg(project, options = {}) {
|
|
|
1110
1122
|
...clip.background ? ["box=1", `boxcolor=${color(clip.background)}`, `boxborderw=${Math.round((_nullishCoalesce(clip.fontSize, () => ( 64))) / 2)}`] : [],
|
|
1111
1123
|
`enable='between(t,${sec(clip.start)},${sec(end)})'`
|
|
1112
1124
|
];
|
|
1113
|
-
if (_optionalChain([clip, 'access',
|
|
1125
|
+
if (_optionalChain([clip, 'access', _32 => _32.transform, 'optionalAccess', _33 => _33.rotation])) notes.push(`Title "${clip.id}" is drawn without its rotation (drawtext cannot rotate).`);
|
|
1114
1126
|
graph.push(`[${cur}]drawtext=${opts.join(":")}[${next}]`);
|
|
1115
1127
|
cur = next;
|
|
1116
1128
|
continue;
|
|
1117
1129
|
}
|
|
1118
1130
|
const size = asset ? { width: _nullishCoalesce(asset.width, () => ( project.width)), height: _nullishCoalesce(asset.height, () => ( project.height)) } : { width: project.width, height: project.height };
|
|
1119
|
-
const rect = placeVideoRect(project, size, _nullishCoalesce(clip.fit, () => ( (clip.type === "media" ? "contain" : "fill"))), clip.transform);
|
|
1131
|
+
const rect = clip.type === "text" ? { x: 0, y: 0, width: project.width, height: project.height } : placeVideoRect(project, size, _nullishCoalesce(clip.fit, () => ( (clip.type === "media" ? "contain" : "fill"))), clip.transform);
|
|
1120
1132
|
const chain = [];
|
|
1121
1133
|
let source;
|
|
1122
1134
|
if (clip.type === "color") source = `color=c=${color(clip.color)}:s=${even(rect.width)}x${even(rect.height)}:r=${fps}:d=${sec(span)}`;
|
|
@@ -1136,7 +1148,7 @@ function toVideoFfmpeg(project, options = {}) {
|
|
|
1136
1148
|
const test = dir === "right" ? `lt(X,W*${p})` : dir === "left" ? `gt(X,W*(1-${p}))` : dir === "down" ? `lt(Y,H*${p})` : `gt(Y,H*(1-${p}))`;
|
|
1137
1149
|
chain.push(`geq=lum='lum(X,Y)':cb='cb(X,Y)':cr='cr(X,Y)':a='if(${test},alpha(X,Y),0)'`);
|
|
1138
1150
|
}
|
|
1139
|
-
if (_optionalChain([clip, 'access',
|
|
1151
|
+
if (_optionalChain([clip, 'access', _34 => _34.transform, 'optionalAccess', _35 => _35.rotation]) && clip.type !== "text") chain.push(`rotate=${clip.transform.rotation}*PI/180:c=none:ow=rotw(${clip.transform.rotation}*PI/180):oh=roth(${clip.transform.rotation}*PI/180)`);
|
|
1140
1152
|
chain.push(`setpts=PTS+${sec(t0)}/TB`);
|
|
1141
1153
|
const cx = rect.x + rect.width / 2;
|
|
1142
1154
|
const cy = rect.y + rect.height / 2;
|
|
@@ -1155,8 +1167,9 @@ function toVideoFfmpeg(project, options = {}) {
|
|
|
1155
1167
|
}
|
|
1156
1168
|
graph.push(`[${cur}]format=yuv420p[vout]`);
|
|
1157
1169
|
if (audio.length) graph.push(`${audio.join("")}amix=inputs=${audio.length}:normalize=0:duration=longest,apad,atrim=0:${sec(D)}[aout]`);
|
|
1158
|
-
if (project.tracks.some((t) => t.clips.some((c) => c.type === "media" && _optionalChain([assets, 'access',
|
|
1170
|
+
if (project.tracks.some((t) => t.clips.some((c) => c.type === "media" && _optionalChain([assets, 'access', _36 => _36.get, 'call', _37 => _37(c.asset), 'optionalAccess', _38 => _38.kind]) === "video" && _optionalChain([assets, 'access', _39 => _39.get, 'call', _40 => _40(c.asset), 'optionalAccess', _41 => _41.hasAudio]) === void 0)))
|
|
1159
1171
|
notes.push('Video assets are assumed to have sound; set "hasAudio": false on any that do not, or ffmpeg will stop at a missing audio stream.');
|
|
1172
|
+
if (usesDrawtext) notes.push("Titles use drawtext, which needs an ffmpeg built with libfreetype (Homebrew's is not: check `ffmpeg -filters | grep drawtext`); pass titleImage to render them as images instead.");
|
|
1160
1173
|
const filterComplex = graph.join(";");
|
|
1161
1174
|
const args = [
|
|
1162
1175
|
"-y",
|
|
@@ -1186,7 +1199,7 @@ var VideoPreviewEngine = (_class2 = class {
|
|
|
1186
1199
|
this.source = source;
|
|
1187
1200
|
this.options = options;
|
|
1188
1201
|
this.canvas = canvas;
|
|
1189
|
-
this.ctx = options.context !== void 0 ? options.context : _nullishCoalesce(_optionalChain([canvas, 'access',
|
|
1202
|
+
this.ctx = options.context !== void 0 ? options.context : _nullishCoalesce(_optionalChain([canvas, 'access', _42 => _42.getContext, 'optionalCall', _43 => _43("2d")]), () => ( null));
|
|
1190
1203
|
this.unsubscribe = source.subscribe(() => this.update());
|
|
1191
1204
|
this.update();
|
|
1192
1205
|
}
|
|
@@ -1234,8 +1247,8 @@ var VideoPreviewEngine = (_class2 = class {
|
|
|
1234
1247
|
entry.media.pause();
|
|
1235
1248
|
entry.media.removeEventListener("seeked", entry.onReady);
|
|
1236
1249
|
entry.media.removeEventListener("loadeddata", entry.onReady);
|
|
1237
|
-
_optionalChain([entry, 'access',
|
|
1238
|
-
_optionalChain([entry, 'access',
|
|
1250
|
+
_optionalChain([entry, 'access', _44 => _44.media, 'access', _45 => _45.removeAttribute, 'optionalCall', _46 => _46("src")]);
|
|
1251
|
+
_optionalChain([entry, 'access', _47 => _47.media, 'access', _48 => _48.load, 'optionalCall', _49 => _49()]);
|
|
1239
1252
|
this.media.delete(entry.clip);
|
|
1240
1253
|
}
|
|
1241
1254
|
/** Brings the media elements in step with the editor and draws the frame. */
|
|
@@ -1268,7 +1281,7 @@ var VideoPreviewEngine = (_class2 = class {
|
|
|
1268
1281
|
for (const layer of frame.layers) {
|
|
1269
1282
|
if (layer.type !== "media" || layer.assetKind !== "video" || !layer.src) continue;
|
|
1270
1283
|
const sound = sounding.get(layer.clip);
|
|
1271
|
-
sync(layer.clip, layer.src, "video", _nullishCoalesce(layer.sourceTime, () => ( 0)), _nullishCoalesce(_optionalChain([sound, 'optionalAccess',
|
|
1284
|
+
sync(layer.clip, layer.src, "video", _nullishCoalesce(layer.sourceTime, () => ( 0)), _nullishCoalesce(_optionalChain([sound, 'optionalAccess', _50 => _50.speed]), () => ( 1)), sound ? sound.gain : null);
|
|
1272
1285
|
sounding.delete(layer.clip);
|
|
1273
1286
|
}
|
|
1274
1287
|
for (const a of sounding.values()) sync(a.clip, a.src, "audio", a.sourceTime, a.speed, a.gain);
|
|
@@ -1301,7 +1314,7 @@ var VideoPreviewEngine = (_class2 = class {
|
|
|
1301
1314
|
if (this.canvas.width !== w) this.canvas.width = w;
|
|
1302
1315
|
if (this.canvas.height !== h) this.canvas.height = h;
|
|
1303
1316
|
drawVideoFrame(this.ctx, frame, this.sourceFor, resolution);
|
|
1304
|
-
_optionalChain([this, 'access',
|
|
1317
|
+
_optionalChain([this, 'access', _51 => _51.options, 'access', _52 => _52.onFrame, 'optionalCall', _53 => _53(frame)]);
|
|
1305
1318
|
}
|
|
1306
1319
|
/** Stops following the editor and releases every media element. */
|
|
1307
1320
|
destroy() {
|
|
@@ -1408,7 +1421,7 @@ var VideoEditorController = (_class3 = class {
|
|
|
1408
1421
|
this.applying = false;
|
|
1409
1422
|
}
|
|
1410
1423
|
this.notify();
|
|
1411
|
-
_optionalChain([this, 'access',
|
|
1424
|
+
_optionalChain([this, 'access', _54 => _54.onChange, 'optionalCall', _55 => _55(project)]);
|
|
1412
1425
|
}
|
|
1413
1426
|
commit(label, next) {
|
|
1414
1427
|
const before = this.project;
|
|
@@ -1472,7 +1485,7 @@ var VideoEditorController = (_class3 = class {
|
|
|
1472
1485
|
}
|
|
1473
1486
|
/** Selects clips (unknown ids are dropped). `add` toggles them into the current selection. */
|
|
1474
1487
|
select(clips, options = {}) {
|
|
1475
|
-
const known = _nullishCoalesce(_optionalChain([clips, 'optionalAccess',
|
|
1488
|
+
const known = _nullishCoalesce(_optionalChain([clips, 'optionalAccess', _56 => _56.filter, 'call', _57 => _57((id) => findVideoClip(this.project, id))]), () => ( []));
|
|
1476
1489
|
let next;
|
|
1477
1490
|
if (options.add) {
|
|
1478
1491
|
next = [...this.selection];
|
|
@@ -2069,7 +2082,7 @@ function videoClipLabel(clip, asset) {
|
|
|
2069
2082
|
if (clip.name) return clip.name;
|
|
2070
2083
|
if (clip.type === "text") return clip.text.split("\n")[0];
|
|
2071
2084
|
if (clip.type === "color") return clip.color;
|
|
2072
|
-
const base = _nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess',
|
|
2085
|
+
const base = _nullishCoalesce(_nullishCoalesce(_optionalChain([asset, 'optionalAccess', _58 => _58.name]), () => ( _optionalChain([asset, 'optionalAccess', _59 => _59.src, 'access', _60 => _60.replace, 'call', _61 => _61(/^.*[\\/]/, "")]))), () => ( clip.asset));
|
|
2073
2086
|
const speed = videoClipSpeed(clip);
|
|
2074
2087
|
return speed !== 1 ? `${base} (${Math.round(speed * 100)}%)` : base;
|
|
2075
2088
|
}
|
|
@@ -2108,7 +2121,7 @@ function videoAssetDropEdit(project, assetId, options = {}) {
|
|
|
2108
2121
|
const asset = videoAssetMap(project).get(assetId);
|
|
2109
2122
|
if (!asset) return null;
|
|
2110
2123
|
const kind = asset.kind === "audio" ? "audio" : "video";
|
|
2111
|
-
const track = _nullishCoalesce(options.track, () => ( _optionalChain([project, 'access',
|
|
2124
|
+
const track = _nullishCoalesce(options.track, () => ( _optionalChain([project, 'access', _62 => _62.tracks, 'access', _63 => _63.find, 'call', _64 => _64((t) => t.kind === kind && !t.locked), 'optionalAccess', _65 => _65.id])));
|
|
2112
2125
|
if (!track) return null;
|
|
2113
2126
|
return { op: "add_clip", track, clip: { type: "media", asset: asset.id, ...options.start !== void 0 ? { start: options.start } : {} }, ...options.ripple ? { ripple: true } : {} };
|
|
2114
2127
|
}
|
|
@@ -2215,5 +2228,7 @@ function probeVideoMedia(src, kind, timeout = 15e3) {
|
|
|
2215
2228
|
|
|
2216
2229
|
|
|
2217
2230
|
|
|
2218
|
-
|
|
2231
|
+
|
|
2232
|
+
|
|
2233
|
+
exports.VIDEO_CLIP_TYPES = VIDEO_CLIP_TYPES; exports.VIDEO_DEFAULT_STILL_DURATION = VIDEO_DEFAULT_STILL_DURATION; exports.VIDEO_DEFAULT_TITLE_DURATION = VIDEO_DEFAULT_TITLE_DURATION; exports.VIDEO_EDIT_OPS = VIDEO_EDIT_OPS; exports.VIDEO_FITS = VIDEO_FITS; exports.VIDEO_ISSUE_CODES = VIDEO_ISSUE_CODES; exports.VIDEO_TIME_EPSILON = VIDEO_TIME_EPSILON; exports.VIDEO_TRANSITION_TYPES = VIDEO_TRANSITION_TYPES; exports.VIDEO_WIPE_DIRECTIONS = VIDEO_WIPE_DIRECTIONS; exports.VideoEditorController = VideoEditorController; exports.VideoPreviewEngine = VideoPreviewEngine; exports.allVideoClipIds = allVideoClipIds; exports.applyVideoEdits = applyVideoEdits; exports.checkVideoProject = checkVideoProject; exports.createVideoEditorToolProvider = createVideoEditorToolProvider; exports.createVideoProject = createVideoProject; exports.describeVideoProject = describeVideoProject; exports.drawVideoFrame = drawVideoFrame; exports.ffmpegFilterValue = ffmpegFilterValue; exports.findVideoClip = findVideoClip; exports.findVideoGaps = findVideoGaps; exports.formatVideoSeconds = formatVideoSeconds; exports.formatVideoTimecode = formatVideoTimecode; exports.nextFreeVideoSlot = nextFreeVideoSlot; exports.parseVideoAsset = parseVideoAsset; exports.parseVideoClip = parseVideoClip; exports.parseVideoMarker = parseVideoMarker; exports.parseVideoProject = parseVideoProject; exports.parseVideoTrack = parseVideoTrack; exports.parseVideoTransform = parseVideoTransform; exports.parseVideoTransition = parseVideoTransition; exports.placeVideoRect = placeVideoRect; exports.planVideoClipDrag = planVideoClipDrag; exports.probeVideoMedia = probeVideoMedia; exports.snapToVideoFrame = snapToVideoFrame; exports.snapVideoTime = snapVideoTime; exports.sortedVideoClips = sortedVideoClips; exports.toVideoEdl = toVideoEdl; exports.toVideoFfmpeg = toVideoFfmpeg; exports.videoAssetDropEdit = videoAssetDropEdit; exports.videoAssetKindOf = videoAssetKindOf; exports.videoAssetMap = videoAssetMap; exports.videoClipAfter = videoClipAfter; exports.videoClipBefore = videoClipBefore; exports.videoClipEnd = videoClipEnd; exports.videoClipHandles = videoClipHandles; exports.videoClipLabel = videoClipLabel; exports.videoClipOverhang = videoClipOverhang; exports.videoClipSourceRange = videoClipSourceRange; exports.videoClipSpeed = videoClipSpeed; exports.videoClipTint = videoClipTint; exports.videoClipsAt = videoClipsAt; exports.videoContactSheetSvg = videoContactSheetSvg; exports.videoDropTracks = videoDropTracks; exports.videoFrameAt = videoFrameAt; exports.videoFrameDuration = videoFrameDuration; exports.videoFrameToSvg = videoFrameToSvg; exports.videoFrames = videoFrames; exports.videoIssueKey = videoIssueKey; exports.videoOverlap = videoOverlap; exports.videoProjectDuration = videoProjectDuration; exports.videoProjectSvg = videoProjectSvg; exports.videoRulerTicks = videoRulerTicks; exports.videoSnapPoints = videoSnapPoints; exports.videoTextStyle = videoTextStyle; exports.videoTitleFrame = videoTitleFrame; exports.videoWipeRect = videoWipeRect;
|
|
2219
2234
|
//# sourceMappingURL=index.cjs.map
|