This commit is contained in:
Sam Lavigne 2023-08-24 14:14:32 -04:00
parent 648dadaeca
commit 66327ad1c8
3 changed files with 201 additions and 182 deletions

View File

@ -5,8 +5,8 @@
import Output from "./Output.svelte"; import Output from "./Output.svelte";
import Filter from "./Filter.svelte"; import Filter from "./Filter.svelte";
import FilterPicker from "./FilterPicker.svelte"; import FilterPicker from "./FilterPicker.svelte";
// import Graph from "./Graph.svelte"; import Graph from "./Graph.svelte";
import GraphOld from "./GraphOld.svelte"; // import GraphOld from "./GraphOld.svelte";
import { FFmpeg } from "@ffmpeg/ffmpeg"; import { FFmpeg } from "@ffmpeg/ffmpeg";
import { fetchFile, toBlobURL } from "@ffmpeg/util"; import { fetchFile, toBlobURL } from "@ffmpeg/util";
import { dndzone } from "svelte-dnd-action"; import { dndzone } from "svelte-dnd-action";
@ -195,13 +195,13 @@
</div> </div>
</section> </section>
<section class="graph">
<GraphOld />
</section>
<!-- <section class="graph"> --> <!-- <section class="graph"> -->
<!-- <Graph /> --> <!-- <GraphOld /> -->
<!-- </section> --> <!-- </section> -->
<section class="graph">
<Graph />
</section>
</main> </main>
<style> <style>

View File

@ -7,51 +7,6 @@
ffmpeg: Node, ffmpeg: Node,
}; };
console.log($nodes);
// const nodes = writable([
// {
// id: "1",
// type: "ffmpeg",
// data: { label: "test.mp4", inputs: [], outputs: ["v", "a"] },
// position: { x: 0, y: 0 },
// },
// {
// id: "2",
// type: "ffmpeg",
// data: { label: "filter", inputs: ["v"], outputs: ["v"] },
// position: { x: 0, y: 150 },
// },
// {
// id: "3",
// type: "ffmpeg",
// data: { label: "output.mp4", inputs: ["v", "a"], outputs: [] },
// position: { x: 100, y: 20 },
// },
// ]);
// same for edges
// const edges = writable([
// {
// id: "1-2",
// type: "default",
// source: "1",
// sourceHandle: "v_0",
// targetHandle: "v_0",
// target: "2",
// label: "Edge Text",
// },
// {
// id: "2-3",
// type: "default",
// source: "2",
// target: "3",
// sourceHandle: "v_0",
// targetHandle: "v_0",
// label: "Edge Text",
// },
// ]);
const defaultEdgeOptions = { const defaultEdgeOptions = {
deletable: true, deletable: true,
}; };

View File

