Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: CI

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
lint:
name: Biome Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Run Biome check
run: bun run check

test:
name: Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Run tests
run: bun run test:run

build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Build
run: bun run build
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
109 changes: 75 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,131 @@

Convert your videos to the required format for macOS and iOS App Store app previews.

**Why this exists:** When uploading MP4 app recordings to Apple's App Store Connect, uploads often fail silently without any indication why. Apple secretly checks for specific video formatting requirements. This tool applies those formats to your video so it can be properly uploaded.

## Features

- Convert videos to macOS App Store format (1920×1080)
- Convert videos to iOS App Store format (886×1920)
- Add silent audio track (fixes Apple upload issues)
- Fast server-side processing with native FFmpeg
- Progress tracking for upload and download
- Instant preview of converted videos
- Add silent audio track (fixes common Apple upload rejections)
- Fast server-side processing with FFmpeg
- Desktop-only (video processing requires desktop browser)

## Requirements

### System Requirements

- **Node.js** 18.x or higher
- **FFmpeg** installed on the server (required for video processing)

### Video Requirements

- Format: MP4
- Duration: 15-30 seconds
- Max file size: 500MB

## Server Requirements

This application requires FFmpeg to be installed on the server. For optimal performance, follow these installation instructions:
This application requires FFmpeg to be installed on the server.

### macOS

```bash
# Using Homebrew
brew install ffmpeg

# Verify installation
ffmpeg -version
```

### Ubuntu/Debian

```bash
# Update package lists
sudo apt update

# Install FFmpeg
sudo apt install -y ffmpeg

# Verify installation
ffmpeg -version
```

### CentOS/RHEL/Fedora

```bash
# For CentOS/RHEL 8 or newer and Fedora
sudo dnf install -y ffmpeg ffmpeg-devel

# Verify installation
ffmpeg -version
```

### Windows Server
### Windows

1. Download FFmpeg from the [official website](https://www.ffmpeg.org/download.html)
2. Extract the files to a folder, e.g., `C:\ffmpeg`
3. Add the `bin` folder to your system PATH
4. Verify by running `ffmpeg -version` in the command prompt
1. Download FFmpeg from [ffmpeg.org/download.html](https://www.ffmpeg.org/download.html)
2. Extract to `C:\ffmpeg`
3. Add `C:\ffmpeg\bin` to system PATH
4. Verify: `ffmpeg -version`

## Development

```bash
# Install dependencies
pnpm install
bun install

# Start the development server
pnpm dev
bun dev

# Run tests
bun test

# Run tests with coverage
bun test:coverage

# Lint
bun lint

# Build for production
bun run build
```

## Building for Production
## Tech Stack

```bash
# Build the application
pnpm build
- **Framework:** Next.js 16
- **Language:** TypeScript
- **Styling:** Tailwind CSS
- **UI Components:** shadcn/ui + Magic UI
- **Animation:** Motion (Framer Motion)
- **Testing:** Vitest + React Testing Library
- **Video Processing:** FFmpeg (server-side)

## Project Structure

# Start the production server
pnpm start
```
src/
├── app/ # Next.js App Router
│ ├── api/convert/ # Video conversion API endpoint
│ └── page.tsx # Main page
├── components/
│ ├── magicui/ # Magic UI components
│ ├── providers/ # React context providers
│ ├── ui/ # shadcn/ui components
│ └── video-convert/ # Video conversion flow
├── hooks/ # Custom React hooks
├── lib/ # Utility functions
├── types/ # TypeScript types
└── __tests__/ # Test files
```

## Deployment

This application can be deployed to any Node.js hosting platforms that support Next.js, such as:
Deploy to any Node.js platform that supports Next.js:

- Vercel
- Netlify
- AWS Amplify
- Railway
- Render
- DigitalOcean App Platform
- Heroku
- AWS (EC2, ECS, Lambda)

**Important:** Ensure FFmpeg is installed on your deployment server. The app will return a 503 error if FFmpeg is not available.

### Environment Variables

**Important:** Ensure that FFmpeg is installed on your deployment server for the video conversion to work properly.
No environment variables are required for basic operation. For production, consider:

```env
NODE_ENV=production
```

## License

Expand Down
45 changes: 45 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.10/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"includes": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.js", "./src/**/*.jsx"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"useExhaustiveDependencies": "warn",
"useHookAtTopLevel": "error",
"noUnusedImports": "error",
"noUnusedVariables": "error"
},
"suspicious": {
"noExplicitAny": "warn"
},
"style": {
"noUnusedTemplateLiteral": "off"
},
"a11y": {
"useSemanticElements": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"semicolons": "always",
"trailingCommas": "all"
}
}
}
Loading