├── remotion ├── src │ ├── api │ │ └── s3-client.ts │ ├── tailwind.css │ ├── HelloWorld │ │ ├── constants.ts │ │ ├── Subtitle.tsx │ │ ├── Atom.tsx │ │ ├── Title.tsx │ │ ├── Arc.tsx │ │ └── Logo.tsx │ ├── index.ts │ ├── Video.tsx │ ├── Root.tsx │ ├── HelloWorld.tsx │ ├── components │ │ ├── code-block.tsx │ │ └── Logo.tsx │ ├── compositions │ │ ├── TikTokVideo.tsx │ │ └── Template1.tsx │ └── scenes.json ├── .eslintrc ├── .prettierrc ├── .gitignore ├── tailwind.config.js ├── tsconfig.json ├── remotion.config.ts ├── package.json └── README.md ├── .gitignore ├── api ├── requirements.txt ├── Dockerfile └── app.py ├── package.json ├── .env.example ├── init-databases.sh ├── LICENSE ├── README.md ├── resourcs.md ├── docker-compose.yml ├── setup-nocodb.sh ├── n8n-workflow.json └── swagger.json /remotion/src/api/s3-client.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /remotion/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@remotion" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | dist 4 | build 5 | .DS_Store 6 | logs/ 7 | -------------------------------------------------------------------------------- /remotion/src/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /api/requirements.txt: -------------------------------------------------------------------------------- 1 | flask 2 | requests 3 | beautifulsoup4 4 | boto3 5 | openai 6 | python-dotenv 7 | lxml -------------------------------------------------------------------------------- /remotion/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "bracketSpacing": true, 4 | "tabWidth": 2 5 | } 6 | -------------------------------------------------------------------------------- /remotion/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .DS_Store 4 | .env 5 | 6 | # Ignore the output video from Git but not videos you import into src/. 7 | out 8 | -------------------------------------------------------------------------------- /remotion/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | module.exports = { 3 | content: ["./src/**/*.{ts,tsx,js,jsx}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /remotion/src/HelloWorld/constants.ts: -------------------------------------------------------------------------------- 1 | // Change any of these to update your video live. 2 | 3 | export const COLOR_1 = "#86A8E7"; 4 | 5 | export const FONT_FAMILY = "SF Pro Text, Helvetica, Arial, sans-serif"; 6 | -------------------------------------------------------------------------------- /remotion/src/index.ts: -------------------------------------------------------------------------------- 1 | // This is your entry file! Refer to it when you render: 2 | // npx remotion render HelloWorld out/video.mp4 3 | 4 | import { registerRoot } from "remotion"; 5 | import { RemotionRoot } from "./Root"; 6 | 7 | registerRoot(RemotionRoot); 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tiktok-generator", 3 | "version": "1.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "docker compose up -d", 7 | "stop": "docker compose down", 8 | "restart": "docker compose restart", 9 | "remotion": "cd remotion && npm start", 10 | "build": "cd remotion && npm run build" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # MinIO Configuration 2 | MINIO_ACCESS_KEY=minioadmin 3 | MINIO_SECRET_KEY=minioadmin 4 | MINIO_ENDPOINT=http://localhost:9000 5 | 6 | # OpenAI Configuration 7 | OPENAI_API_KEY=your-api-key-here 8 | 9 | # NocoDB Configuration 10 | NOCODB_URL=http://localhost:8080 11 | NOCODB_AUTH_TOKEN=your-auth-token-here 12 | 13 | # n8n Configuration 14 | N8N_ENDPOINT=http://localhost:5678 15 | -------------------------------------------------------------------------------- /remotion/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "jsx": "react-jsx", 6 | "strict": true, 7 | "noEmit": true, 8 | "lib": ["es2015"], 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noUnusedLocals": true, 13 | "incremental": true, 14 | "resolveJsonModule": true 15 | }, 16 | "exclude": ["remotion.config.ts"] 17 | } 18 | -------------------------------------------------------------------------------- /remotion/remotion.config.ts: -------------------------------------------------------------------------------- 1 | // See all configuration options: https://remotion.dev/docs/config 2 | // Each option also is available as a CLI flag: https://remotion.dev/docs/cli 3 | 4 | // Note: When using the Node.JS APIs, the config file doesn't apply. Instead, pass options directly to the APIs 5 | 6 | import { Config } from "@remotion/cli/config"; 7 | import { enableTailwind } from '@remotion/tailwind'; 8 | 9 | Config.setVideoImageFormat("jpeg"); 10 | Config.setOverwriteOutput(true); 11 | Config.overrideWebpackConfig(enableTailwind); 12 | -------------------------------------------------------------------------------- /init-databases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -u 5 | 6 | function create_user_and_database() { 7 | local database=$1 8 | echo " Creating user and database '$database'" 9 | psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL 10 | CREATE DATABASE $database; 11 | GRANT ALL PRIVILEGES ON DATABASE $database TO $POSTGRES_USER; 12 | EOSQL 13 | } 14 | 15 | if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then 16 | echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" 17 | for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do 18 | create_user_and_database $db 19 | done 20 | echo "Multiple databases created" 21 | fi 22 | -------------------------------------------------------------------------------- /remotion/src/HelloWorld/Subtitle.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { interpolate, useCurrentFrame } from "remotion"; 3 | import { FONT_FAMILY } from "./constants"; 4 | 5 | const subtitle: React.CSSProperties = { 6 | fontFamily: FONT_FAMILY, 7 | fontSize: 40, 8 | textAlign: "center", 9 | position: "absolute", 10 | bottom: 700, 11 | width: "100%", 12 | color: "#ccd6f6" 13 | }; 14 | 15 | const codeStyle: React.CSSProperties = { 16 | color: "#64ffda", 17 | }; 18 | 19 | export const Subtitle: React.FC = () => { 20 | const frame = useCurrentFrame(); 21 | const opacity = interpolate(frame, [0, 30], [0, 1]); 22 | return ( 23 |
24 | A place where you become a{" "} TRUE developer 25 |
26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-slim 2 | 3 | WORKDIR /app 4 | 5 | # Install system dependencies 6 | RUN apt-get update && apt-get install -y \ 7 | curl \ 8 | gcc \ 9 | python3-dev \ 10 | libxml2-dev \ 11 | libxslt-dev \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | # Create log directory 15 | RUN mkdir -p /app/logs && chmod 777 /app/logs 16 | 17 | # Install Python dependencies 18 | COPY requirements.txt . 19 | RUN pip install --no-cache-dir -r requirements.txt 20 | 21 | # Copy application code 22 | COPY app.py . 23 | 24 | # Environment variables 25 | ENV FLASK_APP=app.py 26 | ENV FLASK_ENV=production 27 | ENV PYTHONUNBUFFERED=1 28 | 29 | # Health check 30 | HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ 31 | CMD curl -f http://localhost:5000/health || exit 1 32 | 33 | # Expose port 34 | EXPOSE 5000 35 | 36 | # Run application 37 | CMD ["python", "app.py"] -------------------------------------------------------------------------------- /remotion/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "remotion", 3 | "version": "1.0.0", 4 | "description": "My Remotion video", 5 | "repository": {}, 6 | "license": "UNLICENSED", 7 | "private": true, 8 | "dependencies": { 9 | "@remotion/cli": "^4.0.226", 10 | "@remotion/media-utils": "^4.0.226", 11 | "@remotion/player": "^4.0.226", 12 | "@remotion/tailwind": "4.0.226", 13 | "@remotion/zod-types": "4.0.226", 14 | "prism-react-renderer": "^2.4.0", 15 | "react": "18.3.1", 16 | "react-dom": "18.3.1", 17 | "remotion": "^4.0.226", 18 | "zod": "^3.22.3" 19 | }, 20 | "devDependencies": { 21 | "@remotion/eslint-config": "4.0.226", 22 | "@types/react": "18.3.1", 23 | "@types/web": "0.0.166", 24 | "eslint": "8.56.0", 25 | "prettier": "3.3.3", 26 | "typescript": "5.5.4" 27 | }, 28 | "scripts": { 29 | "dev": "remotion studio", 30 | "build": "remotion render HelloWorld out/video.mp4", 31 | "upgrade": "remotion upgrade", 32 | "test": "eslint src --ext ts,tsx,js,jsx && tsc" 33 | }, 34 | "sideEffects": [ 35 | "*.css" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /remotion/src/HelloWorld/Atom.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import { random, useVideoConfig } from "remotion"; 3 | 4 | export const Atom: React.FC<{ 5 | scale: number; 6 | color1: string; 7 | color2: string; 8 | }> = ({ scale, color1, color2 }) => { 9 | const config = useVideoConfig(); 10 | 11 | // Each SVG ID must be unique to not conflict with each other 12 | const [gradientId] = useState(() => String(random(null))); 13 | 14 | return ( 15 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | 35 | ); 36 | }; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Ezedin Fedlu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TikTok-Forge 2 | 🎬 Automated TikTok video generation pipeline powered by AI 3 | 4 | ## Description 5 | TikTok Forge is an enterprise-grade video automation framework that transforms text scripts into engaging TikTok videos. Built with Remotion, OpenAI, and n8n, it streamlines the entire video production workflow from script to social media upload. 6 | 7 | ## Key Features 8 | - 🤖 AI-powered script analysis and scene generation 9 | - 🎨 Dynamic video templating system 10 | - 🔄 Automated asset generation and management 11 | - 📦 Containerized development environment 12 | - 🔌 Modular architecture for easy customization 13 | - 🎵 Automated audio processing and synchronization 14 | - 📊 Built-in performance monitoring 15 | - 🔄 CI/CD ready configuration 16 | 17 | ## Tech Stack 18 | - Frontend: Remotion (React-based video generation) 19 | - Automation: n8n workflows 20 | - Database: NocoDB (PostgreSQL) 21 | - Storage: MinIO (S3-compatible) 22 | - AI: OpenAI GPT-4 23 | - Container: Docker & Docker Compose 24 | - API: RESTful endpoints 25 | 26 | ## Target Users 27 | - Content creators and marketing teams 28 | - Digital agencies 29 | - Social media managers 30 | - Content automation platforms 31 | - Video production companies 32 | 33 | ## License 34 | (MIT)[LICENSE] 35 | -------------------------------------------------------------------------------- /remotion/README.md: -------------------------------------------------------------------------------- 1 | # Remotion video 2 | 3 |

