frostpv 1.0.8 → 1.0.10

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.
Files changed (2) hide show
  1. package/index.js +73 -25
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -58,7 +58,13 @@ const videoPlatforms = [
58
58
  "https://twitter.com",
59
59
  "https://www.twitter.com",
60
60
  "https://vm.tiktok.com/",
61
- "https://vt.tiktok.com/"
61
+ "https://vt.tiktok.com/",
62
+ "https://www.youtube.com",
63
+ "https://youtube.com",
64
+ "https://youtu.be",
65
+ "https://m.youtube.com",
66
+ "https://www.youtube.com/watch?"
67
+
62
68
  ];
63
69
 
64
70
  // Blacklist links
@@ -1145,41 +1151,83 @@ async function downloadSmartVideo(url, config) {
1145
1151
  try {
1146
1152
  const data = await youtube(url);
1147
1153
  // Try to find the video URL in the response
1148
- // Common patterns: data.url, data.mp4, data.link, or direct string
1149
1154
 
1150
1155
  if (!data) throw new Error("No data returned from youtube downloader");
1151
1156
 
1152
- // Recursive function to find a valid video URL in the object
1153
- const findVideoUrl = (obj) => {
1154
- if (!obj) return null;
1155
- if (typeof obj === 'string' && obj.startsWith('http')) return obj;
1157
+ // Helper to check if a value looks like a video URL
1158
+ const isVideoUrl = (val) => typeof val === 'string' && val.startsWith('http') && !val.includes('.mp3');
1159
+
1160
+ let bestUrl = null;
1161
+ let bestScore = -1;
1162
+
1163
+ // Function to score keys based on quality
1164
+ const getScore = (key) => {
1165
+ const k = key.toLowerCase();
1166
+ if (k.includes('1080')) return 100;
1167
+ if (k.includes('720')) return 80;
1168
+ if (k.includes('480')) return 60;
1169
+ if (k.includes('hd')) return 90;
1170
+ if (k.includes('sd')) return 50;
1171
+ if (k.includes('360')) return 40;
1172
+ if (k.includes('mp4')) return 30;
1173
+ if (k.includes('video')) return 20;
1174
+ return 10;
1175
+ };
1156
1176
 
1157
- if (Array.isArray(obj)) {
1158
- for (const item of obj) {
1159
- const found = findVideoUrl(item);
1160
- if (found) return found;
1177
+ // Recursive function to gather all candidates
1178
+ const gatherCandidates = (obj) => {
1179
+ if (!obj) return;
1180
+
1181
+ if (typeof obj === 'object') {
1182
+ for (const key in obj) {
1183
+ const val = obj[key];
1184
+ if (isVideoUrl(val)) {
1185
+ const score = getScore(key);
1186
+ if (score > bestScore) {
1187
+ bestScore = score;
1188
+ bestUrl = val;
1189
+ }
1190
+ } else if (typeof val === 'object') {
1191
+ // Check if this object represents a format (e.g. { quality: '720p', url: '...' })
1192
+ if (val.url && isVideoUrl(val.url)) {
1193
+ let score = getScore(key); // Score from key name
1194
+ if (val.quality || val.resolution) {
1195
+ score = Math.max(score, getScore(String(val.quality || val.resolution)));
1196
+ }
1197
+ if (score > bestScore) {
1198
+ bestScore = score;
1199
+ bestUrl = val.url;
1200
+ }
1201
+ }
1202
+ // Recurse
1203
+ gatherCandidates(val);
1204
+ }
1161
1205
  }
1162
- } else if (typeof obj === 'object') {
1163
- // Prioritize certain keys
1164
- const priorities = ['url', 'link', 'download', 'mp4', 'video', 'src'];
1206
+ }
1207
+ };
1208
+
1209
+ gatherCandidates(data);
1210
+
1211
+ // If no scored candidate found, try direct simple extraction with priority keys
1212
+ if (!bestUrl) {
1213
+ const priorities = ['mp4', 'url', 'link', 'download', 'video'];
1214
+ const findSimple = (obj) => {
1215
+ if (!obj) return null;
1165
1216
  for (const key of priorities) {
1166
- if (obj[key]) {
1167
- const found = findVideoUrl(obj[key]);
1168
- if (found) return found;
1169
- }
1217
+ if (obj[key] && isVideoUrl(obj[key])) return obj[key];
1170
1218
  }
1171
- // If not found in priorities, check all keys
1172
- for (const key of Object.keys(obj)) {
1173
- if (!priorities.includes(key)) {
1174
- const found = findVideoUrl(obj[key]);
1219
+ for (const key in obj) {
1220
+ if (typeof obj[key] === 'object') {
1221
+ const found = findSimple(obj[key]);
1175
1222
  if (found) return found;
1176
1223
  }
1177
1224
  }
1178
- }
1179
- return null;
1180
- };
1225
+ return null;
1226
+ };
1227
+ bestUrl = findSimple(data);
1228
+ }
1181
1229
 
1182
- videoUrl = findVideoUrl(data);
1230
+ videoUrl = bestUrl;
1183
1231
 
1184
1232
  if (!videoUrl) {
1185
1233
  console.log('YouTube data dump:', JSON.stringify(data, null, 2)); // Debug log since we can't test
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frostpv",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "downloads",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -13,7 +13,7 @@
13
13
  "license": "ISC",
14
14
  "dependencies": {
15
15
  "axios": "1.12.0",
16
- "btch-downloader": "6.0.20",
16
+ "btch-downloader": "6.0.23",
17
17
  "btch-downloader-old": "npm:btch-downloader@4.0.15",
18
18
  "express": "^5.1.0",
19
19
  "ffmpeg-ffprobe-static": "^6.1.1-rc.5",