diff --git a/.env.sample b/.env.sample
new file mode 100644
index 0000000..3273657
--- /dev/null
+++ b/.env.sample
@@ -0,0 +1,16 @@
+# AI Keys
+# LLMs
+OPENAI_API_KEY="key here"
+GOOGLE_AI_API_KEY="key here"
+ANTHROPIC_API_KEY="key here"
+# TTS
+ELEVENLABS_API_KEY="key here"
+NEETS_API_KEY="key here"
+# Image
+PEXELS_API_KEY="key here"
+
+# Server Config
+SERVER_RES_PATH="res"
+SERVER_TEMP_PATH="video_temp"
+SERVER_IP="localhost"
+SERVER_PORT=3001
diff --git a/.gitignore b/.gitignore
index c108f85..55ad8f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -132,7 +132,6 @@ dist
# Old code
old/
python/
-ui/
# Video/audio output
*.mp4
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..30912ae
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,17 @@
+# v0.2.0
+- TODO: Add description
+- Inital release of local web UI (Frontend uses Next.js, backend uses Express.js)
+- Server API support (--server) (gets API keys from environment variables)
+- Reworked AI script generation by giving each video type its own prompt to build its data object
+- Support for getting API keys from environment variables
+- OpenAI API support
+- Google Gemini AI API support
+- Anthropic (Claude) API support
+- Added video orientation support (vertical, horizontal)
+- Forked `ffcreator` and `inkpaint` as internal dependencies in `packages` directory
+
+# v0.1.1
+- Fixed bug that prevented the program from running
+
+# v0.1.0
+- Initial release
diff --git a/README.md b/README.md
index 501bafd..e871063 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,9 @@ AutoShorts is a fully fledged package that generates shorts videos with the help
If you want to support the development of this package, consider buying me a coffee:
-[![ko-fi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/shafilalam)
+[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/I2I6SYOFB)
-Your support will help me to continue the development of this package. Thank you!
+![AutoShorts UI](example/images/ui.png)
> [!WARNING]
> The package author is not responsible for any misuse of the package, any content generated by the package, and any loss arising from the use of the package. Use at your own risk. Package is subject to change and may have breaking changes in the future. Not meant for production usage.
@@ -17,8 +17,6 @@ The package is built with a flexible abstraction layer which allows you to quick
This repo includes a CLI interface and JS interface. The CLI interface is built on top of the JS interface. The JS interface is the core of the package and can be used to generate videos programmatically.
-**GUI interface is coming soon.**
-
> [!NOTE]
> This package is in the early stages of development and may have bugs - especially when interacting with AI to generate scripts. This package is not meant to be used in production environments yet. Since AI output is unpredictable, work is being done to make the output more predictable and controllable. If the AI generates an incorrect JSON output, then you can manually edit the JSON output to fix the issue. This package is subject to change and may have breaking changes in the future. Use at your own risk.
@@ -45,26 +43,67 @@ You can request new video types and tools to be added to the package by creating
# Installation
-Note: By default, the package use Ollama to generate scripts. Therefore a working Ollama installation is required. It is recommended to use the `llama3.1` model for best results. You can install this model by running the following command: `ollama pull llama3.1`. Using other local models may result in incorrect output. You can use other AI APIs such as OpenAI ChatGPT 4o, Google Gemini AI, and Anthropic Claude by providing the necessary API keys.
+Note: By default, the package use Ollama to generate scripts. Therefore a working Ollama installation is required. It is recommended to use the `llama3.2` model for best results.
+
+You can install this model by running the following command: `ollama pull llama3.2`.
+
+Using other local models may result in incorrect output.
+
+You can use other AI APIs such as OpenAI ChatGPT 4o, Google Gemini AI, and Anthropic Claude by providing the necessary API keys and setting the `aiType` parameter to the appropriate value.
+
+# Example (Web UI)
+
+AutoShorts comes with a web UI that allows you to generate videos with a simple interface. The UI is built with Next.js and Express.js. The web UI relies on the backend server.
+
+> [!NOTE]
+> The web UI is in the early stages of development and may have bugs. The UI is not meant to be used in production environments yet. If you encounter any issues, please create an issue on the GitHub repo. Feel free to contribute to the UI by creating a pull request.
+
+This example will clone the repository and start the backend server and frontend server.
+
+## Clone the repository
-## For JS Interface
```bash
-# Install the package
-npm install auto-shorts
+git clone
+cd auto-shorts
+npm install
+```
-# Download the necessary resources (to './res' folder by default)
-npx auto-shorts --download
+## Setup backend server
+
+First, create a `.env` file with the following content:
+
+```bash
+# Server Config
+SERVER_RES_PATH="[path to res folder]" # Download from "npx auto-shorts --download [path]"
+SERVER_TEMP_PATH="[path to temp folder]" # Can be any path like "video_temp"
+SERVER_IP="localhost"
+SERVER_PORT="[port number]" # Can be any port number like 3001
```
-## For CLI Interface (global installation)
+Then, run the following commands to start the backend server:
+
```bash
-# Install the package globally
-npm install -g auto-shorts
+npm run start-server
+```
-# Download the necessary resources (to './res' folder by default)
-npx auto-shorts --download
+## Setup frontend server
+
+First, create a `.env` file in the `ui` folder with the following content:
+
+```bash
+# Server Config
+NEXT_PUBLIC_BACKEND_URL="http://localhost:[port number]" # Use the same port number as the backend server (ex: http://localhost:3001)
+```
+
+Then, run the following commands to start the frontend server:
+
+```bash
+npm run install-ui-deps
+npm run start-ui-dev
```
+The web UI should now be accessible at `http://localhost:3000`.
+
# Example (CLI Interface)
Note: Since LLMs can hallucinate and are not deterministic, the videos may not generate the expected output. You can manually edit the JSON output to fix the issue.
@@ -82,7 +121,7 @@ npx auto-shorts --download
# Use OpenAI gpt-4o-mini to generate the script, ElevenLabs to generate the voice, and Pexels to generate the image
npx auto-shorts -p "make a news short about TypeScript" --aiType OpenAIGen --ttsType ElevenLabs --imageType PexelsImageGen --elevenLabsAPIKey YOUR_ELEVENLABS_API_KEY --pexelsAPIKey YOUR_PEXELS_API_KEY --openaiAPIKey YOUR_OPENAI_API_KEY
-# Use local Ollama llama3.1 to generate the script, Built-in TTS to generate the voice, and Google Scraper to generate the image (default, no need to provide API keys)
+# Use local Ollama llama3.2 to generate the script, Built-in TTS to generate the voice, and Google Scraper to generate the image (default, no need to provide API keys)
npx auto-shorts -p "make a news short about TypeScript"
```
@@ -98,7 +137,18 @@ npx auto-shorts --help
# Example (JS Interface)
-Note: You will need to download the necessary resources before running the code. You can do this by running the following command:
+First, make sure to install the package and download the necessary resources.
+
+```bash
+# Install the package
+npm install auto-shorts
+
+# Download the necessary resources (to './res' folder by default)
+npx auto-shorts --download
+```
+
+You will need to download the necessary resources before running the code. You can do this by running the following command:
+
```bash
npx auto-shorts --download [path]
```
@@ -178,7 +228,7 @@ task.on('done', (output) => {
- OpenAI (and compatible endpoints like Ollama, Groq, etc.) (e.g., GPT-4o)
- Google Gemini AI (e.g., Gemini 1.5 Pro/Flash)
- Anthropic (e.g, Claude)
-- Ollama local LLMs (e.g., llama3.1)
+- Ollama local LLMs (e.g., llama3.2)
# API Keys
@@ -208,23 +258,29 @@ If this package is missing any video types or AI tools that you would like to se
The package is structured as follows:
- `src`: Contains the source code for the package
+- `ui`: Contains the GUI code for the package
- `example`: Contains example code to use the package
- `test`: Contains test code for the package
- `packages`: Contains the internal dependencies for the package (forked versions of `ffcreator` and `inkpaint`)
# Todo
-- [ ] Add GUI
+- [*] Add GUI
- [ ] Fix logging
-- [ ] Make AI output structured for local LLMs (gpt4, gemini, claude are fine)
-- [ ] Add more video types (Twitter/X posts, Reddit posts, etc.)
- [ ] Add Docker support
-- [ ] Add more AI tools (e.g., OpenAI, Neets.ai, AI Image Generators, etc.)
+- [ ] Get GUI production-ready
- [ ] Add more customization options (custom fonts, colors, images, etc.)
+- [ ] Allow custom images and background music via GUI
+- [ ] Work on a more general 'AI-powered' video editor instead of automatic video generation
+- [ ] Add support for more general video generation (e.g., long-form videos)
+- [ ] Option to convert long video to short video
+- [ ] Add more video types (Twitter/X posts, Reddit posts, etc.)
+- [ ] Add more AI tools (e.g., OpenAI, Neets.ai, AI Image Generators, etc.)
+- [*] Make AI output structured for LLMs
- [ ] Add more error handling
- [ ] Add more tests
- [ ] Add more documentation
-- [ ] Add support for more general video generation (e.g., long-form videos)
- [ ] Fix external dependencies vulnerabilities (only on dev dependencies)
+- [ ] Expose more options for video customization (ElevenLabs voice customization, LLM temperature, etc.)
## Star History
diff --git a/example/images/ui.png b/example/images/ui.png
new file mode 100644
index 0000000..25a9ea9
Binary files /dev/null and b/example/images/ui.png differ
diff --git a/package-lock.json b/package-lock.json
index c7e3609..7a5aad3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -21,7 +21,9 @@
"cli-progress": "^3.12.0",
"command-line-args": "^6.0.0",
"command-line-usage": "^7.0.3",
+ "console-error": "^0.0.4",
"console-info": "^0.0.5",
+ "cors": "^2.8.5",
"dotenv": "^16.4.5",
"elevenlabs": "^0.16.0",
"express": "^4.21.0",
@@ -49,6 +51,7 @@
"@types/cli-progress": "^3.11.6",
"@types/command-line-args": "^5.2.3",
"@types/command-line-usage": "^5.0.4",
+ "@types/cors": "^2.8.17",
"@types/eslint__js": "^8.42.3",
"@types/express": "^4.17.21",
"@types/fluent-ffmpeg": "^2.1.24",
@@ -4203,6 +4206,15 @@
"@types/node": "*"
}
},
+ "node_modules/@types/cors": {
+ "version": "2.8.17",
+ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
+ "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/eslint": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz",
@@ -6954,6 +6966,11 @@
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
},
+ "node_modules/console-error": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/console-error/-/console-error-0.0.4.tgz",
+ "integrity": "sha512-tyQF/oporapv/KZpMBxmd8URCZT40eRVoKhYdtKj3Kozca0TDcwkZLGK8dLFcJbAOveKwGUxPSKRxvLgWJKTSA=="
+ },
"node_modules/console-info": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/console-info/-/console-info-0.0.5.tgz",
@@ -7035,6 +7052,18 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
},
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/cosmiconfig": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
diff --git a/package.json b/package.json
index cf385c3..e32e75d 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,9 @@
],
"scripts": {
"start": "tsc && node dist/cli.js",
+ "start-server": "tsc && node dist/cli.js --server",
+ "start-ui-dev": "cd ui && npm run dev",
+ "install-ui-deps": "cd ui && npm install",
"build": "tsc",
"build-all": "npm -w packages/inkpaint run build",
"lint": "eslint .",
@@ -40,7 +43,9 @@
"cli-progress": "^3.12.0",
"command-line-args": "^6.0.0",
"command-line-usage": "^7.0.3",
+ "console-error": "^0.0.4",
"console-info": "^0.0.5",
+ "cors": "^2.8.5",
"dotenv": "^16.4.5",
"elevenlabs": "^0.16.0",
"express": "^4.21.0",
@@ -65,6 +70,7 @@
"@types/cli-progress": "^3.11.6",
"@types/command-line-args": "^5.2.3",
"@types/command-line-usage": "^5.0.4",
+ "@types/cors": "^2.8.17",
"@types/eslint__js": "^8.42.3",
"@types/express": "^4.17.21",
"@types/fluent-ffmpeg": "^2.1.24",
diff --git a/ui/.env.sample b/ui/.env.sample
new file mode 100644
index 0000000..f7bb65c
--- /dev/null
+++ b/ui/.env.sample
@@ -0,0 +1,2 @@
+# The URL of the backend server
+NEXT_PUBLIC_BACKEND_URL=http://localhost:3001
diff --git a/ui/.eslintignore b/ui/.eslintignore
new file mode 100644
index 0000000..af6ab76
--- /dev/null
+++ b/ui/.eslintignore
@@ -0,0 +1,20 @@
+.now/*
+*.css
+.changeset
+dist
+esm/*
+public/*
+tests/*
+scripts/*
+*.config.js
+.DS_Store
+node_modules
+coverage
+.next
+build
+!.commitlintrc.cjs
+!.lintstagedrc.cjs
+!jest.config.js
+!plopfile.js
+!react-shim.js
+!tsup.config.ts
\ No newline at end of file
diff --git a/ui/.eslintrc.json b/ui/.eslintrc.json
new file mode 100644
index 0000000..d3067d4
--- /dev/null
+++ b/ui/.eslintrc.json
@@ -0,0 +1,92 @@
+{
+ "$schema": "https://json.schemastore.org/eslintrc.json",
+ "env": {
+ "browser": false,
+ "es2021": true,
+ "node": true
+ },
+ "extends": [
+ "plugin:react/recommended",
+ "plugin:prettier/recommended",
+ "plugin:react-hooks/recommended",
+ "plugin:jsx-a11y/recommended"
+ ],
+ "plugins": ["react", "unused-imports", "import", "@typescript-eslint", "jsx-a11y", "prettier"],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaFeatures": {
+ "jsx": true
+ },
+ "ecmaVersion": 12,
+ "sourceType": "module"
+ },
+ "settings": {
+ "react": {
+ "version": "detect"
+ }
+ },
+ "rules": {
+ "no-console": "warn",
+ "react/prop-types": "off",
+ "react/jsx-uses-react": "off",
+ "react/react-in-jsx-scope": "off",
+ "react-hooks/exhaustive-deps": "off",
+ "jsx-a11y/click-events-have-key-events": "warn",
+ "jsx-a11y/interactive-supports-focus": "warn",
+ "prettier/prettier": "warn",
+ "no-unused-vars": "off",
+ "unused-imports/no-unused-vars": "off",
+ "unused-imports/no-unused-imports": "warn",
+ "@typescript-eslint/no-unused-vars": [
+ "warn",
+ {
+ "args": "after-used",
+ "ignoreRestSiblings": false,
+ "argsIgnorePattern": "^_.*?$"
+ }
+ ],
+ "import/order": [
+ "warn",
+ {
+ "groups": [
+ "type",
+ "builtin",
+ "object",
+ "external",
+ "internal",
+ "parent",
+ "sibling",
+ "index"
+ ],
+ "pathGroups": [
+ {
+ "pattern": "~/**",
+ "group": "external",
+ "position": "after"
+ }
+ ],
+ "newlines-between": "always"
+ }
+ ],
+ "react/self-closing-comp": "warn",
+ "react/jsx-sort-props": [
+ "warn",
+ {
+ "callbacksLast": true,
+ "shorthandFirst": true,
+ "noSortAlphabetically": false,
+ "reservedFirst": true
+ }
+ ],
+ "padding-line-between-statements": [
+ "warn",
+ {"blankLine": "always", "prev": "*", "next": "return"},
+ {"blankLine": "always", "prev": ["const", "let", "var"], "next": "*"},
+ {
+ "blankLine": "any",
+ "prev": ["const", "let", "var"],
+ "next": ["const", "let", "var"]
+ }
+ ]
+ }
+}
diff --git a/ui/.gitignore b/ui/.gitignore
new file mode 100644
index 0000000..8f322f0
--- /dev/null
+++ b/ui/.gitignore
@@ -0,0 +1,35 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/ui/.npmrc b/ui/.npmrc
new file mode 100644
index 0000000..43c97e7
--- /dev/null
+++ b/ui/.npmrc
@@ -0,0 +1 @@
+package-lock=false
diff --git a/ui/.vscode/settings.json b/ui/.vscode/settings.json
new file mode 100644
index 0000000..3662b37
--- /dev/null
+++ b/ui/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "typescript.tsdk": "node_modules/typescript/lib"
+}
\ No newline at end of file
diff --git a/ui/LICENSE b/ui/LICENSE
new file mode 100644
index 0000000..c573ab3
--- /dev/null
+++ b/ui/LICENSE
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2024 Shafil Alam
+Copyright (c) 2023 Next UI
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/ui/README.md b/ui/README.md
new file mode 100644
index 0000000..08df0a9
--- /dev/null
+++ b/ui/README.md
@@ -0,0 +1,53 @@
+# Next.js & NextUI Template
+
+This is a template for creating applications using Next.js 14 (app directory) and NextUI (v2).
+
+[Try it on CodeSandbox](https://githubbox.com/nextui-org/next-app-template)
+
+## Technologies Used
+
+- [Next.js 14](https://nextjs.org/docs/getting-started)
+- [NextUI v2](https://nextui.org/)
+- [Tailwind CSS](https://tailwindcss.com/)
+- [Tailwind Variants](https://tailwind-variants.org)
+- [TypeScript](https://www.typescriptlang.org/)
+- [Framer Motion](https://www.framer.com/motion/)
+- [next-themes](https://github.com/pacocoursey/next-themes)
+
+## How to Use
+
+### Use the template with create-next-app
+
+To create a new project based on this template using `create-next-app`, run the following command:
+
+```bash
+npx create-next-app -e https://github.com/nextui-org/next-app-template
+```
+
+### Install dependencies
+
+You can use one of them `npm`, `yarn`, `pnpm`, `bun`, Example using `npm`:
+
+```bash
+npm install
+```
+
+### Run the development server
+
+```bash
+npm run dev
+```
+
+### Setup pnpm (optional)
+
+If you are using `pnpm`, you need to add the following code to your `.npmrc` file:
+
+```bash
+public-hoist-pattern[]=*@nextui-org/*
+```
+
+After modifying the `.npmrc` file, you need to run `pnpm install` again to ensure that the dependencies are installed correctly.
+
+## License
+
+Licensed under the [MIT license](https://github.com/nextui-org/next-app-template/blob/main/LICENSE).
diff --git a/ui/app/about/layout.tsx b/ui/app/about/layout.tsx
new file mode 100644
index 0000000..98956a5
--- /dev/null
+++ b/ui/app/about/layout.tsx
@@ -0,0 +1,13 @@
+export default function AboutLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/ui/app/about/page.tsx b/ui/app/about/page.tsx
new file mode 100644
index 0000000..8287673
--- /dev/null
+++ b/ui/app/about/page.tsx
@@ -0,0 +1,25 @@
+"use client";
+
+import { title } from "@/components/primitives";
+import { BACKEND_ENDPOINT } from "@/config/backend";
+import { Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from "@nextui-org/table";
+
+export default function AboutPage() {
+ return (
+
+
About
+
+
+ NAME
+ VALUE
+
+
+
+ Backend URL Endpoint
+ {BACKEND_ENDPOINT}
+
+
+