4 | 5 | 6 | 7 | Animated Remotion Logo 8 | 9 | 10 |

11 | 12 | Welcome to your Remotion project! 13 | 14 | ## Commands 15 | 16 | **Install Dependencies** 17 | 18 | ```console 19 | npm i 20 | ``` 21 | 22 | **Start Preview** 23 | 24 | ```console 25 | npm run dev 26 | ``` 27 | 28 | **Render video** 29 | 30 | ```console 31 | npx remotion render 32 | ``` 33 | 34 | **Upgrade Remotion** 35 | 36 | ```console 37 | npm run upgrade 38 | ``` 39 | 40 | ## Docs 41 | 42 | Get started with Remotion by reading the [fundamentals page](https://www.remotion.dev/docs/the-fundamentals). 43 | 44 | ## Help 45 | 46 | We provide help on our [Discord server](https://discord.gg/6VzzNDwUwV). 47 | 48 | ## Issues 49 | 50 | Found an issue with Remotion? [File an issue here](https://github.com/remotion-dev/remotion/issues/new). 51 | 52 | ## License 53 | 54 | Note that for some entities a company license is needed. [Read the terms here](https://github.com/remotion-dev/remotion/blob/main/LICENSE.md). 55 | -------------------------------------------------------------------------------- /remotion/src/HelloWorld/Title.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { spring, useCurrentFrame, useVideoConfig } from "remotion"; 3 | import { FONT_FAMILY } from "./constants"; 4 | 5 | const title: React.CSSProperties = { 6 | fontFamily: FONT_FAMILY, 7 | fontWeight: "bold", 8 | fontSize: 56, 9 | textAlign: "center", 10 | position: "absolute", 11 | bottom: 766, 12 | width: "100%", 13 | }; 14 | 15 | const word: React.CSSProperties = { 16 | marginLeft: 10, 17 | marginRight: 10, 18 | display: "inline-block", 19 | }; 20 | 21 | export const Title: React.FC<{ 22 | titleText: string; 23 | titleColor: string; 24 | }> = ({ titleText, titleColor }) => { 25 | const videoConfig = useVideoConfig(); 26 | const frame = useCurrentFrame(); 27 | 28 | const words = titleText.split(" "); 29 | 30 | return ( 31 |

