Align preview typography with FFmpeg output, add video/song title split, and ship OSS updates.
Separate YouTube video titles from on-video song/artist fields with Pro gating, serve curated fonts and watermark assets for 1:1 preview parity, and include billing/API/docs/deploy stack for self-hosted release. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
682020ff5a
commit
c8015937f9
@@ -0,0 +1,130 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Video editing
|
||||
|
||||
Self-hosted Songs2VID includes a **Layout Studio** on the dashboard upload form: art-track compositions, blur backgrounds, typography, and watermarks with live preview. The same options are available on the [REST API](./api/endpoints.md).
|
||||
|
||||
## Classic vs art-track
|
||||
|
||||
| Mode | Behavior |
|
||||
|------|----------|
|
||||
| **Classic** (no template) | Cover letterboxed on a black frame — simple and reliable |
|
||||
| **Art-track template** | Cover + title/artist arranged by a fixed template, with a blurred cover fill behind |
|
||||
|
||||
Templates are enum-based. Free-form cover coordinates (`x`, `y`, `coverX`, …) are rejected so encoding stays predictable.
|
||||
|
||||
### Templates
|
||||
|
||||
| Template | Layout |
|
||||
|----------|--------|
|
||||
| `COVER_LEFT_TEXT_RIGHT` | Cover on the left; title & artist on the right |
|
||||
| `COVER_TOP_TEXT_BOTTOM` | Cover on top; title & artist below |
|
||||
| `COVER_RIGHT_TEXT_LEFT` | Cover on the right; title & artist on the left |
|
||||
| `CENTERED_COMPACT` | Centered cover with a compact title/artist stack |
|
||||
|
||||
Pick a template in the UI under **Composition**, or set `metadata.layout.template` in the API.
|
||||
|
||||
## Title and artist
|
||||
|
||||
Each track can have:
|
||||
|
||||
- **Title** — used on the video and as the YouTube title (often prefilled from the filename)
|
||||
- **Artist** — drawn under the title on art-track layouts (max 80 characters)
|
||||
|
||||
Artist is especially useful when ID3 tags or your API payload include it.
|
||||
|
||||
## Blur background
|
||||
|
||||
When an art-track template is active, the encoder builds a full-frame background from the cover:
|
||||
|
||||
- **Blur amount** (`blurAmount`, `0`–`100`, default `55`) — FFmpeg `boxblur` intensity
|
||||
- **Background opacity** (`blurOpacity`, `0`–`100`, default `100`) — how strong the blurred fill is versus solid black (`0` = black, `100` = full blur)
|
||||
|
||||
Use lower opacity for a darker, more subdued frame; higher for a soft wash of the artwork.
|
||||
|
||||
## Fine-tuning
|
||||
|
||||
All values are clamped. These nudge the composition inside the template — they are not free-form canvas placement.
|
||||
|
||||
| Control | Field | Range | Default | What it does |
|
||||
|---------|-------|-------|---------|--------------|
|
||||
| Padding | `textPadding` | 16–120 px | 48 | Space around cover and text |
|
||||
| Title ↔ artist | `titleArtistGap` | 0–64 px | 10 | Vertical gap between title and artist |
|
||||
| Text horizontal | `textOffsetX` | −120–120 px | 0 | Shift the text block left/right |
|
||||
| Text vertical | `textOffsetY` | −120–120 px | 0 | Shift the text block up/down |
|
||||
|
||||
In the dashboard, sliders update the live preview. Via API, nest them under `metadata.layout` (camelCase or snake_case aliases are accepted).
|
||||
|
||||
## Per-track covers
|
||||
|
||||
Upload a shared cover for the batch, then optionally set a different image per item (`metadata.imagePath` after uploading with `type=image`). Useful for singles that share an album batch but need distinct artwork.
|
||||
|
||||
## Watermarks
|
||||
|
||||
Modes:
|
||||
|
||||
| Mode | Effect |
|
||||
|------|--------|
|
||||
| `none` | No watermark |
|
||||
| `default` | Built-in Songs2VID branding |
|
||||
| `text` | Custom text with optional typography |
|
||||
| `logo` | Custom PNG (upload with `type=logo`, then set `logoPath`) |
|
||||
|
||||
### Position and offset
|
||||
|
||||
- **Position**: `top-left` · `top-right` · `bottom-left` · `bottom-right` · `center`
|
||||
- **Offsets** (`offsetX` / `offsetY`): `0`–`200` px from the chosen anchor (default `20`)
|
||||
|
||||
### Typography (text mode)
|
||||
|
||||
Curated fonts (bundled under `assets/fonts` after fetch):
|
||||
|
||||
- `system` — FFmpeg default
|
||||
- `inter` · `montserrat` · `roboto` · `oswald` · `playfair`
|
||||
- `custom` — your `.ttf` / `.otf` (max 10 MB; upload with `type=font`, set `fontKey: "custom"` and `fontPath`)
|
||||
|
||||
Refresh curated files if missing:
|
||||
|
||||
```bash
|
||||
node scripts/fetch-watermark-fonts.mjs
|
||||
```
|
||||
|
||||
Text length is capped at 80 characters.
|
||||
|
||||
## Dashboard workflow
|
||||
|
||||
1. Add audio (and optional per-track covers)
|
||||
2. Open **Layout Studio** on a track
|
||||
3. Choose classic or a template, then tune blur, padding, gaps, and text offsets
|
||||
4. Configure watermark mode, font, and position
|
||||
5. Preview updates live; submit to enqueue encoding
|
||||
|
||||
## API
|
||||
|
||||
See [Endpoints](./api/endpoints.md) for curl examples. Layout and watermark objects live under each item’s `metadata`:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "My Track",
|
||||
"artist": "My Artist",
|
||||
"layout": {
|
||||
"template": "COVER_LEFT_TEXT_RIGHT",
|
||||
"blurAmount": 60,
|
||||
"blurOpacity": 85,
|
||||
"textPadding": 48,
|
||||
"titleArtistGap": 12,
|
||||
"textOffsetX": 0,
|
||||
"textOffsetY": 0
|
||||
},
|
||||
"watermark": {
|
||||
"mode": "text",
|
||||
"text": "My Label",
|
||||
"fontKey": "montserrat",
|
||||
"position": "bottom-right",
|
||||
"offsetX": 24,
|
||||
"offsetY": 24
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user