@ -8,6 +8,8 @@ export const nodes = writable([]);
export const edges = writable([]); export const edges = writable([]);
export const auto = writable(true); export const auto = writable(true);
const PREFIX = "";
addNode({ name: "punch.mp4" }, "input"); addNode({ name: "punch.mp4" }, "input");
addNode({ name: "out.mp4" }, "output"); addNode({ name: "out.mp4" }, "output");
@ -26,136 +28,138 @@ function makeFilterArgs(f) {
return fCommand; return fCommand;
} }
export const previewCommand = derived([edges, nodes], ([$edges, $nodes]) => { export const previewCommandSvelvet = derived([edges, nodes], ([$edges, $nodes]) => {
// [0:v]f1=val,f2=val[out] -map out // [0:v]f1=val,f2=val[out] -map out
// [0:v]f1=val,f2=val[1];[1][1:v]overlay[out] -map out` // [0:v]f1=val,f2=val[1];[1][1:v]overlay[out] -map out`
let finalCommand = []; let finalCommand = [];
let filtergraph = []; let filtergraph = [];
const inputs = $nodes.filter(n => n.nodeType == "input"); const inputs = $nodes.filter((n) => n.nodeType == "input");
const outputs = $nodes.filter(n => n.nodeType == "output"); const outputs = $nodes.filter((n) => n.nodeType == "output");
const inputIds = {}; const inputIds = {};
for (let i=0; i<inputs.length; i++) { for (let i = 0; i < inputs.length; i++) {
const inp = inputs[i]; const inp = inputs[i];
inputIds[inp.id] = i; inputIds[inp.id] = i;
} }
const edgeIds = {}; const edgeIds = {};
for (let i = 0; i < $edges.length; i++) { for (let i = 0; i < $edges.length; i++) {
const e = $edges[i]; const e = $edges[i];
edgeIds[e.id] = i + 1; edgeIds[e.id] = i + 1;
const source = $nodes.find(n => "N-" + n.id === e.source); const source = $nodes.find((n) => PREFIX + n.id === e.source);
const target = $nodes.find(n => "N-" + n.id === e.target); const target = $nodes.find((n) => PREFIX + n.id === e.target);
if (!source || !target) continue; if (!source || !target) continue;
if (source.nodeType === "input") { if (source.nodeType === "input") {
if (e.sourceAnchor.startsWith("A-v")) { if (e.sourceAnchor.startsWith("A-v")) {
edgeIds[e.id] = inputIds[source.id] + ":v"; edgeIds[e.id] = inputIds[source.id] + ":v";
} }
if (e.sourceAnchor.startsWith("A-a")) { if (e.sourceAnchor.startsWith("A-a")) {
edgeIds[e.id] = inputIds[source.id] + ":a"; edgeIds[e.id] = inputIds[source.id] + ":a";
} }
} }
if (target.nodeType === "output") {
edgeIds[e.id] = "out";
}
}
if (target.nodeType === "output") {
edgeIds[e.id] = "out";
}
}
for (let n of $nodes.filter((n) => n.nodeType == "filter")) { for (let n of $nodes.filter((n) => n.nodeType == "filter")) {
let cmd = ""; let cmd = "";
const outs = $edges.filter((e) => e.source == "N-" + n.id); const outs = $edges.filter((e) => e.source == PREFIX + n.id);
const ins = $edges.filter((e) => e.target == "N-" + n.id); const ins = $edges.filter((e) => e.target == PREFIX + n.id);
if (outs.length == 0 && ins.length == 0) continue; if (outs.length == 0 && ins.length == 0) continue;
for (let i of ins) { for (let i of ins) {
const eid = edgeIds[i.id]; const eid = edgeIds[i.id];
cmd += `[${eid}]` cmd += `[${eid}]`;
} }
cmd += makeFilterArgs(n.data); cmd += makeFilterArgs(n.data);
for (let o of outs) { for (let o of outs) {
const eid = edgeIds[o.id]; const eid = edgeIds[o.id];
cmd += `[${eid}]` cmd += `[${eid}]`;
} }
filtergraph.push(cmd); filtergraph.push(cmd);
} }
finalCommand.push("ffmpeg"); finalCommand.push("ffmpeg");
for (let inp of inputs) { for (let inp of inputs) {
finalCommand.push("-i"); finalCommand.push("-i");
finalCommand.push(inp.data.name); finalCommand.push(inp.data.name);
} }
finalCommand.push("-filter_complex") finalCommand.push("-filter_complex");
finalCommand.push('"' + filtergraph.join(';') + '"'); finalCommand.push('"' + filtergraph.join(";") + '"');
for (let out of outputs) { for (let out of outputs) {
finalCommand.push("-map"); finalCommand.push("-map");
finalCommand.push('"[out]"'); finalCommand.push('"[out]"');
} }
for (let inp of inputs) { for (let inp of inputs) {
finalCommand.push("-map"); finalCommand.push("-map");
finalCommand.push(inputIds[inp.id] + ":a"); finalCommand.push(inputIds[inp.id] + ":a");
} }
for (let out of outputs) { for (let out of outputs) {
finalCommand.push(out.data.name); finalCommand.push(out.data.name);
} }
const entireCommand = finalCommand.join(" "); const entireCommand = finalCommand.join(" ");
return entireCommand; return entireCommand;
}); });
export const previewCommandOld2 = derived([edges, nodes], ([$edges, $nodes]) => { export const previewCommand = derived([edges, nodes], ([$edges, $nodes]) => {
// [0:v]f1=val,f2=val[out] -map out // [0:v]f1=val,f2=val[out] -map out
// [0:v]f1=val,f2=val[1];[1][1:v]overlay[out] -map out` // [0:v]f1=val,f2=val[1];[1][1:v]overlay[out] -map out`
let finalCommand = []; let hasVid = false;
let hasAud = false;
let finalCommand = [];
let filtergraph = []; let filtergraph = [];
const inputs = $nodes.filter(n => n.nodeType == "input"); const inputs = $nodes.filter((n) => n.nodeType == "input");
const outputs = $nodes.filter(n => n.nodeType == "output"); const outputs = $nodes.filter((n) => n.nodeType == "output");
const inputIds = {}; const inputIds = {};
for (let i=0; i<inputs.length; i++) { for (let i = 0; i < inputs.length; i++) {
const inp = inputs[i]; const inp = inputs[i];
inputIds[inp.id] = i; inputIds[inp.id] = i;
} }
const edgeIds = {}; const edgeIds = {};
for (let i = 0; i < $edges.length; i++) { for (let i = 0; i < $edges.length; i++) {
const e = $edges[i]; const e = $edges[i];
edgeIds[e.id] = i + 1; edgeIds[e.id] = i + 1;
const source = $nodes.find(n => n.id === e.source); const source = $nodes.find((n) => n.id === e.source);
const target = $nodes.find(n => n.id === e.target); const target = $nodes.find((n) => n.id === e.target);
if (source.nodeType === "input") { if (source.nodeType === "input") {
if (e.sourceHandle.includes("v")) { if (e.sourceHandle.includes("v")) {
edgeIds[e.id] = inputIds[source.id] + ":v"; edgeIds[e.id] = inputIds[source.id] + ":v";
} }
if (e.sourceHandle.includes("a")) { if (e.sourceHandle.includes("a")) {
edgeIds[e.id] = inputIds[source.id] + ":a"; edgeIds[e.id] = inputIds[source.id] + ":a";
} }
} }
if (target.nodeType === "output") {
edgeIds[e.id] = "out";
}
}
if (target.nodeType === "output") {
const outType = e.targetHandle.includes("a") ? "aud_out" : "vid_out";
edgeIds[e.id] = outType;
}
}
for (let n of $nodes.filter((n) => n.nodeType == "filter")) { for (let n of $nodes.filter((n) => n.nodeType == "filter")) {
let cmd = ""; let cmd = "";
@ -166,44 +170,56 @@ export const previewCommandOld2 = derived([edges, nodes], ([$edges, $nodes]) =>
if (outs.length == 0 && ins.length == 0) continue; if (outs.length == 0 && ins.length == 0) continue;
for (let i of ins) { for (let i of ins) {
const eid = edgeIds[i.id]; const eid = edgeIds[i.id];
cmd += `[${eid}]` cmd += `[${eid}]`;
} }
cmd += makeFilterArgs(n.data); cmd += makeFilterArgs(n.data);
for (let o of outs) { for (let o of outs) {
const eid = edgeIds[o.id]; const eid = edgeIds[o.id];
cmd += `[${eid}]` cmd += `[${eid}]`;
} }
filtergraph.push(cmd); filtergraph.push(cmd);
} }
finalCommand.push("ffmpeg"); finalCommand.push("ffmpeg");
for (let inp of inputs) { for (let inp of inputs) {
finalCommand.push("-i"); finalCommand.push("-i");
finalCommand.push(inp.data.name); finalCommand.push(inp.data.name);
} }
finalCommand.push("-filter_complex") if (filtergraph.length > 0) {
const fg = '"' + filtergraph.join(";") + '"';
hasVid = fg.includes(":v]")
hasAud = fg.includes(":a]")
finalCommand.push('"' + filtergraph.join(';') + '"'); finalCommand.push("-filter_complex");
finalCommand.push(fg);
for (let out of outputs) {
finalCommand.push("-map"); finalCommand.push("-map");
finalCommand.push('"[out]"'); if (hasAud) {
} finalCommand.push('"[aud_out]"');
} else {
finalCommand.push('0:a');
}
for (let inp of inputs) { if (hasVid) {
finalCommand.push("-map"); finalCommand.push("-map");
finalCommand.push(inputIds[inp.id] + ":a"); finalCommand.push('"[vid_out]"');
} }
}
for (let out of outputs) { // for (let inp of inputs) {
finalCommand.push(out.data.name); // finalCommand.push("-map");
} // finalCommand.push(inputIds[inp.id] + ":a");
// }
const entireCommand = finalCommand.join(" "); for (let out of outputs) {
return entireCommand; finalCommand.push(out.data.name);
}
const entireCommand = finalCommand.join(" ");
return entireCommand;
}); });
export const previewCommandOld = derived(nodes, ($nodes) => { export const previewCommandOld = derived(nodes, ($nodes) => {
@ -243,6 +259,65 @@ export const output = derived(nodes, ($nodes) => {
return $nodes.filter((n) => n.nodeType === "output").map((n) => n.data); return $nodes.filter((n) => n.nodeType === "output").map((n) => n.data);
}); });
nodes.subscribe(($nodes) => {
console.log($nodes);
const isAuto = get(auto);
if (!isAuto) return;
const outputNodes = $nodes.filter((n) => n.nodeType === "output");
const inputNodes = $nodes.filter((n) => n.nodeType === "input");
const filterNodes = $nodes.filter((n) => n.nodeType === "filter");
const orderedNodes = []
.concat(inputNodes, filterNodes, outputNodes)
.filter((n) => n != undefined);
const filled = [];
// find next open output for same input
let newEdges = [];
for (let i = 0; i < orderedNodes.length; i++) {
const n1 = orderedNodes[i];
for (let j = 0; j < n1.data.outputs.length; j++) {
const edgeType = n1.data.outputs[j];
for (let k = i + 1; k < orderedNodes.length; k++) {
const n2 = orderedNodes[k];
const ind = n2.data.inputs.indexOf(edgeType);
if (ind > -1 && !filled.includes(n2.id + edgeType + ind)) {
newEdges.push({
id: uuidv4(),
type: "default",
source: n1.id,
target: n2.id,
sourceHandle: edgeType + "_" + j,
targetHandle: edgeType + "_" + ind,
});
filled.push(n2.id + edgeType + ind);
break;
}
}
}
}
// for (let i = 0; i < orderedNodes.length - 1; i++) {
// const n1 = orderedNodes[i];
// const n2 = orderedNodes[i + 1];
// for (let j = 0; j < n1.data.outputs.length; j++) {
// const edgeType = n1.data.outputs[j];
// if (n2.data.inputs.includes(edgeType)) {
// newEdges.push({
// id: uuidv4(),
// type: "default",
// source: n1.id,
// target: n2.id,
// sourceHandle: edgeType + "_0",
// targetHandle: edgeType + "_0",
// });
// }
// }
// }
console.log("new", newEdges);
edges.set(newEdges);
});
export function addNode(data, type) { export function addNode(data, type) {
let ins = []; let ins = [];
let outs = []; let outs = [];
@ -271,9 +346,7 @@ export function addNode(data, type) {
const h = 50; const h = 50;
const margin = 10; const margin = 10;
const existing = get(nodes); let existing = get(nodes);
const ouputNode = existing.find(n => n.nodeType === 'output');
const inputNodes = existing.find(n => n.nodeType === "input");
if (type === "input") { if (type === "input") {
const inps = existing.filter((n) => n.nodeType === "input"); const inps = existing.filter((n) => n.nodeType === "input");
@ -288,7 +361,6 @@ export function addNode(data, type) {
data.inputs = ins; data.inputs = ins;
data.outputs = outs; data.outputs = outs;
let node = { let node = {
id: uuidv4(), id: uuidv4(),
type: "ffmpeg", type: "ffmpeg",
@ -302,15 +374,7 @@ export function addNode(data, type) {
return n; return n;
}); });
if (auto) { //autolayout();
const prev = existing[existing.length - 2];
if (prev) {
// set each prev out to new node in
// set new node out to output in
}
}
//autolayout();
// edges.update((_edges) => { // edges.update((_edges) => {
// const target = existing[existing.length - 2]; // const target = existing[existing.length - 2];
@ -333,13 +397,13 @@ export function removeNode(id) {
return _nodes; return _nodes;
}); });
edges.update((_edges) => { edges.update((_edges) => {
for (let i=_edges.length-1; i--; i>=0) { for (let i = _edges.length - 1; i--; i >= 0) {
const e = _edges[i]; const e = _edges[i];
if ("N-" + e.source === id || "N-" + e.target === id) { if ("N-" + e.source === id || "N-" + e.target === id) {
_edges.splice(i, 1); _edges.splice(i, 1);
} }
} }
return _edges; return _edges;
}); });
} }