fullpwerr commited on
Commit
3ed6900
·
1 Parent(s): 16bd39e
Files changed (10) hide show
  1. lib/fb.js +2 -2
  2. lib/ig.js +1 -1
  3. lib/kuaishou.js +1 -1
  4. lib/qqm.js +1 -1
  5. lib/skrep.js +1 -1
  6. lib/snapchat.js +1 -1
  7. lib/soundcloud.js +1 -1
  8. lib/spotify.js +1 -1
  9. lib/twt.js +1 -1
  10. lib/ytdl.js +33 -56
lib/fb.js CHANGED
@@ -79,10 +79,10 @@ async function fbdl(url) {
79
  return { status: 200, title: "", thumbnail, video }
80
  } catch (e) {
81
  if (!(e instanceof SyntaxError)) throw e
82
- return { status: 401, error: true, message: eval(js.split(" = ")[1]) }
83
  }
84
  } catch (error) {
85
- return { status: 401, error: true, message: "Failed to fetch data" }
86
  }
87
  }
88
 
 
79
  return { status: 200, title: "", thumbnail, video }
80
  } catch (e) {
81
  if (!(e instanceof SyntaxError)) throw e
82
+ return { status: 500, error: true, message: eval(js.split(" = ")[1]) }
83
  }
84
  } catch (error) {
85
+ return { status: 500, error: true, message: "Failed to fetch data" }
86
  }
87
  }
88
 
lib/ig.js CHANGED
@@ -64,7 +64,7 @@ async function igdl(url) {
64
  return res;
65
  } catch (err) {
66
  console.error("[ERROR IG]\n\n", e);
67
- return { status: 401, message: err.message};
68
  }
69
  }
70
  module.exports = igdl;
 
64
  return res;
65
  } catch (err) {
66
  console.error("[ERROR IG]\n\n", e);
67
+ return { status: 500, message: err.message};
68
  }
69
  }
70
  module.exports = igdl;
lib/kuaishou.js CHANGED
@@ -105,7 +105,7 @@ async function validasi(url, maxRetries = 3) {
105
  console.log("Gagal, mencoba ulang...");
106
  }
107
  console.error("Scraping gagal setelah 3 kali percobaan.");
108
- return { status: 401, message: "eror"};
109
  }
110
 
111
  module.exports = validasi;
 
105
  console.log("Gagal, mencoba ulang...");
106
  }
107
  console.error("Scraping gagal setelah 3 kali percobaan.");
108
+ return { status: 500, message: "eror"};
109
  }
110
 
111
  module.exports = validasi;
lib/qqm.js CHANGED
@@ -80,7 +80,7 @@ async function getInfo(url) {
80
  }))
81
  });
82
  } catch (e) {
83
- reject({ status: 401, message: e.message});
84
  }
85
  });
86
  });
 
80
  }))
81
  });
82
  } catch (e) {
83
+ reject({ status: 500, message: e.message});
84
  }
85
  });
86
  });
lib/skrep.js CHANGED
@@ -59,7 +59,7 @@ async function ttt(link) {
59
  */
60
  return res;
61
  } catch (e) {
62
- return { status: 404, message: e.message}
63
  }
64
  }
65
 
 
59
  */
60
  return res;
61
  } catch (e) {
62
+ return { status: 500, message: e.message}
63
  }
64
  }
65
 
lib/snapchat.js CHANGED
@@ -41,7 +41,7 @@ async function spotlight(url) {
41
  console.log("Tidak ditemukan data JSON yang sesuai.");
42
  }
43
  } catch (error) {
44
- return { status: 404, message: error.message}
45
  console.error("Gagal mengambil data:", error.message);
46
  }
47
  }
 
41
  console.log("Tidak ditemukan data JSON yang sesuai.");
42
  }
43
  } catch (error) {
44
+ return { status: 500, message: error.message}
45
  console.error("Gagal mengambil data:", error.message);
46
  }
47
  }
lib/soundcloud.js CHANGED
@@ -139,7 +139,7 @@ async function soundcloud(query, type) {
139
  return resd
140
  }
141
  } catch (e) {
142
- return { status: 404, message: e.message}
143
  }
144
  }
145
 
 
139
  return resd
140
  }
141
  } catch (e) {
142
+ return { status: 500, message: e.message}
143
  }
144
  }
145
 
lib/spotify.js CHANGED
@@ -94,7 +94,7 @@ async function spotifyTrack(trackUrl) {
94
  console.log(res)
95
  return res
96
  } catch (e) {
97
- return { status: 404, message: e.message}
98
  }
99
  }
100
 
 
94
  console.log(res)
95
  return res
96
  } catch (e) {
97
+ return { status: 500, message: e.message}
98
  }
99
  }
100
 
lib/twt.js CHANGED
@@ -44,7 +44,7 @@ async function getTwitterVideoInfo(url) {
44
 
45
  resolve(res);
46
  } catch (parseError) {
47
- reject("Failed to parse JSON response");
48
  }
49
  });
50
  });
 
44
 
45
  resolve(res);
46
  } catch (parseError) {
47
+ return { status: 500, message: e.message}
48
  }
49
  });
50
  });
lib/ytdl.js CHANGED
@@ -1,20 +1,18 @@
1
  const { spawn } = require("child_process");
2
  const path = require("path");
3
- const fs = require("fs");
4
 
5
- const tmp = path.join(__dirname, "../tmp"); // path to your tmp folder
6
- const ytdlp = "yt-dlp"; // Assume yt-dlp is installed globally inside the Docker container
7
- const cookiesPath = path.join(__dirname, "./cookies/yt.txt");
8
 
