1 | const search = require("./search.js");
|
2 |
|
3 | const WatchUrl = "https://www.youtube.com/watch?v="
|
4 | const Url = "https://www.youtube.com"
|
5 |
|
6 | const toSeconds = (timeString) => {
|
7 | const timeArray = timeString.split(':').reverse();
|
8 | let seconds = 0;
|
9 | for (let i = 0; i < timeArray.length; i++) {
|
10 | seconds += parseInt(timeArray[i], 10) * Math.pow(60, i);
|
11 | }
|
12 | return isNaN(seconds) ? 0 : seconds;
|
13 | };
|
14 |
|
15 |
|
16 | const extractData = async (query) => {
|
17 | if (typeof query !== "string" || query.trim() === "") {
|
18 | throw new Error("Invalid search query. Search query must be a non-empty string");
|
19 | }
|
20 |
|
21 | const searchData = await search(query);
|
22 |
|
23 | const videoData = searchData.filter(item => item.videoRenderer).map(item => {
|
24 | const videoRenderer = item.videoRenderer;
|
25 | const id = videoRenderer.videoId;
|
26 | const title = videoRenderer.title.runs[0].text;
|
27 | const thumbnail = {
|
28 | url: videoRenderer.thumbnail.thumbnails[0].url,
|
29 | width: videoRenderer.thumbnail.thumbnails[0].width,
|
30 | height: videoRenderer.thumbnail.thumbnails[0].height
|
31 | };
|
32 | if(!videoRenderer.viewCountText.simpleText) videoRenderer.viewCountText.simpleText = '0';
|
33 | if(!videoRenderer.lengthText) {
|
34 | videoRenderer.lengthText = {};
|
35 | videoRenderer.lengthText.simpleText = '00:00';
|
36 | }
|
37 | const viewCount = parseInt((videoRenderer.viewCountText || {})?.simpleText.replace(/[^0-9]/g, "")) || 0;
|
38 | const shortViewCount = shortNumber(viewCount);
|
39 | const duration = videoRenderer.lengthText?.simpleText || "00:00";
|
40 | const seconds = toSeconds(duration);
|
41 | const author = videoRenderer.ownerText.runs[0];
|
42 | const authorUrl = author.navigationEndpoint.browseEndpoint.canonicalBaseUrl || author.navigationEndpoint.commandMetadata.webCommandMetadata.url;
|
43 | const isVerified = !!(videoRenderer.ownerBadges && JSON.stringify(videoRenderer.ownerBadges).includes('VERIFIED'));
|
44 |
|
45 | const publishedAt = videoRenderer.publishedTimeText?.simpleText || "";
|
46 |
|
47 | const watchUrl = WatchUrl + id;
|
48 |
|
49 | return {
|
50 | type: "video",
|
51 | id,
|
52 | title,
|
53 | thumbnail,
|
54 | viewCount,
|
55 | shortViewCount,
|
56 | duration,
|
57 | seconds,
|
58 | author: author ? {
|
59 | name: author.text,
|
60 | url: Url + authorUrl,
|
61 | verified: isVerified
|
62 | } : null,
|
63 | watchUrl,
|
64 | publishedAt
|
65 | };
|
66 | });
|
67 |
|
68 | return videoData;
|
69 |
|
70 | };
|
71 |
|
72 | function shortNumber(num) {
|
73 | const suffixes = ["", "K", "M", "B", "T"];
|
74 | const magnitude = Math.floor(Math.log10(num) / 3);
|
75 | const scaled = num / Math.pow(10, magnitude * 3);
|
76 | const suffix = suffixes[magnitude];
|
77 | return scaled.toFixed(1) + suffix;
|
78 | }
|
79 |
|
80 | module.exports = extractData;
|