@lmna22/aio-downloader 1.0.1

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/README.md ADDED
@@ -0,0 +1,416 @@
1
+ # @lmna22/aio-downloader
2
+
3
+ > All-in-one media downloader for YouTube, Instagram, TikTok, Pinterest, Pixiv, and X/Twitter.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@lmna22/aio-downloader.svg)](https://www.npmjs.com/package/@lmna22/aio-downloader)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D14.0.0-brightgreen.svg)](https://nodejs.org/)
8
+
9
+ Scrape and download videos, audio, and images from multiple platforms with a single, unified API. No API keys required.
10
+
11
+ ---
12
+
13
+ ## ✨ Features
14
+
15
+ | Platform | Video | Audio | Image | Search |
16
+ |---|---|---|---|---|
17
+ | **YouTube** | ✅ (Multiple qualities) | ✅ (MP3) | — | — |
18
+ | **Instagram** | ✅ | — | ✅ | — |
19
+ | **TikTok** | ✅ (Buffer) | ✅ | — | — |
20
+ | **Pinterest** | — | — | ✅ | ✅ |
21
+ | **Pixiv** | — | — | ✅ (Original Resolution) | ✅ |
22
+ | **X / Twitter** | ✅ (Best quality) | — | ✅ | — |
23
+
24
+ - 🔗 **Auto-detect platform** from URL — just pass any supported link
25
+ - 📦 **Programmatic API** — designed for Node.js applications, bots, and scripts
26
+ - 📥 **Built-in download helper** with progress callback
27
+ - 🔍 **Search support** for Pinterest and Pixiv (pass keywords instead of URLs)
28
+ - 🚫 **No API keys** — all data is scraped from public sources
29
+ - 🔄 **Multi-method fallback** — Instagram uses 4 different methods for maximum reliability
30
+ - 🎬 **YouTube quality selection** — choose from 144p to 2160p, or audio-only MP3
31
+
32
+ ---
33
+
34
+ ## 📦 Installation
35
+
36
+ ```bash
37
+ npm install @lmna22/aio-downloader
38
+ ```
39
+
40
+ All required dependencies are bundled and will be installed automatically.
41
+
42
+ **Optional:** For Pinterest/Pixiv fallback when axios scraping is blocked:
43
+
44
+ ```bash
45
+ npm install puppeteer
46
+ ```
47
+
48
+ ---
49
+
50
+ ## 🚀 Quick Start
51
+
52
+ ```javascript
53
+ const { aioDownloader } = require("@lmna22/aio-downloader");
54
+
55
+ // Auto-detects the platform from the URL
56
+ const result = await aioDownloader("https://www.youtube.com/watch?v=dQw4w9WgXcQ", { quality: 5 });
57
+ console.log(result);
58
+ ```
59
+
60
+ ---
61
+
62
+ ## 📖 Usage Examples
63
+
64
+ ### YouTube
65
+
66
+ ```javascript
67
+ const { youtubeDownloader, youtubePlaylistDownloader } = require("@lmna22/aio-downloader");
68
+
69
+ // Quality options:
70
+ // 1 = 144p, 2 = 360p, 3 = 480p, 4 = 720p,
71
+ // 5 = 1080p, 6 = 1440p, 7 = 2160p,
72
+ // 8 = Audio only (MP3), 9 = Get bitrate list
73
+
74
+ // Download a video in 1080p
75
+ const result = await youtubeDownloader("https://www.youtube.com/watch?v=dQw4w9WgXcQ", 5);
76
+
77
+ if (result.status) {
78
+ console.log(result.data.title); // "Rick Astley - Never Gonna Give You Up"
79
+ console.log(result.data.channel); // "Rick Astley"
80
+ console.log(result.data.views); // 1500000000
81
+ console.log(result.data.size); // Buffer size in bytes
82
+ console.log(result.data.type); // "mp4" or "mp3"
83
+
84
+ // Save to file
85
+ const fs = require("fs");
86
+ fs.writeFileSync(`${result.data.title}.${result.data.type}`, result.data.result);
87
+ }
88
+
89
+ // Download audio only
90
+ const audio = await youtubeDownloader("https://www.youtube.com/watch?v=dQw4w9WgXcQ", 8);
91
+
92
+ // Get available audio bitrates
93
+ const bitrates = await youtubeDownloader("https://www.youtube.com/watch?v=dQw4w9WgXcQ", 9);
94
+ console.log(bitrates.data.bitrateList);
95
+
96
+ // Download entire playlist
97
+ const playlist = await youtubePlaylistDownloader(
98
+ "https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf",
99
+ 5, // quality
100
+ "./my-playlist" // output folder
101
+ );
102
+ ```
103
+
104
+ ### Instagram
105
+
106
+ ```javascript
107
+ const { instagramDownloader } = require("@lmna22/aio-downloader");
108
+
109
+ const result = await instagramDownloader("https://www.instagram.com/p/ABC123/");
110
+
111
+ if (result.status) {
112
+ console.log(result.data.url); // Array of download URLs
113
+ console.log(result.data.caption); // Post caption
114
+ console.log(result.data.username); // "@username"
115
+ console.log(result.data.like); // Like count
116
+ console.log(result.data.comment); // Comment count
117
+ console.log(result.data.isVideo); // true/false
118
+
119
+ // Download all media
120
+ const { download } = require("@lmna22/aio-downloader");
121
+ for (let i = 0; i < result.data.url.length; i++) {
122
+ await download(result.data.url[i], `./downloads/ig_${i + 1}.mp4`);
123
+ }
124
+ }
125
+ ```
126
+
127
+ ### TikTok
128
+
129
+ ```javascript
130
+ const { tiktokDownloader } = require("@lmna22/aio-downloader");
131
+
132
+ const result = await tiktokDownloader("https://www.tiktok.com/@user/video/1234567890");
133
+
134
+ if (result.status) {
135
+ const data = result.data;
136
+
137
+ console.log(data.description); // Video description
138
+ console.log(data.author.nickname); // Author name
139
+ console.log(data.author.uniqueId); // @username
140
+ console.log(data.stats.likes); // Like count
141
+ console.log(data.stats.comments); // Comment count
142
+ console.log(data.stats.plays); // Play count
143
+ console.log(data.music.title); // Music title
144
+ console.log(data.videoInfo.duration); // Duration in seconds
145
+ console.log(data.videoInfo.width); // Video width
146
+ console.log(data.videoInfo.height); // Video height
147
+
148
+ // Video is returned as a Buffer — save directly
149
+ if (data.videoBuffer) {
150
+ const fs = require("fs");
151
+ fs.writeFileSync("tiktok_video.mp4", data.videoBuffer);
152
+ }
153
+ }
154
+ ```
155
+
156
+ ### Pinterest
157
+
158
+ ```javascript
159
+ const { pinterestDownloader } = require("@lmna22/aio-downloader");
160
+
161
+ // From a direct pin URL
162
+ const data = await pinterestDownloader("https://www.pinterest.com/pin/123456789/");
163
+
164
+ // Or search by keyword
165
+ const searchResults = await pinterestDownloader("aesthetic wallpaper", { limit: 20 });
166
+
167
+ console.log(data.results);
168
+ // [
169
+ // {
170
+ // id: "123456789",
171
+ // title: "Beautiful Wallpaper",
172
+ // link: "https://www.pinterest.com/pin/123456789/",
173
+ // image: "https://i.pinimg.com/originals/...",
174
+ // source: "example.com"
175
+ // }
176
+ // ]
177
+ ```
178
+
179
+ ### Pixiv
180
+
181
+ ```javascript
182
+ const { pixivDownloader } = require("@lmna22/aio-downloader");
183
+
184
+ // From an artwork URL
185
+ const data = await pixivDownloader("https://www.pixiv.net/artworks/12345678");
186
+
187
+ // Or search by tag/keyword
188
+ const searchResults = await pixivDownloader("landscape", { limit: 5 });
189
+
190
+ console.log(data.results);
191
+ // [
192
+ // {
193
+ // id: "12345678",
194
+ // title: "Beautiful Landscape",
195
+ // link: "https://www.pixiv.net/artworks/12345678",
196
+ // image: "https://i.pximg.net/img-original/...",
197
+ // artist: "ArtistName",
198
+ // artistUrl: "https://www.pixiv.net/users/999",
199
+ // userId: "999",
200
+ // images: ["https://i.pximg.net/img-original/..."]
201
+ // }
202
+ // ]
203
+
204
+ // Skip enrichment for faster results (no original resolution images)
205
+ const fast = await pixivDownloader("landscape", { limit: 10, enrich: false });
206
+ ```
207
+
208
+ ### X / Twitter
209
+
210
+ ```javascript
211
+ const { twitterDownloader } = require("@lmna22/aio-downloader");
212
+
213
+ const result = await twitterDownloader("https://x.com/user/status/1234567890");
214
+
215
+ if (result.status) {
216
+ console.log(result.data.author); // "username"
217
+ console.log(result.data.description); // Tweet text
218
+ console.log(result.data.like); // Like count
219
+ console.log(result.data.view); // View count
220
+ console.log(result.data.retweet); // Retweet count
221
+ console.log(result.data.sensitiveContent); // true/false
222
+
223
+ // result.data.result contains media items:
224
+ // [
225
+ // { type: "video", thumb: "https://...", url: "https://..." },
226
+ // { type: "image", url: "https://...?format=png&name=large" },
227
+ // { type: "gif", thumb: "https://...", url: "https://..." }
228
+ // ]
229
+
230
+ // Download all media
231
+ const { download } = require("@lmna22/aio-downloader");
232
+ for (let i = 0; i < result.data.result.length; i++) {
233
+ const media = result.data.result[i];
234
+ const ext = media.type === "image" ? ".png" : ".mp4";
235
+ await download(media.url, `./downloads/tweet_${i + 1}${ext}`);
236
+ }
237
+ }
238
+ ```
239
+
240
+ ---
241
+
242
+ ## 📥 Download Helper
243
+
244
+ Use the built-in `download` helper to save files to disk:
245
+
246
+ ```javascript
247
+ const { download } = require("@lmna22/aio-downloader");
248
+
249
+ // Download with progress tracking
250
+ const result = await download("https://example.com/video.mp4", "./downloads/video.mp4", {
251
+ onProgress: ({ downloaded, total, percentage }) => {
252
+ console.log(`${percentage}% - ${downloaded}/${total} bytes`);
253
+ },
254
+ });
255
+
256
+ console.log(result);
257
+ // { path: "./downloads/video.mp4", size: 26345678, filename: "video.mp4" }
258
+ ```
259
+
260
+ ---
261
+
262
+ ## 🌐 Auto-detect Platform
263
+
264
+ ```javascript
265
+ const { aioDownloader, detectPlatform } = require("@lmna22/aio-downloader");
266
+
267
+ // Auto-detect and scrape
268
+ await aioDownloader("https://www.youtube.com/watch?v=abc123", { quality: 5 });
269
+ await aioDownloader("https://www.instagram.com/p/xyz/");
270
+ await aioDownloader("https://www.tiktok.com/@user/video/123");
271
+ await aioDownloader("https://www.pinterest.com/pin/456/");
272
+ await aioDownloader("https://www.pixiv.net/artworks/789");
273
+ await aioDownloader("https://x.com/user/status/101112");
274
+
275
+ // Force a specific platform
276
+ await aioDownloader("https://example.com/video", { platform: "youtube", quality: 5 });
277
+
278
+ // Detect platform only
279
+ detectPlatform("https://youtube.com/watch?v=abc"); // "youtube"
280
+ detectPlatform("https://instagram.com/p/xyz"); // "instagram"
281
+ detectPlatform("https://tiktok.com/@user/video/1"); // "tiktok"
282
+ detectPlatform("https://pinterest.com/pin/123"); // "pinterest"
283
+ detectPlatform("https://pixiv.net/artworks/456"); // "pixiv"
284
+ detectPlatform("https://x.com/user/status/789"); // "twitter"
285
+ detectPlatform("https://unknown.com"); // null
286
+ ```
287
+
288
+ ---
289
+
290
+ ## 📚 API Reference
291
+
292
+ ### `aioDownloader(url, options?)`
293
+
294
+ Auto-detect platform and scrape media data.
295
+
296
+ | Parameter | Type | Description |
297
+ |---|---|---|
298
+ | `url` | `string` | The URL to scrape |
299
+ | `options.platform` | `string` | Force a specific platform |
300
+ | `options.quality` | `number` | YouTube quality (1-9) |
301
+
302
+ ---
303
+
304
+ ### `youtubeDownloader(url, quality)`
305
+
306
+ | Parameter | Type | Description |
307
+ |---|---|---|
308
+ | `url` | `string` | YouTube video URL |
309
+ | `quality` | `number` | 1=144p, 2=360p, 3=480p, 4=720p, 5=1080p, 6=1440p, 7=2160p, 8=MP3, 9=bitrate list |
310
+
311
+ **Returns:** `{ creator, status, data: { title, result (Buffer), size, quality, desc, views, likes, channel, uploadDate, thumb, type } }`
312
+
313
+ ---
314
+
315
+ ### `youtubePlaylistDownloader(url, quality, folderPath?)`
316
+
317
+ Downloads all videos from a YouTube playlist.
318
+
319
+ **Returns:** `{ creator, status, data: { title, resultPath[], metadata[] } }`
320
+
321
+ ---
322
+
323
+ ### `instagramDownloader(url)`
324
+
325
+ Uses 4 fallback methods for maximum reliability.
326
+
327
+ **Returns:** `{ creator, status, data: { url[], caption, username, like, comment, isVideo } }`
328
+
329
+ ---
330
+
331
+ ### `tiktokDownloader(url)`
332
+
333
+ Returns video as a Buffer (no watermark).
334
+
335
+ **Returns:** `{ creator, status, data: { videoId, description, videoUrl, videoBuffer (Buffer), videoInfo, author, music, stats, locationCreated } }`
336
+
337
+ ---
338
+
339
+ ### `pinterestDownloader(input, options?)`
340
+
341
+ | Parameter | Type | Description |
342
+ |---|---|---|
343
+ | `input` | `string` | Pin URL or search keyword |
344
+ | `options.limit` | `number` | Max results for search (default: 10) |
345
+
346
+ **Returns:** `{ status, platform, method, total, results: [{ id, title, link, image, source }] }`
347
+
348
+ ---
349
+
350
+ ### `pixivDownloader(input, options?)`
351
+
352
+ | Parameter | Type | Description |
353
+ |---|---|---|
354
+ | `input` | `string` | Artwork URL or search keyword |
355
+ | `options.limit` | `number` | Max results (default: 10) |
356
+ | `options.enrich` | `boolean` | Fetch original resolution images (default: true) |
357
+
358
+ **Returns:** `{ status, platform, method, total, results: [{ id, title, link, image, artist, artistUrl, userId, images[] }] }`
359
+
360
+ ---
361
+
362
+ ### `twitterDownloader(url)`
363
+
364
+ Extracts best quality video/image/gif from tweets via Twitter GraphQL API.
365
+
366
+ **Returns:** `{ creator, status, data: { author, like, view, retweet, description, sensitiveContent, result: [{ type, url, thumb? }] } }`
367
+
368
+ ---
369
+
370
+ ### `download(url, outputPath, options?)`
371
+
372
+ Helper to download any file to disk.
373
+
374
+ | Parameter | Type | Description |
375
+ |---|---|---|
376
+ | `url` | `string` | Direct download URL |
377
+ | `outputPath` | `string` | Local file path |
378
+ | `options.headers` | `object` | Custom request headers |
379
+ | `options.timeout` | `number` | Timeout in ms (default: 120000) |
380
+ | `options.onProgress` | `function` | `({ downloaded, total, percentage })` |
381
+
382
+ **Returns:** `{ path, size, filename }`
383
+
384
+ ---
385
+
386
+ ### `detectPlatform(url)`
387
+
388
+ **Returns:** `"youtube"` | `"instagram"` | `"tiktok"` | `"pinterest"` | `"pixiv"` | `"twitter"` | `null`
389
+
390
+ ---
391
+
392
+ ## ⚠️ Error Handling
393
+
394
+ All functions return `{ status: false, message: "..." }` on failure:
395
+
396
+ ```javascript
397
+ const { youtubeDownloader } = require("@lmna22/aio-downloader");
398
+
399
+ const result = await youtubeDownloader("https://www.youtube.com/watch?v=invalid", 5);
400
+ if (!result.status) {
401
+ console.error("Failed:", result.message);
402
+ }
403
+ ```
404
+
405
+ ---
406
+
407
+ ## 📋 Requirements
408
+
409
+ - **Node.js** >= 14.0.0
410
+ - **puppeteer** (optional) — fallback for Pinterest/Pixiv when axios scraping is blocked
411
+
412
+ ---
413
+
414
+ ## 📄 License
415
+
416
+ MIT
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@lmna22/aio-downloader",
3
+ "version": "1.0.1",
4
+ "description": "All-in-one media downloader for YouTube, Instagram, TikTok, Pinterest, Pixiv, and X/Twitter. Scrape and download videos, audio, and images from multiple platforms with a single library.",
5
+ "main": "src/index.js",
6
+ "scripts": {
7
+ "test": "node -e \"const aio = require('./src/index.js'); console.log('Exports:', Object.keys(aio)); console.log('Platform detection:', aio.detectPlatform('https://youtube.com/watch?v=test'));\""
8
+ },
9
+ "keywords": [
10
+ "downloader",
11
+ "youtube",
12
+ "instagram",
13
+ "tiktok",
14
+ "pinterest",
15
+ "pixiv",
16
+ "twitter",
17
+ "x",
18
+ "video",
19
+ "audio",
20
+ "image",
21
+ "media",
22
+ "scraper",
23
+ "aio"
24
+ ],
25
+ "author": "",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": ""
30
+ },
31
+ "dependencies": {
32
+ "axios": "^1.7.0",
33
+ "axios-cookiejar-support": "^5.0.0",
34
+ "cheerio": "^1.0.0",
35
+ "ffmpeg-static": "^5.0.0",
36
+ "qs": "^6.13.0",
37
+ "tough-cookie": "^5.1.0",
38
+ "youtube-dl-exec": "^3.0.0"
39
+ },
40
+ "peerDependencies": {
41
+ "puppeteer": ">=20.0.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "puppeteer": {
45
+ "optional": true
46
+ }
47
+ },
48
+ "engines": {
49
+ "node": ">=14.0.0"
50
+ }
51
+ }
@@ -0,0 +1,53 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const axios = require("axios");
4
+ const { DEFAULT_UA } = require("./utils");
5
+
6
+ async function download(url, outputPath, options = {}) {
7
+ const dir = path.dirname(outputPath);
8
+ if (!fs.existsSync(dir)) {
9
+ fs.mkdirSync(dir, { recursive: true });
10
+ }
11
+
12
+ const res = await axios.get(url, {
13
+ responseType: "stream",
14
+ headers: {
15
+ "User-Agent": DEFAULT_UA,
16
+ ...options.headers,
17
+ },
18
+ timeout: options.timeout || 120000,
19
+ });
20
+
21
+ const totalBytes = parseInt(res.headers["content-length"] || "0", 10);
22
+ let downloadedBytes = 0;
23
+
24
+ if (options.onProgress && typeof options.onProgress === "function") {
25
+ res.data.on("data", (chunk) => {
26
+ downloadedBytes += chunk.length;
27
+ options.onProgress({
28
+ downloaded: downloadedBytes,
29
+ total: totalBytes,
30
+ percentage: totalBytes > 0 ? Math.round((downloadedBytes / totalBytes) * 100) : 0,
31
+ });
32
+ });
33
+ }
34
+
35
+ return new Promise((resolve, reject) => {
36
+ const writer = fs.createWriteStream(outputPath);
37
+ res.data.pipe(writer);
38
+
39
+ writer.on("finish", () => {
40
+ const stats = fs.statSync(outputPath);
41
+ resolve({
42
+ path: outputPath,
43
+ size: stats.size,
44
+ filename: path.basename(outputPath),
45
+ });
46
+ });
47
+
48
+ writer.on("error", reject);
49
+ res.data.on("error", reject);
50
+ });
51
+ }
52
+
53
+ module.exports = download;
package/src/index.js ADDED
@@ -0,0 +1,62 @@
1
+ const { youtubeDownloader, youtubePlaylistDownloader } = require("./lib/youtube");
2
+ const instagramDownloader = require("./lib/instagram");
3
+ const tiktokDownloader = require("./lib/tiktok");
4
+ const pinterestDownloader = require("./lib/pinterest");
5
+ const pixivDownloader = require("./lib/pixiv");
6
+ const twitterDownloader = require("./lib/twitter");
7
+ const download = require("./download");
8
+
9
+ const PLATFORM_PATTERNS = [
10
+ { name: "youtube", test: (url) => /(?:youtube\.com\/watch|youtu\.be\/|youtube\.com\/shorts|youtube\.com\/playlist)/i.test(url) },
11
+ { name: "instagram", test: (url) => /instagram\.com\//i.test(url) },
12
+ { name: "tiktok", test: (url) => /tiktok\.com\//i.test(url) },
13
+ { name: "pinterest", test: (url) => /pinterest\./i.test(url) },
14
+ { name: "pixiv", test: (url) => /pixiv\.net\//i.test(url) },
15
+ { name: "twitter", test: (url) => /(?:twitter\.com\/|x\.com\/)/i.test(url) },
16
+ ];
17
+
18
+ function detectPlatform(url) {
19
+ for (const p of PLATFORM_PATTERNS) {
20
+ if (p.test(url)) return p.name;
21
+ }
22
+ return null;
23
+ }
24
+
25
+ const scrapers = {
26
+ youtube: (url, options) => youtubeDownloader(url, options?.quality),
27
+ instagram: (url) => instagramDownloader(url),
28
+ tiktok: (url) => tiktokDownloader(url),
29
+ pinterest: (url, options) => pinterestDownloader(url, options),
30
+ pixiv: (url, options) => pixivDownloader(url, options),
31
+ twitter: (url) => twitterDownloader(url),
32
+ };
33
+
34
+ async function aioDownloader(url, options = {}) {
35
+ const platform = options.platform || detectPlatform(url);
36
+
37
+ if (!platform) {
38
+ throw new Error(
39
+ `Unsupported or unrecognized URL: ${url}. Supported platforms: YouTube, Instagram, TikTok, Pinterest, Pixiv, X/Twitter.`
40
+ );
41
+ }
42
+
43
+ const scraper = scrapers[platform];
44
+ if (!scraper) {
45
+ throw new Error(`No scraper found for platform: ${platform}`);
46
+ }
47
+
48
+ return scraper(url, options);
49
+ }
50
+
51
+ module.exports = {
52
+ aioDownloader,
53
+ detectPlatform,
54
+ download,
55
+ youtubeDownloader,
56
+ youtubePlaylistDownloader,
57
+ instagramDownloader,
58
+ tiktokDownloader,
59
+ pinterestDownloader,
60
+ pixivDownloader,
61
+ twitterDownloader,
62
+ };