zhg.sql 1.4.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.
Files changed (3) hide show
  1. package/README.md +13 -0
  2. package/index.js +864 -0
  3. package/package.json +23 -0
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # @leoo-vanth/zarv7z
2
+
3
+ ![Depfu](https://img.shields.io/depfu/fent/node-ytdl-core)
4
+ [![codecov](https://codecov.io/gh/fent/node-ytdl-core/branch/master/graph/badge.svg)](https://codecov.io/)
5
+
6
+ Yet another downloader module. Written with only Javascript and a node-friendly streaming interface.
7
+
8
+ # By L7z
9
+
10
+ ![My Card ](https://cardivo.vercel.app/api?name=Leoo%20Firyahya%20S.Kom%20&description=Kegagalan%20dibuat%20hanya%20oleh%20mereka%20yang%20gagal%20untuk%20berani,%20bukan%20oleh%20mereka%20yang%20berani%20gagal&image=https://files.catbox.moe/9draas.png&backgroundColor=%23ecf0f1&instagram=@zarv7z&github=zarv7z&pattern=leaf&colorPattern=%23eaeaea)
11
+
12
+
13
+ ___
package/index.js ADDED
@@ -0,0 +1,864 @@
1
+ const axios = require('axios')
2
+ const cheerio = require('cheerio')
3
+ const { createDecipheriv } = require('crypto')
4
+ const fs = require('fs')
5
+ const FormData = require('form-data')
6
+ const path = require('path')
7
+ const { spawn } = require('child_process')
8
+ const YTDL = require('@distube/ytdl-core')
9
+ const ffmpeg = require('fluent-ffmpeg')
10
+ const randomKarakter = (length) => {
11
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
12
+ return Array.from({ length }, () => chars.charAt(Math.floor(Math.random() * chars.length))).join('')
13
+ }
14
+
15
+ const FileSize = (path) => {
16
+ const bytes = fs.statSync(path).size
17
+ if (bytes >= 1073741824) return (bytes / 1073741824).toFixed(2) + ' GB'
18
+ if (bytes >= 1048576) return (bytes / 1048576).toFixed(2) + ' MB'
19
+ if (bytes >= 1024) return (bytes / 1024).toFixed(2) + ' KB'
20
+ return bytes + ' B'
21
+ }
22
+
23
+ async function catbox(path) {
24
+ const data = new FormData()
25
+ data.append('reqtype', 'fileupload')
26
+ data.append('userhash', '')
27
+ data.append('fileToUpload', fs.createReadStream(path))
28
+ const config = {
29
+ method: 'POST',
30
+ url: 'https://catbox.moe/user/api.php',
31
+ headers: {
32
+ ...data.getHeaders(),
33
+ 'User-Agent': 'Mozilla/5.0 (Android 10; Mobile; rv:131.0) Gecko/131.0 Firefox/131.0',
34
+ },
35
+ data: data
36
+ }
37
+ const api = await axios.request(config)
38
+ return api.data
39
+ }
40
+
41
+ async function uguu(path) {
42
+ try {
43
+ const form = new FormData()
44
+ form.append('files[]', fs.createReadStream(path))
45
+
46
+ const { data } = await axios.post('https://uguu.se/upload', form, {
47
+ headers: {
48
+ ...form.getHeaders()
49
+ }
50
+ })
51
+
52
+ return data.files[0].url
53
+ } catch (err) {
54
+ throw new Error(err.message)
55
+ }
56
+ }
57
+
58
+ async function theoks(path) {
59
+ try {
60
+ let form = new FormData()
61
+ form.append('files[]', fs.createReadStream(path))
62
+
63
+ let { data } = await axios.post('https://pomf-api.theoks.net/upload.php', form, {
64
+ headers: form.getHeaders()
65
+ })
66
+
67
+ return data.files[0].url
68
+ } catch (err) {
69
+ throw new Error(err.message)
70
+ }
71
+ }
72
+
73
+ async function litterbox(path) {
74
+ try {
75
+ let form = new FormData()
76
+ form.append('fileToUpload', fs.createReadStream(path))
77
+ form.append('reqtype', 'fileupload')
78
+ form.append('time', '24h')
79
+
80
+ let { data } = await axios.post('https://litterbox.catbox.moe/resources/internals/api.php', form, {
81
+ headers: {
82
+ ...form.getHeaders()
83
+ }
84
+ })
85
+
86
+ return data
87
+ } catch (err) {
88
+ throw new Error(err.message)
89
+ }
90
+ }
91
+
92
+ async function cloudmini(path) {
93
+ try {
94
+ const file_buffer = fs.readFileSync(path)
95
+ const file_type = path.split('.').pop()
96
+ const file_name = path.split('/').pop()
97
+ const unique_id = randomKarakter(2) + (file_buffer.length + file_type + file_name).length
98
+
99
+ const form = new FormData()
100
+ form.append('file', fs.createReadStream(path), `${unique_id}.${file_type}`)
101
+
102
+ const response = await axios.post('https://files.cloudmini.net/upload', form, {
103
+ headers: { ...form.getHeaders() }
104
+ })
105
+
106
+ const { filename } = response.data
107
+ return `https://files.cloudmini.net/download/${filename}`
108
+ } catch (err) {
109
+ throw new Error(err.message)
110
+ }
111
+ }
112
+
113
+ async function tempfiles(path) {
114
+ try {
115
+ const form = new FormData()
116
+ form.append('file', fs.createReadStream(path))
117
+
118
+ const { data } = await axios.post('https://tmpfiles.org/api/v1/upload', form, {
119
+ headers: {
120
+ ...form.getHeaders()
121
+ }
122
+ })
123
+
124
+ return data.data.url
125
+ } catch (err) {
126
+ throw new Error(err.message)
127
+ }
128
+ }
129
+
130
+ const QualsVideo = ["144", "240", "360", "480", "720", "1080"]
131
+ const QualsAudio = ['32', '64', '128', '192', '256', '320']
132
+
133
+ const downloadFolder = '/home/container'
134
+ if (!fs.existsSync(downloadFolder)) fs.mkdirSync(downloadFolder)
135
+
136
+ async function ytdlv1(url, type, qual = null) {
137
+ let cookie
138
+ const match = cookie?.match(/Expires=([^;]+)/)
139
+ const date = match ? new Date(match[1]) : null
140
+ const now = new Date()
141
+
142
+ if (!cookie || (date && now > date)) {
143
+ const yt_page = await axios.get("https://www.youtube.com", { timeout: 5000 })
144
+ cookie = yt_page.headers['set-cookie']?.join('; ') || ''
145
+ }
146
+
147
+ const config = { requestOptions: { headers: { Cookie: cookie } } }
148
+ const info = await YTDL.getInfo(url, config)
149
+ const video = info.videoDetails
150
+ const file_id = randomKarakter(8)
151
+
152
+ if (type === 'mp3') {
153
+ const file_path = `./${file_id}.mp3`
154
+
155
+ const stream = YTDL(url, {
156
+ filter: 'audioonly',
157
+ highWaterMark: 32 * 1024 * 1024,
158
+ requestOptions: { headers: { Cookie: cookie } }
159
+ })
160
+
161
+ const ffmpeg = spawn('ffmpeg', [
162
+ '-i', 'pipe:0',
163
+ '-b:a', `${qual}k`,
164
+ '-preset', 'ultrafast',
165
+ '-movflags', '+faststart',
166
+ file_path
167
+ ])
168
+
169
+ stream.pipe(ffmpeg.stdin)
170
+
171
+ await new Promise((resolve, reject) => {
172
+ ffmpeg.on('close', resolve)
173
+ ffmpeg.on('error', reject)
174
+ })
175
+
176
+ const file_size = FileSize(file_path)
177
+ return {
178
+ audio: {
179
+ title: video.title,
180
+ duration: video.lengthSeconds,
181
+ views: video.viewCount,
182
+ likes: video.likes,
183
+ quality: qual + 'kbps',
184
+ description: video.description,
185
+ thumbnail: video.thumbnails.pop().url
186
+ },
187
+ channel: {
188
+ name: video.ownerChannelName,
189
+ subscriber: video.author.subscriber_count,
190
+ verified: video.author.verified,
191
+ url: video.author.channel_url
192
+ },
193
+ file_name: `${video.title}.mp3`,
194
+ file_size,
195
+ download: file_path
196
+ }
197
+ }
198
+
199
+ const formats = info.formats.map(f => ({
200
+ itag: f.itag,
201
+ quality: f.qualityLabel || 'Audio',
202
+ hasAudio: !!f.audioBitrate,
203
+ url: f.url,
204
+ type: f.mimeType.split(';')[0]
205
+ }))
206
+
207
+ let format_video = formats.find(f => f.quality.includes(`${qual}p`) && !f.hasAudio) || formats.find(f => f.quality.includes('p') && !f.hasAudio)
208
+ let format_audio = formats.find(f => f.hasAudio)
209
+
210
+ if (!format_video || !format_audio) return { availableFormats: formats }
211
+
212
+ const video_path = `./${file_id}.mp4`
213
+
214
+ const video_stream = YTDL(url, {
215
+ quality: format_video.itag,
216
+ highWaterMark: 64 * 1024 * 1024,
217
+ requestOptions: { headers: { Cookie: cookie } }
218
+ })
219
+
220
+ const audio_stream = YTDL(url, {
221
+ quality: format_audio.itag,
222
+ highWaterMark: 32 * 1024 * 1024,
223
+ requestOptions: { headers: { Cookie: cookie } }
224
+ })
225
+
226
+ const ffmpeg = spawn('ffmpeg', [
227
+ '-i', 'pipe:3',
228
+ '-i', 'pipe:4',
229
+ '-c:v', 'copy',
230
+ '-c:a', 'aac',
231
+ '-preset', 'ultrafast',
232
+ '-movflags', '+faststart',
233
+ video_path
234
+ ], { stdio: ['ignore', 'ignore', 'ignore', 'pipe', 'pipe'] })
235
+
236
+ video_stream.pipe(ffmpeg.stdio[3])
237
+ audio_stream.pipe(ffmpeg.stdio[4])
238
+
239
+ await new Promise((resolve, reject) => {
240
+ ffmpeg.on('close', resolve)
241
+ ffmpeg.on('error', reject)
242
+ })
243
+
244
+ const file_size = FileSize(video_path)
245
+ return {
246
+ video: {
247
+ title: video.title,
248
+ duration: video.lengthSeconds,
249
+ views: video.viewCount,
250
+ likes: video.likes,
251
+ quality: format_video.quality,
252
+ description: video.description,
253
+ thumbnail: video.thumbnails.pop().url
254
+ },
255
+ channel: {
256
+ name: video.ownerChannelName,
257
+ subscriber: video.author.subscriber_count,
258
+ verified: video.author.verified,
259
+ url: video.author.channel_url
260
+ },
261
+ file_name: `${video.title}.mp4`,
262
+ file_size,
263
+ download: video_path
264
+ }
265
+ }
266
+
267
+ async function ytdlv2(url, type, quality) {
268
+ const api = {
269
+ base: 'https://media.savetube.me/api',
270
+ cdn: '/random-cdn',
271
+ info: '/v2/info',
272
+ download: '/download'
273
+ }
274
+
275
+ const headers = {
276
+ accept: '*/*',
277
+ 'content-type': 'application/json',
278
+ origin: 'https://yt.savetube.me',
279
+ referer: 'https://yt.savetube.me/',
280
+ 'user-agent': 'Postify/1.0.0'
281
+ }
282
+
283
+ const vid_quality = ['144', '240', '360', '480', '720', '1080']
284
+ const aud_quality = ['32', '64', '128', '192', '256', '320']
285
+
286
+ const hex_to_buf = (hex) => Buffer.from(hex, 'hex')
287
+
288
+ const decrypt = (enc) => {
289
+ try {
290
+ const secret_key = 'C5D58EF67A7584E4A29F6C35BBC4EB12'
291
+ const data = Buffer.from(enc, 'base64')
292
+ const iv = data.slice(0, 16)
293
+ const content = data.slice(16)
294
+ const key = hex_to_buf(secret_key)
295
+
296
+ const decipher = createDecipheriv('aes-128-cbc', key, iv)
297
+ let decrypted = Buffer.concat([decipher.update(content), decipher.final()])
298
+
299
+ return JSON.parse(decrypted.toString())
300
+ } catch (error) {
301
+ throw new Error(error.message)
302
+ }
303
+ }
304
+
305
+ const get_id = (url) => {
306
+ const regex = [
307
+ /youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})/,
308
+ /youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/,
309
+ /youtube\.com\/v\/([a-zA-Z0-9_-]{11})/,
310
+ /youtube\.com\/shorts\/([a-zA-Z0-9_-]{11})/,
311
+ /youtu\.be\/([a-zA-Z0-9_-]{11})/
312
+ ]
313
+ for (let r of regex) {
314
+ let match = url.match(r)
315
+ if (match) return match[1]
316
+ }
317
+ return null
318
+ }
319
+
320
+ const dl_file = (url, file_path) => {
321
+ return new Promise(async (resolve, reject) => {
322
+ try {
323
+ const response = await axios({
324
+ url,
325
+ method: 'GET',
326
+ responseType: 'stream'
327
+ })
328
+ const writer = fs.createWriteStream(file_path)
329
+ response.data.pipe(writer)
330
+ writer.on('finish', () => resolve(file_path))
331
+ writer.on('error', reject)
332
+ } catch (error) {
333
+ reject(error)
334
+ }
335
+ })
336
+ }
337
+
338
+ const convert_audio = (input, output, bitrate) => {
339
+ return new Promise((resolve, reject) => {
340
+ const process = spawn('ffmpeg', [
341
+ '-i', 'pipe:0',
342
+ '-b:a', `${bitrate}k`,
343
+ '-preset', 'ultrafast',
344
+ '-movflags', '+faststart',
345
+ output
346
+ ])
347
+
348
+ const readStream = fs.createReadStream(input)
349
+ readStream.pipe(process.stdin)
350
+
351
+ process.on('close', (code) => {
352
+ if (code === 0) resolve(output)
353
+ else reject(new Error('Error :('))
354
+ })
355
+ })
356
+ }
357
+
358
+ const id = get_id(url)
359
+
360
+ try {
361
+ const { data: cdn_res } = await axios.get(api.base+api.cdn, { headers })
362
+ const cdn = cdn_res.cdn
363
+
364
+ const { data: info_res } = await axios.post(`https://${cdn}${api.info}`, {
365
+ url: `https://www.youtube.com/watch?v=${id}`
366
+ }, { headers })
367
+
368
+ const decrypted = decrypt(info_res.data)
369
+
370
+ if (type === 'mp4') {
371
+ if (!vid_quality.includes(quality.toString())) quality = '360'
372
+ } else if (type === 'mp3') {
373
+ if (!aud_quality.includes(quality.toString())) quality = '192'
374
+ }
375
+
376
+ const { data: dl_res } = await axios.post(`https://${cdn}${api.download}`, {
377
+ id,
378
+ downloadType: type === 'mp3' ? 'audio' : 'video',
379
+ quality,
380
+ key: decrypted.key
381
+ }, { headers })
382
+
383
+ const file_name = `${randomKarakter(4)}.${type}`
384
+ const file_path = './' + file_name
385
+
386
+ await dl_file(dl_res.data.downloadUrl, file_path)
387
+
388
+ if (type === 'mp3') {
389
+ const output_file = `./${randomKarakter(4)}.mp3`
390
+ await convert_audio(file_path, output_file, quality)
391
+ fs.unlinkSync(file_path)
392
+ return {
393
+ title: decrypted.title,
394
+ format: 'mp3',
395
+ quality: quality+'kbps',
396
+ duration: decrypted.duration,
397
+ thumbnail: decrypted.thumbnail || `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`,
398
+ file_name: decrypted.title+'.mp3',
399
+ file_size: FileSize(output_file),
400
+ download: output_file
401
+ }
402
+ }
403
+
404
+ return {
405
+ title: decrypted.title,
406
+ format: 'mp4',
407
+ quality: quality+'p',
408
+ duration: decrypted.duration,
409
+ thumbnail: decrypted.thumbnail || `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`,
410
+ file_name: decrypted.title+'.mp4',
411
+ file_size: FileSize(file_path),
412
+ download: file_path
413
+ }
414
+ } catch (err) {
415
+ return { error: err.message }
416
+ }
417
+ }
418
+
419
+ async function getTokenFB() {
420
+ const { data: html } = await axios.get("https://fbdown.me/")
421
+ const $ = cheerio.load(html)
422
+ return $("#token").val()
423
+ }
424
+
425
+ async function fbdl(url) {
426
+ try {
427
+ const token = await getTokenFB()
428
+ const formData = new FormData()
429
+ formData.append("url", url)
430
+ formData.append("token", token)
431
+
432
+ const { data } = await axios.post(
433
+ "https://fbdown.me/wp-json/aio-dl/video-data",
434
+ formData,
435
+ { headers: { ...formData.getHeaders() } }
436
+ )
437
+
438
+ return {
439
+ title: data.title,
440
+ thumbnail: data.thumbnail,
441
+ videos: data.medias.map(v => ({
442
+ url: v.url,
443
+ quality: v.quality,
444
+ size: v.formattedSize
445
+ }))
446
+ }
447
+ } catch (err) {
448
+ throw Error(err.message)
449
+ }
450
+ }
451
+
452
+ async function igdl(url) {
453
+ const { data } = await axios.post(
454
+ 'https://yt1s.io/api/ajaxSearch',
455
+ new URLSearchParams({
456
+ p: 'home',
457
+ q: url,
458
+ w: '',
459
+ lang: 'en'
460
+ }),
461
+ {
462
+ headers: {
463
+ 'User-Agent': 'Postify/1.0.0',
464
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
465
+ 'Accept': 'application/json, text/plain, */*',
466
+ 'Origin': 'https://yt1s.io',
467
+ 'Referer': 'https://yt1s.io/'
468
+ }
469
+ }
470
+ )
471
+
472
+ const $ = cheerio.load(data.data)
473
+
474
+ return $('a.abutton.is-success.is-fullwidth.btn-premium')
475
+ .map((_, el) => ({
476
+ title: $(el).attr('title'),
477
+ url: $(el).attr('href')
478
+ }))
479
+ .get()
480
+ }
481
+
482
+ async function ttdl(url) {
483
+ return new Promise(async (resolve, reject) => {
484
+ try {
485
+ let data = []
486
+
487
+ function formatNumber(integer) {
488
+ let numb = parseInt(integer)
489
+ return Number(numb).toLocaleString().replace(/,/g, '.')
490
+ }
491
+
492
+ function formatDate(n, locale = 'en') {
493
+ let d = new Date(n)
494
+ return d.toLocaleDateString(locale, {
495
+ weekday: 'long',
496
+ day: 'numeric',
497
+ month: 'long',
498
+ year: 'numeric',
499
+ hour: 'numeric',
500
+ minute: 'numeric',
501
+ second: 'numeric'
502
+ })
503
+ }
504
+
505
+ let domain = 'https://www.tikwm.com/api/'
506
+ let res = await (await axios.post(domain, {}, {
507
+ headers: {
508
+ 'Accept': 'application/json, text/javascript, */*; q=0.01',
509
+ 'Accept-Language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7',
510
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
511
+ 'Origin': 'https://www.tikwm.com',
512
+ 'Referer': 'https://www.tikwm.com/',
513
+ 'Sec-Ch-Ua': '"Not)A;Brand" ;v="24" , "Chromium" ;v="116"',
514
+ 'Sec-Ch-Ua-Mobile': '?1',
515
+ 'Sec-Ch-Ua-Platform': 'Android',
516
+ 'Sec-Fetch-Dest': 'empty',
517
+ 'Sec-Fetch-Mode': 'cors',
518
+ 'Sec-Fetch-Site': 'same-origin',
519
+ 'User-Agent': 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36',
520
+ 'X-Requested-With': 'XMLHttpRequest'
521
+ },
522
+ params: {
523
+ url: url,
524
+ count: 12,
525
+ cursor: 0,
526
+ web: 1,
527
+ hd: 1
528
+ }
529
+ })).data.data
530
+ if (!res.size) {
531
+ res.images.map(v => {
532
+ data.push({
533
+ type: 'photo',
534
+ url: v
535
+ })
536
+ })
537
+ } else {
538
+ data.push({
539
+ type: 'watermark',
540
+ url: 'https://www.tikwm.com' + res.wmplay,
541
+ }, {
542
+ type: 'nowatermark',
543
+ url: 'https://www.tikwm.com' + res.play,
544
+ }, {
545
+ type: 'nowatermark_hd',
546
+ url: 'https://www.tikwm.com' + res.hdplay
547
+ })
548
+ }
549
+ let json = {
550
+ title: res.title,
551
+ region: res.region,
552
+ durations: res.duration,
553
+ cover: 'https://www.tikwm.com' + res.cover,
554
+ size_wm: res.wm_size,
555
+ size_nowm: res.size,
556
+ size_nowm_hd: res.hd_size,
557
+ data: data,
558
+ music_info: {
559
+ id: res.music_info.id,
560
+ title: res.music_info.title,
561
+ author: res.music_info.author,
562
+ album: res.music_info.album ? res.music_info.album : null,
563
+ url: 'https://www.tikwm.com' + res.music || res.music_info.play
564
+ },
565
+ stats: {
566
+ views: formatNumber(res.play_count),
567
+ likes: formatNumber(res.digg_count),
568
+ comment: formatNumber(res.comment_count),
569
+ share: formatNumber(res.share_count),
570
+ download: formatNumber(res.download_count)
571
+ },
572
+ author: {
573
+ id: res.author.id,
574
+ fullname: res.author.unique_id,
575
+ nickname: res.author.nickname,
576
+ avatar: 'https://www.tikwm.com' + res.author.avatar
577
+ }
578
+ }
579
+ resolve(json)
580
+ } catch (e) {
581
+ reject(e)
582
+ }
583
+ })
584
+ }
585
+
586
+ async function ttslide(url) {
587
+ try {
588
+ const res = await axios({
589
+ method: 'POST',
590
+ url: 'https://tikvideo.app/api/ajaxSearch',
591
+ headers: {
592
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
593
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
594
+ },
595
+ data: new URLSearchParams({ q: url, lang: 'id' }).toString(),
596
+ })
597
+
598
+ const result = []
599
+ if (res.data.status === 'ok') {
600
+ const $ = cheerio.load(res.data.data)
601
+ $('img').each((index, element) => {
602
+ const imgSrc = $(element).attr('src')
603
+ if (imgSrc && !imgSrc.includes('.webp')) {
604
+ result.push(imgSrc)
605
+ }
606
+ })
607
+ }
608
+
609
+ return result.length > 0 ? result : null
610
+ } catch (err) {
611
+ throw Error(err.message)
612
+ }
613
+ }
614
+
615
+ async function spotify(url) {
616
+ try {
617
+ const response = await axios.get(`https://api.siputzx.my.id/api/d/spotify?url=${encodeURIComponent(url)}`)
618
+ return {
619
+ title: response.data.data.title,
620
+ download: response.data.data.download,
621
+ image: response.data.data.image,
622
+ duration: response.data.data.durasi
623
+ }
624
+ } catch (err) {
625
+ console.error(err)
626
+ }
627
+ }
628
+
629
+ async function capcut(url) {
630
+ const BASE_URI = "https://snapsave.cc/wp-json/aio-dl/video-data"
631
+ const headers = {
632
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
633
+ 'Accept': 'application/json, text/plain, */*',
634
+ 'Accept-Language': 'en-US,en;q=0.9',
635
+ 'Content-Type': 'application/json;charset=UTF-8',
636
+ 'Connection': 'keep-alive',
637
+ 'Referer': 'https://snapsave.cc/capcut-video-downloader/',
638
+ 'Origin': 'https://snapsave.cc',
639
+ 'X-Requested-With': 'XMLHttpRequest',
640
+ 'Cache-Control': 'no-cache',
641
+ 'Pragma': 'no-cache',
642
+ 'DNT': '1'
643
+ }
644
+
645
+ try {
646
+ const response = await axios.get(`https://snapsave.cc/capcut-video-downloader/#url=${encodeURIComponent(url)}`, { headers })
647
+ const $ = cheerio.load(response.data)
648
+ const token = $("#token").val()
649
+
650
+ const payload = {
651
+ url,
652
+ token,
653
+ hash: "aHR0cHM6Ly93d3cuY2FwY3V0LmNvbS9pZC1pZC90ZW1wbGF0ZS1kZXRhaWwvRm9yLXlvdS0vNzQxNDE2Mjk3MzU3ODU2MjgyMg==1073YWlvLWRs"
654
+ }
655
+
656
+ const { data: videoData } = await axios.post(BASE_URI, payload, { headers })
657
+
658
+ return {
659
+ title: videoData.title,
660
+ thumbnail: videoData.thumbnail,
661
+ source: videoData.source,
662
+ media: videoData.medias.map((item) => ({
663
+ url: item.url,
664
+ quality: item.quality,
665
+ format: item.extension,
666
+ size: item.formattedSize
667
+ }))
668
+ }
669
+
670
+ } catch (err) {
671
+ throw Error(err.message)
672
+ }
673
+ }
674
+
675
+ async function threads(url) {
676
+ try {
677
+ const { data } = await axios.get('https://threads.snapsave.app/api/action', {
678
+ params: { url: url },
679
+ headers: {
680
+ 'accept': 'application/json, text/plain, */*',
681
+ 'referer': 'https://threads.snapsave.app/',
682
+ 'user-agent': 'Postify/1.0.0',
683
+ },
684
+ timeout: 10000,
685
+ })
686
+
687
+ const type = (type) => ({
688
+ GraphImage: 'Photo',
689
+ GraphVideo: 'Video',
690
+ GraphSidecar: 'Gallery',
691
+ }[type] || type)
692
+
693
+ return {
694
+ postInfo: {
695
+ id: data.postinfo.id,
696
+ username: data.postinfo.username,
697
+ avatarUrl: data.postinfo.avatar_url,
698
+ mediaTitle: data.postinfo.media_title,
699
+ type: type(data.postinfo.__type),
700
+ },
701
+ media: data.items.map((item) => ({
702
+ type: type(item.__type),
703
+ id: item.id,
704
+ url: item.url,
705
+ width: item.width,
706
+ height: item.height,
707
+ ...(item.__type === 'GraphVideo' && {
708
+ thumbnailUrl: item.display_url,
709
+ videoUrl: item.video_url,
710
+ duration: item.video_duration,
711
+ }),
712
+ })),
713
+ }
714
+ } catch (err) {
715
+ throw Error(err.message)
716
+ }
717
+ }
718
+
719
+ async function terabox(url) {
720
+ const terabox = {
721
+ api: {
722
+ base: "https://teraboxdl.site/api/",
723
+ token: "token",
724
+ terabox: "terabox"
725
+ },
726
+ headers: {
727
+ 'authority': 'teraboxdl.site',
728
+ 'user-agent': 'Postify/1.0.0'
729
+ },
730
+ token: null
731
+ }
732
+
733
+ const getToken = async () => {
734
+ if (terabox.token) return terabox.token
735
+
736
+ try {
737
+ const { data } = await axios.get(`${terabox.api.base}${terabox.api.token}`, { headers: terabox.headers })
738
+
739
+ terabox.token = data.token
740
+ return terabox.token
741
+
742
+ } catch (err) {
743
+ throw Error(err.message)
744
+ }
745
+ }
746
+
747
+ const isUrl = (url) => {
748
+ const match = url.match(/https?:\/\/(?:www\.)?(?:\w+)\.(com|app)\/s\/([^\/]+)/i)
749
+ return match ? `https://1024terabox.com/s/${match[2]}` : null
750
+ }
751
+
752
+ const request = async (endpoint, params = {}) => {
753
+ const token = await getToken()
754
+ const url = `${terabox.api.base}${endpoint}?` + new URLSearchParams(params)
755
+
756
+ try {
757
+ const { data } = await axios.get(url, { headers: { ...terabox.headers, 'x-access-token': token } })
758
+ const fileData = data.data.all_files[0]
759
+
760
+ return {
761
+ file_name: fileData.file_name,
762
+ file_id: fileData.fs_id,
763
+ size: fileData.size,
764
+ thumbnail: fileData.thumb,
765
+ download: fileData.download_url,
766
+ bytes: fileData.sizebytes
767
+ }
768
+
769
+ } catch (err) {
770
+ throw Error(err.message)
771
+ }
772
+ }
773
+
774
+ const linkNya = isUrl(url.trim())
775
+ return await request(terabox.api.terabox, { url: linkNya })
776
+ }
777
+
778
+ async function gdrive(url) {
779
+ let id = (url.match(/\/?id=(.+)/i) || url.match(/\/d\/(.*?)\//))[1]
780
+
781
+ let { data } = await axios.post(`https://drive.google.com/uc?id=${id}&authuser=0&export=download`, null, {
782
+ headers: {
783
+ 'accept-encoding': 'gzip, deflate, br',
784
+ 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
785
+ 'origin': 'https://drive.google.com',
786
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
787
+ 'x-client-data': 'CKG1yQEIkbbJAQiitskBCMS2yQEIqZ3KAQioo8oBGLeYygE=',
788
+ 'x-drive-first-party': 'DriveWebUi',
789
+ 'x-json-requested': 'true'
790
+ }
791
+ })
792
+
793
+ let { fileName, sizeBytes, downloadUrl } = JSON.parse(data.slice(4))
794
+
795
+ return {
796
+ download: downloadUrl,
797
+ fileName,
798
+ fileSize: `${(sizeBytes / (1024 * 1024)).toFixed(2)} MB`,
799
+ mimetype: (await axios.head(downloadUrl)).headers['content-type'],
800
+ extension: fileName.split('.').pop(),
801
+ modified: (await axios.head(downloadUrl)).headers['last-modified']
802
+ }
803
+ }
804
+
805
+ async function whatmusic(input) {
806
+ try {
807
+ let file_path = './sampah.mp3'
808
+
809
+ if (Buffer.isBuffer(input)) {
810
+ fs.writeFileSync(file_path, input)
811
+ } else if (typeof input === 'string') {
812
+ if (/^https?:\/\//.test(input)) {
813
+ let response = await axios.get(input, { responseType: 'arraybuffer' })
814
+ fs.writeFileSync(file_path, Buffer.from(response.data))
815
+ } else if (fs.existsSync(input)) {
816
+ file_path = input
817
+ }
818
+ } else {
819
+ throw Error('Harus berupa URL, file atau buffer!')
820
+ }
821
+
822
+ let outputna = './hasilnya.mp3'
823
+
824
+ return new Promise((resolve, reject) => {
825
+ ffmpeg(file_path)
826
+ .audioCodec('libmp3lame')
827
+ .saveToFile(outputna)
828
+ .on('error', (err) => {
829
+ fs.unlinkSync(file_path)
830
+ reject(err.message)
831
+ })
832
+ .on('end', async () => {
833
+ fs.unlinkSync(file_path)
834
+ let sample = fs.readFileSync(outputna)
835
+
836
+ acr.identify(sample).then((metadata) => {
837
+ fs.unlinkSync(outputna)
838
+ if (metadata.status.msg === 'No result') {
839
+ return reject('Nggak ketemu :(')
840
+ }
841
+
842
+ let song = metadata.metadata.music[0]
843
+ let spotify_data = song.external_metadata?.spotify
844
+ let youtube_id = song.external_metadata?.youtube?.vid || null
845
+
846
+ resolve({
847
+ title: song.title,
848
+ artists: song.artists.map(a => a.name).join(', '),
849
+ album: song.album.name,
850
+ release_date: song.release_date,
851
+ label: song.label,
852
+ duration: song.duration_ms,
853
+ spotify: spotify_data?.track?.id ? { name: song.title, url: `https://open.spotify.com/track/${spotify_data.track.id}` } : null,
854
+ youtube: youtube_id ? `https://www.youtube.com/watch?v=${youtube_id}` : null
855
+ })
856
+ }).catch((err) => reject(err.message))
857
+ })
858
+ })
859
+ } catch (err) {
860
+ throw Error(err.message)
861
+ }
862
+ }
863
+
864
+ module.exports = { catbox, uguu, theoks, litterbox, cloudmini, tempfiles, ytdlv1, ytdlv2, fbdl, igdl, ttdl, ttslide, spotify, capcut, threads, terabox, gdrive, whatmusic }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "zhg.sql",
3
+ "version": "1.4.5",
4
+ "description": "Modules Converter.",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"No tests specified\" && exit 0"
8
+ },
9
+ "keywords": [
10
+ "api",
11
+ "meta-api",
12
+ "file-uploader",
13
+ "downloader"
14
+ ],
15
+ "author": "vourfly",
16
+ "license": "MIT",
17
+ "dependencies": {
18
+ "@distube/ytdl-core": "^4.16.4",
19
+ "axios": "^1.8.1",
20
+ "cheerio": "^1.0.0",
21
+ "form-data": "^4.0.2"
22
+ }
23
+ }