file uploads

This commit is contained in:
Sam Lavigne 2023-08-30 18:01:10 -04:00
parent 88f4aa920f
commit 2196c17e04
4 changed files with 341 additions and 315 deletions

View File

@ -1,6 +1,15 @@
<script> <script>
import { onMount } from "svelte"; import { onMount } from "svelte";
import { selectedFilter, nodes, inputs, outputs, previewCommand } from "./stores.js"; import {
selectedFilter,
nodes,
inputs,
outputs,
auto,
addNode,
inputNames,
previewCommand,
} from "./stores.js";
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";
@ -9,9 +18,7 @@
const isChrome = navigator.userAgent.match(/chrome|chromium|crios/i); const isChrome = navigator.userAgent.match(/chrome|chromium|crios/i);
const baseURL = `https://unpkg.com/@ffmpeg/core${!isChrome ? "-mt" : ""}@0.12.2/dist/esm`; const baseURL = `https://unpkg.com/@ffmpeg/core${!isChrome ? "-mt" : ""}@0.12.2/dist/esm`;
// const baseURL = "";
const TIMEOUT = 40000; const TIMEOUT = 40000;
const ffmpeg = new FFmpeg(); const ffmpeg = new FFmpeg();
let videoValue = "/" + $inputs[0].name; let videoValue = "/" + $inputs[0].name;
@ -22,6 +29,18 @@
let commandRef; let commandRef;
let vidPlayerRef; let vidPlayerRef;
let renderProgress = 0; let renderProgress = 0;
let fileinput;
function addInput() {
addNode({ ...$inputNames[$inputNames.length - 1] }, "input");
}
async function onFileSelected(e) {
let vid = e.target.files[0];
await ffmpeg.writeFile(vid.name, await fetchFile(vid));
$inputNames.push({ name: vid.name, url: vid.name });
addInput();
}
function copyCommand() { function copyCommand() {
commandRef.select(); commandRef.select();
@ -38,20 +57,18 @@
try { try {
if (log.trim() != "") log += "\n\n"; if (log.trim() != "") log += "\n\n";
for (let vid of $inputs) { const fontNames = [
await ffmpeg.writeFile(vid.name, await fetchFile("/" + vid.name)); ...new Set([...$previewCommand.join(" ").matchAll(/\W([a-z]+\.ttf)/g)].map((f) => f[1])),
} ];
const fontNames = [...new Set([...$previewCommand.join(" ").matchAll(/\W([a-z]+\.ttf)/g)].map(f => f[1]))];
for (let f of fontNames) { for (let f of fontNames) {
await ffmpeg.writeFile(f, await fetchFile("/" + f)); await ffmpeg.writeFile(f, await fetchFile("/" + f));
} }
let clist = [...$previewCommand]; let clist = [...$previewCommand];
clist.shift() // remove "ffmpeg" from start of command clist.shift(); // remove "ffmpeg" from start of command
clist.unshift("-hide_banner", "-loglevel", "error") clist.unshift("-hide_banner", "-loglevel", "error");
clist = clist.map(c => c.replaceAll('"', "")); clist = clist.map((c) => c.replaceAll('"', ""));
if (outname.endsWith("mp4")) { if (outname.endsWith("mp4")) {
clist.splice(clist.length - 1, 0, "-pix_fmt"); clist.splice(clist.length - 1, 0, "-pix_fmt");
clist.splice(clist.length - 1, 0, "yuv420p"); clist.splice(clist.length - 1, 0, "yuv420p");
@ -95,6 +112,9 @@
workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, "text/javascript"), workerURL: await toBlobURL(`${baseURL}/ffmpeg-core.worker.js`, "text/javascript"),
}); });
} }
for (let vid of $inputNames) {
await ffmpeg.writeFile(vid.name, await fetchFile(vid.url));
}
ffmpegLoaded = true; ffmpegLoaded = true;
} }
@ -196,7 +216,23 @@
</section> </section>
<section class="graph"> <section class="graph">
<Graph /> <div class="graph-holder">
<div class="nav">
<button on:click={addInput}>Add Sample Input</button>
<button on:click={() => fileinput.click()}>Upload File</button>
<input
type="file"
accept="video/*"
on:change={(e) => onFileSelected(e)}
bind:this={fileinput}
style="display: none;"
/>
<label for="auto"
><input id="auto" type="checkbox" bind:checked={$auto} />Automatic Layout</label
>
</div>
<Graph {fetchFile} ffmepg={ffmpeg} />
</div>
</section> </section>
<section class="filter-editor"> <section class="filter-editor">
@ -383,6 +419,11 @@
ol li { ol li {
margin-bottom: 5px; margin-bottom: 5px;
} }
.graph-holder {
flex-direction: column;
display: flex;
flex: 1;
}
@media only screen and (max-width: 1400px) { @media only screen and (max-width: 1400px) {
} }

