chore(xtream-mock-server): add artwork mock data and script to generate artwork for IPTVnator releases
- Implemented a TypeScript script that generates original fictional demo artwork for IPTVnator release screenshots. - The script supports multiple artwork kinds (poster and backdrop) and qualities (low, medium, high, auto). - It includes functionality for dry runs, generating artwork, manifest creation, and validation of generated assets. - Integrated with OpenAI's image generation API to create artwork based on provided prompts and fixture data. - Added a manifest file to track generated assets and their metadata. - Ensured output directories are created as needed and included error handling for API requests. Entire-Checkpoint: c6e522b4276c
No files matched your search
@@ -14,21 +14,30 @@ pnpm nx run xtream-mock-server:serve
|
||||
|
||||
# Start with file-watch (auto-restart on code changes)
|
||||
pnpm nx run xtream-mock-server:serve-with-watch
|
||||
|
||||
# Start the mock server plus the Electron app
|
||||
pnpm run serve:marketing-demo
|
||||
|
||||
# Start the mock server plus the browser web app
|
||||
pnpm run serve:marketing-demo:web
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Available Scenarios (credential pairs)
|
||||
|
||||
| Username | Password | Scenario | Live cats | VOD cats | Series cats | Items/cat | Status |
|
||||
|----------|----------|----------|-----------|----------|-------------|-----------|--------|
|
||||
| `user1` | `pass1` | default | 8 | 8 | 8 | 40 | active |
|
||||
| `large` | `large` | large catalog | 20 | 20 | 20 | 200 | active |
|
||||
| `series` | `series` | series-heavy | 3 | 4 | 15 | 30 | active |
|
||||
| `minimal` | `minimal` | minimal (edge cases) | 2 | 2 | 2 | 5 | active |
|
||||
| `epg` | `epg` | EPG fixture | 2 | 1 | 1 | 3 | active |
|
||||
| `expired` | `expired` | expired account | 4 | 4 | 4 | 10 | Expired |
|
||||
| `inactive` | `inactive` | disabled account | 4 | 4 | 4 | 10 | Disabled |
|
||||
| Username | Password | Scenario | Live cats | VOD cats | Series cats | Items/cat | Status |
|
||||
| ----------- | ----------- | ---------------------- | --------- | -------- | ----------- | --------- | -------- |
|
||||
| `user1` | `pass1` | default | 8 | 8 | 8 | 40 | active |
|
||||
| `large` | `large` | large catalog | 20 | 20 | 20 | 200 | active |
|
||||
| `stress` | `stress` | stress catalog | 16 | 16 | 16 | 120 | active |
|
||||
| `series` | `series` | series-heavy | 3 | 4 | 15 | 30 | active |
|
||||
| `minimal` | `minimal` | minimal (edge cases) | 2 | 2 | 2 | 5 | active |
|
||||
| `epg` | `epg` | EPG fixture | 2 | 1 | 1 | 3 | active |
|
||||
| `emptyvod` | `emptyvod` | empty VOD metadata | 2 | 2 | 2 | 5 | active |
|
||||
| `marketing` | `marketing` | fictional release demo | 4 | 4 | 4 | curated | active |
|
||||
| `expired` | `expired` | expired account | 4 | 4 | 4 | 10 | Expired |
|
||||
| `inactive` | `inactive` | disabled account | 4 | 4 | 4 | 10 | Disabled |
|
||||
|
||||
Any other credential pair is auto-generated using a hash of `username:password` as the faker seed (6 categories, 30 items each, active account).
|
||||
|
||||
@@ -40,27 +49,29 @@ Any other credential pair is auto-generated using a hash of `username:password`
|
||||
|
||||
`GET /player_api.php?action=<action>&username=<u>&password=<p>[&...]`
|
||||
|
||||
| Action | Description |
|
||||
|--------|-------------|
|
||||
| (none) / `get_account_info` | User info + server info |
|
||||
| `get_live_categories` | Live TV categories |
|
||||
| `get_vod_categories` | VOD (movie) categories |
|
||||
| `get_series_categories` | Series categories |
|
||||
| `get_live_streams` | Live streams (optionally filtered by `category_id`) |
|
||||
| `get_vod_streams` | VOD streams (optionally filtered by `category_id`) |
|
||||
| `get_series` | Series list (optionally filtered by `category_id`) |
|
||||
| `get_vod_info?vod_id=<id>` | Full movie details |
|
||||
| `get_series_info?series_id=<id>` | Full series info (seasons + episodes) |
|
||||
| `get_short_epg?stream_id=<id>[&limit=N]` | EPG listings for a live channel |
|
||||
| `get_simple_data_table?stream_id=<id>` | Full per-channel EPG schedule |
|
||||
| `get_simple_date_table?stream_id=<id>` | Legacy typo alias for full per-channel EPG schedule |
|
||||
| Action | Description |
|
||||
| ---------------------------------------- | --------------------------------------------------- |
|
||||
| (none) / `get_account_info` | User info + server info |
|
||||
| `get_live_categories` | Live TV categories |
|
||||
| `get_vod_categories` | VOD (movie) categories |
|
||||
| `get_series_categories` | Series categories |
|
||||
| `get_live_streams` | Live streams (optionally filtered by `category_id`) |
|
||||
| `get_vod_streams` | VOD streams (optionally filtered by `category_id`) |
|
||||
| `get_series` | Series list (optionally filtered by `category_id`) |
|
||||
| `get_vod_info?vod_id=<id>` | Full movie details |
|
||||
| `get_series_info?series_id=<id>` | Full series info (seasons + episodes) |
|
||||
| `get_short_epg?stream_id=<id>[&limit=N]` | EPG listings for a live channel |
|
||||
| `get_simple_data_table?stream_id=<id>` | Full per-channel EPG schedule |
|
||||
| `get_simple_date_table?stream_id=<id>` | Legacy typo alias for full per-channel EPG schedule |
|
||||
|
||||
### PWA CORS Proxy Endpoint
|
||||
|
||||
IPTVnator's PWA routes Xtream calls through a backend proxy:
|
||||
|
||||
```
|
||||
GET /xtream?url=<serverUrl>&action=<action>&username=<u>&password=<p>
|
||||
```
|
||||
|
||||
Response: `{ payload: <data>, action: <action> }`
|
||||
|
||||
### Stream URLs (stub redirects)
|
||||
@@ -133,12 +144,39 @@ application code.
|
||||
- **Cached per session**: Data generated once on first request, reused until `/reset`
|
||||
- **EPG**: Titles and descriptions are base64-encoded (matches real Xtream API)
|
||||
- **Dedicated EPG fixture**: `epg:epg` returns stable live channels plus deterministic `get_short_epg` and `get_simple_data_table` payloads for timezone-focused tests
|
||||
- **Release screenshot fixture**: `marketing:marketing` returns fictional live, VOD, and series data with local generated artwork under `apps/xtream-mock-server/public/marketing`
|
||||
- **Timestamp precedence coverage**: The `epg:epg` scenario intentionally shifts raw `start` / `end` strings away from `start_timestamp` / `stop_timestamp` so UI tests can prove timestamps drive rendering
|
||||
- **Stream IDs**: Live 10,000+, VOD 20,000+, Series 30,000+
|
||||
- **Category IDs**: Live 101+, VOD 201+, Series 301+
|
||||
|
||||
---
|
||||
|
||||
## Release Demo Artwork
|
||||
|
||||
The `marketing:marketing` fixture uses 30 original fictional titles for release
|
||||
screenshots. Poster and backdrop PNGs are served from:
|
||||
|
||||
```text
|
||||
apps/xtream-mock-server/public/marketing/{poster,backdrop}/
|
||||
```
|
||||
|
||||
Generate or validate those assets with:
|
||||
|
||||
```bash
|
||||
pnpm release:artwork:dry-run
|
||||
pnpm release:artwork:generate
|
||||
pnpm release:artwork:validate
|
||||
```
|
||||
|
||||
`release:artwork:generate` uses `gpt-image-2` through the OpenAI Image API and
|
||||
requires `OPENAI_API_KEY`. The screenshot capture workflow only reads committed
|
||||
local assets; it does not call OpenAI. If a local PNG is missing, the mock
|
||||
server falls back to its deterministic SVG renderer for development continuity.
|
||||
The prompt manifest deliberately varies genres and visual media across titles
|
||||
so the catalog does not collapse into one superhero/poster style.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
See `docs/architecture/xtream-mock-server.md` for a full description of the
|
||||
|
||||
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 2.9 MiB |
|
After Width: | Height: | Size: 2.4 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 2.0 MiB |
@@ -0,0 +1,728 @@
|
||||
{
|
||||
"assetRoot": "apps/xtream-mock-server/public/marketing",
|
||||
"assets": [
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/crimson-skylark.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Crimson Skylark\" (2026).\nGenre: Aerial Rescue Adventure.\nStory seed: Every sunrise needs a signal. A high-altitude rescue courier follows sunrise signals through the storm routes above Meridian City.\nVisual direction: an aerial rescue courier navigating storm routes above Meridian City, a solar signal crest glowing in the cloudbreak\nVisual medium and style: golden-hour aerial adventure photography with realistic rescue-drama production design, wind, clouds, practical flight gear, and natural lens flare\nPalette and texture: sunrise coral, storm gray, aviation green, grainy but realistic atmospheric haze\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 single rescue courier against a huge storm sky, diagonal flight path, naturalistic poster photography; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "crimson-skylark",
|
||||
"title": "Crimson Skylark"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/crimson-skylark.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Crimson Skylark\" (2026).\nGenre: Aerial Rescue Adventure.\nStory seed: Every sunrise needs a signal. A high-altitude rescue courier follows sunrise signals through the storm routes above Meridian City.\nVisual direction: an aerial rescue courier navigating storm routes above Meridian City, a solar signal crest glowing in the cloudbreak\nVisual medium and style: golden-hour aerial adventure photography with realistic rescue-drama production design, wind, clouds, practical flight gear, and natural lens flare\nPalette and texture: sunrise coral, storm gray, aviation green, grainy but realistic atmospheric haze\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 vast sky route above a modern city, layered storm clouds, small courier silhouette, breathable horizon; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "crimson-skylark",
|
||||
"title": "Crimson Skylark"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/the-voltage-guard.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The Voltage Guard\" (2025).\nGenre: Disaster Action Thriller.\nStory seed: Power is only heroic when it is shared. Four transit workers race to keep the night trains moving as a thunderstorm turns the city grid unstable.\nVisual direction: transit workers protecting an elevated rail grid from a living thunderstorm, blue-white electricity reflected in wet streets\nVisual medium and style: gritty disaster-thriller photography, rain-soaked infrastructure, documentary realism, sparks, emergency work lights, no fantasy costumes\nPalette and texture: steel blue, sodium orange, wet asphalt black, white electrical flares\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 workers and rail geometry forming a tense action triangle, practical uniforms and tools; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "the-voltage-guard",
|
||||
"title": "The Voltage Guard"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/the-voltage-guard.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The Voltage Guard\" (2025).\nGenre: Disaster Action Thriller.\nStory seed: Power is only heroic when it is shared. Four transit workers race to keep the night trains moving as a thunderstorm turns the city grid unstable.\nVisual direction: transit workers protecting an elevated rail grid from a living thunderstorm, blue-white electricity reflected in wet streets\nVisual medium and style: gritty disaster-thriller photography, rain-soaked infrastructure, documentary realism, sparks, emergency work lights, no fantasy costumes\nPalette and texture: steel blue, sodium orange, wet asphalt black, white electrical flares\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide elevated transit grid under unstable weather, workers small in frame, strong industrial depth; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "the-voltage-guard",
|
||||
"title": "The Voltage Guard"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/midnight-mantle.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Midnight Mantle\" (2024).\nGenre: Gothic Mystery.\nStory seed: The city has one last trick. A retired stage magician investigates a living cloak rumor haunting the old theatre district after dark.\nVisual direction: an old theatre district at night, a mysterious cloak rumor visualized through shadows, marquee light, and rain-soaked cobblestones\nVisual medium and style: gothic noir illustration with theatrical shadow shapes, old print texture, rain, velvet blacks, and painterly mystery atmosphere\nPalette and texture: deep violet, amber marquee light, wet black streets, muted crimson accents\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 theatre silhouette and sweeping cloak as an abstract mystery shape, not a superhero pose; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "midnight-mantle",
|
||||
"title": "Midnight Mantle"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/midnight-mantle.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Midnight Mantle\" (2024).\nGenre: Gothic Mystery.\nStory seed: The city has one last trick. A retired stage magician investigates a living cloak rumor haunting the old theatre district after dark.\nVisual direction: an old theatre district at night, a mysterious cloak rumor visualized through shadows, marquee light, and rain-soaked cobblestones\nVisual medium and style: gothic noir illustration with theatrical shadow shapes, old print texture, rain, velvet blacks, and painterly mystery atmosphere\nPalette and texture: deep violet, amber marquee light, wet black streets, muted crimson accents\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 empty theatre district at night, marquee glow without readable letters, cloak-like shadow crossing rooftops; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "midnight-mantle",
|
||||
"title": "Midnight Mantle"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/quantum-comet.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Quantum Comet\" (2026).\nGenre: Cosmic Science Fiction.\nStory seed: Faster than tomorrow. An orbital cartographer rides a fractured comet trail to stop a time-lost armada.\nVisual direction: an orbital cartographer crossing fractured comet trails beside a time-bent armada, star maps glowing in cold blue light\nVisual medium and style: hard science-fiction concept art with crisp spacecraft detail, star charts, comet ice, scale diagrams, and luminous navigation UI shapes without readable text\nPalette and texture: icy cyan, white comet dust, deep navy, precise magenta navigation glows\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 cartographer figure and fractured comet arc arranged like a scientific expedition poster; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "quantum-comet",
|
||||
"title": "Quantum Comet"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/quantum-comet.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Quantum Comet\" (2026).\nGenre: Cosmic Science Fiction.\nStory seed: Faster than tomorrow. An orbital cartographer rides a fractured comet trail to stop a time-lost armada.\nVisual direction: an orbital cartographer crossing fractured comet trails beside a time-bent armada, star maps glowing in cold blue light\nVisual medium and style: hard science-fiction concept art with crisp spacecraft detail, star charts, comet ice, scale diagrams, and luminous navigation UI shapes without readable text\nPalette and texture: icy cyan, white comet dust, deep navy, precise magenta navigation glows\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide comet trail and distant armada silhouettes, clean negative space around the center; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "quantum-comet",
|
||||
"title": "Quantum Comet"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/orbit-of-atlas.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Orbit of Atlas\" (2025).\nGenre: Cosmic Survival Adventure.\nStory seed: Hold the sky. A rescue pilot navigates a fractured moon orbit long enough for a remote colony to evacuate.\nVisual direction: a rescue pilot navigating a cracked moon orbit over a fragile colony, gravity ribbons bending dust and sunlight\nVisual medium and style: epic cosmic survival painting with mineral surfaces, colony lights, gravitational dust ribbons, and solemn scale\nPalette and texture: burnt gold, moon gray, dusty umber, cold blue space shadows\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 small rescue pilot dwarfed by a cracked moon, monumental survival mood; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "orbit-of-atlas",
|
||||
"title": "Orbit of Atlas"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/orbit-of-atlas.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Orbit of Atlas\" (2025).\nGenre: Cosmic Survival Adventure.\nStory seed: Hold the sky. A rescue pilot navigates a fractured moon orbit long enough for a remote colony to evacuate.\nVisual direction: a rescue pilot navigating a cracked moon orbit over a fragile colony, gravity ribbons bending dust and sunlight\nVisual medium and style: epic cosmic survival painting with mineral surfaces, colony lights, gravitational dust ribbons, and solemn scale\nPalette and texture: burnt gold, moon gray, dusty umber, cold blue space shadows\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 fractured moon over a remote colony, dust and sunlight bending in wide arcs; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "orbit-of-atlas",
|
||||
"title": "Orbit of Atlas"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/nova-relay.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Nova Relay\" (2023).\nGenre: Space Opera.\nStory seed: The message arrives in light. Twin signal runners cross a star bridge to deliver the last warning before a solar network goes dark.\nVisual direction: twin signal runners racing across a luminous star bridge, urgent light messages streaking toward a blue planet\nVisual medium and style: sleek space-opera animation art with clean silhouettes, radiant motion trails, glossy star-bridge architecture, and optimistic color\nPalette and texture: electric teal, royal blue, white light trails, warm planetary glow\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 twin runners crossing a luminous bridge with strong graphic diagonals; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "nova-relay",
|
||||
"title": "Nova Relay"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/nova-relay.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Nova Relay\" (2023).\nGenre: Space Opera.\nStory seed: The message arrives in light. Twin signal runners cross a star bridge to deliver the last warning before a solar network goes dark.\nVisual direction: twin signal runners racing across a luminous star bridge, urgent light messages streaking toward a blue planet\nVisual medium and style: sleek space-opera animation art with clean silhouettes, radiant motion trails, glossy star-bridge architecture, and optimistic color\nPalette and texture: electric teal, royal blue, white light trails, warm planetary glow\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 star bridge leading toward a blue planet, two tiny figures and sweeping light messages; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "nova-relay",
|
||||
"title": "Nova Relay"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/beacon-boy-and-the-clockwork-garden.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Beacon Boy and the Clockwork Garden\" (2026).\nGenre: Animated Family Fantasy.\nStory seed: Small heroes grow tall. A young inventor and his grandmother awaken a garden of mechanical guardians beneath the city park.\nVisual direction: a young inventor and grandmother discovering mechanical garden guardians under a city park, brass leaves and gentle lantern light\nVisual medium and style: storybook 3D animated fantasy, handmade brass mechanisms, moss, warm lantern light, rounded forms, and tactile toy-like detail\nPalette and texture: moss green, brass gold, warm amber, soft twilight blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 young inventor, grandmother, and clockwork garden guardian in a warm discovery tableau; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "beacon-boy-and-the-clockwork-garden",
|
||||
"title": "Beacon Boy and the Clockwork Garden"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/beacon-boy-and-the-clockwork-garden.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Beacon Boy and the Clockwork Garden\" (2026).\nGenre: Animated Family Fantasy.\nStory seed: Small heroes grow tall. A young inventor and his grandmother awaken a garden of mechanical guardians beneath the city park.\nVisual direction: a young inventor and grandmother discovering mechanical garden guardians under a city park, brass leaves and gentle lantern light\nVisual medium and style: storybook 3D animated fantasy, handmade brass mechanisms, moss, warm lantern light, rounded forms, and tactile toy-like detail\nPalette and texture: moss green, brass gold, warm amber, soft twilight blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 hidden underground garden with gears, vines, lanterns, and gentle mechanical guardians; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "beacon-boy-and-the-clockwork-garden",
|
||||
"title": "Beacon Boy and the Clockwork Garden"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/the-invisible-saturday.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The Invisible Saturday\" (2024).\nGenre: Family, Adventure.\nStory seed: Seen or unseen, courage counts. Two siblings learn to turn invisible every Saturday and use the gift to save their neighborhood fair.\nVisual direction: two adventurous siblings at a neighborhood fair where only their footprints, floating ribbons, and playful shadows reveal them\nVisual medium and style: bright claymation-inspired family comedy, miniature fairground sets, visible handmade textures, playful invisible-person gags\nPalette and texture: cotton-candy pink, sunny yellow, grass green, soft sky blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 floating ribbons, footprints, and balloons implying invisible siblings at a fair; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "the-invisible-saturday",
|
||||
"title": "The Invisible Saturday"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/the-invisible-saturday.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The Invisible Saturday\" (2024).\nGenre: Family, Adventure.\nStory seed: Seen or unseen, courage counts. Two siblings learn to turn invisible every Saturday and use the gift to save their neighborhood fair.\nVisual direction: two adventurous siblings at a neighborhood fair where only their footprints, floating ribbons, and playful shadows reveal them\nVisual medium and style: bright claymation-inspired family comedy, miniature fairground sets, visible handmade textures, playful invisible-person gags\nPalette and texture: cotton-candy pink, sunny yellow, grass green, soft sky blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide neighborhood fair scene with playful impossible traces and generous open sky; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "the-invisible-saturday",
|
||||
"title": "The Invisible Saturday"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/captain-kindling.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Captain Kindling\" (2022).\nGenre: Animated Family Comedy.\nStory seed: A spark can lead the way. A camp counselor with ember-bright powers teaches a team of misfits how to protect a forest town.\nVisual direction: a forest camp at dusk with ember-bright protective magic, young misfit campers gathered around a warm heroic spark\nVisual medium and style: warm hand-painted camping comedy illustration, cozy forest dusk, ember glow, imperfect brush texture, gentle humor\nPalette and texture: campfire orange, pine green, twilight purple, warm tan canvas\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 camp counselor spark and misfit camper silhouettes around a glowing clearing; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "captain-kindling",
|
||||
"title": "Captain Kindling"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/captain-kindling.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Captain Kindling\" (2022).\nGenre: Animated Family Comedy.\nStory seed: A spark can lead the way. A camp counselor with ember-bright powers teaches a team of misfits how to protect a forest town.\nVisual direction: a forest camp at dusk with ember-bright protective magic, young misfit campers gathered around a warm heroic spark\nVisual medium and style: warm hand-painted camping comedy illustration, cozy forest dusk, ember glow, imperfect brush texture, gentle humor\nPalette and texture: campfire orange, pine green, twilight purple, warm tan canvas\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide forest camp at dusk with cabin lights, ember trails, and friendly wilderness depth; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "captain-kindling",
|
||||
"title": "Captain Kindling"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/paper-moon-parade.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Paper Moon Parade\" (2026).\nGenre: Flat Kids Fantasy.\nStory seed: Fold the night into wonder. A paper-cut moon rolls through a tiny town and invites every shy child to join a midnight parade.\nVisual direction: a flat paper-cut moon rolling through a tiny town with simple parade shapes and shy children joining in\nVisual medium and style: simple flat paper-cut illustration for children, large clean shapes, visible paper grain, gentle handmade collage, no realistic rendering\nPalette and texture: midnight blue, butter yellow, pale lavender, soft coral, warm paper white\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 big smiling paper moon, tiny town silhouettes, parade shapes, lots of clean negative space; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "paper-moon-parade",
|
||||
"title": "Paper Moon Parade"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/paper-moon-parade.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Paper Moon Parade\" (2026).\nGenre: Flat Kids Fantasy.\nStory seed: Fold the night into wonder. A paper-cut moon rolls through a tiny town and invites every shy child to join a midnight parade.\nVisual direction: a flat paper-cut moon rolling through a tiny town with simple parade shapes and shy children joining in\nVisual medium and style: simple flat paper-cut illustration for children, large clean shapes, visible paper grain, gentle handmade collage, no realistic rendering\nPalette and texture: midnight blue, butter yellow, pale lavender, soft coral, warm paper white\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide paper-cut town street under a rolling moon with simple parade banners and sparse stars; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "paper-moon-parade",
|
||||
"title": "Paper Moon Parade"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/dot-and-the-cloud-train.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Dot and the Cloud Train\" (2025).\nGenre: Preschool Cartoon Adventure.\nStory seed: Every stop is a color. A small dot boards a soft cloud train and learns the colors of weather with a group of round little friends.\nVisual direction: a small dot boarding a soft cloud train that stops at simple weather-color stations\nVisual medium and style: ultra-simple preschool cartoon, rounded vector shapes, soft gradients, thick friendly outlines, very low detail\nPalette and texture: sky blue, marshmallow white, lemon yellow, strawberry pink, mint green\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 small dot character stepping onto a rounded cloud train, clear simple shapes for young kids; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "dot-and-the-cloud-train",
|
||||
"title": "Dot and the Cloud Train"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/dot-and-the-cloud-train.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Dot and the Cloud Train\" (2025).\nGenre: Preschool Cartoon Adventure.\nStory seed: Every stop is a color. A small dot boards a soft cloud train and learns the colors of weather with a group of round little friends.\nVisual direction: a small dot boarding a soft cloud train that stops at simple weather-color stations\nVisual medium and style: ultra-simple preschool cartoon, rounded vector shapes, soft gradients, thick friendly outlines, very low detail\nPalette and texture: sky blue, marshmallow white, lemon yellow, strawberry pink, mint green\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide pastel sky with a cloud train crossing simple weather-color stops; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "dot-and-the-cloud-train",
|
||||
"title": "Dot and the Cloud Train"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/tiny-planet-picnic.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Tiny Planet Picnic\" (2024).\nGenre: Simple Family Sci-Fi Cartoon.\nStory seed: Pack a lunch for the stars. Three children prepare a picnic on a pocket-sized planet where flowers orbit like friendly satellites.\nVisual direction: children preparing a picnic on a pocket-sized planet where flowers orbit like friendly satellites\nVisual medium and style: minimal flat family sci-fi cartoon, clean vector-like shapes, playful scale, sparse details, soft geometric planets\nPalette and texture: peach, teal, lilac, sunny yellow, deep space blue used sparingly\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 three children on a tiny round planet with picnic blanket and orbiting flowers; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "tiny-planet-picnic",
|
||||
"title": "Tiny Planet Picnic"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/tiny-planet-picnic.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Tiny Planet Picnic\" (2024).\nGenre: Simple Family Sci-Fi Cartoon.\nStory seed: Pack a lunch for the stars. Three children prepare a picnic on a pocket-sized planet where flowers orbit like friendly satellites.\nVisual direction: children preparing a picnic on a pocket-sized planet where flowers orbit like friendly satellites\nVisual medium and style: minimal flat family sci-fi cartoon, clean vector-like shapes, playful scale, sparse details, soft geometric planets\nPalette and texture: peach, teal, lilac, sunny yellow, deep space blue used sparingly\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide tiny planet landscape with flowers orbiting like satellites and open simple sky; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "tiny-planet-picnic",
|
||||
"title": "Tiny Planet Picnic"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/masks-of-tomorrow.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Masks of Tomorrow\" (2025).\nGenre: Creative Documentary.\nStory seed: Behind every emblem is a city. A fictional documentary profile of costume makers, signal engineers, and citizens building a city festival from scratch.\nVisual direction: costume makers, signal engineers, and citizens preparing original hero emblems in a workshop filled with fabric, tools, and soft window light\nVisual medium and style: fashion-documentary editorial photography, fabric tables, workshop tools, mirrors, fittings, and soft daylight realism\nPalette and texture: cream fabric, graphite tools, tomato red thread, daylight blue shadows\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 hands, mannequins, and unfinished masks arranged as an editorial magazine cover image; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "masks-of-tomorrow",
|
||||
"title": "Masks of Tomorrow"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/masks-of-tomorrow.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Masks of Tomorrow\" (2025).\nGenre: Creative Documentary.\nStory seed: Behind every emblem is a city. A fictional documentary profile of costume makers, signal engineers, and citizens building a city festival from scratch.\nVisual direction: costume makers, signal engineers, and citizens preparing original hero emblems in a workshop filled with fabric, tools, and soft window light\nVisual medium and style: fashion-documentary editorial photography, fabric tables, workshop tools, mirrors, fittings, and soft daylight realism\nPalette and texture: cream fabric, graphite tools, tomato red thread, daylight blue shadows\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 busy workshop with textiles and signal equipment, human craft details, no logo marks; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "masks-of-tomorrow",
|
||||
"title": "Masks of Tomorrow"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/signal-tower-seven.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Signal Tower Seven\" (2023).\nGenre: Retro Rescue Drama.\nStory seed: Not all heroes fly. A retro-styled chronicle of radio operators who coordinate mountain rescues during a record winter blackout.\nVisual direction: retro radio operators coordinating rescues from a tall signal room, analog dials, maps, and amber emergency light\nVisual medium and style: retro 1970s disaster-drama poster art, analog radio equipment, snowy mountain rescue maps, screen-print texture\nPalette and texture: faded mustard, radio-room brown, emergency red, winter blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 radio operator profile, signal tower, and storm map shapes in vintage rescue-drama layout; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "signal-tower-seven",
|
||||
"title": "Signal Tower Seven"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/signal-tower-seven.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Signal Tower Seven\" (2023).\nGenre: Retro Rescue Drama.\nStory seed: Not all heroes fly. A retro-styled chronicle of radio operators who coordinate mountain rescues during a record winter blackout.\nVisual direction: retro radio operators coordinating rescues from a tall signal room, analog dials, maps, and amber emergency light\nVisual medium and style: retro 1970s disaster-drama poster art, analog radio equipment, snowy mountain rescue maps, screen-print texture\nPalette and texture: faded mustard, radio-room brown, emergency red, winter blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide analog signal room overlooking winter mountains and storm lights; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "signal-tower-seven",
|
||||
"title": "Signal Tower Seven"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/the-league-of-lanterns.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The League of Lanterns\" (2024).\nGenre: Human Interest Documentary.\nStory seed: When the grid fails, people glow. A narrated archive of a volunteer lantern network that lights safe paths during impossible blackouts.\nVisual direction: volunteers carrying lanterns through an impossible blackout, safe glowing paths forming across city streets\nVisual medium and style: human-interest documentary photography with natural faces, handheld lanterns, dark streets, and hopeful realism\nPalette and texture: blackout navy, lantern gold, brick red, soft skin tones\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 volunteers carrying lanterns through darkness, intimate eye-level composition; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "the-league-of-lanterns",
|
||||
"title": "The League of Lanterns"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/the-league-of-lanterns.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The League of Lanterns\" (2024).\nGenre: Human Interest Documentary.\nStory seed: When the grid fails, people glow. A narrated archive of a volunteer lantern network that lights safe paths during impossible blackouts.\nVisual direction: volunteers carrying lanterns through an impossible blackout, safe glowing paths forming across city streets\nVisual medium and style: human-interest documentary photography with natural faces, handheld lanterns, dark streets, and hopeful realism\nPalette and texture: blackout navy, lantern gold, brick red, soft skin tones\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide city block during blackout with lantern paths and community silhouettes; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "the-league-of-lanterns",
|
||||
"title": "The League of Lanterns"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/the-quiet-aquarium.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The Quiet Aquarium\" (2026).\nGenre: Abstract Meditative Drama.\nStory seed: Silence has currents. An abstract night watch follows drifting shapes, quiet visitors, and glowing tanks inside a closed city aquarium.\nVisual direction: abstract glowing aquarium tanks after closing time, drifting shapes, quiet visitors, and calm water-light\nVisual medium and style: abstract meditative poster art, flat translucent shapes, slow gradients, simplified fish silhouettes, calm museum-like composition\nPalette and texture: deep sea blue, glass cyan, muted violet, soft black, small coral accents\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 large abstract aquarium window with drifting shapes and one quiet visitor silhouette; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "the-quiet-aquarium",
|
||||
"title": "The Quiet Aquarium"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/the-quiet-aquarium.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"The Quiet Aquarium\" (2026).\nGenre: Abstract Meditative Drama.\nStory seed: Silence has currents. An abstract night watch follows drifting shapes, quiet visitors, and glowing tanks inside a closed city aquarium.\nVisual direction: abstract glowing aquarium tanks after closing time, drifting shapes, quiet visitors, and calm water-light\nVisual medium and style: abstract meditative poster art, flat translucent shapes, slow gradients, simplified fish silhouettes, calm museum-like composition\nPalette and texture: deep sea blue, glass cyan, muted violet, soft black, small coral accents\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide closed aquarium interior with glowing tanks, drifting abstract fish shapes, and quiet negative space; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "the-quiet-aquarium",
|
||||
"title": "The Quiet Aquarium"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/square-city-sonata.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Square City Sonata\" (2023).\nGenre: Abstract Musical.\nStory seed: Every corner keeps time. Blocks, windows, crosswalks, and streetlights become a geometric city symphony over one bright afternoon.\nVisual direction: geometric blocks, windows, crosswalks, and streetlights arranged as a flat city symphony\nVisual medium and style: Bauhaus-inspired abstract musical city art, flat geometric blocks, no perspective realism, rhythmic rectangles and circles\nPalette and texture: cream, brick red, cobalt blue, mustard yellow, charcoal\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 stacked city blocks, windows, and circles arranged like a musical score; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "square-city-sonata",
|
||||
"title": "Square City Sonata"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/square-city-sonata.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Square City Sonata\" (2023).\nGenre: Abstract Musical.\nStory seed: Every corner keeps time. Blocks, windows, crosswalks, and streetlights become a geometric city symphony over one bright afternoon.\nVisual direction: geometric blocks, windows, crosswalks, and streetlights arranged as a flat city symphony\nVisual medium and style: Bauhaus-inspired abstract musical city art, flat geometric blocks, no perspective realism, rhythmic rectangles and circles\nPalette and texture: cream, brick red, cobalt blue, mustard yellow, charcoal\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide geometric city grid with crosswalk rhythms and streetlight circles across a flat afternoon; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "square-city-sonata",
|
||||
"title": "Square City Sonata"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "poster/lanterns-under-snow.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Lanterns Under Snow\" (2022).\nGenre: Minimalist Folk Tale.\nStory seed: Small lights travel far. A minimalist winter tale about neighbors carrying warm paper lanterns across a silent hill town.\nVisual direction: neighbors carrying warm paper lanterns across a silent snowy hill town\nVisual medium and style: minimal winter folk illustration, flat shapes, quiet negative space, soft paper texture, restrained detail\nPalette and texture: snow white, ink navy, lantern amber, muted pine green, pale gray\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 single warm lantern path climbing a snowy hill town with small simple figures; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "lanterns-under-snow",
|
||||
"title": "Lanterns Under Snow"
|
||||
},
|
||||
{
|
||||
"contentType": "movie",
|
||||
"filename": "backdrop/lanterns-under-snow.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional movie: \"Lanterns Under Snow\" (2022).\nGenre: Minimalist Folk Tale.\nStory seed: Small lights travel far. A minimalist winter tale about neighbors carrying warm paper lanterns across a silent hill town.\nVisual direction: neighbors carrying warm paper lanterns across a silent snowy hill town\nVisual medium and style: minimal winter folk illustration, flat shapes, quiet negative space, soft paper texture, restrained detail\nPalette and texture: snow white, ink navy, lantern amber, muted pine green, pale gray\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide snowy hillside town with sparse houses, paper lantern dots, and a calm empty sky; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "lanterns-under-snow",
|
||||
"title": "Lanterns Under Snow"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/skyline-sentinels.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Skyline Sentinels\" (2025).\nGenre: Urban Ensemble Drama.\nStory seed: The city looks up. A young maintenance crew patrols the rooftops, rails, and river bridges of Meridian City.\nVisual direction: a young rooftop rescue team watching rails, bridges, and river lights from high above Meridian City at sunrise\nVisual medium and style: urban infrastructure drama photography, maintenance crew realism, rooftops, rails, bridge cables, sunrise work shift mood\nPalette and texture: concrete gray, safety yellow, sunrise peach, river blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 young maintenance crew on a roof with tools and city geometry, not heroic costumes; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "skyline-sentinels",
|
||||
"title": "Skyline Sentinels"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/skyline-sentinels.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Skyline Sentinels\" (2025).\nGenre: Urban Ensemble Drama.\nStory seed: The city looks up. A young maintenance crew patrols the rooftops, rails, and river bridges of Meridian City.\nVisual direction: a young rooftop rescue team watching rails, bridges, and river lights from high above Meridian City at sunrise\nVisual medium and style: urban infrastructure drama photography, maintenance crew realism, rooftops, rails, bridge cables, sunrise work shift mood\nPalette and texture: concrete gray, safety yellow, sunrise peach, river blue\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide rooftop and bridge panorama with work lights and morning haze; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "skyline-sentinels",
|
||||
"title": "Skyline Sentinels"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/the-aegis-club.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"The Aegis Club\" (2024).\nGenre: Workplace Dramedy.\nStory seed: Legacy is a living room. Retired public servants reopen an old social club and mentor the next generation between neighborhood emergencies.\nVisual direction: retired heroes in a restored neighborhood social club, worn memorabilia, warm lamps, and a new generation training nearby\nVisual medium and style: warm workplace dramedy photography, neighborhood social club interiors, old wood, mismatched chairs, trophies, candid ensemble energy\nPalette and texture: walnut brown, faded green upholstery, brass lamps, soft cream walls\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 group around an old club table with lived-in props and gentle humor; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "the-aegis-club",
|
||||
"title": "The Aegis Club"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/the-aegis-club.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"The Aegis Club\" (2024).\nGenre: Workplace Dramedy.\nStory seed: Legacy is a living room. Retired public servants reopen an old social club and mentor the next generation between neighborhood emergencies.\nVisual direction: retired heroes in a restored neighborhood social club, worn memorabilia, warm lamps, and a new generation training nearby\nVisual medium and style: warm workplace dramedy photography, neighborhood social club interiors, old wood, mismatched chairs, trophies, candid ensemble energy\nPalette and texture: walnut brown, faded green upholstery, brass lamps, soft cream walls\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide social club room with training area, memorabilia, and warm lamps; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "the-aegis-club",
|
||||
"title": "The Aegis Club"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/starfall-academy.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Starfall Academy\" (2026).\nGenre: Animated Space School.\nStory seed: Homework can save a planet. Cadets with unruly science experiments learn rescue work on a school ship near the asteroid belt.\nVisual direction: cadets with unstable cosmic powers aboard a school ship near the asteroid belt, classroom windows filled with stars\nVisual medium and style: colorful anime-inspired space-school illustration with expressive cadets, school-ship corridors, science experiments, and star windows\nPalette and texture: bubblegum pink, starship white, asteroid gray, neon mint\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 cadets and floating school equipment in dynamic anime school-club composition; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "starfall-academy",
|
||||
"title": "Starfall Academy"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/starfall-academy.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Starfall Academy\" (2026).\nGenre: Animated Space School.\nStory seed: Homework can save a planet. Cadets with unruly science experiments learn rescue work on a school ship near the asteroid belt.\nVisual direction: cadets with unstable cosmic powers aboard a school ship near the asteroid belt, classroom windows filled with stars\nVisual medium and style: colorful anime-inspired space-school illustration with expressive cadets, school-ship corridors, science experiments, and star windows\nPalette and texture: bubblegum pink, starship white, asteroid gray, neon mint\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide school-ship classroom near asteroid belt with desks, windows, and drifting experiment lights; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "starfall-academy",
|
||||
"title": "Starfall Academy"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/tomorrow-bureau.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Tomorrow Bureau\" (2025).\nGenre: Science Fiction, Thriller.\nStory seed: The future files first. Analysts with one-day foresight prevent disasters while trying not to rewrite their own lives.\nVisual direction: future analysts in a glass-walled operations room sorting one-day-ahead disaster files, clocks and reflections layered across the scene\nVisual medium and style: minimalist bureaucratic sci-fi thriller, glass offices, files, clocks, reflection grids, restrained corporate unease\nPalette and texture: frosted glass, desaturated teal, paper white, warning red pinpoints\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 analyst silhouette amid files and clocks, clean tense graphic composition; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "tomorrow-bureau",
|
||||
"title": "Tomorrow Bureau"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/tomorrow-bureau.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Tomorrow Bureau\" (2025).\nGenre: Science Fiction, Thriller.\nStory seed: The future files first. Analysts with one-day foresight prevent disasters while trying not to rewrite their own lives.\nVisual direction: future analysts in a glass-walled operations room sorting one-day-ahead disaster files, clocks and reflections layered across the scene\nVisual medium and style: minimalist bureaucratic sci-fi thriller, glass offices, files, clocks, reflection grids, restrained corporate unease\nPalette and texture: frosted glass, desaturated teal, paper white, warning red pinpoints\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide operations room with glass walls, layered clock reflections, and negative space; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "tomorrow-bureau",
|
||||
"title": "Tomorrow Bureau"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/alley-mask.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Alley Mask\" (2023).\nGenre: Street Noir Mystery.\nStory seed: Every shortcut has a secret. A bike courier investigates strange coded signals appearing in the city alleys.\nVisual direction: a bike courier stepping through deep city shadows while following strange signal glyphs in narrow alleys after rain\nVisual medium and style: neo-noir street photography, bicycle courier realism, coded light marks, wet alleys, handheld camera energy\nPalette and texture: wet asphalt, sodium yellow, deep green shadows, chalk-white signal marks\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 bike courier and alley geometry, face partly obscured by ordinary rain gear, grounded mystery; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "alley-mask",
|
||||
"title": "Alley Mask"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/alley-mask.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Alley Mask\" (2023).\nGenre: Street Noir Mystery.\nStory seed: Every shortcut has a secret. A bike courier investigates strange coded signals appearing in the city alleys.\nVisual direction: a bike courier stepping through deep city shadows while following strange signal glyphs in narrow alleys after rain\nVisual medium and style: neo-noir street photography, bicycle courier realism, coded light marks, wet alleys, handheld camera energy\nPalette and texture: wet asphalt, sodium yellow, deep green shadows, chalk-white signal marks\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide narrow alley after rain with coded signal glyphs and long perspective; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "alley-mask",
|
||||
"title": "Alley Mask"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/neon-sparrow.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Neon Sparrow\" (2024).\nGenre: Cyberpunk Mystery.\nStory seed: Small wings, bright city. A rooftop messenger follows glowing clues that only appear after midnight rain.\nVisual direction: a rooftop messenger following glowing clues that appear in midnight rain, neon reflections and small bright wing motifs\nVisual medium and style: stylized cyberpunk graphic novel art, rooftop rain, neon clue trails, birdlike light motifs, bold ink shapes\nPalette and texture: magenta neon, cyan rain, black ink, pale green glow\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 rooftop messenger and sparrow-like light trail in bold graphic silhouette; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "neon-sparrow",
|
||||
"title": "Neon Sparrow"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/neon-sparrow.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Neon Sparrow\" (2024).\nGenre: Cyberpunk Mystery.\nStory seed: Small wings, bright city. A rooftop messenger follows glowing clues that only appear after midnight rain.\nVisual direction: a rooftop messenger following glowing clues that appear in midnight rain, neon reflections and small bright wing motifs\nVisual medium and style: stylized cyberpunk graphic novel art, rooftop rain, neon clue trails, birdlike light motifs, bold ink shapes\nPalette and texture: magenta neon, cyan rain, black ink, pale green glow\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide rain-soaked rooftop cityscape with glowing clues and open sky; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "neon-sparrow",
|
||||
"title": "Neon Sparrow"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/cape-makers.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Cape Makers\" (2024).\nGenre: Mockumentary, Design.\nStory seed: Every symbol is handmade. A fictional behind-the-scenes series about the tailors, engineers, and artists who design stage gear.\nVisual direction: tailors, engineers, and artists building original stage gear in a busy design studio, fabric tests and hand-built emblems everywhere\nVisual medium and style: behind-the-scenes craft docuseries photography, sewing machines, engineering benches, stage fabric, candid hands-at-work details\nPalette and texture: indigo cloth, warm workshop bulbs, steel tools, chalk marks\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 tailors and engineers at work around stage gear, tactile documentary composition; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "cape-makers",
|
||||
"title": "Cape Makers"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/cape-makers.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Cape Makers\" (2024).\nGenre: Mockumentary, Design.\nStory seed: Every symbol is handmade. A fictional behind-the-scenes series about the tailors, engineers, and artists who design stage gear.\nVisual direction: tailors, engineers, and artists building original stage gear in a busy design studio, fabric tests and hand-built emblems everywhere\nVisual medium and style: behind-the-scenes craft docuseries photography, sewing machines, engineering benches, stage fabric, candid hands-at-work details\nPalette and texture: indigo cloth, warm workshop bulbs, steel tools, chalk marks\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide busy design studio with fabric rolls, benches, sketches without readable text; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "cape-makers",
|
||||
"title": "Cape Makers"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/citizens-of-the-beacon.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Citizens of the Beacon\" (2022).\nGenre: Mockumentary, Human Interest.\nStory seed: A city can be a hero too. Ordinary residents tell the stories behind a citywide rescue network built after the first beacon lit.\nVisual direction: ordinary residents maintaining a citywide rescue network after the first beacon, hopeful faces lit by practical signal lamps\nVisual medium and style: quiet social documentary photography, ordinary residents, practical signal lamps, neighborhood streets, compassionate realism\nPalette and texture: lamp amber, dusk blue, concrete gray, muted household colors\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 ordinary residents around a beacon lamp, intimate human-interest portrait; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "citizens-of-the-beacon",
|
||||
"title": "Citizens of the Beacon"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/citizens-of-the-beacon.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Citizens of the Beacon\" (2022).\nGenre: Mockumentary, Human Interest.\nStory seed: A city can be a hero too. Ordinary residents tell the stories behind a citywide rescue network built after the first beacon lit.\nVisual direction: ordinary residents maintaining a citywide rescue network after the first beacon, hopeful faces lit by practical signal lamps\nVisual medium and style: quiet social documentary photography, ordinary residents, practical signal lamps, neighborhood streets, compassionate realism\nPalette and texture: lamp amber, dusk blue, concrete gray, muted household colors\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide neighborhood rescue network at dusk with lamps in windows and street corners; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "citizens-of-the-beacon",
|
||||
"title": "Citizens of the Beacon"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/bubble-street-workshop.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Bubble Street Workshop\" (2026).\nGenre: Flat Kids Craft Cartoon.\nStory seed: Round ideas roll further. Neighbors build simple inventions from circles, paper, and string in a cheerful street workshop.\nVisual direction: neighbors building simple inventions from circles, paper, string, and bright workshop tables\nVisual medium and style: flat kids craft cartoon, simple circles and paper shapes, playful handmade textures, bright but not busy\nPalette and texture: bubblegum pink, craft paper tan, sky blue, crayon green, sunflower yellow\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 round neighbors building a simple invention from paper, string, and circles; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "bubble-street-workshop",
|
||||
"title": "Bubble Street Workshop"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/bubble-street-workshop.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Bubble Street Workshop\" (2026).\nGenre: Flat Kids Craft Cartoon.\nStory seed: Round ideas roll further. Neighbors build simple inventions from circles, paper, and string in a cheerful street workshop.\nVisual direction: neighbors building simple inventions from circles, paper, string, and bright workshop tables\nVisual medium and style: flat kids craft cartoon, simple circles and paper shapes, playful handmade textures, bright but not busy\nPalette and texture: bubblegum pink, craft paper tan, sky blue, crayon green, sunflower yellow\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide cheerful street workshop with tables, bubbles, paper circles, and open simple storefront shapes; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "bubble-street-workshop",
|
||||
"title": "Bubble Street Workshop"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/flatland-detectives.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Flatland Detectives\" (2025).\nGenre: Geometric Mystery Comedy.\nStory seed: Every clue has a shape. Two geometric detectives solve gentle neighborhood mysteries using maps, shadows, and shape clues.\nVisual direction: two geometric detectives solving gentle neighborhood mysteries using maps, shadows, and shape clues\nVisual medium and style: flat geometric mystery comedy, shape-language characters, simple shadows, crisp poster design, no realism\nPalette and texture: warm gray, detective orange, navy, cream, clue green\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 two geometric detectives inspecting a simple shape clue with playful noir lighting; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "flatland-detectives",
|
||||
"title": "Flatland Detectives"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/flatland-detectives.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Flatland Detectives\" (2025).\nGenre: Geometric Mystery Comedy.\nStory seed: Every clue has a shape. Two geometric detectives solve gentle neighborhood mysteries using maps, shadows, and shape clues.\nVisual direction: two geometric detectives solving gentle neighborhood mysteries using maps, shadows, and shape clues\nVisual medium and style: flat geometric mystery comedy, shape-language characters, simple shadows, crisp poster design, no realism\nPalette and texture: warm gray, detective orange, navy, cream, clue green\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide flat neighborhood map scene with shadows, arrows, and geometric clues; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "flatland-detectives",
|
||||
"title": "Flatland Detectives"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/color-orchard.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Color Orchard\" (2024).\nGenre: Preschool Nature Cartoon.\nStory seed: Pick a color, grow a song. A preschool orchard changes color each morning while tiny caretakers learn seasons, sharing, and sound.\nVisual direction: a preschool orchard changing color each morning while tiny caretakers learn seasons and sound\nVisual medium and style: preschool nature cartoon, very simple flat rounded shapes, soft friendly faces implied by objects, low detail\nPalette and texture: apple red, leaf green, pear yellow, sky blue, soft soil brown\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 tiny caretakers under one large color-changing tree, simple fruit shapes and musical notes without text; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "color-orchard",
|
||||
"title": "Color Orchard"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/color-orchard.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Color Orchard\" (2024).\nGenre: Preschool Nature Cartoon.\nStory seed: Pick a color, grow a song. A preschool orchard changes color each morning while tiny caretakers learn seasons, sharing, and sound.\nVisual direction: a preschool orchard changing color each morning while tiny caretakers learn seasons and sound\nVisual medium and style: preschool nature cartoon, very simple flat rounded shapes, soft friendly faces implied by objects, low detail\nPalette and texture: apple red, leaf green, pear yellow, sky blue, soft soil brown\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide gentle orchard made of rounded flat trees changing colors across the morning; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "color-orchard",
|
||||
"title": "Color Orchard"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "poster/museum-of-little-robots.png",
|
||||
"kind": "poster",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: portrait cover/poster PNG for a fictional streaming demo catalog.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Museum of Little Robots\" (2025).\nGenre: Flat Retro-Future Cartoon.\nStory seed: Tiny gears, big curiosity. Small helpful robots wake up after closing time to arrange exhibits in a quiet retro-future museum.\nVisual direction: small helpful robots arranging exhibits after closing time in a quiet retro-future museum\nVisual medium and style: flat retro-future cartoon, simple rounded robots, clean museum shapes, limited details, soft mid-century geometry\nPalette and texture: dusty teal, warm cream, tomato red, brushed metal gray, muted orange\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: portrait 2:3 small helpful robots arranging one oversized exhibit in a quiet museum hall; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.",
|
||||
"quality": "medium",
|
||||
"size": "1024x1536",
|
||||
"slug": "museum-of-little-robots",
|
||||
"title": "Museum of Little Robots"
|
||||
},
|
||||
{
|
||||
"contentType": "series",
|
||||
"filename": "backdrop/museum-of-little-robots.png",
|
||||
"kind": "backdrop",
|
||||
"manualApprovalStatus": "pending-human-review",
|
||||
"model": "gpt-image-2",
|
||||
"prompt": "Use case: ads-marketing\nAsset type: landscape backdrop PNG for a fictional streaming demo details screen.\nCreate original fictional demo artwork for IPTVnator release screenshots.\nFictional series: \"Museum of Little Robots\" (2025).\nGenre: Flat Retro-Future Cartoon.\nStory seed: Tiny gears, big curiosity. Small helpful robots wake up after closing time to arrange exhibits in a quiet retro-future museum.\nVisual direction: small helpful robots arranging exhibits after closing time in a quiet retro-future museum\nVisual medium and style: flat retro-future cartoon, simple rounded robots, clean museum shapes, limited details, soft mid-century geometry\nPalette and texture: dusty teal, warm cream, tomato red, brushed metal gray, muted orange\nSafety and originality constraints: Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark. No watermarks, no studio logos, no credits, no title typography, and no legible text.\nComposition: wide 16:9 wide retro-future museum after closing with tiny robots, plinths, and simple geometric exhibits; darker edges and open negative space so app UI overlays remain readable; no text or logos.",
|
||||
"quality": "medium",
|
||||
"size": "1536x864",
|
||||
"slug": "museum-of-little-robots",
|
||||
"title": "Museum of Little Robots"
|
||||
}
|
||||
],
|
||||
"model": "gpt-image-2",
|
||||
"outputFormat": "png",
|
||||
"version": 1
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 2.9 MiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 3.8 MiB |
|
After Width: | Height: | Size: 3.3 MiB |
|
After Width: | Height: | Size: 3.8 MiB |
|
After Width: | Height: | Size: 3.9 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 2.9 MiB |
@@ -11,6 +11,11 @@ import {
|
||||
import { generateVodStreams, generateVodDetails, RawVodStream, RawVodDetails } from './generators/vod.generator.js';
|
||||
import { generateSeriesItems, generateSeriesInfo, RawSeriesItem, RawSeriesInfo } from './generators/series.generator.js';
|
||||
import { RawCategory } from './generators/categories.generator.js';
|
||||
import {
|
||||
buildMarketingPortalFixture,
|
||||
buildMarketingSeriesInfo,
|
||||
buildMarketingVodDetails,
|
||||
} from './generators/marketing.generator.js';
|
||||
import { getScenario, ScenarioConfig } from './scenarios.js';
|
||||
|
||||
export interface PortalData {
|
||||
@@ -34,6 +39,27 @@ function generatePortalData(username: string, password: string): PortalData {
|
||||
|
||||
const { categoryCount, itemsPerCategory, seasonsPerSeries, episodesPerSeason } = scenario;
|
||||
|
||||
if (scenario.marketingFixture) {
|
||||
const marketingFixture = buildMarketingPortalFixture();
|
||||
for (const s of marketingFixture.seriesItems) {
|
||||
if (!seriesInfoCache.has(s.series_id)) {
|
||||
seriesInfoCache.set(
|
||||
s.series_id,
|
||||
buildMarketingSeriesInfo(
|
||||
s,
|
||||
seasonsPerSeries,
|
||||
episodesPerSeason
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
scenario,
|
||||
...marketingFixture,
|
||||
};
|
||||
}
|
||||
|
||||
let liveCategories = generateCategories('live', categoryCount.live);
|
||||
const vodCategories = generateCategories('vod', categoryCount.vod);
|
||||
const seriesCategories = generateCategories('series', categoryCount.series);
|
||||
@@ -88,7 +114,12 @@ export function getVodDetails(username: string, password: string, vodId: number)
|
||||
vodDetailsCache.set(vodId, { info: [] });
|
||||
return vodDetailsCache.get(vodId) ?? null;
|
||||
}
|
||||
vodDetailsCache.set(vodId, generateVodDetails(stream));
|
||||
vodDetailsCache.set(
|
||||
vodId,
|
||||
data.scenario.marketingFixture
|
||||
? buildMarketingVodDetails(stream)
|
||||
: generateVodDetails(stream)
|
||||
);
|
||||
}
|
||||
return vodDetailsCache.get(vodId) ?? null;
|
||||
}
|
||||
@@ -99,7 +130,20 @@ export function getSeriesInfo(username: string, password: string, seriesId: numb
|
||||
const series = data.seriesItems.find(s => s.series_id === seriesId);
|
||||
if (!series) return null;
|
||||
const scenario = getScenario(username, password);
|
||||
seriesInfoCache.set(seriesId, generateSeriesInfo(series, scenario.seasonsPerSeries, scenario.episodesPerSeason));
|
||||
seriesInfoCache.set(
|
||||
seriesId,
|
||||
scenario.marketingFixture
|
||||
? buildMarketingSeriesInfo(
|
||||
series,
|
||||
scenario.seasonsPerSeries,
|
||||
scenario.episodesPerSeason
|
||||
)
|
||||
: generateSeriesInfo(
|
||||
series,
|
||||
scenario.seasonsPerSeries,
|
||||
scenario.episodesPerSeason
|
||||
)
|
||||
);
|
||||
}
|
||||
return seriesInfoCache.get(seriesId) ?? null;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ export interface ScenarioConfig {
|
||||
epgFixture?: 'timezone-focus';
|
||||
/** Optional deterministic VOD detail profile for metadata fallback tests. */
|
||||
vodDetailsFixture?: 'empty-metadata';
|
||||
/** Optional fictional release-marketing dataset with local demo artwork. */
|
||||
marketingFixture?: true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,6 +107,19 @@ export const SCENARIOS: Record<string, ScenarioConfig> = {
|
||||
expiryDate: '2099-12-31',
|
||||
vodDetailsFixture: 'empty-metadata',
|
||||
},
|
||||
'marketing:marketing': {
|
||||
name: 'marketing-demo',
|
||||
description:
|
||||
'Fictional catalog for release screenshots — local generated artwork, no real media covers',
|
||||
seed: 8020,
|
||||
categoryCount: { live: 4, vod: 4, series: 4 },
|
||||
itemsPerCategory: 6,
|
||||
seasonsPerSeries: 3,
|
||||
episodesPerSeason: 6,
|
||||
accountStatus: 'Active',
|
||||
expiryDate: '2099-12-31',
|
||||
marketingFixture: true,
|
||||
},
|
||||
'expired:expired': {
|
||||
name: 'expired',
|
||||
description: 'Expired account — tests subscription expiry UI flow',
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import http from 'http';
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { dispatchAction } from './app/routes/dispatch.js';
|
||||
import { resetAll } from './app/data-store.js';
|
||||
import { renderMarketingAssetSvg } from './app/generators/marketing.generator.js';
|
||||
|
||||
const app = express();
|
||||
const PORT = parseInt(process.env['PORT'] ?? '3211', 10);
|
||||
const marketingRasterAssetRoot = join(
|
||||
process.cwd(),
|
||||
'apps/xtream-mock-server/public/marketing'
|
||||
);
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
@@ -21,6 +28,40 @@ app.post('/reset', (_req, res) => {
|
||||
res.json({ status: 'reset' });
|
||||
});
|
||||
|
||||
// ─── Local fictional artwork for release screenshots ──────────────────────────
|
||||
app.get('/assets/marketing/:kind/:slug', (req, res) => {
|
||||
const kind = req.params['kind'] as
|
||||
| 'backdrop'
|
||||
| 'episode'
|
||||
| 'logo'
|
||||
| 'poster'
|
||||
| 'season';
|
||||
const slug = req.params['slug'] ?? '';
|
||||
const size =
|
||||
typeof req.query['size'] === 'string' ? req.query['size'] : undefined;
|
||||
|
||||
if (!['backdrop', 'episode', 'logo', 'poster', 'season'].includes(kind)) {
|
||||
res.status(404).send('Unknown marketing asset kind');
|
||||
return;
|
||||
}
|
||||
|
||||
const rasterSlug = slug.replace(/\.(svg|png)$/i, '');
|
||||
const rasterPath = join(marketingRasterAssetRoot, kind, `${rasterSlug}.png`);
|
||||
|
||||
if (existsSync(rasterPath)) {
|
||||
res
|
||||
.type('image/png')
|
||||
.set('Cache-Control', 'public, max-age=3600')
|
||||
.send(readFileSync(rasterPath));
|
||||
return;
|
||||
}
|
||||
|
||||
res
|
||||
.type('image/svg+xml')
|
||||
.set('Cache-Control', 'public, max-age=3600')
|
||||
.send(renderMarketingAssetSvg(kind, slug, size));
|
||||
});
|
||||
|
||||
// ─── Direct Xtream player_api.php endpoint ─────────────────────────────────────
|
||||
app.get('/player_api.php', dispatchAction);
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ Re-requesting with the same credentials returns the exact same data until
|
||||
```
|
||||
apps/xtream-mock-server/
|
||||
├── project.json ← Nx targets: serve (port 3211), serve-with-watch
|
||||
├── public/
|
||||
│ └── marketing/ ← committed fictional release artwork PNGs
|
||||
├── tsconfig.json
|
||||
└── src/
|
||||
├── main.ts ← Express app bootstrap, all routes wired up
|
||||
@@ -53,6 +55,7 @@ apps/xtream-mock-server/
|
||||
├── generators/
|
||||
│ ├── categories.generator.ts
|
||||
│ ├── live.generator.ts ← Live streams + EPG listings
|
||||
│ ├── marketing.generator.ts ← Fictional release screenshot fixture
|
||||
│ ├── vod.generator.ts ← VOD streams + VodDetails
|
||||
│ └── series.generator.ts ← Series items + SeriesInfo
|
||||
├── handlers/
|
||||
@@ -82,9 +85,11 @@ Response: raw JSON (no envelope). Matches the real Xtream Codes API format.
|
||||
### PWA proxy endpoint
|
||||
|
||||
IPTVnator's PWA routes Xtream calls through:
|
||||
|
||||
```
|
||||
GET /xtream?url=<serverUrl>&action=<action>&username=<u>&password=<p>
|
||||
```
|
||||
|
||||
Response: `{ payload: <data>, action: <action> }`
|
||||
|
||||
This mirrors the backend proxy in `apps/electron-backend` so the same
|
||||
@@ -109,16 +114,22 @@ All redirect to a publicly available HLS test stream
|
||||
|
||||
```json
|
||||
{
|
||||
"user_info": {
|
||||
"username": "user1", "password": "pass1",
|
||||
"status": "active", "exp_date": "4102444799",
|
||||
"is_trial": "0", "active_cons": "1", "max_connections": "2",
|
||||
"allowed_output_formats": ["m3u8", "ts", "rtmp"]
|
||||
},
|
||||
"server_info": {
|
||||
"url": "http://localhost:3211", "port": "3211",
|
||||
"timezone": "UTC", "timestamp_now": 1234567890
|
||||
}
|
||||
"user_info": {
|
||||
"username": "user1",
|
||||
"password": "pass1",
|
||||
"status": "active",
|
||||
"exp_date": "4102444799",
|
||||
"is_trial": "0",
|
||||
"active_cons": "1",
|
||||
"max_connections": "2",
|
||||
"allowed_output_formats": ["m3u8", "ts", "rtmp"]
|
||||
},
|
||||
"server_info": {
|
||||
"url": "http://localhost:3211",
|
||||
"port": "3211",
|
||||
"timezone": "UTC",
|
||||
"timestamp_now": 1234567890
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -135,11 +146,15 @@ All redirect to a publicly available HLS test stream
|
||||
|
||||
```json
|
||||
{
|
||||
"num": 1, "name": "Acme Corp TV",
|
||||
"stream_type": "live", "stream_id": 10000,
|
||||
"stream_icon": "https://picsum.photos/seed/live-10000/100/100",
|
||||
"epg_channel_id": "channel-10000.mock",
|
||||
"category_id": "101", "tv_archive": 0, "tv_archive_duration": 0
|
||||
"num": 1,
|
||||
"name": "Acme Corp TV",
|
||||
"stream_type": "live",
|
||||
"stream_id": 10000,
|
||||
"stream_icon": "https://picsum.photos/seed/live-10000/100/100",
|
||||
"epg_channel_id": "channel-10000.mock",
|
||||
"category_id": "101",
|
||||
"tv_archive": 0,
|
||||
"tv_archive_duration": 0
|
||||
}
|
||||
```
|
||||
|
||||
@@ -147,15 +162,18 @@ All redirect to a publicly available HLS test stream
|
||||
|
||||
```json
|
||||
{
|
||||
"epg_listings": [
|
||||
{
|
||||
"id": "1000000", "epg_id": "channel-10000.mock",
|
||||
"title": "base64encodedTitle",
|
||||
"description": "base64encodedDescription",
|
||||
"start": "2024-01-01 12:00:00", "end": "2024-01-01 12:30:00",
|
||||
"start_timestamp": "1704110400", "stop_timestamp": "1704112200"
|
||||
}
|
||||
]
|
||||
"epg_listings": [
|
||||
{
|
||||
"id": "1000000",
|
||||
"epg_id": "channel-10000.mock",
|
||||
"title": "base64encodedTitle",
|
||||
"description": "base64encodedDescription",
|
||||
"start": "2024-01-01 12:00:00",
|
||||
"end": "2024-01-01 12:30:00",
|
||||
"start_timestamp": "1704110400",
|
||||
"stop_timestamp": "1704112200"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -167,19 +185,19 @@ Both actions return the same full per-channel schedule shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"epg_listings": [
|
||||
{
|
||||
"id": "10000-current",
|
||||
"epg_id": "channel-10000.mock",
|
||||
"title": "base64encodedTitle",
|
||||
"description": "base64encodedDescription",
|
||||
"start": "2026-04-05 04:30:00",
|
||||
"end": "2026-04-05 05:00:00",
|
||||
"start_timestamp": "1775363400",
|
||||
"stop_timestamp": "1775365200",
|
||||
"channel_id": "channel-10000.mock"
|
||||
}
|
||||
]
|
||||
"epg_listings": [
|
||||
{
|
||||
"id": "10000-current",
|
||||
"epg_id": "channel-10000.mock",
|
||||
"title": "base64encodedTitle",
|
||||
"description": "base64encodedDescription",
|
||||
"start": "2026-04-05 04:30:00",
|
||||
"end": "2026-04-05 05:00:00",
|
||||
"start_timestamp": "1775363400",
|
||||
"stop_timestamp": "1775365200",
|
||||
"channel_id": "channel-10000.mock"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -214,16 +232,19 @@ sometimes only respond to that misspelled action.
|
||||
|
||||
## Scenarios
|
||||
|
||||
| Key (`username:password`) | Seed | Categories | Items/cat | Account status |
|
||||
|---------------------------|------|------------|-----------|----------------|
|
||||
| `user1:pass1` | 1001 | 8 each | 40 | active |
|
||||
| `large:large` | 9999 | 20 each | 200 | active |
|
||||
| `series:series` | 2002 | live:3, vod:4, series:15 | 30 | active |
|
||||
| `minimal:minimal` | 3003 | 2 each | 5 | active |
|
||||
| `epg:epg` | 6006 | live:2, vod:1, series:1 | 3 | active |
|
||||
| `expired:expired` | 4004 | 4 each | 10 | Expired |
|
||||
| `inactive:inactive` | 5005 | 4 each | 10 | Disabled |
|
||||
| `<any other>` | hash | 6 each | 30 | active |
|
||||
| Key (`username:password`) | Seed | Categories | Items/cat | Account status |
|
||||
| ------------------------- | ---- | ------------------------ | --------- | -------------- |
|
||||
| `user1:pass1` | 1001 | 8 each | 40 | active |
|
||||
| `large:large` | 9999 | 20 each | 200 | active |
|
||||
| `stress:stress` | 7777 | 16 each | 120 | active |
|
||||
| `series:series` | 2002 | live:3, vod:4, series:15 | 30 | active |
|
||||
| `minimal:minimal` | 3003 | 2 each | 5 | active |
|
||||
| `epg:epg` | 6006 | live:2, vod:1, series:1 | 3 | active |
|
||||
| `emptyvod:emptyvod` | 7007 | 2 each | 5 | active |
|
||||
| `marketing:marketing` | 8020 | live:4, vod:4, series:4 | curated | active |
|
||||
| `expired:expired` | 4004 | 4 each | 10 | Expired |
|
||||
| `inactive:inactive` | 5005 | 4 each | 10 | Disabled |
|
||||
| `<any other>` | hash | 6 each | 30 | active |
|
||||
|
||||
### `epg:epg` fixture details
|
||||
|
||||
@@ -238,6 +259,26 @@ That deliberate mismatch lets Electron tests verify the renderer uses timestamp
|
||||
fields for sorting, current-program selection, progress bars, and local clock
|
||||
labels instead of trusting provider-local strings.
|
||||
|
||||
### `marketing:marketing` fixture details
|
||||
|
||||
This scenario is reserved for release screenshots and marketing materials:
|
||||
|
||||
- VOD and series data use 30 curated fictional titles instead of faker-generated
|
||||
titles or real media metadata
|
||||
- posters and backdrops are served from committed PNG files in
|
||||
`apps/xtream-mock-server/public/marketing/{poster,backdrop}/`
|
||||
- `tools/release/generate-marketing-artwork.ts` generates the PNGs with
|
||||
`gpt-image-2` only when `OPENAI_API_KEY` is present; it also writes the
|
||||
prompt/asset manifest at `apps/xtream-mock-server/public/marketing/manifest.json`
|
||||
- the manifest assigns distinct genre and visual-medium profiles per title,
|
||||
including documentary, noir, animated family, retro rescue drama, cyberpunk,
|
||||
anime-inspired space school, and workplace dramedy styles
|
||||
- screenshot capture remains deterministic and offline because
|
||||
`tools/release/capture-v020-screenshots.ts` consumes the local mock server
|
||||
assets and never calls OpenAI
|
||||
- the SVG renderer in `marketing.generator.ts` remains the fallback for missing
|
||||
assets, live logos, season covers, and episode thumbnails
|
||||
|
||||
---
|
||||
|
||||
## Playwright Integration
|
||||
@@ -275,5 +316,8 @@ await page.route('**/localhost:3000/xtream**', async (route) => {
|
||||
- **Add new actions**: Implement a handler function and add a `case` in `routes/dispatch.ts`
|
||||
- **Add new scenarios**: Add an entry to `SCENARIOS` in `scenarios.ts`
|
||||
- **Add deterministic EPG fixtures**: Extend `ScenarioConfig.epgFixture` and populate `epgListingsByStreamId` in `data-store.ts`
|
||||
- **Refresh release artwork**: Run `pnpm release:artwork:dry-run`, then
|
||||
`OPENAI_API_KEY=... pnpm release:artwork:generate`, inspect the generated PNGs,
|
||||
and finish with `pnpm release:artwork:validate`
|
||||
- **Adjust data volume**: Change `itemsPerCategory`, `seasonsPerSeries`, or `episodesPerSeason` per scenario
|
||||
- **Custom stream URLs**: Edit the HLS stub redirect in `main.ts`
|
||||
@@ -0,0 +1,759 @@
|
||||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
import sharp from 'sharp';
|
||||
import {
|
||||
listMarketingArtworkFixtures,
|
||||
type MarketingArtworkFixture,
|
||||
} from '../../apps/xtream-mock-server/src/app/generators/marketing.generator.js';
|
||||
|
||||
type ArtworkKind = 'backdrop' | 'poster';
|
||||
type ArtworkQuality = 'low' | 'medium' | 'high' | 'auto';
|
||||
type RunMode = 'dry-run' | 'generate' | 'manifest' | 'validate';
|
||||
|
||||
type ArtworkJob = {
|
||||
contentType: 'movie' | 'series';
|
||||
filename: string;
|
||||
kind: ArtworkKind;
|
||||
outputPath: string;
|
||||
prompt: string;
|
||||
quality: ArtworkQuality;
|
||||
size: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
type ArtworkManifest = {
|
||||
assetRoot: string;
|
||||
assets: Array<{
|
||||
contentType: 'movie' | 'series';
|
||||
filename: string;
|
||||
kind: ArtworkKind;
|
||||
manualApprovalStatus: 'pending-human-review';
|
||||
model: string;
|
||||
prompt: string;
|
||||
quality: ArtworkQuality;
|
||||
size: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
}>;
|
||||
model: string;
|
||||
outputFormat: 'png';
|
||||
version: 1;
|
||||
};
|
||||
|
||||
const workspaceRoot = process.cwd();
|
||||
const assetRoot = path.join(
|
||||
workspaceRoot,
|
||||
'apps/xtream-mock-server/public/marketing'
|
||||
);
|
||||
const manifestPath = path.join(assetRoot, 'manifest.json');
|
||||
const relativeAssetRoot = 'apps/xtream-mock-server/public/marketing';
|
||||
const defaultModel = 'gpt-image-2';
|
||||
const outputFormat = 'png';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const mode = getMode(args);
|
||||
const model = getStringArg('--model') ?? process.env['OPENAI_IMAGE_MODEL'] ?? defaultModel;
|
||||
const quality = getQualityArg('--quality') ?? getQuality(process.env['OPENAI_IMAGE_QUALITY']) ?? 'medium';
|
||||
const force = args.includes('--force');
|
||||
const limit = getNumberArg('--limit');
|
||||
const delayMs = getNumberArg('--delay-ms') ?? 0;
|
||||
|
||||
const allJobs = buildArtworkJobs(model, quality);
|
||||
const jobs = allJobs.slice(0, limit ?? undefined);
|
||||
|
||||
async function main(): Promise<void> {
|
||||
if (mode === 'dry-run') {
|
||||
printDryRun();
|
||||
return;
|
||||
}
|
||||
|
||||
ensureOutputDirs();
|
||||
writeManifest(model, allJobs);
|
||||
|
||||
if (mode === 'manifest') {
|
||||
console.log(`Wrote artwork manifest: ${relativePath(manifestPath)}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === 'generate') {
|
||||
await generateMissingArtwork();
|
||||
}
|
||||
|
||||
await validateArtwork(jobs);
|
||||
}
|
||||
|
||||
function buildArtworkJobs(
|
||||
selectedModel: string,
|
||||
selectedQuality: ArtworkQuality
|
||||
): ArtworkJob[] {
|
||||
return listMarketingArtworkFixtures().flatMap((fixture) =>
|
||||
(['poster', 'backdrop'] as const).map((kind) => {
|
||||
const filename = `${kind}/${fixture.slug}.png`;
|
||||
return {
|
||||
contentType: fixture.contentType,
|
||||
filename,
|
||||
kind,
|
||||
outputPath: path.join(assetRoot, filename),
|
||||
prompt: buildPrompt(fixture, kind),
|
||||
quality: selectedQuality,
|
||||
size: kind === 'poster' ? '1024x1536' : '1536x864',
|
||||
slug: fixture.slug,
|
||||
title: fixture.name,
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function buildPrompt(fixture: MarketingArtworkFixture, kind: ArtworkKind): string {
|
||||
const profile = promptProfileForTitle(fixture.name);
|
||||
const direction = visualDirectionForTitle(fixture.name);
|
||||
const shared = [
|
||||
`Create original fictional demo artwork for IPTVnator release screenshots.`,
|
||||
`Fictional ${fixture.contentType}: "${fixture.name}" (${fixture.year}).`,
|
||||
`Genre: ${fixture.genre}.`,
|
||||
`Story seed: ${fixture.tagline} ${fixture.description}`,
|
||||
`Visual direction: ${direction}`,
|
||||
`Visual medium and style: ${profile.style}`,
|
||||
`Palette and texture: ${profile.palette}`,
|
||||
[
|
||||
'Safety and originality constraints:',
|
||||
'Do not depict or reference any real movie, series, franchise, celebrity, actor likeness, branded character, copyrighted logo, trademarked costume, existing poster composition, or readable brand mark.',
|
||||
'No watermarks, no studio logos, no credits, no title typography, and no legible text.',
|
||||
].join(' '),
|
||||
];
|
||||
|
||||
if (kind === 'poster') {
|
||||
return [
|
||||
'Use case: ads-marketing',
|
||||
'Asset type: portrait cover/poster PNG for a fictional streaming demo catalog.',
|
||||
...shared,
|
||||
`Composition: portrait 2:3 ${profile.posterComposition}; high contrast at thumbnail size; title-safe image with no necessary text because the app UI renders metadata separately.`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
return [
|
||||
'Use case: ads-marketing',
|
||||
'Asset type: landscape backdrop PNG for a fictional streaming demo details screen.',
|
||||
...shared,
|
||||
`Composition: wide 16:9 ${profile.backdropComposition}; darker edges and open negative space so app UI overlays remain readable; no text or logos.`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
type PromptProfile = {
|
||||
backdropComposition: string;
|
||||
palette: string;
|
||||
posterComposition: string;
|
||||
style: string;
|
||||
};
|
||||
|
||||
function promptProfileForTitle(title: string): PromptProfile {
|
||||
const profiles: Record<string, PromptProfile> = {
|
||||
'Crimson Skylark': {
|
||||
style: 'golden-hour aerial adventure photography with realistic rescue-drama production design, wind, clouds, practical flight gear, and natural lens flare',
|
||||
palette:
|
||||
'sunrise coral, storm gray, aviation green, grainy but realistic atmospheric haze',
|
||||
posterComposition:
|
||||
'single rescue courier against a huge storm sky, diagonal flight path, naturalistic poster photography',
|
||||
backdropComposition:
|
||||
'vast sky route above a modern city, layered storm clouds, small courier silhouette, breathable horizon',
|
||||
},
|
||||
'The Voltage Guard': {
|
||||
style: 'gritty disaster-thriller photography, rain-soaked infrastructure, documentary realism, sparks, emergency work lights, no fantasy costumes',
|
||||
palette:
|
||||
'steel blue, sodium orange, wet asphalt black, white electrical flares',
|
||||
posterComposition:
|
||||
'workers and rail geometry forming a tense action triangle, practical uniforms and tools',
|
||||
backdropComposition:
|
||||
'wide elevated transit grid under unstable weather, workers small in frame, strong industrial depth',
|
||||
},
|
||||
'Midnight Mantle': {
|
||||
style: 'gothic noir illustration with theatrical shadow shapes, old print texture, rain, velvet blacks, and painterly mystery atmosphere',
|
||||
palette:
|
||||
'deep violet, amber marquee light, wet black streets, muted crimson accents',
|
||||
posterComposition:
|
||||
'theatre silhouette and sweeping cloak as an abstract mystery shape, not a superhero pose',
|
||||
backdropComposition:
|
||||
'empty theatre district at night, marquee glow without readable letters, cloak-like shadow crossing rooftops',
|
||||
},
|
||||
'Quantum Comet': {
|
||||
style: 'hard science-fiction concept art with crisp spacecraft detail, star charts, comet ice, scale diagrams, and luminous navigation UI shapes without readable text',
|
||||
palette:
|
||||
'icy cyan, white comet dust, deep navy, precise magenta navigation glows',
|
||||
posterComposition:
|
||||
'cartographer figure and fractured comet arc arranged like a scientific expedition poster',
|
||||
backdropComposition:
|
||||
'wide comet trail and distant armada silhouettes, clean negative space around the center',
|
||||
},
|
||||
'Orbit of Atlas': {
|
||||
style: 'epic cosmic survival painting with mineral surfaces, colony lights, gravitational dust ribbons, and solemn scale',
|
||||
palette:
|
||||
'burnt gold, moon gray, dusty umber, cold blue space shadows',
|
||||
posterComposition:
|
||||
'small rescue pilot dwarfed by a cracked moon, monumental survival mood',
|
||||
backdropComposition:
|
||||
'fractured moon over a remote colony, dust and sunlight bending in wide arcs',
|
||||
},
|
||||
'Nova Relay': {
|
||||
style: 'sleek space-opera animation art with clean silhouettes, radiant motion trails, glossy star-bridge architecture, and optimistic color',
|
||||
palette:
|
||||
'electric teal, royal blue, white light trails, warm planetary glow',
|
||||
posterComposition:
|
||||
'twin runners crossing a luminous bridge with strong graphic diagonals',
|
||||
backdropComposition:
|
||||
'star bridge leading toward a blue planet, two tiny figures and sweeping light messages',
|
||||
},
|
||||
'Beacon Boy and the Clockwork Garden': {
|
||||
style: 'storybook 3D animated fantasy, handmade brass mechanisms, moss, warm lantern light, rounded forms, and tactile toy-like detail',
|
||||
palette:
|
||||
'moss green, brass gold, warm amber, soft twilight blue',
|
||||
posterComposition:
|
||||
'young inventor, grandmother, and clockwork garden guardian in a warm discovery tableau',
|
||||
backdropComposition:
|
||||
'hidden underground garden with gears, vines, lanterns, and gentle mechanical guardians',
|
||||
},
|
||||
'The Invisible Saturday': {
|
||||
style: 'bright claymation-inspired family comedy, miniature fairground sets, visible handmade textures, playful invisible-person gags',
|
||||
palette:
|
||||
'cotton-candy pink, sunny yellow, grass green, soft sky blue',
|
||||
posterComposition:
|
||||
'floating ribbons, footprints, and balloons implying invisible siblings at a fair',
|
||||
backdropComposition:
|
||||
'wide neighborhood fair scene with playful impossible traces and generous open sky',
|
||||
},
|
||||
'Captain Kindling': {
|
||||
style: 'warm hand-painted camping comedy illustration, cozy forest dusk, ember glow, imperfect brush texture, gentle humor',
|
||||
palette:
|
||||
'campfire orange, pine green, twilight purple, warm tan canvas',
|
||||
posterComposition:
|
||||
'camp counselor spark and misfit camper silhouettes around a glowing clearing',
|
||||
backdropComposition:
|
||||
'wide forest camp at dusk with cabin lights, ember trails, and friendly wilderness depth',
|
||||
},
|
||||
'Masks of Tomorrow': {
|
||||
style: 'fashion-documentary editorial photography, fabric tables, workshop tools, mirrors, fittings, and soft daylight realism',
|
||||
palette:
|
||||
'cream fabric, graphite tools, tomato red thread, daylight blue shadows',
|
||||
posterComposition:
|
||||
'hands, mannequins, and unfinished masks arranged as an editorial magazine cover image',
|
||||
backdropComposition:
|
||||
'busy workshop with textiles and signal equipment, human craft details, no logo marks',
|
||||
},
|
||||
'Signal Tower Seven': {
|
||||
style: 'retro 1970s disaster-drama poster art, analog radio equipment, snowy mountain rescue maps, screen-print texture',
|
||||
palette:
|
||||
'faded mustard, radio-room brown, emergency red, winter blue',
|
||||
posterComposition:
|
||||
'radio operator profile, signal tower, and storm map shapes in vintage rescue-drama layout',
|
||||
backdropComposition:
|
||||
'wide analog signal room overlooking winter mountains and storm lights',
|
||||
},
|
||||
'The League of Lanterns': {
|
||||
style: 'human-interest documentary photography with natural faces, handheld lanterns, dark streets, and hopeful realism',
|
||||
palette:
|
||||
'blackout navy, lantern gold, brick red, soft skin tones',
|
||||
posterComposition:
|
||||
'volunteers carrying lanterns through darkness, intimate eye-level composition',
|
||||
backdropComposition:
|
||||
'wide city block during blackout with lantern paths and community silhouettes',
|
||||
},
|
||||
'Paper Moon Parade': {
|
||||
style: 'simple flat paper-cut illustration for children, large clean shapes, visible paper grain, gentle handmade collage, no realistic rendering',
|
||||
palette:
|
||||
'midnight blue, butter yellow, pale lavender, soft coral, warm paper white',
|
||||
posterComposition:
|
||||
'big smiling paper moon, tiny town silhouettes, parade shapes, lots of clean negative space',
|
||||
backdropComposition:
|
||||
'wide paper-cut town street under a rolling moon with simple parade banners and sparse stars',
|
||||
},
|
||||
'Dot and the Cloud Train': {
|
||||
style: 'ultra-simple preschool cartoon, rounded vector shapes, soft gradients, thick friendly outlines, very low detail',
|
||||
palette:
|
||||
'sky blue, marshmallow white, lemon yellow, strawberry pink, mint green',
|
||||
posterComposition:
|
||||
'small dot character stepping onto a rounded cloud train, clear simple shapes for young kids',
|
||||
backdropComposition:
|
||||
'wide pastel sky with a cloud train crossing simple weather-color stops',
|
||||
},
|
||||
'Tiny Planet Picnic': {
|
||||
style: 'minimal flat family sci-fi cartoon, clean vector-like shapes, playful scale, sparse details, soft geometric planets',
|
||||
palette:
|
||||
'peach, teal, lilac, sunny yellow, deep space blue used sparingly',
|
||||
posterComposition:
|
||||
'three children on a tiny round planet with picnic blanket and orbiting flowers',
|
||||
backdropComposition:
|
||||
'wide tiny planet landscape with flowers orbiting like satellites and open simple sky',
|
||||
},
|
||||
'The Quiet Aquarium': {
|
||||
style: 'abstract meditative poster art, flat translucent shapes, slow gradients, simplified fish silhouettes, calm museum-like composition',
|
||||
palette:
|
||||
'deep sea blue, glass cyan, muted violet, soft black, small coral accents',
|
||||
posterComposition:
|
||||
'large abstract aquarium window with drifting shapes and one quiet visitor silhouette',
|
||||
backdropComposition:
|
||||
'wide closed aquarium interior with glowing tanks, drifting abstract fish shapes, and quiet negative space',
|
||||
},
|
||||
'Square City Sonata': {
|
||||
style: 'Bauhaus-inspired abstract musical city art, flat geometric blocks, no perspective realism, rhythmic rectangles and circles',
|
||||
palette:
|
||||
'cream, brick red, cobalt blue, mustard yellow, charcoal',
|
||||
posterComposition:
|
||||
'stacked city blocks, windows, and circles arranged like a musical score',
|
||||
backdropComposition:
|
||||
'wide geometric city grid with crosswalk rhythms and streetlight circles across a flat afternoon',
|
||||
},
|
||||
'Lanterns Under Snow': {
|
||||
style: 'minimal winter folk illustration, flat shapes, quiet negative space, soft paper texture, restrained detail',
|
||||
palette:
|
||||
'snow white, ink navy, lantern amber, muted pine green, pale gray',
|
||||
posterComposition:
|
||||
'single warm lantern path climbing a snowy hill town with small simple figures',
|
||||
backdropComposition:
|
||||
'wide snowy hillside town with sparse houses, paper lantern dots, and a calm empty sky',
|
||||
},
|
||||
'Skyline Sentinels': {
|
||||
style: 'urban infrastructure drama photography, maintenance crew realism, rooftops, rails, bridge cables, sunrise work shift mood',
|
||||
palette:
|
||||
'concrete gray, safety yellow, sunrise peach, river blue',
|
||||
posterComposition:
|
||||
'young maintenance crew on a roof with tools and city geometry, not heroic costumes',
|
||||
backdropComposition:
|
||||
'wide rooftop and bridge panorama with work lights and morning haze',
|
||||
},
|
||||
'The Aegis Club': {
|
||||
style: 'warm workplace dramedy photography, neighborhood social club interiors, old wood, mismatched chairs, trophies, candid ensemble energy',
|
||||
palette:
|
||||
'walnut brown, faded green upholstery, brass lamps, soft cream walls',
|
||||
posterComposition:
|
||||
'group around an old club table with lived-in props and gentle humor',
|
||||
backdropComposition:
|
||||
'wide social club room with training area, memorabilia, and warm lamps',
|
||||
},
|
||||
'Starfall Academy': {
|
||||
style: 'colorful anime-inspired space-school illustration with expressive cadets, school-ship corridors, science experiments, and star windows',
|
||||
palette:
|
||||
'bubblegum pink, starship white, asteroid gray, neon mint',
|
||||
posterComposition:
|
||||
'cadets and floating school equipment in dynamic anime school-club composition',
|
||||
backdropComposition:
|
||||
'wide school-ship classroom near asteroid belt with desks, windows, and drifting experiment lights',
|
||||
},
|
||||
'Tomorrow Bureau': {
|
||||
style: 'minimalist bureaucratic sci-fi thriller, glass offices, files, clocks, reflection grids, restrained corporate unease',
|
||||
palette:
|
||||
'frosted glass, desaturated teal, paper white, warning red pinpoints',
|
||||
posterComposition:
|
||||
'analyst silhouette amid files and clocks, clean tense graphic composition',
|
||||
backdropComposition:
|
||||
'wide operations room with glass walls, layered clock reflections, and negative space',
|
||||
},
|
||||
'Alley Mask': {
|
||||
style: 'neo-noir street photography, bicycle courier realism, coded light marks, wet alleys, handheld camera energy',
|
||||
palette:
|
||||
'wet asphalt, sodium yellow, deep green shadows, chalk-white signal marks',
|
||||
posterComposition:
|
||||
'bike courier and alley geometry, face partly obscured by ordinary rain gear, grounded mystery',
|
||||
backdropComposition:
|
||||
'wide narrow alley after rain with coded signal glyphs and long perspective',
|
||||
},
|
||||
'Neon Sparrow': {
|
||||
style: 'stylized cyberpunk graphic novel art, rooftop rain, neon clue trails, birdlike light motifs, bold ink shapes',
|
||||
palette:
|
||||
'magenta neon, cyan rain, black ink, pale green glow',
|
||||
posterComposition:
|
||||
'rooftop messenger and sparrow-like light trail in bold graphic silhouette',
|
||||
backdropComposition:
|
||||
'wide rain-soaked rooftop cityscape with glowing clues and open sky',
|
||||
},
|
||||
'Cape Makers': {
|
||||
style: 'behind-the-scenes craft docuseries photography, sewing machines, engineering benches, stage fabric, candid hands-at-work details',
|
||||
palette:
|
||||
'indigo cloth, warm workshop bulbs, steel tools, chalk marks',
|
||||
posterComposition:
|
||||
'tailors and engineers at work around stage gear, tactile documentary composition',
|
||||
backdropComposition:
|
||||
'wide busy design studio with fabric rolls, benches, sketches without readable text',
|
||||
},
|
||||
'Citizens of the Beacon': {
|
||||
style: 'quiet social documentary photography, ordinary residents, practical signal lamps, neighborhood streets, compassionate realism',
|
||||
palette:
|
||||
'lamp amber, dusk blue, concrete gray, muted household colors',
|
||||
posterComposition:
|
||||
'ordinary residents around a beacon lamp, intimate human-interest portrait',
|
||||
backdropComposition:
|
||||
'wide neighborhood rescue network at dusk with lamps in windows and street corners',
|
||||
},
|
||||
'Bubble Street Workshop': {
|
||||
style: 'flat kids craft cartoon, simple circles and paper shapes, playful handmade textures, bright but not busy',
|
||||
palette:
|
||||
'bubblegum pink, craft paper tan, sky blue, crayon green, sunflower yellow',
|
||||
posterComposition:
|
||||
'round neighbors building a simple invention from paper, string, and circles',
|
||||
backdropComposition:
|
||||
'wide cheerful street workshop with tables, bubbles, paper circles, and open simple storefront shapes',
|
||||
},
|
||||
'Flatland Detectives': {
|
||||
style: 'flat geometric mystery comedy, shape-language characters, simple shadows, crisp poster design, no realism',
|
||||
palette:
|
||||
'warm gray, detective orange, navy, cream, clue green',
|
||||
posterComposition:
|
||||
'two geometric detectives inspecting a simple shape clue with playful noir lighting',
|
||||
backdropComposition:
|
||||
'wide flat neighborhood map scene with shadows, arrows, and geometric clues',
|
||||
},
|
||||
'Color Orchard': {
|
||||
style: 'preschool nature cartoon, very simple flat rounded shapes, soft friendly faces implied by objects, low detail',
|
||||
palette:
|
||||
'apple red, leaf green, pear yellow, sky blue, soft soil brown',
|
||||
posterComposition:
|
||||
'tiny caretakers under one large color-changing tree, simple fruit shapes and musical notes without text',
|
||||
backdropComposition:
|
||||
'wide gentle orchard made of rounded flat trees changing colors across the morning',
|
||||
},
|
||||
'Museum of Little Robots': {
|
||||
style: 'flat retro-future cartoon, simple rounded robots, clean museum shapes, limited details, soft mid-century geometry',
|
||||
palette:
|
||||
'dusty teal, warm cream, tomato red, brushed metal gray, muted orange',
|
||||
posterComposition:
|
||||
'small helpful robots arranging one oversized exhibit in a quiet museum hall',
|
||||
backdropComposition:
|
||||
'wide retro-future museum after closing with tiny robots, plinths, and simple geometric exhibits',
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
profiles[title] ?? {
|
||||
backdropComposition:
|
||||
'immersive genre scene with clean depth and readable negative space',
|
||||
palette: 'balanced multi-color palette with tactile texture',
|
||||
posterComposition:
|
||||
'distinctive key image built around an original fictional subject',
|
||||
style: 'original genre artwork with a clearly differentiated visual language',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function visualDirectionForTitle(title: string): string {
|
||||
const directions: Record<string, string> = {
|
||||
'Crimson Skylark':
|
||||
'an aerial rescue courier navigating storm routes above Meridian City, a solar signal crest glowing in the cloudbreak',
|
||||
'The Voltage Guard':
|
||||
'transit workers protecting an elevated rail grid from a living thunderstorm, blue-white electricity reflected in wet streets',
|
||||
'Midnight Mantle':
|
||||
'an old theatre district at night, a mysterious cloak rumor visualized through shadows, marquee light, and rain-soaked cobblestones',
|
||||
'Quantum Comet':
|
||||
'an orbital cartographer crossing fractured comet trails beside a time-bent armada, star maps glowing in cold blue light',
|
||||
'Orbit of Atlas':
|
||||
'a rescue pilot navigating a cracked moon orbit over a fragile colony, gravity ribbons bending dust and sunlight',
|
||||
'Nova Relay':
|
||||
'twin signal runners racing across a luminous star bridge, urgent light messages streaking toward a blue planet',
|
||||
'Beacon Boy and the Clockwork Garden':
|
||||
'a young inventor and grandmother discovering mechanical garden guardians under a city park, brass leaves and gentle lantern light',
|
||||
'The Invisible Saturday':
|
||||
'two adventurous siblings at a neighborhood fair where only their footprints, floating ribbons, and playful shadows reveal them',
|
||||
'Captain Kindling':
|
||||
'a forest camp at dusk with ember-bright protective magic, young misfit campers gathered around a warm heroic spark',
|
||||
'Masks of Tomorrow':
|
||||
'costume makers, signal engineers, and citizens preparing original hero emblems in a workshop filled with fabric, tools, and soft window light',
|
||||
'Signal Tower Seven':
|
||||
'retro radio operators coordinating rescues from a tall signal room, analog dials, maps, and amber emergency light',
|
||||
'The League of Lanterns':
|
||||
'volunteers carrying lanterns through an impossible blackout, safe glowing paths forming across city streets',
|
||||
'Paper Moon Parade':
|
||||
'a flat paper-cut moon rolling through a tiny town with simple parade shapes and shy children joining in',
|
||||
'Dot and the Cloud Train':
|
||||
'a small dot boarding a soft cloud train that stops at simple weather-color stations',
|
||||
'Tiny Planet Picnic':
|
||||
'children preparing a picnic on a pocket-sized planet where flowers orbit like friendly satellites',
|
||||
'The Quiet Aquarium':
|
||||
'abstract glowing aquarium tanks after closing time, drifting shapes, quiet visitors, and calm water-light',
|
||||
'Square City Sonata':
|
||||
'geometric blocks, windows, crosswalks, and streetlights arranged as a flat city symphony',
|
||||
'Lanterns Under Snow':
|
||||
'neighbors carrying warm paper lanterns across a silent snowy hill town',
|
||||
'Skyline Sentinels':
|
||||
'a young rooftop rescue team watching rails, bridges, and river lights from high above Meridian City at sunrise',
|
||||
'The Aegis Club':
|
||||
'retired heroes in a restored neighborhood social club, worn memorabilia, warm lamps, and a new generation training nearby',
|
||||
'Starfall Academy':
|
||||
'cadets with unstable cosmic powers aboard a school ship near the asteroid belt, classroom windows filled with stars',
|
||||
'Tomorrow Bureau':
|
||||
'future analysts in a glass-walled operations room sorting one-day-ahead disaster files, clocks and reflections layered across the scene',
|
||||
'Alley Mask':
|
||||
'a bike courier stepping through deep city shadows while following strange signal glyphs in narrow alleys after rain',
|
||||
'Neon Sparrow':
|
||||
'a rooftop messenger following glowing clues that appear in midnight rain, neon reflections and small bright wing motifs',
|
||||
'Cape Makers':
|
||||
'tailors, engineers, and artists building original stage gear in a busy design studio, fabric tests and hand-built emblems everywhere',
|
||||
'Citizens of the Beacon':
|
||||
'ordinary residents maintaining a citywide rescue network after the first beacon, hopeful faces lit by practical signal lamps',
|
||||
'Bubble Street Workshop':
|
||||
'neighbors building simple inventions from circles, paper, string, and bright workshop tables',
|
||||
'Flatland Detectives':
|
||||
'two geometric detectives solving gentle neighborhood mysteries using maps, shadows, and shape clues',
|
||||
'Color Orchard':
|
||||
'a preschool orchard changing color each morning while tiny caretakers learn seasons and sound',
|
||||
'Museum of Little Robots':
|
||||
'small helpful robots arranging exhibits after closing time in a quiet retro-future museum',
|
||||
};
|
||||
|
||||
return directions[title] ?? 'an original cinematic genre scene for a fictional streaming title';
|
||||
}
|
||||
|
||||
async function generateMissingArtwork(): Promise<void> {
|
||||
const apiKey = process.env['OPENAI_API_KEY'];
|
||||
|
||||
if (!apiKey) {
|
||||
throw new Error('OPENAI_API_KEY is required for --generate.');
|
||||
}
|
||||
|
||||
for (const [index, job] of jobs.entries()) {
|
||||
if (existsSync(job.outputPath) && !force) {
|
||||
console.log(
|
||||
`[${index + 1}/${jobs.length}] exists, skipping ${job.filename}`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[${index + 1}/${jobs.length}] generating ${job.filename} (${job.size}, ${job.quality})`
|
||||
);
|
||||
const imageBytes = await requestImage(apiKey, job);
|
||||
writeFileSync(job.outputPath, imageBytes);
|
||||
|
||||
if (delayMs > 0 && index < jobs.length - 1) {
|
||||
await sleep(delayMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function requestImage(apiKey: string, job: ArtworkJob): Promise<Buffer> {
|
||||
const payload = {
|
||||
model,
|
||||
prompt: job.prompt,
|
||||
quality: job.quality,
|
||||
size: job.size,
|
||||
output_format: outputFormat,
|
||||
moderation: 'auto',
|
||||
};
|
||||
|
||||
for (let attempt = 1; attempt <= 4; attempt += 1) {
|
||||
const response = await fetch('https://api.openai.com/v1/images/generations', {
|
||||
body: JSON.stringify(payload),
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
const body = await response.json().catch(() => undefined);
|
||||
|
||||
if (response.ok) {
|
||||
const imageBase64 = readImageBase64(body);
|
||||
return Buffer.from(imageBase64, 'base64');
|
||||
}
|
||||
|
||||
const message = readErrorMessage(body) ?? `${response.status} ${response.statusText}`;
|
||||
if ((response.status === 429 || response.status >= 500) && attempt < 4) {
|
||||
const retryAfter = Number(response.headers.get('retry-after'));
|
||||
const waitMs = Number.isFinite(retryAfter)
|
||||
? retryAfter * 1000
|
||||
: attempt * 15_000;
|
||||
console.warn(
|
||||
`OpenAI image request failed for ${job.filename}: ${message}. Retrying in ${Math.round(
|
||||
waitMs / 1000
|
||||
)}s.`
|
||||
);
|
||||
await sleep(waitMs);
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`OpenAI image request failed for ${job.filename}: ${message}`
|
||||
);
|
||||
}
|
||||
|
||||
throw new Error(`OpenAI image request failed for ${job.filename}.`);
|
||||
}
|
||||
|
||||
function readImageBase64(body: unknown): string {
|
||||
if (
|
||||
typeof body === 'object' &&
|
||||
body !== null &&
|
||||
'data' in body &&
|
||||
Array.isArray((body as { data: unknown }).data)
|
||||
) {
|
||||
const first = (body as { data: Array<{ b64_json?: unknown }> }).data[0];
|
||||
if (typeof first?.b64_json === 'string' && first.b64_json.length > 0) {
|
||||
return first.b64_json;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('OpenAI response did not include data[0].b64_json.');
|
||||
}
|
||||
|
||||
function readErrorMessage(body: unknown): string | undefined {
|
||||
if (
|
||||
typeof body === 'object' &&
|
||||
body !== null &&
|
||||
'error' in body &&
|
||||
typeof (body as { error?: { message?: unknown } }).error?.message === 'string'
|
||||
) {
|
||||
return (body as { error: { message: string } }).error.message;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function validateArtwork(selectedJobs: ArtworkJob[]): Promise<void> {
|
||||
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8')) as ArtworkManifest;
|
||||
const expectedManifestCount = selectedJobs.length;
|
||||
|
||||
if (manifest.version !== 1 || manifest.assets.length < expectedManifestCount) {
|
||||
throw new Error(
|
||||
`Manifest has ${manifest.assets.length} assets, expected at least ${expectedManifestCount}.`
|
||||
);
|
||||
}
|
||||
|
||||
for (const job of selectedJobs) {
|
||||
if (!existsSync(job.outputPath)) {
|
||||
throw new Error(`Missing generated artwork: ${relativePath(job.outputPath)}`);
|
||||
}
|
||||
|
||||
const metadata = await sharp(job.outputPath).metadata();
|
||||
const [expectedWidth, expectedHeight] = job.size.split('x').map(Number);
|
||||
|
||||
if (metadata.format !== 'png') {
|
||||
throw new Error(`Artwork is not PNG: ${relativePath(job.outputPath)}`);
|
||||
}
|
||||
|
||||
if (metadata.width !== expectedWidth || metadata.height !== expectedHeight) {
|
||||
throw new Error(
|
||||
`Artwork has invalid dimensions: ${relativePath(job.outputPath)} ` +
|
||||
`expected ${job.size}, got ${metadata.width}x${metadata.height}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Validated ${selectedJobs.length} artwork assets and manifest: ${relativePath(
|
||||
manifestPath
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
function writeManifest(selectedModel: string, selectedJobs: ArtworkJob[]): void {
|
||||
const manifest: ArtworkManifest = {
|
||||
assetRoot: relativeAssetRoot,
|
||||
assets: selectedJobs.map((job) => ({
|
||||
contentType: job.contentType,
|
||||
filename: job.filename,
|
||||
kind: job.kind,
|
||||
manualApprovalStatus: 'pending-human-review',
|
||||
model: selectedModel,
|
||||
prompt: job.prompt,
|
||||
quality: job.quality,
|
||||
size: job.size,
|
||||
slug: job.slug,
|
||||
title: job.title,
|
||||
})),
|
||||
model: selectedModel,
|
||||
outputFormat,
|
||||
version: 1,
|
||||
};
|
||||
|
||||
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
|
||||
}
|
||||
|
||||
function printDryRun(): void {
|
||||
const manifest = {
|
||||
assetRoot: relativeAssetRoot,
|
||||
assets: jobs.map((job) => ({
|
||||
filename: job.filename,
|
||||
kind: job.kind,
|
||||
model,
|
||||
quality: job.quality,
|
||||
size: job.size,
|
||||
title: job.title,
|
||||
})),
|
||||
count: jobs.length,
|
||||
outputFormat,
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(manifest, null, 2));
|
||||
}
|
||||
|
||||
function ensureOutputDirs(): void {
|
||||
mkdirSync(path.join(assetRoot, 'poster'), { recursive: true });
|
||||
mkdirSync(path.join(assetRoot, 'backdrop'), { recursive: true });
|
||||
}
|
||||
|
||||
function getMode(argv: string[]): RunMode {
|
||||
const selectedModes = [
|
||||
argv.includes('--dry-run') ? 'dry-run' : undefined,
|
||||
argv.includes('--generate') ? 'generate' : undefined,
|
||||
argv.includes('--manifest') ? 'manifest' : undefined,
|
||||
argv.includes('--validate') ? 'validate' : undefined,
|
||||
].filter(Boolean) as RunMode[];
|
||||
|
||||
if (selectedModes.length > 1) {
|
||||
throw new Error('Choose only one mode: --dry-run, --manifest, --generate, or --validate.');
|
||||
}
|
||||
|
||||
return selectedModes[0] ?? 'dry-run';
|
||||
}
|
||||
|
||||
function getStringArg(name: string): string | undefined {
|
||||
const index = args.indexOf(name);
|
||||
return index >= 0 ? args[index + 1] : undefined;
|
||||
}
|
||||
|
||||
function getNumberArg(name: string): number | undefined {
|
||||
const raw = getStringArg(name);
|
||||
if (raw === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const value = Number(raw);
|
||||
if (!Number.isFinite(value) || value < 0) {
|
||||
throw new Error(`${name} must be a non-negative number.`);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function getQualityArg(name: string): ArtworkQuality | undefined {
|
||||
return getQuality(getStringArg(name));
|
||||
}
|
||||
|
||||
function getQuality(raw: string | undefined): ArtworkQuality | undefined {
|
||||
if (
|
||||
raw === 'low' ||
|
||||
raw === 'medium' ||
|
||||
raw === 'high' ||
|
||||
raw === 'auto'
|
||||
) {
|
||||
return raw;
|
||||
}
|
||||
|
||||
if (raw === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
throw new Error('Quality must be one of: low, medium, high, auto.');
|
||||
}
|
||||
|
||||
function relativePath(filePath: string): string {
|
||||
return path.relative(workspaceRoot, filePath);
|
||||
}
|
||||
|
||||
function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
main().catch((error: unknown) => {
|
||||
console.error(error instanceof Error ? error.message : error);
|
||||
process.exit(1);
|
||||
});
|
||||