9
  function runYtDlp(args) {
10
  return new Promise((resolve, reject) => {
11
  const process = spawn(ytdlp, args, { stdio: ["ignore", "pipe", "pipe"] });
12
  let stdout = "";
13
  let stderr = "";
14
-
15
  process.stdout.on("data", (data) => (stdout += data.toString()));
16
  process.stderr.on("data", (data) => (stderr += data.toString()));
17
-
18
  process.on("close", (code) => {
19
  if (code === 0) resolve(stdout.trim());
20
  else reject(new Error(stderr.trim() || `yt-dlp exited with code ${code}`));
@@ -22,63 +20,42 @@ function runYtDlp(args) {
22
  });
23
  }
24
 
25
- async function getInfo(url) {
 
 
 
 
 
26
  try {
27
  const result = await runYtDlp(["-j", "--cookies", cookiesPath, url]);
28
  const info = JSON.parse(result);
 
 
 
 
 
 
 
 
29
  return {
30
- id: info.id,
31
- title: info.title,
32
- thumbnail: `https://i.ytimg.com/vi/${info.id}/maxresdefault.jpg`,
33
- description: info.description,
34
- duration: info.duration,
35
- views: info.view_count,
36
- likes: info.like_count,
37
- comments: info.comment_count,
38
- uploaded: info.timestamp,
39
- channel: {
40
- id: info.channel_id,
41
- handle: info.uploader_id,
42
- name: info.uploader,
43
- picture: info.channel_thumbnail || "",
44
- subscribers: info.channel_follower_count,
45
- verified: !!info.channel_is_verified,
46
- },
47
- videos: [...new Set(info.formats.filter(v => v.video_ext === "mp4").map(v => v.height + "p"))],
48
  };
49
  } catch (err) {
50
  throw new Error(`Failed to get video info: ${err.message}`);
51
  }
52
  }
53
 
54
- async function getVideo(url, quality = "480p") {
55
- const ts = Date.now();
56
- const outputFile = `${tmp}/${ts}.mp4`;
57
- try {
58
- await runYtDlp(["-f", `ba[ext=m4a]+bv[height=${quality.slice(0, -1)}]`, "--merge-output-format", "mp4", "-o", outputFile, url]);
59
- const result = fs.readFileSync(outputFile);
60
- fs.unlinkSync(outputFile);
61
- return result;
62
- } catch (err) {
63
- throw new Error(`Failed to download video: ${err.message}`);
64
- }
65
- }
66
-
67
- async function getAudio(url) {
68
- const ts = Date.now();
69
- const outputFile = `${tmp}/${ts}.mp3`;
70
- try {
71
- await runYtDlp(["-f", "ba", "-o", outputFile, url]);
72
- const result = fs.readFileSync(outputFile);
73
- fs.unlinkSync(outputFile);
74
- return result;
75
- } catch (err) {
76
- throw new Error(`Failed to download audio: ${err.message}`);
77
- }
78
- }
79
-
80
- module.exports = {
81
- getInfo,
82
- getAudio,
83
- getVideo,
84
- };
 
1
  const { spawn } = require("child_process");
2
  const path = require("path");
 
3
 
4
+ const ytdlp = "yt-dlp"; // Asumsi yt-dlp sudah terinstall global di Docker
5
+ const cookiesPath = path.join(__dirname, "./cookies/twt.txt");
 
6
 
7
  function runYtDlp(args) {
8
  return new Promise((resolve, reject) => {
9
  const process = spawn(ytdlp, args, { stdio: ["ignore", "pipe", "pipe"] });
10
  let stdout = "";
11
  let stderr = "";
12
+
13
  process.stdout.on("data", (data) => (stdout += data.toString()));
14
  process.stderr.on("data", (data) => (stderr += data.toString()));
15
+
16
  process.on("close", (code) => {
17
  if (code === 0) resolve(stdout.trim());
18
  else reject(new Error(stderr.trim() || `yt-dlp exited with code ${code}`));
 
20
  });
21
  }
22
 
23
+ /**
24
+ * Mengambil metadata video Twitter menggunakan yt-dlp.
25
+ * @param {string} url - URL tweet yang berisi video.
26
+ * @returns {Promise<Object>} - Metadata video dalam format JSON.
27
+ */
28
+ async function getTwitterVideoInfo(url) {
29
  try {
30
  const result = await runYtDlp(["-j", "--cookies", cookiesPath, url]);
31
  const info = JSON.parse(result);
32
+
33
+ // Pastikan `formats` ada, jika tidak buat array kosong
34
+ const videoFormats = (info.formats || []).filter(
35
+ (f) => (f.video_ext !== "none" && f.audio_ext !== "none") || f.url.includes(".mp4")
36
+ );
37
+
38
+ const audioFormats = (info.formats || []).filter((f) => f.video_ext === "none" && f.audio_ext !== "none");
39
+
40
  return {
41
+ status: 200,
42
+ title: info.title || "No Title",
43
+ description: info.description || "",
44
+ thumbnail: info.thumbnail || "",
45
+ video: videoFormats.map((v) => ({
46
+ format_id: v.format_id,
47
+ resolution: v.resolution || `${v.width}x${v.height}`,
48
+ url: v.url,
49
+ })),
50
+ audio: audioFormats.map((a) => ({
51
+ format_id: a.format_id,
52
+ bitrate: a.abr,
53
+ url: a.url,
54
+ })),
 
 
 
 
55
  };
56
  } catch (err) {
57
  throw new Error(`Failed to get video info: ${err.message}`);
58
  }
59
  }
60
 
61
+ module.exports = getTwitterVideoInfo;