32 | {words.map((t, i) => { 33 | const delay = i * 5; 34 | 35 | const scale = spring({ 36 | fps: videoConfig.fps, 37 | frame: frame - delay, 38 | config: { 39 | damping: 200, 40 | }, 41 | }); 42 | 43 | return ( 44 | 52 | {t} 53 | 54 | ); 55 | })} 56 |

57 | ); 58 | }; 59 | -------------------------------------------------------------------------------- /resourcs.md: -------------------------------------------------------------------------------- 1 | - resources 2 | - api for nocodb 3 | - [NocoDB Data API](https://data-apis-v2.nocodb.com/#tag/Table-Records) 4 | - [NocoDB Meta API](https://meta-apis-v2.nocodb.com/) 5 | 6 | - download swagger documentation and make the ai call endpoints to do the actions 7 | 8 | - remotion 9 | - [Remotion](https://www.remotion.dev/) 10 | 11 | 12 | 13 | 1. 𝐖𝐫𝐢𝐭𝐢𝐧𝐠 𝐓𝐨𝐨𝐥𝐬 14 | 15 | • Notion AI 16 | • Monica 17 | • TextFX 18 | • QuillBot 19 | • Jenni AI 20 | • ChatGPT 21 | 22 | 2. 𝐒𝐄𝐎 𝐓𝐨𝐨𝐥𝐬 23 | 24 | • LongShot 25 | • Semrush 26 | • Alli AI 27 | • Seona AI 28 | • Blogseo 29 | • Vidiq 30 | 31 | 3. 𝐂𝐨𝐝𝐢𝐧𝐠 𝐓𝐨𝐨𝐥𝐬 32 | 33 | • Codeium 34 | • Replit 35 | • Mars AI 36 | • Safurai 37 | • GitFluence 38 | • Phind 39 | 40 | 4. 𝐒𝐭𝐚𝐫𝐭𝐮𝐩 𝐓𝐨𝐨𝐥𝐬 41 | 42 | • Durable 43 | • Namelix 44 | • Bizway 45 | • Tekmatix 46 | • RhetorAI 47 | • CreativAI 48 | 49 | 5. 𝐋𝐨𝐠𝐨 𝐆𝐞𝐧𝐞𝐫𝐚𝐭𝐨𝐫 𝐓𝐨𝐨𝐥𝐬 50 | 51 | • Looka 52 | • Namecheap 53 | • Logoai 54 | • MakeLogo 55 | • Designs.ai 56 | • Brandmark 57 | 58 | 6. 𝐏𝐫𝐨𝐝𝐮𝐜𝐭𝐢𝐯𝐢𝐭𝐲 𝐓𝐨𝐨𝐥𝐬 59 | 60 | • Bright Eye 61 | • Audioread 62 | • GitMind 63 | • Magical 64 | • Taskade 65 | • Google Bard 66 | 67 | 7. 𝐈𝐦𝐚𝐠𝐞 𝐓𝐨𝐨𝐥𝐬 68 | 69 | • Stable Diffusion 70 | • SeaArt 71 | • LucidPic 72 | • Pebblely 73 | • Synthesys 74 | • Dall-E3 75 | 76 | 8. 𝐀𝐫𝐭 𝐓𝐨𝐨𝐥𝐬 77 | 78 | • Midjourney 79 | • Leonardo 80 | • Ideogram 81 | • Firefly 82 | • Playground AI 83 | • Leap 84 | 85 | 9. 𝐕𝐢𝐝𝐞𝐨 𝐓𝐨𝐨𝐥𝐬 86 | 87 | • HeyGen 88 | • Shuffl 89 | • Fliki 90 | • TopviewAI 91 | • Runway 92 | • Synthesie 93 | -------------------------------------------------------------------------------- /remotion/src/Video.tsx: -------------------------------------------------------------------------------- 1 | // src/Video.tsx 2 | import { Composition } from "remotion"; 3 | import { z } from "zod"; 4 | import VideoTemplate, { parseTimingString } from "./compositions/Template1"; 5 | import scenes from "./scenes.json"; 6 | 7 | // // Define Zod schema for props validation 8 | // const TikTokVideoSchema = z 9 | // .object({ 10 | // title: z.string(), 11 | // description: z.string().optional(), 12 | // backgroundImage: z.string().optional(), 13 | // audioSrc: z.string().optional(), 14 | // style: z.enum(["caption", "split", "fullscreen"]).optional(), 15 | // duration: z.number().optional(), 16 | // }) 17 | // .passthrough(); // Allow additional properties 18 | 19 | 20 | const DynamicVideoSchema = z 21 | .object({ 22 | scenes: z.array( 23 | z.object({}) 24 | ) 25 | }) 26 | .passthrough(); // Allow additional properties 27 | 28 | export const RemotionVideo: React.FC = () => { 29 | const totalDuration = scenes.scenes.reduce((acc, scene) => { 30 | const { end } = parseTimingString(scene.timing); 31 | return Math.max(acc, end); 32 | }, 0); 33 | return ( 34 | <> 35 | > 36 | id="TikTokVideo" 37 | component={VideoTemplate} 38 | durationInFrames={totalDuration} 39 | fps={30} 40 | width={1080} 41 | height={1920} 42 | schema={DynamicVideoSchema} 43 | defaultProps={ 44 | { 45 | scenes: scenes.scenes 46 | } 47 | } 48 | /> 49 | 50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /remotion/src/Root.tsx: -------------------------------------------------------------------------------- 1 | import "./tailwind.css"; 2 | import { Composition } from "remotion"; 3 | import { HelloWorld, myCompSchema } from "./HelloWorld"; 4 | import { Logo, myCompSchema2 } from "./HelloWorld/Logo"; 5 | import { RemotionVideo } from "./Video"; 6 | 7 | // Each is an entry in the sidebar! 8 | 9 | export const RemotionRoot: React.FC = () => { 10 | return ( 11 | <> 12 | out/video.mp4 15 | id="HelloWorld" 16 | component={HelloWorld} 17 | durationInFrames={150} 18 | fps={30} 19 | width={1080} 20 | height={1920} 21 | // You can override these props for each render: 22 | // https://www.remotion.dev/docs/parametrized-rendering 23 | schema={myCompSchema} 24 | defaultProps={{ 25 | titleText: "Learn Programming with Ezedin!", 26 | titleColor: "#ccd6f6", 27 | logoColor1: "#91EAE4", 28 | logoColor2: "#86A8E7", 29 | }} 30 | /> 31 | 32 | {/* Mount any React component to make it show up in the sidebar and work on it individually! */} 33 |