View File

@ -1,5 +1,5 @@
<script> <script>
import { addNode, nodes, edges, auto, selectedFilter } from "./stores.js"; import { nodes, edges, auto, selectedFilter } from "./stores.js";
import { import {
SvelteFlowProvider, SvelteFlowProvider,
SvelteFlow, SvelteFlow,
@ -7,7 +7,7 @@
Background, Background,
BackgroundVariant, BackgroundVariant,
} from "@xyflow/svelte"; } from "@xyflow/svelte";
import '@xyflow/svelte/dist/style.css'; import "@xyflow/svelte/dist/style.css";
import Node from "./Node.svelte"; import Node from "./Node.svelte";
import FitComp from "./FitComp.svelte"; import FitComp from "./FitComp.svelte";
import ButtonEdge from "./ButtonEdge.svelte"; import ButtonEdge from "./ButtonEdge.svelte";
@ -28,22 +28,10 @@
} }
} }
} }
function addInput() {
addNode({ name: "shoe.mp4" }, "input");
}
</script> </script>
<SvelteFlowProvider> <SvelteFlowProvider>
<div class="holder">
<FitComp /> <FitComp />
<div class="nav">
<button on:click={addInput}>Add Input</button>
<label for="auto"
><input id="auto" type="checkbox" bind:checked={$auto} />Automatic Layout</label
>
</div>
<div class="flow"> <div class="flow">
<div style="height: 100%; width: 100%"> <div style="height: 100%; width: 100%">
<SvelteFlow <SvelteFlow
@ -72,15 +60,9 @@
</SvelteFlow> </SvelteFlow>
</div> </div>
</div> </div>
</div>
</SvelteFlowProvider> </SvelteFlowProvider>
<style> <style>
.holder {
flex-direction: column;
display: flex;
flex: 1;
}
.flow { .flow {
flex: 1; flex: 1;
margin-top: 10px; margin-top: 10px;

View File

@ -13,8 +13,8 @@
function resetNode() { function resetNode() {
// hack to deselect node and apply changes on chrome // hack to deselect node and apply changes on chrome
$nodes.find(n => n.id === id).selected = false; $nodes.find((n) => n.id === id).selected = false;
$nodes = $nodes $nodes = $nodes;
} }
function changeFile() { function changeFile() {

View File

@ -7,15 +7,18 @@ export const auto = writable(true);
export const selectedFilter = writable(); export const selectedFilter = writable();
export const INPUTNAMES = [ export const INPUTNAMES = [
{name: "punch.mp4", ext: "mp4", outputs: ["v", "a"], inputs: []}, { name: "punch.mp4", url: "/punch.mp4", ext: "mp4", outputs: ["v", "a"], inputs: [] },
{name: "shoe.mp4", ext: "mp4", outputs: ["v", "a"], inputs: []} { name: "shoe.mp4", url: "/shoe.mp4", ext: "mp4", outputs: ["v", "a"], inputs: [] },
]; ];
export const OUTPUTNAMES = [ export const OUTPUTNAMES = [
{ name: "out.mp4", ext: "mp4", inputs: ["v", "a"], outputs: [] }, { name: "out.mp4", ext: "mp4", inputs: ["v", "a"], outputs: [] },
{name: "out.gif", ext: "gif", inputs: ["v"], outputs: []} { name: "out.gif", ext: "gif", inputs: ["v"], outputs: [] },
]; ];
export const inputNames = writable(INPUTNAMES);
export const outputNames = writable(OUTPUTNAMES);
addNode({ ...INPUTNAMES[0] }, "input"); addNode({ ...INPUTNAMES[0] }, "input");
addNode({ ...OUTPUTNAMES[0] }, "output"); addNode({ ...OUTPUTNAMES[0] }, "output");