diff --git a/apps/website/docs/api/classes/FFmpeg.md b/apps/website/docs/api/classes/FFmpeg.md
index 778e718..faf0400 100644
--- a/apps/website/docs/api/classes/FFmpeg.md
+++ b/apps/website/docs/api/classes/FFmpeg.md
@@ -28,7 +28,7 @@ const ffmpeg = new FFmpeg();
#### Defined in
-[packages/ffmpeg/src/classes.ts:97](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L97)
+[packages/ffmpeg/src/classes.ts:97](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L97)
## Properties
@@ -38,7 +38,7 @@ const ffmpeg = new FFmpeg();
#### Defined in
-[packages/ffmpeg/src/classes.ts:95](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L95)
+[packages/ffmpeg/src/classes.ts:95](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L95)
___
@@ -51,7 +51,7 @@ be called when we receive message from web worker.
#### Defined in
-[packages/ffmpeg/src/classes.ts:94](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L94)
+[packages/ffmpeg/src/classes.ts:94](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L94)
___
@@ -61,7 +61,7 @@ ___
#### Defined in
-[packages/ffmpeg/src/classes.ts:88](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L88)
+[packages/ffmpeg/src/classes.ts:88](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L88)
___
@@ -121,7 +121,7 @@ node_modules/@types/node/events.d.ts:290
#### Defined in
-[packages/ffmpeg/src/classes.ts:84](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L84)
+[packages/ffmpeg/src/classes.ts:84](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L84)
___
@@ -131,7 +131,7 @@ ___
#### Defined in
-[packages/ffmpeg/src/classes.ts:85](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L85)
+[packages/ffmpeg/src/classes.ts:85](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L85)
___
@@ -141,7 +141,7 @@ ___
#### Defined in
-[packages/ffmpeg/src/classes.ts:86](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L86)
+[packages/ffmpeg/src/classes.ts:86](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L86)
## Event Methods
@@ -172,7 +172,7 @@ ffmpeg.on(FFmpeg.DOWNLOAD, ({ url, total, received, delta, done }) => {
#### Defined in
-[packages/ffmpeg/src/classes.ts:33](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L33)
+[packages/ffmpeg/src/classes.ts:33](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L33)
▸ **on**(`event`, `listener`): [`FFmpeg`](FFmpeg.md)
@@ -203,7 +203,7 @@ log includes output to stdout and stderr.
#### Defined in
-[packages/ffmpeg/src/classes.ts:52](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L52)
+[packages/ffmpeg/src/classes.ts:52](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L52)
▸ **on**(`event`, `listener`): [`FFmpeg`](FFmpeg.md)
@@ -235,7 +235,7 @@ input and output video/audio file are the same.
#### Defined in
-[packages/ffmpeg/src/classes.ts:69](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L69)
+[packages/ffmpeg/src/classes.ts:69](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L69)
___
@@ -278,7 +278,7 @@ const data = ffmpeg.readFile("video.mp4");
#### Defined in
-[packages/ffmpeg/src/classes.ts:197](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L197)
+[packages/ffmpeg/src/classes.ts:197](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L197)
___
@@ -303,7 +303,7 @@ as it initializes WebAssembly and other essential variables.
#### Defined in
-[packages/ffmpeg/src/classes.ts:166](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L166)
+[packages/ffmpeg/src/classes.ts:166](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L166)
___
@@ -320,7 +320,7 @@ Terminate all ongoing API calls and terminate web worker.
#### Defined in
-[packages/ffmpeg/src/classes.ts:218](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L218)
+[packages/ffmpeg/src/classes.ts:218](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L218)
___
@@ -344,7 +344,7 @@ Create a directory.
#### Defined in
-[packages/ffmpeg/src/classes.ts:315](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L315)
+[packages/ffmpeg/src/classes.ts:315](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L315)
___
@@ -366,7 +366,7 @@ Delete an empty directory.
#### Defined in
-[packages/ffmpeg/src/classes.ts:337](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L337)
+[packages/ffmpeg/src/classes.ts:337](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L337)
___
@@ -388,7 +388,7 @@ Delete a file.
#### Defined in
-[packages/ffmpeg/src/classes.ts:293](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L293)
+[packages/ffmpeg/src/classes.ts:293](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L293)
___
@@ -410,7 +410,7 @@ List directory contents.
#### Defined in
-[packages/ffmpeg/src/classes.ts:326](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L326)
+[packages/ffmpeg/src/classes.ts:326](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L326)
___
@@ -441,7 +441,7 @@ const data = await ffmpeg.readFile("video.mp4");
#### Defined in
-[packages/ffmpeg/src/classes.ts:272](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L272)
+[packages/ffmpeg/src/classes.ts:272](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L272)
___
@@ -464,7 +464,7 @@ Rename a file or directory.
#### Defined in
-[packages/ffmpeg/src/classes.ts:304](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L304)
+[packages/ffmpeg/src/classes.ts:304](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L304)
___
@@ -496,7 +496,7 @@ await ffmpeg.writeFile("text.txt", "hello world");
#### Defined in
-[packages/ffmpeg/src/classes.ts:246](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L246)
+[packages/ffmpeg/src/classes.ts:246](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L246)
___
@@ -514,7 +514,7 @@ register worker message event handlers.
#### Defined in
-[packages/ffmpeg/src/classes.ts:104](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L104)
+[packages/ffmpeg/src/classes.ts:104](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L104)
___
@@ -537,7 +537,7 @@ Generic function to send messages to web worker.
#### Defined in
-[packages/ffmpeg/src/classes.ts:143](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/e3bc2e1/packages/ffmpeg/src/classes.ts#L143)
+[packages/ffmpeg/src/classes.ts:143](https://github.com/ffmpegwasm/ffmpeg.wasm/blob/1582ee2/packages/ffmpeg/src/classes.ts#L143)
___
diff --git a/apps/website/package.json b/apps/website/package.json
index 43d4bcc..7a2c4ae 100644
--- a/apps/website/package.json
+++ b/apps/website/package.json
@@ -21,6 +21,7 @@
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@ffmpeg/ffmpeg": "^0.12.0-alpha.0",
+ "@ffmpeg/util": "^0.12.0-alpha.0",
"@fontsource/roboto": "^4.5.8",
"@mdx-js/react": "^1.6.22",
"@mui/icons-material": "^5.10.6",
@@ -28,11 +29,13 @@
"clsx": "^1.2.1",
"prism-react-renderer": "^1.3.5",
"react": "^17.0.2",
+ "react-ace": "^10.1.0",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.1.0",
"@tsconfig/docusaurus": "^1.0.5",
+ "@types/ace": "^0.0.48",
"docusaurus-plugin-typedoc": "^0.17.5",
"typedoc": "^0.23.15",
"typedoc-plugin-markdown": "^3.13.6",
diff --git a/apps/website/src/components/MuiThemeProvider/index.tsx b/apps/website/src/components/MuiThemeProvider/index.tsx
new file mode 100644
index 0000000..36d61f6
--- /dev/null
+++ b/apps/website/src/components/MuiThemeProvider/index.tsx
@@ -0,0 +1,20 @@
+import React from "react";
+import { useColorMode } from "@docusaurus/theme-common";
+import { ThemeProvider, createTheme } from "@mui/material/styles";
+
+const lightTheme = createTheme({});
+const darkTheme = createTheme({
+ palette: {
+ mode: "dark",
+ },
+});
+
+export default function MuiThemeProvider(props: any) {
+ const { colorMode } = useColorMode();
+ return (
+
+ );
+}
diff --git a/apps/website/src/components/Playground/CoreDownloader.tsx b/apps/website/src/components/Playground/CoreDownloader.tsx
new file mode 100644
index 0000000..838ea86
--- /dev/null
+++ b/apps/website/src/components/Playground/CoreDownloader.tsx
@@ -0,0 +1,16 @@
+import * as React from "react";
+import Typography from "@mui/material/Typography";
+import Container from "@mui/material/Container";
+import LinearProgressWithLabel from "./LinearProgressWithLabel";
+import { CORE_SIZE } from "./const";
+
+export default function CoreDownloader({ url, received }) {
+ const total = CORE_SIZE[url];
+ return (
+
+ {`Downloading ${url}`}
+ {`(${received} / ${total} bytes)`}
+
+
+ );
+}
diff --git a/apps/website/src/components/Playground/CoreSelector.tsx b/apps/website/src/components/Playground/CoreSelector.tsx
new file mode 100644
index 0000000..fd47da7
--- /dev/null
+++ b/apps/website/src/components/Playground/CoreSelector.tsx
@@ -0,0 +1,53 @@
+import * as React from "react";
+import Button from "@mui/material/Button";
+import Container from "@mui/material/Container";
+import Radio from "@mui/material/Radio";
+import RadioGroup from "@mui/material/RadioGroup";
+import FormControlLabel from "@mui/material/FormControlLabel";
+import FormControl from "@mui/material/FormControl";
+import FormLabel from "@mui/material/FormLabel";
+import styles from "./styles.module.css";
+
+interface CoreSelectorProps {
+ option: string;
+ onChange: (event: React.ChangeEvent) => any;
+ onSubmit: () => any;
+}
+export default function CoreSelector({
+ option,
+ onChange,
+ onSubmit,
+}: CoreSelectorProps) {
+ return (
+
+
+
+ Select a Core Option
+
+ }
+ label="Core (Slower, but stable)"
+ />
+ }
+ label="Core Multi-threaded (Faster, but lower compatibility and unstable)"
+ />
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/website/src/components/Playground/Editor.tsx b/apps/website/src/components/Playground/Editor.tsx
new file mode 100644
index 0000000..b872ef5
--- /dev/null
+++ b/apps/website/src/components/Playground/Editor.tsx
@@ -0,0 +1,246 @@
+///
+
+import * as React from "react";
+import Box from "@mui/material/Box";
+import Grid from "@mui/material/Grid";
+import Stack from "@mui/material/Stack";
+import Button from "@mui/material/Button";
+import Typography from "@mui/material/Typography";
+import FolderIcon from "@mui/icons-material/Folder";
+import List from "@mui/material/List";
+import ListItem from "@mui/material/ListItem";
+import ListItemIcon from "@mui/material/ListItemIcon";
+import ListItemText from "@mui/material/ListItemText";
+import IconButton from "@mui/material/IconButton";
+import MoreVertIcon from "@mui/icons-material/MoreVert";
+import RefreshIcon from "@mui/icons-material/Refresh";
+import UploadFileIcon from "@mui/icons-material/UploadFile";
+import UploadIcon from "@mui/icons-material/Upload";
+import Tooltip from "@mui/material/Tooltip";
+import Menu from "@mui/material/Menu";
+import MenuItem from "@mui/material/MenuItem";
+import { useColorMode } from "@docusaurus/theme-common";
+import { FFmpeg } from "@ffmpeg/ffmpeg";
+import { fetchFile } from "@ffmpeg/util";
+import AceEditor from "react-ace";
+import styles from "./styles.module.css";
+import { getFFmpeg } from "./ffmpeg";
+import { SAMPLE_FILES } from "./const";
+import LinearProgressWithLabel from "./LinearProgressWithLabel";
+import "ace-builds/src-noconflict/mode-json";
+import "ace-builds/src-noconflict/mode-javascript";
+import "ace-builds/src-noconflict/mode-text";
+import "ace-builds/src-noconflict/theme-dracula";
+import "ace-builds/src-noconflict/theme-github";
+
+const defaultArgs = JSON.stringify(["-i", "video.avi", "video.mp4"], null, 2);
+const options = ["Download", "Download as Text File", "Delete"];
+
+const genFFmpegText = (args: string) => {
+ let data: any = [];
+ try {
+ data = JSON.parse(args);
+ } catch (e) {}
+ return `// equivalent ffmpeg.wasm API call
+ffmpeg.exec(${JSON.stringify(data)});
+
+// equivalent ffmpeg command line
+ffmpeg ${data.join(" ")}`;
+};
+
+export default function Editor() {
+ const { useState, useEffect } = React;
+ const [args, setArgs] = useState(defaultArgs);
+ const [logs, setLogs] = useState([]);
+ const [output, setOutput] = useState();
+ const [path, setPath] = useState("/");
+ const [nodes, setNodes] = useState([]);
+ const [progress, setProgress] = useState(-1);
+ const { colorMode } = useColorMode();
+ const theme = colorMode === "dark" ? "github" : "dracula";
+
+ const scrollToEnd = () => {
+ output && output.renderer.scrollToLine(Number.POSITIVE_INFINITY);
+ };
+
+ const loadSamples = async () => {
+ const ffmpeg = getFFmpeg();
+ Object.keys(SAMPLE_FILES).forEach(async (name) => {
+ await ffmpeg.writeFile(name, await fetchFile(SAMPLE_FILES[name]));
+ });
+ // Somehow we need to wait a little bit before reading the new nodes.
+ setTimeout(async () => {
+ setNodes(await ffmpeg.listDir(path));
+ }, 500);
+ };
+
+ const refreshDir = async () => {
+ setNodes(await getFFmpeg().listDir(path));
+ };
+
+ const exec = async () => {
+ const ffmpeg = getFFmpeg();
+ setProgress(-1);
+ const logListener = ({ message }) => {
+ setLogs((_logs) => [..._logs, message]);
+ scrollToEnd();
+ };
+ const progListener = ({ progress: prog }) => {
+ setProgress(prog * 100);
+ };
+ ffmpeg.on(FFmpeg.LOG, logListener);
+ ffmpeg.on(FFmpeg.PROGRESS, progListener);
+ await ffmpeg.exec(JSON.parse(args));
+ ffmpeg.removeListener(FFmpeg.LOG, logListener);
+ ffmpeg.removeListener(FFmpeg.PROGRESS, progListener);
+ setNodes(await ffmpeg.listDir(path));
+ };
+
+ useEffect(() => {
+ const ffmpeg = getFFmpeg();
+ ffmpeg.listDir(path).then((nodes) => {
+ setNodes(nodes);
+ });
+ }, []);
+
+ return (
+
+
+
+
+ File System:
+
+
+ {}} aria-label="upload-media-file">
+
+
+
+
+ {}} aria-label="upload-text">
+
+
+
+
+
+
+
+
+
+
+ {`${path}`}
+
+ {nodes.map((node, index) => (
+
+
+
+
+
+ >
+ }
+ >
+
+
+
+
+
+ ))}
+
+
+
+
+
+ Edit JSON below to update command:
+ setArgs(value)}
+ setOptions={{ tabSize: 2 }}
+ />
+
+
+
+
+
+
+ {progress === -1 ? (
+ <>>
+ ) : (
+ <>
+ Transcoding Progress:
+
+ >
+ )}
+ setOutput(editor)}
+ />
+
+
+
+
+ );
+}
diff --git a/apps/website/src/components/Playground/LinearProgressWithLabel.tsx b/apps/website/src/components/Playground/LinearProgressWithLabel.tsx
new file mode 100644
index 0000000..2789c36
--- /dev/null
+++ b/apps/website/src/components/Playground/LinearProgressWithLabel.tsx
@@ -0,0 +1,23 @@
+import * as React from "react";
+import Box from "@mui/material/Box";
+import Typography from "@mui/material/Typography";
+import LinearProgress, {
+ LinearProgressProps,
+} from "@mui/material/LinearProgress";
+
+export default function LinearProgressWithLabel(
+ props: LinearProgressProps & { value: number }
+) {
+ return (
+
+
+
+
+
+ {`${Math.round(
+ props.value
+ )}%`}
+
+
+ );
+}
diff --git a/apps/website/src/components/Playground/const.ts b/apps/website/src/components/Playground/const.ts
new file mode 100644
index 0000000..907dd87
--- /dev/null
+++ b/apps/website/src/components/Playground/const.ts
@@ -0,0 +1,12 @@
+export const CORE_SIZE = {
+ "https://unpkg.com/@ffmpeg/core@0.12.0-alpha.2/dist/umd/ffmpeg-core.js": 111646,
+ "https://unpkg.com/@ffmpeg/core@0.12.0-alpha.2/dist/umd/ffmpeg-core.wasm": 31967534,
+ "https://unpkg.com/@ffmpeg/core-mt@0.12.0-alpha.2/dist/umd/ffmpeg-core.js": 130002,
+ "https://unpkg.com/@ffmpeg/core-mt@0.12.0-alpha.2/dist/umd/ffmpeg-core.wasm": 32441947,
+ "https://unpkg.com/@ffmpeg/core-mt@0.12.0-alpha.2/dist/umd/ffmpeg-core.worker.js": 2978,
+};
+
+export const SAMPLE_FILES = {
+ "video.avi":
+ "https://raw.githubusercontent.com/ffmpegwasm/testdata/master/video-3s.avi",
+};
diff --git a/apps/website/src/components/Playground/ffmpeg.ts b/apps/website/src/components/Playground/ffmpeg.ts
new file mode 100644
index 0000000..99765c9
--- /dev/null
+++ b/apps/website/src/components/Playground/ffmpeg.ts
@@ -0,0 +1,5 @@
+import { FFmpeg } from "@ffmpeg/ffmpeg";
+
+let ffmpeg = new FFmpeg();
+
+export const getFFmpeg = () => ffmpeg;
diff --git a/apps/website/src/components/Playground/index.tsx b/apps/website/src/components/Playground/index.tsx
index b9b644d..dd66d87 100644
--- a/apps/website/src/components/Playground/index.tsx
+++ b/apps/website/src/components/Playground/index.tsx
@@ -1,38 +1,54 @@
-import React, { useState } from "react";
+import * as React from "react";
import { FFmpeg } from "@ffmpeg/ffmpeg";
-import Button from "@mui/material/Button";
-import { useColorMode } from "@docusaurus/theme-common";
-import { ThemeProvider, createTheme } from "@mui/material/styles";
+import MuiThemeProvider from "@site/src/components/MuiThemeProvider";
+import CoreSelector from "./CoreSelector";
+import CoreDownloader from "./CoreDownloader";
+import Editor from "./Editor";
+import { getFFmpeg } from "./ffmpeg";
-const lightTheme = createTheme({});
-const darkTheme = createTheme({
- palette: {
- mode: "dark",
- },
-});
+enum State {
+ NOT_LOADED,
+ LOADING,
+ LOADED,
+}
export default function Playground() {
- const [loaded, setLoaded] = useState(false);
- const { colorMode } = useColorMode();
- const ffmpeg = new FFmpeg();
+ const { useState } = React;
+ const [state, setState] = useState(State.LOADED);
+ const [option, setOption] = useState("core");
+ const [url, setURL] = useState("");
+ const [received, setReceived] = useState(0);
const load = async () => {
- ffmpeg.on(FFmpeg.DOWNLOAD, ({ url, total, received, done }) => {
- console.log(url, total, received, done);
+ setState(State.LOADING);
+ const ffmpeg = getFFmpeg();
+ ffmpeg.terminate();
+ ffmpeg.on(FFmpeg.DOWNLOAD, ({ url: _url, received: _received }) => {
+ setURL(_url as string);
+ setReceived(_received);
});
- await ffmpeg.load({
- coreURL: "http://localhost:8080/packages/core/dist/umd/ffmpeg-core.js",
- });
- setLoaded(true);
+ await ffmpeg.load();
+ setState(State.LOADED);
};
+
return (
-
- {loaded ? (
- <>>
- ) : (
-
- )}
-
+
+ {(() => {
+ switch (state) {
+ case State.LOADING:
+ return ;
+ case State.LOADED:
+ return ;
+ default:
+ return <>>;
+ }
+ })()}
+ {
+ setOption((event.target as HTMLInputElement).value);
+ }}
+ onSubmit={load}
+ />
+
);
}
diff --git a/apps/website/src/components/Playground/styles.module.css b/apps/website/src/components/Playground/styles.module.css
new file mode 100644
index 0000000..b6a7e1e
--- /dev/null
+++ b/apps/website/src/components/Playground/styles.module.css
@@ -0,0 +1,13 @@
+.margin {
+ margin-bottom: 32px;
+}
+
+.alignRight {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.fsTitle {
+ align-items: center;
+ justify-content: space-between;
+}
diff --git a/package-lock.json b/package-lock.json
index 1c24c41..597d0f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -48,6 +48,7 @@
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@ffmpeg/ffmpeg": "^0.12.0-alpha.0",
+ "@ffmpeg/util": "^0.12.0-alpha.0",
"@fontsource/roboto": "^4.5.8",
"@mdx-js/react": "^1.6.22",
"@mui/icons-material": "^5.10.6",
@@ -55,11 +56,13 @@
"clsx": "^1.2.1",
"prism-react-renderer": "^1.3.5",
"react": "^17.0.2",
+ "react-ace": "^10.1.0",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "2.1.0",
"@tsconfig/docusaurus": "^1.0.5",
+ "@types/ace": "^0.0.48",
"docusaurus-plugin-typedoc": "^0.17.5",
"typedoc": "^0.23.15",
"typedoc-plugin-markdown": "^3.13.6",
@@ -6099,6 +6102,12 @@
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
},
+ "node_modules/@types/ace": {
+ "version": "0.0.48",
+ "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.48.tgz",
+ "integrity": "sha512-esV6hOWiDOZ6d7w5S11iLu6LQsPGe/9RPzhri7gNNLdrK1LFpO9/m7IZhQL6dat0JHICJ7l51zvHAiCgnPLLHA==",
+ "dev": true
+ },
"node_modules/@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@@ -6838,6 +6847,11 @@
"node": ">= 0.6"
}
},
+ "node_modules/ace-builds": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.11.2.tgz",
+ "integrity": "sha512-1VNeUF56b6gkaeeWJXMBBuz5n0ceDchjUwwVmTKpNM/N3YRrUEpykGEEsg7Y1PKP7IRyqtXfAu6VJDg7OZaLfA=="
+ },
"node_modules/acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@@ -9884,6 +9898,11 @@
"node": ">=0.3.1"
}
},
+ "node_modules/diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -14057,6 +14076,16 @@
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
"integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw=="
},
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"node_modules/lodash.ismatch": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
@@ -17862,6 +17891,22 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "dependencies": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-base16-styling": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz",
@@ -27277,6 +27322,12 @@
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
},
+ "@types/ace": {
+ "version": "0.0.48",
+ "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.48.tgz",
+ "integrity": "sha512-esV6hOWiDOZ6d7w5S11iLu6LQsPGe/9RPzhri7gNNLdrK1LFpO9/m7IZhQL6dat0JHICJ7l51zvHAiCgnPLLHA==",
+ "dev": true
+ },
"@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@@ -27907,6 +27958,11 @@
"negotiator": "0.6.3"
}
},
+ "ace-builds": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.11.2.tgz",
+ "integrity": "sha512-1VNeUF56b6gkaeeWJXMBBuz5n0ceDchjUwwVmTKpNM/N3YRrUEpykGEEsg7Y1PKP7IRyqtXfAu6VJDg7OZaLfA=="
+ },
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
@@ -30127,6 +30183,11 @@
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true
},
+ "diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -33195,6 +33256,16 @@
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
"integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw=="
},
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
"lodash.ismatch": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
@@ -35976,6 +36047,18 @@
"object-assign": "^4.1.1"
}
},
+ "react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "requires": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ }
+ },
"react-base16-styling": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz",
@@ -39122,15 +39205,18 @@
"@emotion/react": "^11.10.4",
"@emotion/styled": "^11.10.4",
"@ffmpeg/ffmpeg": "^0.12.0-alpha.0",
+ "@ffmpeg/util": "^0.12.0-alpha.0",
"@fontsource/roboto": "^4.5.8",
"@mdx-js/react": "^1.6.22",
"@mui/icons-material": "^5.10.6",
"@mui/material": "^5.10.8",
"@tsconfig/docusaurus": "^1.0.5",
+ "@types/ace": "^0.0.48",
"clsx": "^1.2.1",
"docusaurus-plugin-typedoc": "^0.17.5",
"prism-react-renderer": "^1.3.5",
"react": "^17.0.2",
+ "react-ace": "^10.1.0",
"react-dom": "^17.0.2",
"typedoc": "^0.23.15",
"typedoc-plugin-markdown": "^3.13.6",
diff --git a/package.json b/package.json
index b442751..a939252 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,8 @@
"test:browser:server": "http-server -c-1 --cors -p 3000 .",
"test:node": "mocha --exit --bail -t 60000",
"test:node:core:mt": "npm run test:node -- --require tests/test-helper-mt.js tests/ffmpeg-core.test.js",
- "test:node:core:st": "npm run test:node -- --require tests/test-helper-st.js tests/ffmpeg-core.test.js"
+ "test:node:core:st": "npm run test:node -- --require tests/test-helper-st.js tests/ffmpeg-core.test.js",
+ "prepublishOnly": "lerna run build --scope='@ffmpeg/*'"
},
"workspaces": [
"packages/*",
diff --git a/packages/util/tsconfig.json b/packages/util/tsconfig.json
index 4082f16..9607e81 100644
--- a/packages/util/tsconfig.json
+++ b/packages/util/tsconfig.json
@@ -1,3 +1,6 @@
{
- "extends": "../../tsconfig.json"
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "declaration": true
+ }
}