getraw 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yml +43 -0
- package/CLAUDE.md +1 -1
- package/README.md +107 -116
- package/RESEARCH.md +109 -109
- package/STATUS.md +1 -1
- package/docs/plugin-guide.md +1 -1
- package/docs/supported-sites.md +1 -1
- package/package.json +4 -4
- package/skills/getraw/SKILL.md +163 -0
- package/src/cli/index.ts +1 -1
- package/src/cli/options.ts +2 -2
- package/src/core/types.ts +1 -1
- package/src/downloaders/dash.ts +1 -1
- package/src/downloaders/fragment.ts +1 -1
- package/src/downloaders/hls.ts +1 -1
- package/src/downloaders/http.ts +1 -1
- package/src/extractors/niconico/index.ts +1 -1
- package/src/extractors/reddit/gallery.ts +1 -1
- package/src/extractors/reddit/index.ts +3 -3
- package/src/extractors/twitter/index.ts +1 -1
- package/src/networking/cookies.ts +1 -1
- package/src/networking/tls.ts +1 -1
- package/tests/unit/extractors/misc.test.ts +1 -1
- package/tools/dashboard.ts +1 -1
- package/video/.hyperframes/expanded-prompt.md +173 -0
- package/video/design.md +82 -0
- package/video/index.html +684 -0
- package/video/renders/video_2026-06-16_23-50-45.meta.json +1 -0
- package/video/renders/video_2026-06-16_23-50-45.mp4 +0 -0
package/STATUS.md
CHANGED
package/docs/plugin-guide.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Plugin Guide — Writing a Custom Extractor
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
getraw extractors are classes that extend `BaseExtractor` from `src/core/types.ts`. Once written, they are registered via `registerExtractor` from `src/extractors/base.ts`. getraw then tries each registered extractor in order before falling back to the generic extractor.
|
|
4
4
|
|
|
5
5
|
## BaseExtractor Interface
|
|
6
6
|
|
package/docs/supported-sites.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Supported Sites
|
|
2
2
|
|
|
3
|
-
All extractors implement `BaseExtractor` from `src/core/types.ts`. The `_VALID_URL` regex for each is listed below —
|
|
3
|
+
All extractors implement `BaseExtractor` from `src/core/types.ts`. The `_VALID_URL` regex for each is listed below — getraw tests URLs against these in registration order, falling back to the `generic` extractor for any `http(s)://` URL.
|
|
4
4
|
|
|
5
5
|
| # | Extractor name | Site | URL pattern | Formats | Notes |
|
|
6
6
|
|---|---------------|------|-------------|---------|-------|
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "getraw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Fast media downloader CLI built natively in Bun/TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"getraw": "./src/cli/index.ts"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"dev": "bun run src/cli/index.ts",
|
|
11
11
|
"test": "bun test",
|
|
12
|
-
"build": "bun build src/cli/index.ts --compile --outfile=
|
|
12
|
+
"build": "bun build src/cli/index.ts --compile --outfile=getraw",
|
|
13
13
|
"dashboard": "bun run tools/dashboard.ts"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/
|
|
28
|
+
"url": "https://github.com/onkits/getraw"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: getraw
|
|
3
|
+
description: Download videos, audio, and metadata from 30+ sites (YouTube, Twitter, TikTok, Instagram, Reddit, Twitch, Vimeo, SoundCloud, and more). Use when the user asks to download media, extract video info, get transcripts/subtitles, rip audio, or fetch metadata from a URL. Wraps the getraw CLI — a yt-dlp replacement built in Bun/TypeScript.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# getraw
|
|
7
|
+
|
|
8
|
+
Download and extract media from 30+ sites. Built in Bun/TypeScript as a yt-dlp replacement.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
Requires `bun` and `getraw` installed:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun install -g getraw
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Optional: `ffmpeg` for audio extraction, format merging, and subtitle embedding.
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
### Download a video
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
getraw "URL"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Downloads the best available format to the current directory.
|
|
29
|
+
|
|
30
|
+
### Get metadata as JSON (no download)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
getraw --dump-json "URL"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Returns full metadata: title, description, uploader, duration, formats, subtitles, thumbnails. Use this when you need info about a video without downloading it. Parse the JSON output for structured data.
|
|
37
|
+
|
|
38
|
+
### List available formats
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
getraw --list-formats "URL"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Shows all available quality/format options (resolution, codec, bitrate, filesize).
|
|
45
|
+
|
|
46
|
+
### Download specific format
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
getraw -f "best[height<=720]" "URL"
|
|
50
|
+
getraw -f "bestvideo+bestaudio" "URL"
|
|
51
|
+
getraw -f "bestaudio" "URL"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Format selection strings:
|
|
55
|
+
- `best` — best single file
|
|
56
|
+
- `bestvideo+bestaudio` — best video + best audio, merged by ffmpeg
|
|
57
|
+
- `bestaudio` — audio only (best quality)
|
|
58
|
+
- `best[height<=720]` — best format at 720p or below
|
|
59
|
+
- Format ID from `--list-formats` (e.g. `137+140`)
|
|
60
|
+
|
|
61
|
+
### Extract audio only
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
getraw -x "URL"
|
|
65
|
+
getraw -x --audio-format mp3 "URL"
|
|
66
|
+
getraw -x --audio-format flac "URL"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Supported audio formats: `mp3`, `aac`, `flac`, `wav`, `opus`, `vorbis`, `m4a`.
|
|
70
|
+
|
|
71
|
+
### Download subtitles
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
getraw --write-subs "URL"
|
|
75
|
+
getraw --write-subs --sub-langs "en,es" "URL"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Downloads subtitle files alongside the video. Use `--sub-langs` to specify languages.
|
|
79
|
+
|
|
80
|
+
### Custom output filename
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
getraw -o "%(title)s.%(ext)s" "URL"
|
|
84
|
+
getraw -o "%(uploader)s - %(title)s [%(id)s].%(ext)s" "URL"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Template variables: `%(title)s`, `%(id)s`, `%(ext)s`, `%(uploader)s`, `%(upload_date)s`, `%(duration)s`, `%(view_count)s`.
|
|
88
|
+
|
|
89
|
+
### Embed metadata
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
getraw --embed-thumbnail --embed-subs "URL"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Embeds thumbnail art and subtitles into the downloaded file (requires ffmpeg).
|
|
96
|
+
|
|
97
|
+
## Supported Sites
|
|
98
|
+
|
|
99
|
+
| Site | URL Pattern |
|
|
100
|
+
|------|------------|
|
|
101
|
+
| YouTube | youtube.com, youtu.be, youtube.com/shorts |
|
|
102
|
+
| Twitter/X | twitter.com/*/status/*, x.com/*/status/* |
|
|
103
|
+
| TikTok | tiktok.com/@*/video/*, vm.tiktok.com/* |
|
|
104
|
+
| Instagram | instagram.com/p/*, instagram.com/reel/* |
|
|
105
|
+
| Reddit | reddit.com/r/*/comments/*, v.redd.it/* |
|
|
106
|
+
| Twitch | twitch.tv/videos/*, twitch.tv/*/clip/* |
|
|
107
|
+
| Vimeo | vimeo.com/* |
|
|
108
|
+
| SoundCloud | soundcloud.com/*/* |
|
|
109
|
+
| Bilibili | bilibili.com/video/* |
|
|
110
|
+
| Dailymotion | dailymotion.com/video/* |
|
|
111
|
+
| Bandcamp | *.bandcamp.com/track/*, *.bandcamp.com/album/* |
|
|
112
|
+
| Rumble | rumble.com/* |
|
|
113
|
+
| TED | ted.com/talks/* |
|
|
114
|
+
| Kick | kick.com/video/*, kick.com/*/clips/* |
|
|
115
|
+
| Streamable | streamable.com/* |
|
|
116
|
+
| PeerTube | Any PeerTube instance |
|
|
117
|
+
| Archive.org | archive.org/details/* |
|
|
118
|
+
| + 13 more | Imgur, Coub, Odysee, Spotify podcasts, NHK, BBC, etc. |
|
|
119
|
+
|
|
120
|
+
## When to Use
|
|
121
|
+
|
|
122
|
+
- User says "download this video" or shares a video URL
|
|
123
|
+
- User wants video/audio metadata (`--dump-json`)
|
|
124
|
+
- User wants to extract audio from a video (`-x`)
|
|
125
|
+
- User wants subtitles or transcripts (`--write-subs`)
|
|
126
|
+
- User wants to check available qualities (`--list-formats`)
|
|
127
|
+
- User wants to save media for offline use or processing
|
|
128
|
+
|
|
129
|
+
## Common Patterns
|
|
130
|
+
|
|
131
|
+
### Get video transcript for summarization
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
getraw --write-subs --sub-langs en --skip-download "URL"
|
|
135
|
+
# Then read the .vtt or .srt file
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Download audio for TTS/transcription pipeline
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
getraw -x --audio-format wav -o "audio.wav" "URL"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Batch download from a list
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
getraw URL1 URL2 URL3
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Get metadata for multiple videos
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
for url in URL1 URL2 URL3; do
|
|
154
|
+
getraw --dump-json "$url"
|
|
155
|
+
done
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Error Handling
|
|
159
|
+
|
|
160
|
+
- If a site is unsupported, getraw returns a clear error with the URL
|
|
161
|
+
- If a format is unavailable, it falls back to the best available
|
|
162
|
+
- Network errors retry 3 times with exponential backoff
|
|
163
|
+
- Use `--verbose` for debug output, `--quiet` to suppress all output
|
package/src/cli/index.ts
CHANGED
package/src/cli/options.ts
CHANGED
|
@@ -81,9 +81,9 @@ export function parseArgs(args: string[]): Options {
|
|
|
81
81
|
|
|
82
82
|
export function printHelp(): void {
|
|
83
83
|
const lines = [
|
|
84
|
-
"
|
|
84
|
+
"getraw — Fast media downloader",
|
|
85
85
|
"",
|
|
86
|
-
"Usage:
|
|
86
|
+
"Usage: getraw [OPTIONS] URL [URL...]",
|
|
87
87
|
"",
|
|
88
88
|
"Options:",
|
|
89
89
|
];
|
package/src/core/types.ts
CHANGED
package/src/downloaders/dash.ts
CHANGED
|
@@ -119,7 +119,7 @@ export class DashDownloader extends Downloader {
|
|
|
119
119
|
throw new DownloadError("No segments found in MPD");
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
const tempDir = `/tmp/
|
|
122
|
+
const tempDir = `/tmp/getraw-dash-${Date.now()}`;
|
|
123
123
|
const fragmenter = new FragmentDownloader();
|
|
124
124
|
await fragmenter.downloadSegments(allSegments, filepath, {
|
|
125
125
|
...options,
|
|
@@ -24,7 +24,7 @@ export class FragmentDownloader {
|
|
|
24
24
|
options: FragmentDownloadOptions,
|
|
25
25
|
): Promise<void> {
|
|
26
26
|
const concurrency = options.concurrency ?? 8;
|
|
27
|
-
const tempDir = options.tempDir ?? "/tmp/
|
|
27
|
+
const tempDir = options.tempDir ?? "/tmp/getraw-fragments";
|
|
28
28
|
|
|
29
29
|
await Bun.$`mkdir -p ${tempDir}`.quiet();
|
|
30
30
|
|
package/src/downloaders/hls.ts
CHANGED
|
@@ -154,7 +154,7 @@ export class HlsDownloader extends Downloader {
|
|
|
154
154
|
segments.push(seg);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
const tempDir = `/tmp/
|
|
157
|
+
const tempDir = `/tmp/getraw-hls-${Date.now()}`;
|
|
158
158
|
const fragmenter = new FragmentDownloader();
|
|
159
159
|
await fragmenter.downloadSegments(segments, filepath, {
|
|
160
160
|
...options,
|
package/src/downloaders/http.ts
CHANGED
|
@@ -174,7 +174,7 @@ export class HttpDownloader extends Downloader {
|
|
|
174
174
|
chunks.push({ start: i, end: Math.min(i + CHUNK_SIZE - 1, totalBytes - 1), index: idx });
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
const tempDir = `/tmp/
|
|
177
|
+
const tempDir = `/tmp/getraw-http-${Date.now()}`;
|
|
178
178
|
await Bun.$`mkdir -p ${tempDir}`.quiet();
|
|
179
179
|
|
|
180
180
|
const baseHeaders = this.buildHeaders(options);
|
|
@@ -126,7 +126,7 @@ export class NiconicoExtractor extends BaseExtractor {
|
|
|
126
126
|
};
|
|
127
127
|
|
|
128
128
|
const sessionResp = await fetch(
|
|
129
|
-
`https://nvapi.nicovideo.jp/v1/watch/${videoId}/access-rights/hls?actionTrackId=
|
|
129
|
+
`https://nvapi.nicovideo.jp/v1/watch/${videoId}/access-rights/hls?actionTrackId=getraw_${Date.now()}`,
|
|
130
130
|
{
|
|
131
131
|
method: "POST",
|
|
132
132
|
headers: {
|
|
@@ -44,7 +44,7 @@ export class RedditGalleryExtractor extends BaseExtractor {
|
|
|
44
44
|
const jsonUrl = normalized.replace(/\?.*$/, "").replace(/\/$/, "") + ".json";
|
|
45
45
|
|
|
46
46
|
const response = await fetch(jsonUrl, {
|
|
47
|
-
headers: { "User-Agent": "
|
|
47
|
+
headers: { "User-Agent": "getraw/1.0" },
|
|
48
48
|
});
|
|
49
49
|
if (!response.ok) {
|
|
50
50
|
throw new ExtractorError(`Reddit API returned ${response.status}`);
|
|
@@ -86,7 +86,7 @@ export class RedditExtractor extends BaseExtractor {
|
|
|
86
86
|
private async _extractVReddIt(url: string): Promise<InfoDict> {
|
|
87
87
|
const jsonUrl = url.endsWith("/") ? url + ".json" : url + "/.json";
|
|
88
88
|
const response = await fetch(jsonUrl, {
|
|
89
|
-
headers: { "User-Agent": "
|
|
89
|
+
headers: { "User-Agent": "getraw/1.0" },
|
|
90
90
|
});
|
|
91
91
|
if (!response.ok) {
|
|
92
92
|
throw new ExtractorError(`Reddit API returned ${response.status}`);
|
|
@@ -104,7 +104,7 @@ export class RedditExtractor extends BaseExtractor {
|
|
|
104
104
|
const normalized = normalizeRedditUrl(url);
|
|
105
105
|
const jsonUrl = normalized.replace(/\?.*$/, "").replace(/\/$/, "") + ".json";
|
|
106
106
|
const response = await fetch(jsonUrl, {
|
|
107
|
-
headers: { "User-Agent": "
|
|
107
|
+
headers: { "User-Agent": "getraw/1.0" },
|
|
108
108
|
});
|
|
109
109
|
if (!response.ok) {
|
|
110
110
|
throw new ExtractorError(`Reddit API returned ${response.status}`);
|
|
@@ -168,7 +168,7 @@ export class RedditExtractor extends BaseExtractor {
|
|
|
168
168
|
width: videoData.width,
|
|
169
169
|
height: videoData.height,
|
|
170
170
|
format_note: "video+audio (merged)",
|
|
171
|
-
http_headers: { "User-Agent": "
|
|
171
|
+
http_headers: { "User-Agent": "getraw/1.0" },
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
174
|
}
|
|
@@ -44,7 +44,7 @@ export class TwitterExtractor extends BaseExtractor {
|
|
|
44
44
|
const apiUrl = `https://cdn.syndication.twimg.com/tweet-result?id=${tweetId}&lang=en&features=tfw_timeline_list%3A%3Btfw_follower_count_sunset%3Atrue&token=0`;
|
|
45
45
|
const resp = await fetch(apiUrl, {
|
|
46
46
|
headers: {
|
|
47
|
-
"User-Agent": "Mozilla/5.0 (compatible;
|
|
47
|
+
"User-Agent": "Mozilla/5.0 (compatible; getraw/1.0)",
|
|
48
48
|
Accept: "application/json",
|
|
49
49
|
Referer: "https://platform.twitter.com/",
|
|
50
50
|
Origin: "https://platform.twitter.com",
|
|
@@ -40,7 +40,7 @@ export function parseNetscapeCookieFile(content: string): Cookie[] {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export function serializeNetscapeCookieFile(cookies: Cookie[]): string {
|
|
43
|
-
const header = "# Netscape HTTP Cookie File\n# Generated by
|
|
43
|
+
const header = "# Netscape HTTP Cookie File\n# Generated by getraw\n";
|
|
44
44
|
const lines = cookies.map((c) =>
|
|
45
45
|
[
|
|
46
46
|
c.domain,
|
package/src/networking/tls.ts
CHANGED
|
@@ -61,7 +61,7 @@ standard fetch()/WebSocket APIs. Full impersonation requires:
|
|
|
61
61
|
2. Custom cipher suite ordering matching the target browser
|
|
62
62
|
3. Custom TLS extensions ordering
|
|
63
63
|
|
|
64
|
-
For now,
|
|
64
|
+
For now, getraw sets a matching User-Agent header which satisfies most sites.
|
|
65
65
|
Sites that perform JA3 fingerprint checking (e.g., some CDN bot detection) may
|
|
66
66
|
require a future implementation using Bun FFI + uTLS or a headless browser approach.
|
|
67
67
|
`;
|
|
@@ -894,8 +894,8 @@ describe("GoogleDriveExtractor parsing", () => {
|
|
|
894
894
|
expect(info.id).toBe("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs");
|
|
895
895
|
expect(info.title).toBe("test-video");
|
|
896
896
|
expect(info.ext).toBe("mp4");
|
|
897
|
-
expect(info.formats![0].url).toContain("drive.google.com/uc");
|
|
898
897
|
expect(info.formats![0].url).toContain("export=download");
|
|
898
|
+
expect(info.formats![0].url).toContain("1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs");
|
|
899
899
|
expect(info.formats![0].filesize).toBe(10485760);
|
|
900
900
|
});
|
|
901
901
|
|
package/tools/dashboard.ts
CHANGED
|
@@ -39,7 +39,7 @@ function parseAndRender(content: string): string {
|
|
|
39
39
|
const output: string[] = [];
|
|
40
40
|
|
|
41
41
|
output.push("");
|
|
42
|
-
output.push(`${COLORS.bold}${COLORS.cyan}
|
|
42
|
+
output.push(`${COLORS.bold}${COLORS.cyan} getraw — Agent Dashboard${COLORS.reset}`);
|
|
43
43
|
output.push(`${COLORS.dim} ${new Date().toLocaleTimeString()}${COLORS.reset}`);
|
|
44
44
|
output.push("");
|
|
45
45
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# getraw — Product Video Expansion
|
|
2
|
+
|
|
3
|
+
## Style Block
|
|
4
|
+
|
|
5
|
+
- **BG:** #0c0c0f (near-black, blue undertone)
|
|
6
|
+
- **FG:** #e8e8ec (off-white)
|
|
7
|
+
- **Accent:** #00ff88 (terminal green)
|
|
8
|
+
- **Surface:** #161620
|
|
9
|
+
- **Muted:** #6b6b80
|
|
10
|
+
- **Headline:** Space Grotesk 700, -0.03em tracking
|
|
11
|
+
- **Code:** JetBrains Mono 400
|
|
12
|
+
- **Labels:** JetBrains Mono 500 uppercase, 0.08em tracking
|
|
13
|
+
|
|
14
|
+
## Rhythm Declaration
|
|
15
|
+
|
|
16
|
+
`hook-PUNCH-breathe-BUILD-PEAK-CTA`
|
|
17
|
+
|
|
18
|
+
6 scenes, ~30 seconds total. Fast hook, slam the name, breathe with the problem, build features, peak with the stats, close with install command.
|
|
19
|
+
|
|
20
|
+
## Global Rules
|
|
21
|
+
|
|
22
|
+
- Primary transition: glitch (0.3s) — 60% of transitions
|
|
23
|
+
- Accent transition: staggered blocks (0.25s) — topic changes
|
|
24
|
+
- All decoratives have ambient motion (scan-line drift, grid pulse, cursor blink)
|
|
25
|
+
- Terminal green (#00ff88) used ONLY for: commands, active highlights, key stats
|
|
26
|
+
- Everything else in off-white or muted
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Scene 1: Hook (0s–5s)
|
|
31
|
+
|
|
32
|
+
**Concept:** A terminal cursor blinks on black. A command types out character by character: `$ getraw "https://youtube.com/watch?v=..."`. The moment Enter is hit, the screen EXPLODES with data — format listings cascading down like a matrix waterfall. The viewer's reaction: "what is this tool?"
|
|
33
|
+
|
|
34
|
+
**Mood:** Cinematic hacker. The opening frame of a tech thriller.
|
|
35
|
+
|
|
36
|
+
**Depth layers:**
|
|
37
|
+
- BG: #0c0c0f solid + subtle scan-line overlay at 8% opacity drifting upward + faint grid dots at 5% pulsing
|
|
38
|
+
- MG: Terminal text, typing animation, cursor blink
|
|
39
|
+
- FG: Faint terminal frame border (1px #2a2a3a), timestamp label top-right "v0.1.0"
|
|
40
|
+
|
|
41
|
+
**Animation choreography:**
|
|
42
|
+
- Cursor BLINKS twice (0.5s interval) at t=0.2
|
|
43
|
+
- Command TYPES character-by-character at 40ms/char starting t=0.8
|
|
44
|
+
- On "enter" at t=3.0: format data CASCADES in from top, staggered 30ms per line
|
|
45
|
+
- Scan-lines drift upward continuously
|
|
46
|
+
|
|
47
|
+
**Transition out:** Glitch, 0.3s, power3.inOut
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Scene 2: Name Drop (5s–10s)
|
|
52
|
+
|
|
53
|
+
**Concept:** The word "getraw" SLAMS into frame at massive scale — 160px, terminal green, filling 70% of the width. Below it, a subtitle types on: "yt-dlp replacement. Built in Bun." The green glows softly, casting light on the dark surface. This is the brand moment.
|
|
54
|
+
|
|
55
|
+
**Mood:** Impact. Like a logo sting but for a CLI tool.
|
|
56
|
+
|
|
57
|
+
**Depth layers:**
|
|
58
|
+
- BG: Radial glow from center (#00ff88 at 12% opacity, scale breathing 1.0→1.05) + ghost text "MEDIA DOWNLOADER" at 4% opacity, 200px, behind the title
|
|
59
|
+
- MG: "getraw" headline + subtitle line
|
|
60
|
+
- FG: Two horizontal rules (top and bottom of frame, #2a2a3a, scaleX from 0), version badge "v0.1.0" bottom-right
|
|
61
|
+
|
|
62
|
+
**Animation choreography:**
|
|
63
|
+
- "getraw" SLAMS from y:80 with scale overshoot (1.05→1.0), expo.out, 0.5s at t=0.3
|
|
64
|
+
- Subtitle TYPES on character-by-character at t=1.2, JetBrains Mono, muted color
|
|
65
|
+
- Horizontal rules DRAW from center outward (scaleX: 0→1) at t=0.5, 0.6s
|
|
66
|
+
- Radial glow BREATHES continuously (scale 1.0↔1.05, 3s loop)
|
|
67
|
+
|
|
68
|
+
**Transition out:** Staggered blocks, 0.25s — signals topic change
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Scene 3: The Problem (10s–15s)
|
|
73
|
+
|
|
74
|
+
**Concept:** Split frame. Left side: "yt-dlp" with a list of pain points stacking up — "Python dependency", "External JS runtime", "36K line interpreter", "Slow startup". Each appears with a red-ish muted strike. Right side: blank, waiting. The viewer feels the weight of the problem before the solution appears.
|
|
75
|
+
|
|
76
|
+
**Mood:** Tension. Editorial comparison. The "before" that makes the "after" land.
|
|
77
|
+
|
|
78
|
+
**Depth layers:**
|
|
79
|
+
- BG: Subtle vertical divider line at center (1px #2a2a3a) + grid dots left half at 5%
|
|
80
|
+
- MG: "yt-dlp" label top-left + stacking pain points + right side empty space
|
|
81
|
+
- FG: Small "THE PROBLEM" label top-center in muted, monospace uppercase
|
|
82
|
+
|
|
83
|
+
**Animation choreography:**
|
|
84
|
+
- "THE PROBLEM" label FADES in at t=0.2, subtle
|
|
85
|
+
- "yt-dlp" SLIDES in from left at t=0.4
|
|
86
|
+
- Pain points STACK one by one, each DROPPING from y:-20 with stagger 0.3s starting t=0.8
|
|
87
|
+
- Each pain point gets a subtle strikethrough line that DRAWS across after landing
|
|
88
|
+
- Right side stays intentionally empty — tension
|
|
89
|
+
|
|
90
|
+
**Transition out:** Glitch, 0.3s
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Scene 4: The Solution (15s–21s)
|
|
95
|
+
|
|
96
|
+
**Concept:** The empty right side from scene 3 is now the full frame. "getraw" in green, and below it, three feature cards STAGGER in: "Native JS execution", "30+ site extractors", "Bun-powered CLI". Each card has a small icon-like label and a one-liner. Clean, confident, no clutter. The solution is elegant.
|
|
97
|
+
|
|
98
|
+
**Mood:** Confidence. Clean resolve after tension.
|
|
99
|
+
|
|
100
|
+
**Depth layers:**
|
|
101
|
+
- BG: Radial glow bottom-left (#00ff88 at 10%) + faint circuit-board pattern at 3% opacity
|
|
102
|
+
- MG: "getraw" label + three feature cards in surface color (#161620) with border
|
|
103
|
+
- FG: Small arrow indicators (→) next to each card, accent green, appearing with stagger
|
|
104
|
+
|
|
105
|
+
**Animation choreography:**
|
|
106
|
+
- "getraw" SLIDES in from left at t=0.2, accent green, smaller (64px)
|
|
107
|
+
- Feature cards CASCADE from right, stagger 0.15s, each from x:40 + opacity:0, expo.out
|
|
108
|
+
- Arrow indicators POP in with scale overshoot 0.15s after their card lands
|
|
109
|
+
- Circuit pattern DRIFTS slowly rightward
|
|
110
|
+
|
|
111
|
+
**Transition out:** Glitch, 0.3s
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Scene 5: Stats (21s–26s)
|
|
116
|
+
|
|
117
|
+
**Concept:** Three big numbers SLAM in simultaneously: "30+" sites, "386" tests, "50ms" startup. Each in massive type (120px), terminal green. Below each number, a label in muted monospace. This is the proof. Numbers don't lie.
|
|
118
|
+
|
|
119
|
+
**Mood:** Peak energy. Data as spectacle.
|
|
120
|
+
|
|
121
|
+
**Depth layers:**
|
|
122
|
+
- BG: Three vertical accent lines (#00ff88 at 8%) behind each stat, full height, subtle pulse
|
|
123
|
+
- MG: Three stat columns with numbers + labels
|
|
124
|
+
- FG: "BENCHMARKS" label top-center, monospace uppercase muted + scan-line overlay intensified to 12%
|
|
125
|
+
|
|
126
|
+
**Animation choreography:**
|
|
127
|
+
- "BENCHMARKS" label FADES in at t=0.1
|
|
128
|
+
- All three numbers SLAM simultaneously from y:60, scale:1.1→1.0, expo.out, 0.4s at t=0.3
|
|
129
|
+
- Labels TYPE on below each number, stagger 0.1s starting t=0.8
|
|
130
|
+
- Accent lines PULSE once on number impact (opacity 8%→15%→8%, 0.6s)
|
|
131
|
+
|
|
132
|
+
**Transition out:** Staggered blocks, 0.3s — wind down
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Scene 6: CTA / Install (26s–30s)
|
|
137
|
+
|
|
138
|
+
**Concept:** Back to terminal. A clean command prompt: `$ bun install -g getraw`. Below it, the npm badge and GitHub link. The cursor blinks at the end. Simple. The viewer knows exactly what to do next.
|
|
139
|
+
|
|
140
|
+
**Mood:** Resolution. Clear call to action. The cursor blink is the mic drop.
|
|
141
|
+
|
|
142
|
+
**Depth layers:**
|
|
143
|
+
- BG: Subtle scan-lines returning + faint radial glow center (#00ff88 at 6%)
|
|
144
|
+
- MG: Install command + npm/GitHub info
|
|
145
|
+
- FG: Terminal frame border, "getraw.dev" bottom-center (aspirational), cursor blinking
|
|
146
|
+
|
|
147
|
+
**Animation choreography:**
|
|
148
|
+
- Terminal frame DRAWS in (border animation, 0.4s) at t=0.1
|
|
149
|
+
- Command TYPES on at t=0.5, 50ms/char, green text
|
|
150
|
+
- npm line FADES in at t=2.0, muted
|
|
151
|
+
- GitHub URL FADES in at t=2.3, muted
|
|
152
|
+
- Cursor BLINKS indefinitely (well, 4 blinks with calculated repeat count)
|
|
153
|
+
|
|
154
|
+
**Transition out:** Final scene — elements fade to black over 0.8s. Last thing visible: the blinking cursor.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Recurring Motifs
|
|
159
|
+
|
|
160
|
+
- Terminal cursor blink (scenes 1, 6)
|
|
161
|
+
- Scan-line overlay (all scenes, varying intensity)
|
|
162
|
+
- Character-by-character typing (scenes 1, 2, 6)
|
|
163
|
+
- Accent green used only for active/important elements
|
|
164
|
+
|
|
165
|
+
## Negative Prompt
|
|
166
|
+
|
|
167
|
+
- No gradient text
|
|
168
|
+
- No cyan or purple — green only
|
|
169
|
+
- No rounded corners > 8px
|
|
170
|
+
- No web-UI card shadows
|
|
171
|
+
- No centered-everything layouts
|
|
172
|
+
- No Inter, Roboto, or banned fonts
|
|
173
|
+
- No pure #000 or #fff
|
package/video/design.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: getraw
|
|
3
|
+
colors:
|
|
4
|
+
primary: "#0c0c0f"
|
|
5
|
+
on-primary: "#e8e8ec"
|
|
6
|
+
accent: "#00ff88"
|
|
7
|
+
accent-dim: "#00cc6a"
|
|
8
|
+
surface: "#161620"
|
|
9
|
+
surface-border: "#2a2a3a"
|
|
10
|
+
muted: "#6b6b80"
|
|
11
|
+
typography:
|
|
12
|
+
headline:
|
|
13
|
+
fontFamily: Space Grotesk
|
|
14
|
+
fontSize: 5rem
|
|
15
|
+
fontWeight: 700
|
|
16
|
+
letterSpacing: -0.03em
|
|
17
|
+
body:
|
|
18
|
+
fontFamily: JetBrains Mono
|
|
19
|
+
fontSize: 1.5rem
|
|
20
|
+
fontWeight: 400
|
|
21
|
+
label:
|
|
22
|
+
fontFamily: JetBrains Mono
|
|
23
|
+
fontSize: 0.875rem
|
|
24
|
+
fontWeight: 500
|
|
25
|
+
textTransform: uppercase
|
|
26
|
+
letterSpacing: 0.08em
|
|
27
|
+
rounded:
|
|
28
|
+
none: 0px
|
|
29
|
+
sm: 4px
|
|
30
|
+
md: 8px
|
|
31
|
+
spacing:
|
|
32
|
+
sm: 8px
|
|
33
|
+
md: 16px
|
|
34
|
+
lg: 40px
|
|
35
|
+
motion:
|
|
36
|
+
energy: high
|
|
37
|
+
easing:
|
|
38
|
+
entry: "expo.out"
|
|
39
|
+
exit: "power3.in"
|
|
40
|
+
ambient: "sine.inOut"
|
|
41
|
+
duration:
|
|
42
|
+
entrance: 0.4
|
|
43
|
+
hold: 1.8
|
|
44
|
+
transition: 0.4
|
|
45
|
+
atmosphere:
|
|
46
|
+
- terminal-cursor
|
|
47
|
+
- scan-lines
|
|
48
|
+
- grid-dots
|
|
49
|
+
transition: glitch
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Overview
|
|
53
|
+
|
|
54
|
+
getraw is a fast media downloader CLI built in Bun/TypeScript — a yt-dlp replacement with native JS execution. The visual identity is terminal-native: dark background, green accent (terminal green), monospace type for code, and sharp geometric motion. Feels like watching a hacker tool come alive.
|
|
55
|
+
|
|
56
|
+
## Colors
|
|
57
|
+
|
|
58
|
+
- **Primary (#0c0c0f):** Near-black background with slight blue undertone
|
|
59
|
+
- **On-primary (#e8e8ec):** Off-white text, not pure white
|
|
60
|
+
- **Accent (#00ff88):** Terminal green — the signature color. Used for highlights, commands, active states
|
|
61
|
+
- **Surface (#161620):** Slightly elevated panels, code blocks
|
|
62
|
+
- **Muted (#6b6b80):** Comments, secondary info
|
|
63
|
+
|
|
64
|
+
## Typography
|
|
65
|
+
|
|
66
|
+
- **Headlines:** Space Grotesk 700 — geometric, techy, not generic
|
|
67
|
+
- **Code/Body:** JetBrains Mono 400 — the developer's monospace
|
|
68
|
+
- **Labels:** JetBrains Mono 500 uppercase — structural metadata
|
|
69
|
+
|
|
70
|
+
## Do's and Don'ts
|
|
71
|
+
|
|
72
|
+
### Do
|
|
73
|
+
- Use terminal-style animations (typing effect, cursor blink, line-by-line reveal)
|
|
74
|
+
- Show real CLI commands and output
|
|
75
|
+
- Use the green accent sparingly but boldly
|
|
76
|
+
- Let the dark background breathe
|
|
77
|
+
|
|
78
|
+
### Don't
|
|
79
|
+
- Use gradients on text
|
|
80
|
+
- Use rounded corners larger than 8px
|
|
81
|
+
- Use decorative serif fonts
|
|
82
|
+
- Use bright colors other than the accent green
|