- Change :hash to :cid throughout - Update cat asset: QmXrj6tSSn1vQXxxEY2Tyoudvt4CeeqR9gGQwSt7WFrhMZ - Update dog effect: QmT99H4MC5p18MGuxAeKGeXD71cGCzMNRxFfvt4FuCwpn6 - Update invert effect: QmPWaW5E5WFrmDjT6w8enqvtJhM8c5jvQu7XN1doHA3Z7J Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
186 lines
5.1 KiB
Markdown
186 lines
5.1 KiB
Markdown
# Art DAG Recipes
|
|
|
|
Declarative media composition using content-addressed primitives and effects.
|
|
|
|
## Recipes
|
|
|
|
| Recipe | Description | Inputs | Status |
|
|
|--------|-------------|--------|--------|
|
|
| [identity-cat](recipes/identity-cat/) | Apply identity effect to cat | fixed | ✅ Working |
|
|
| [identity-then-dog](recipes/identity-then-dog/) | Chain identity → dog effects | fixed | ✅ Working |
|
|
| [dog-concat](recipes/dog-concat/) | Dog video + user video concatenated | fixed + variable | ✅ Working |
|
|
| [beat-cuts](recipes/beat-cuts/) | Cut between videos on beats | variable | 🔮 Future |
|
|
| [energy-reactive](recipes/energy-reactive/) | Effects pulse with music energy | variable | 🔮 Future |
|
|
| [tempo-match](recipes/tempo-match/) | Speed-match videos to music tempo | variable | 🔮 Future |
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Upload a recipe
|
|
artdag upload-recipe recipes/dog-concat/recipe.yaml
|
|
|
|
# Upload your video
|
|
artdag upload /path/to/my-video.mp4
|
|
# → returns content_hash
|
|
|
|
# Run with variable input
|
|
artdag run-recipe <recipe_id> -i source_second:<content_hash>
|
|
```
|
|
|
|
## Recipe Structure
|
|
|
|
```
|
|
recipes/
|
|
├── identity-cat/
|
|
│ ├── recipe.yaml # DAG definition
|
|
│ └── README.md # Documentation
|
|
├── dog-concat/
|
|
│ └── recipe.yaml
|
|
└── beat-cuts/ # Future: audio-reactive
|
|
└── recipe.yaml
|
|
```
|
|
|
|
## Recipe Schema
|
|
|
|
```yaml
|
|
name: recipe-name
|
|
version: "1.0"
|
|
description: "What this recipe does"
|
|
|
|
# Content-addressed references
|
|
registry:
|
|
assets:
|
|
cat:
|
|
hash: "33268b6e..."
|
|
url: "https://..."
|
|
effects:
|
|
dog:
|
|
hash: "d048fe31..."
|
|
|
|
# DAG definition
|
|
dag:
|
|
nodes:
|
|
- id: source_cat
|
|
type: SOURCE
|
|
config:
|
|
asset: cat # Fixed: from registry
|
|
|
|
- id: user_video
|
|
type: SOURCE
|
|
config:
|
|
input: true # Variable: supplied at runtime
|
|
name: "User Video"
|
|
description: "Your video file"
|
|
|
|
- id: result
|
|
type: SEQUENCE
|
|
inputs:
|
|
- source_cat
|
|
- user_video
|
|
|
|
output: result
|
|
|
|
owner: "@giles@artdag.rose-ash.com"
|
|
```
|
|
|
|
## Primitives
|
|
|
|
### Implemented
|
|
|
|
| Primitive | Description | Example |
|
|
|-----------|-------------|---------|
|
|
| `SOURCE` | Load media file | `config: { asset: cat }` or `{ input: true }` |
|
|
| `SEGMENT` | Extract time range | `config: { offset: 0, duration: 5.0 }` |
|
|
| `RESIZE` | Scale/crop/pad | `config: { width: 1920, height: 1080, mode: fit }` |
|
|
| `TRANSFORM` | Visual effects | `config: { effects: { saturation: 1.5 } }` |
|
|
| `SEQUENCE` | Concatenate in time | `config: { transition: { type: cut } }` |
|
|
| `LAYER` | Stack spatially | `config: { inputs: [{}, {opacity: 0.5}] }` |
|
|
| `MUX` | Combine video + audio | `config: { shortest: true }` |
|
|
| `BLEND` | Blend two inputs | `config: { mode: overlay, opacity: 0.5 }` |
|
|
| `EFFECT` | Apply registered effect | `config: { effect: dog }` |
|
|
|
|
### Future (Audio-Reactive)
|
|
|
|
| Primitive | Description | Example |
|
|
|-----------|-------------|---------|
|
|
| `ANALYZE` | Extract audio features | `config: { feature: beats }` |
|
|
| `BIND` | Map data → parameters | `config: { source: energy, target: saturation }` |
|
|
| `MAP` | Apply op to each item | `config: { operation: RANDOM_SLICE }` |
|
|
| `TRANSFORM_DYNAMIC` | Time-varying effects | Effects driven by BIND output |
|
|
| `SOURCE_LIST` | Multiple inputs as list | `config: { input: true, min_items: 2 }` |
|
|
| `GROUP` | Chunk data | `config: { size: 4, output: segments }` |
|
|
| `COMPUTE` | Arithmetic on data | `config: { expression: "tempo / 120" }` |
|
|
|
|
See [PRIMITIVES.md](PRIMITIVES.md) for full design documentation.
|
|
|
|
## Input Types
|
|
|
|
### Fixed Inputs
|
|
Referenced by content hash from registry. Always the same.
|
|
```yaml
|
|
config:
|
|
asset: cat # Resolved from registry.assets.cat.hash
|
|
```
|
|
|
|
### Variable Inputs
|
|
Supplied at runtime by the user.
|
|
```yaml
|
|
config:
|
|
input: true
|
|
name: "My Video"
|
|
description: "Video to process"
|
|
```
|
|
|
|
## DAG Patterns
|
|
|
|
### Chain Effects
|
|
```
|
|
SOURCE → EFFECT → EFFECT → output
|
|
```
|
|
|
|
### Concatenate
|
|
```
|
|
SOURCE ──┐
|
|
├→ SEQUENCE → output
|
|
SOURCE ──┘
|
|
```
|
|
|
|
### Mux Audio + Video
|
|
```
|
|
video SOURCE ──┐
|
|
├→ MUX → output
|
|
audio SOURCE ──┘
|
|
```
|
|
|
|
### Audio-Reactive (Future)
|
|
```
|
|
audio → ANALYZE → BIND ──┐
|
|
├→ TRANSFORM_DYNAMIC → MUX → output
|
|
video ───────────────────┘
|
|
```
|
|
|
|
## Content Addressing
|
|
|
|
Everything is identified by SHA3-256 hash:
|
|
- **Assets**: `33268b6e167deaf018cc538de12dbe562612b33e89a749391cef855b320a269b`
|
|
- **Effects**: `d048fe313433eb4e38f0e24194ffae91b896ca3e6eed3e50b2cc37b7be495555`
|
|
- **Nodes**: `hash(type + config + inputs)` - automatic deduplication
|
|
- **Recipes**: Hash of YAML file
|
|
|
|
Same inputs + same recipe = same output. Always.
|
|
|
|
## Ownership
|
|
|
|
Recipes are signed by ActivityPub actors (e.g., `@giles@artdag.rose-ash.com`).
|
|
|
|
Ownership enables:
|
|
- Provenance tracking
|
|
- Revenue distribution down the creation chain
|
|
- Federated sharing across L2 servers
|
|
|
|
## Registry References
|
|
|
|
- **Assets**: https://git.rose-ash.com/art-dag/registry
|
|
- **Effects**: https://git.rose-ash.com/art-dag/effects
|
|
- **Art Source**: https://git.rose-ash.com/art-dag/art-source
|