flux-dl 1.1.3 → 1.1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flux-dl",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Leistungsstarke Video-Downloader Library für YouTube, Vimeo und Dailymotion - komplett in JavaScript, keine externen Binaries",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -5,6 +5,7 @@ const platforms = require('./platforms');
5
5
  const VideoEncryption = require('./utils/encryption');
6
6
  const RequestSpoofing = require('./utils/requestSpoofing');
7
7
  const BrowserEmulation = require('./utils/browserEmulation');
8
+ const QualityManager = require('./utils/qualityManager');
8
9
 
9
10
  class VideoDownloader {
10
11
  constructor(options = {}) {
@@ -13,17 +14,24 @@ class VideoDownloader {
13
14
  timeout: 30000,
14
15
  encryptionKey: options.encryptionKey || 'default-key',
15
16
  cookiesFile: options.cookiesFile,
17
+ quality: options.quality || 192, // Standard: Medium (192 kbps)
16
18
  ...options
17
19
  };
18
20
 
19
21
  this.encryption = new VideoEncryption(this.options.encryptionKey);
20
22
  this.spoofing = new RequestSpoofing();
21
23
  this.browser = new BrowserEmulation();
24
+ this.qualityManager = new QualityManager();
22
25
 
23
26
  // Load cookies if provided
24
27
  if (this.options.cookiesFile) {
25
28
  this.browser.cookieManager.loadFromFile(this.options.cookiesFile);
26
29
  }
30
+
31
+ // Set default quality if provided
32
+ if (options.quality) {
33
+ this.qualityManager.setDefaultQuality(options.quality);
34
+ }
27
35
  }
28
36
 
29
37
  async getVideoInfo(url) {
@@ -347,6 +355,169 @@ class VideoDownloader {
347
355
  signUrl(url, expiresIn = 3600) {
348
356
  return this.encryption.signUrl(url, expiresIn);
349
357
  }
358
+
359
+ // ========== QUALITY MANAGEMENT API ==========
360
+
361
+ /**
362
+ * Setzt die Qualität für einen bestimmten User
363
+ * @param {string} userId - User ID
364
+ * @param {number} quality - Bitrate (120-360 kbps)
365
+ * @returns {number} Gesetzte Qualität
366
+ */
367
+ setUserQuality(userId, quality) {
368
+ return this.qualityManager.setUserQuality(userId, quality);
369
+ }
370
+
371
+ /**
372
+ * Gibt die erlaubte Qualität für einen User zurück
373
+ * @param {string} userId - User ID
374
+ * @param {boolean} isPremium - Ist Premium User?
375
+ * @returns {number} Erlaubte Bitrate
376
+ */
377
+ getUserQuality(userId, isPremium = false) {
378
+ return this.qualityManager.getUserQuality(userId, isPremium);
379
+ }
380
+
381
+ /**
382
+ * Setzt globale Standard-Qualität
383
+ * @param {number} quality - Bitrate (120-360 kbps)
384
+ */
385
+ setDefaultQuality(quality) {
386
+ this.qualityManager.setDefaultQuality(quality);
387
+ this.options.quality = quality;
388
+ }
389
+
390
+ /**
391
+ * Setzt maximale Qualität für Free Users
392
+ * @param {number} quality - Bitrate (120-360 kbps)
393
+ */
394
+ setMaxQualityForFreeUsers(quality) {
395
+ this.qualityManager.setMaxQualityForFreeUsers(quality);
396
+ }
397
+
398
+ /**
399
+ * Setzt maximale Qualität für Premium Users
400
+ * @param {number} quality - Bitrate (120-360 kbps)
401
+ */
402
+ setMaxQualityForPremiumUsers(quality) {
403
+ this.qualityManager.setMaxQualityForPremiumUsers(quality);
404
+ }
405
+
406
+ /**
407
+ * Gibt verfügbare Qualitätsstufen für User zurück
408
+ * @param {string} userId - User ID
409
+ * @param {boolean} isPremium - Ist Premium User?
410
+ * @returns {Array} Verfügbare Stufen
411
+ */
412
+ getAvailableQualities(userId, isPremium = false) {
413
+ return this.qualityManager.getAvailableQualities(userId, isPremium);
414
+ }
415
+
416
+ /**
417
+ * Prüft ob User bestimmte Qualität nutzen darf
418
+ * @param {string} userId - User ID
419
+ * @param {number} requestedQuality - Gewünschte Qualität
420
+ * @param {boolean} isPremium - Ist Premium User?
421
+ * @returns {boolean} Erlaubt?
422
+ */
423
+ canUserUseQuality(userId, requestedQuality, isPremium = false) {
424
+ return this.qualityManager.canUserUseQuality(userId, requestedQuality, isPremium);
425
+ }
426
+
427
+ /**
428
+ * Download mit User-spezifischer Qualität
429
+ * @param {string} url - Video URL
430
+ * @param {string} outputPath - Output Pfad
431
+ * @param {string} userId - User ID
432
+ * @param {boolean} isPremium - Ist Premium User?
433
+ * @param {function} onProgress - Progress Callback
434
+ * @returns {Promise<Object>} Download Result
435
+ */
436
+ async downloadAudioWithQuality(url, outputPath, userId, isPremium = false, onProgress = null) {
437
+ const userQuality = this.getUserQuality(userId, isPremium);
438
+
439
+ console.log(`🎵 Downloading for user ${userId}`);
440
+ console.log(`📊 Quality: ${this.qualityManager.getQualityLabel(userQuality)}`);
441
+
442
+ // Temporär Qualität setzen
443
+ const originalQuality = this.options.quality;
444
+ this.options.quality = userQuality;
445
+
446
+ try {
447
+ const result = await this.downloadAudio(url, outputPath, onProgress);
448
+ return {
449
+ ...result,
450
+ quality: userQuality,
451
+ qualityLabel: this.qualityManager.getQualityLabel(userQuality)
452
+ };
453
+ } finally {
454
+ // Qualität zurücksetzen
455
+ this.options.quality = originalQuality;
456
+ }
457
+ }
458
+
459
+ /**
460
+ * Stream mit User-spezifischer Qualität
461
+ * @param {string} url - Video URL
462
+ * @param {string} userId - User ID
463
+ * @param {boolean} isPremium - Ist Premium User?
464
+ * @param {function} onProgress - Progress Callback
465
+ * @returns {Promise<Object>} Stream Result
466
+ */
467
+ async getAudioStreamWithQuality(url, userId, isPremium = false, onProgress = null) {
468
+ const userQuality = this.getUserQuality(userId, isPremium);
469
+
470
+ console.log(`🎵 Streaming for user ${userId}`);
471
+ console.log(`📊 Quality: ${this.qualityManager.getQualityLabel(userQuality)}`);
472
+
473
+ // Temporär Qualität setzen
474
+ const originalQuality = this.options.quality;
475
+ this.options.quality = userQuality;
476
+
477
+ try {
478
+ const result = await this.getAudioStream(url, onProgress);
479
+ return {
480
+ ...result,
481
+ quality: userQuality,
482
+ qualityLabel: this.qualityManager.getQualityLabel(userQuality)
483
+ };
484
+ } finally {
485
+ // Qualität zurücksetzen
486
+ this.options.quality = originalQuality;
487
+ }
488
+ }
489
+
490
+ /**
491
+ * Entfernt User-Permission
492
+ * @param {string} userId - User ID
493
+ */
494
+ removeUserQuality(userId) {
495
+ this.qualityManager.removeUserQuality(userId);
496
+ }
497
+
498
+ /**
499
+ * Gibt alle User-Permissions zurück
500
+ * @returns {Object} User-Permissions
501
+ */
502
+ getAllUserPermissions() {
503
+ return this.qualityManager.getAllUserPermissions();
504
+ }
505
+
506
+ /**
507
+ * Exportiert Quality-Konfiguration
508
+ * @returns {Object} Konfiguration
509
+ */
510
+ exportQualityConfig() {
511
+ return this.qualityManager.exportConfig();
512
+ }
513
+
514
+ /**
515
+ * Importiert Quality-Konfiguration
516
+ * @param {Object} config - Konfiguration
517
+ */
518
+ importQualityConfig(config) {
519
+ this.qualityManager.importConfig(config);
520
+ }
350
521
  }
351
522
 
352
523
  module.exports = VideoDownloader;
package/src/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  const VideoDownloader = require('./VideoDownloader');
2
2
  const VideoEncryption = require('./utils/encryption');
3
3
  const YouTubeSearch = require('./utils/youtubeSearch');
4
+ const QualityManager = require('./utils/qualityManager');
4
5
  const { supportedPlatforms } = require('./platforms');
5
6
 
6
7
  module.exports = {
7
8
  VideoDownloader,
8
9
  VideoEncryption,
9
10
  YouTubeSearch,
11
+ QualityManager,
10
12
  supportedPlatforms
11
13
  };
@@ -0,0 +1,270 @@
1
+ /**
2
+ * QUALITY MANAGER - Audio Bitrate Control System
3
+ * Verwaltet Audio-Qualität mit User-Permissions (120-360 kbps)
4
+ */
5
+
6
+ class QualityManager {
7
+ constructor() {
8
+ // Qualitätsstufen (in kbps für Audio)
9
+ this.QUALITY_LEVELS = {
10
+ MINIMUM: 120, // Niedrigste Qualität
11
+ LOW: 128, // Niedrig
12
+ MEDIUM: 192, // Mittel (Standard)
13
+ HIGH: 256, // Hoch
14
+ MAXIMUM: 360 // Höchste Qualität
15
+ };
16
+
17
+ // User-Permissions (wer darf welche Qualität nutzen)
18
+ this.userPermissions = new Map();
19
+
20
+ // Globale Einstellungen
21
+ this.defaultQuality = this.QUALITY_LEVELS.MEDIUM;
22
+ this.maxQualityForFreeUsers = this.QUALITY_LEVELS.MEDIUM;
23
+ this.maxQualityForPremiumUsers = this.QUALITY_LEVELS.MAXIMUM;
24
+ }
25
+
26
+ /**
27
+ * Setzt die erlaubte Qualität für einen User
28
+ * @param {string} userId - User ID
29
+ * @param {number} maxQuality - Maximale Bitrate (120-360)
30
+ */
31
+ setUserQuality(userId, maxQuality) {
32
+ const quality = this.validateQuality(maxQuality);
33
+ this.userPermissions.set(userId, quality);
34
+ return quality;
35
+ }
36
+
37
+ /**
38
+ * Gibt die erlaubte Qualität für einen User zurück
39
+ * @param {string} userId - User ID
40
+ * @param {boolean} isPremium - Ist der User Premium?
41
+ * @returns {number} Erlaubte Bitrate
42
+ */
43
+ getUserQuality(userId, isPremium = false) {
44
+ // Wenn User spezifische Permission hat
45
+ if (this.userPermissions.has(userId)) {
46
+ return this.userPermissions.get(userId);
47
+ }
48
+
49
+ // Sonst nach Premium-Status
50
+ return isPremium ? this.maxQualityForPremiumUsers : this.maxQualityForFreeUsers;
51
+ }
52
+
53
+ /**
54
+ * Validiert und begrenzt Qualitätswert
55
+ * @param {number} quality - Gewünschte Bitrate
56
+ * @returns {number} Validierte Bitrate (120-360)
57
+ */
58
+ validateQuality(quality) {
59
+ const q = parseInt(quality);
60
+
61
+ if (isNaN(q)) {
62
+ return this.defaultQuality;
63
+ }
64
+
65
+ // Begrenze auf Min/Max
66
+ if (q < this.QUALITY_LEVELS.MINIMUM) {
67
+ return this.QUALITY_LEVELS.MINIMUM;
68
+ }
69
+
70
+ if (q > this.QUALITY_LEVELS.MAXIMUM) {
71
+ return this.QUALITY_LEVELS.MAXIMUM;
72
+ }
73
+
74
+ return q;
75
+ }
76
+
77
+ /**
78
+ * Wählt das beste Audio-Format basierend auf Qualitätseinstellung
79
+ * @param {Array} formats - Verfügbare Formate
80
+ * @param {number} targetQuality - Ziel-Bitrate
81
+ * @returns {Object} Bestes Format
82
+ */
83
+ selectBestAudioFormat(formats, targetQuality) {
84
+ // Nur Audio-Formate
85
+ const audioFormats = formats.filter(f =>
86
+ f.mimeType && f.mimeType.includes('audio') && f.url
87
+ );
88
+
89
+ if (audioFormats.length === 0) return null;
90
+
91
+ // Sortiere nach Bitrate
92
+ audioFormats.sort((a, b) => {
93
+ const bitrateA = this.getBitrate(a);
94
+ const bitrateB = this.getBitrate(b);
95
+ return Math.abs(bitrateA - targetQuality) - Math.abs(bitrateB - targetQuality);
96
+ });
97
+
98
+ // Finde Format das am nächsten zur Ziel-Qualität ist
99
+ let bestFormat = audioFormats[0];
100
+
101
+ for (const format of audioFormats) {
102
+ const bitrate = this.getBitrate(format);
103
+
104
+ // Wenn Format unter Ziel-Qualität liegt, nehme es
105
+ if (bitrate <= targetQuality && bitrate > this.getBitrate(bestFormat)) {
106
+ bestFormat = format;
107
+ }
108
+ }
109
+
110
+ return bestFormat;
111
+ }
112
+
113
+ /**
114
+ * Extrahiert Bitrate aus Format
115
+ * @param {Object} format - Format-Objekt
116
+ * @returns {number} Bitrate in kbps
117
+ */
118
+ getBitrate(format) {
119
+ if (format.bitrate) {
120
+ return Math.round(format.bitrate / 1000); // Bits zu kbps
121
+ }
122
+
123
+ if (format.audioBitrate) {
124
+ return format.audioBitrate;
125
+ }
126
+
127
+ // Fallback: Schätze aus Quality-Label
128
+ if (format.qualityLabel) {
129
+ const match = format.qualityLabel.match(/(\d+)kbps/i);
130
+ if (match) {
131
+ return parseInt(match[1]);
132
+ }
133
+ }
134
+
135
+ // Default: Mittel
136
+ return this.QUALITY_LEVELS.MEDIUM;
137
+ }
138
+
139
+ /**
140
+ * Gibt Qualitäts-Label zurück
141
+ * @param {number} bitrate - Bitrate in kbps
142
+ * @returns {string} Label
143
+ */
144
+ getQualityLabel(bitrate) {
145
+ if (bitrate >= this.QUALITY_LEVELS.MAXIMUM) return '🔥 Maximum (360 kbps)';
146
+ if (bitrate >= this.QUALITY_LEVELS.HIGH) return '⭐ High (256 kbps)';
147
+ if (bitrate >= this.QUALITY_LEVELS.MEDIUM) return '✅ Medium (192 kbps)';
148
+ if (bitrate >= this.QUALITY_LEVELS.LOW) return '📊 Low (128 kbps)';
149
+ return '💾 Minimum (120 kbps)';
150
+ }
151
+
152
+ /**
153
+ * Setzt globale Standard-Qualität
154
+ * @param {number} quality - Bitrate (120-360)
155
+ */
156
+ setDefaultQuality(quality) {
157
+ this.defaultQuality = this.validateQuality(quality);
158
+ }
159
+
160
+ /**
161
+ * Setzt maximale Qualität für Free Users
162
+ * @param {number} quality - Bitrate (120-360)
163
+ */
164
+ setMaxQualityForFreeUsers(quality) {
165
+ this.maxQualityForFreeUsers = this.validateQuality(quality);
166
+ }
167
+
168
+ /**
169
+ * Setzt maximale Qualität für Premium Users
170
+ * @param {number} quality - Bitrate (120-360)
171
+ */
172
+ setMaxQualityForPremiumUsers(quality) {
173
+ this.maxQualityForPremiumUsers = this.validateQuality(quality);
174
+ }
175
+
176
+ /**
177
+ * Entfernt User-Permission
178
+ * @param {string} userId - User ID
179
+ */
180
+ removeUserQuality(userId) {
181
+ this.userPermissions.delete(userId);
182
+ }
183
+
184
+ /**
185
+ * Gibt alle User-Permissions zurück
186
+ * @returns {Object} User-Permissions
187
+ */
188
+ getAllUserPermissions() {
189
+ const permissions = {};
190
+ for (const [userId, quality] of this.userPermissions.entries()) {
191
+ permissions[userId] = {
192
+ quality,
193
+ label: this.getQualityLabel(quality)
194
+ };
195
+ }
196
+ return permissions;
197
+ }
198
+
199
+ /**
200
+ * Prüft ob User bestimmte Qualität nutzen darf
201
+ * @param {string} userId - User ID
202
+ * @param {number} requestedQuality - Gewünschte Qualität
203
+ * @param {boolean} isPremium - Ist Premium User?
204
+ * @returns {boolean} Erlaubt?
205
+ */
206
+ canUserUseQuality(userId, requestedQuality, isPremium = false) {
207
+ const maxAllowed = this.getUserQuality(userId, isPremium);
208
+ return requestedQuality <= maxAllowed;
209
+ }
210
+
211
+ /**
212
+ * Gibt verfügbare Qualitätsstufen für User zurück
213
+ * @param {string} userId - User ID
214
+ * @param {boolean} isPremium - Ist Premium User?
215
+ * @returns {Array} Verfügbare Stufen
216
+ */
217
+ getAvailableQualities(userId, isPremium = false) {
218
+ const maxQuality = this.getUserQuality(userId, isPremium);
219
+ const available = [];
220
+
221
+ for (const [name, value] of Object.entries(this.QUALITY_LEVELS)) {
222
+ if (value <= maxQuality) {
223
+ available.push({
224
+ name,
225
+ value,
226
+ label: this.getQualityLabel(value)
227
+ });
228
+ }
229
+ }
230
+
231
+ return available;
232
+ }
233
+
234
+ /**
235
+ * Exportiert Konfiguration
236
+ * @returns {Object} Konfiguration
237
+ */
238
+ exportConfig() {
239
+ return {
240
+ defaultQuality: this.defaultQuality,
241
+ maxQualityForFreeUsers: this.maxQualityForFreeUsers,
242
+ maxQualityForPremiumUsers: this.maxQualityForPremiumUsers,
243
+ userPermissions: Object.fromEntries(this.userPermissions)
244
+ };
245
+ }
246
+
247
+ /**
248
+ * Importiert Konfiguration
249
+ * @param {Object} config - Konfiguration
250
+ */
251
+ importConfig(config) {
252
+ if (config.defaultQuality) {
253
+ this.defaultQuality = this.validateQuality(config.defaultQuality);
254
+ }
255
+
256
+ if (config.maxQualityForFreeUsers) {
257
+ this.maxQualityForFreeUsers = this.validateQuality(config.maxQualityForFreeUsers);
258
+ }
259
+
260
+ if (config.maxQualityForPremiumUsers) {
261
+ this.maxQualityForPremiumUsers = this.validateQuality(config.maxQualityForPremiumUsers);
262
+ }
263
+
264
+ if (config.userPermissions) {
265
+ this.userPermissions = new Map(Object.entries(config.userPermissions));
266
+ }
267
+ }
268
+ }
269
+
270
+ module.exports = QualityManager;