ilhamdev commited on
Commit
601b94a
·
verified ·
1 Parent(s): a55ed4e

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +74 -278
index.js CHANGED
@@ -228,269 +228,78 @@ async function fby2mate(url) {
228
  }
229
  }
230
 
231
- //YTDL-CORE
232
- async function uploadBuffer(media) {
233
- return new Promise(async (resolve, reject) => {
234
- try {
235
- let { fileTypeFromBuffer } = await import('file-type');
236
- let mime = await fileTypeFromBuffer(media);
237
- let form = new FormData();
238
- form.append("files[]", media, `file-${new Date().getTime()}.${mime.ext}`);
239
-
240
- let urls = ["https://pomf.lain.la/upload.php", "https://up1.fileditch.com/upload.php"];
241
- for (let url of urls) {
242
- try {
243
- let response = await axios.post(url, form, {
244
- headers: {
245
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0",
246
- ...form.getHeaders()
247
- }
248
- });
249
- if (response.data?.files[0]?.url) {
250
- resolve(response.data.files[0].url);
251
- return;
252
- }
253
- } catch (err) {
254
- console.error(`Failed to upload to ${url}:`, err.message);
255
- }
256
- }
257
- resolve(null); // If all URLs fail, return null
258
- } catch (error) {
259
- console.error(error);
260
- resolve(null); // Ensure null is returned if there's an error
261
- }
262
- });
263
- }
264
- async function streamToBuffer(stream) {
265
- const chunks = [];
266
- const captureChunks = new Writable({
267
- write(chunk, encoding, callback) {
268
- chunks.push(chunk);
269
- callback();
270
- }
271
- });
272
-
273
- await util.promisify(pipeline)(stream, captureChunks);
274
-
275
- return Buffer.concat(chunks);
276
- }
277
- function formatViews(viewCount) {
278
- if (viewCount >= 1000000000) {
279
- return (viewCount / 1000000000).toFixed(1) + 'B';
280
- } else if (viewCount >= 1000000) {
281
- return (viewCount / 1000000).toFixed(1) + 'M';
282
- } else {
283
- return viewCount >= 1000
284
- ? (viewCount / 1000).toFixed(1) + 'K'
285
- : viewCount.toString();
286
- }
287
- }
288
-
289
- function formatDuration(durationInSeconds) {
290
- const hours = Math.floor(durationInSeconds / 3600);
291
- const minutes = Math.floor((durationInSeconds % 3600) / 60);
292
- const seconds = durationInSeconds % 60;
293
-
294
- return hours > 0
295
- ? hours +
296
- ':' +
297
- minutes.toString().padStart(2, '0') +
298
- ':' +
299
- seconds.toString().padStart(2, '0')
300
- : minutes + ':' + seconds.toString().padStart(2, '0');
301
- }
302
-
303
- function formatSize(bytes, si = false, dp = 2) {
304
- const thresh = si ? 1000 : 1024;
305
-
306
- if (Math.abs(bytes) < thresh) {
307
- return `${bytes} B`;
308
- }
309
-
310
- const units = si
311
- ? ["kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
312
- : ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
313
- let u = -1;
314
- const r = 10 ** dp;
315
-
316
- do {
317
- bytes /= thresh;
318
- ++u;
319
- } while (
320
- Math.round(Math.abs(bytes) * r) / r >= thresh &&
321
- u < units.length - 1
322
- );
323
-
324
- return `${bytes.toFixed(dp)} ${units[u]}`;
325
- }
326
-
327
- /*async function ytmp4(url, quality = 'highestvideo') {
328
- try {
329
- const ID = ytdl.getVideoID(url),
330
- data = await ytdl.getInfo('https://www.youtube.com/watch?v=' + ID);
331
- //const videoStream = await ytdl(ID, { filter: format => format.hasVideo && format.hasAudio, quality: quality });
332
- //let buffer = await streamToBuffer(videoStream);
333
- //let upload = await uploadBuffer(buffer);
334
- //let urel = upload != null ? { url_v2: upload } : null;
335
- let format = ytdl.chooseFormat(data.formats, { filter: format => format.hasVideo && format.hasAudio, quality: quality });
336
-
337
-
338
- if (format) {
339
- return {
340
- title: data.videoDetails.title,
341
- description: data.videoDetails.description,
342
- channel: data.videoDetails.ownerChannelName,
343
- views: formatViews(data.videoDetails.viewCount),
344
- publish: data.videoDetails.publishDate,
345
- duration: formatDuration(data.videoDetails.lengthSeconds),
346
- size: format.contentLength ? formatSize(format.contentLength) : 0,
347
- quality: format.qualityLabel,
348
- thumb: data.videoDetails.thumbnails[0].url,
349
- dl_url: format.url,
350
- //...urel,
351
- };
352
- } else {
353
- throw new Error('No suitable format found');
354
- }
355
- } catch (error) {
356
- console.error('Error occurred:', error);
357
- return error;
358
- }
359
- }
360
-
361
- async function ytmp3(url, bitrate = 'highestaudio') {
362
- try {
363
- const ID = ytdl.getVideoID(url),
364
- data = await ytdl.getInfo('https://www.youtube.com/watch?v=' + ID);
365
- const audioStream = await ytdl(ID, { filter: 'audioonly', quality: bitrate });
366
- //let buffer = await streamToBuffer(audioStream);
367
-
368
-
369
- async function convertToAudio(buffer, ext) {
370
- try {
371
- const tmp = path.join(os.tmpdir(), `${+new Date()}.${ext}`);
372
- const out = `${tmp}.mp3`;
373
- await fs.promises.writeFile(tmp, buffer);
374
-
375
- const ffmpegProcess = cp.spawn('ffmpeg', [
376
- '-y',
377
- '-i', tmp,
378
- '-vn',
379
- '-ac', '2',
380
- '-b:a', '128k',
381
- '-ar', '44100',
382
- '-f', 'mp3',
383
- out
384
- ]);
385
-
386
- await new Promise((resolve, reject) => {
387
- ffmpegProcess.on('error', (err) => {
388
- console.error(err);
389
- reject(err);
390
- });
391
- ffmpegProcess.on('close', (code) => {
392
- if (code !== 0) {
393
- reject(`ffmpeg process closed with code: ${code}`);
394
- } else {
395
- resolve();
396
- }
397
- });
398
- });
399
-
400
- const result = await fs.promises.readFile(out);
401
- await fs.promises.unlink(tmp);
402
- await fs.promises.unlink(out);
403
- return result;
404
- } catch (e) {
405
- console.error(e);
406
- throw e;
407
- }
408
- }
409
- //let konver = await convertToAudio(buffer, "mp4");
410
- //let upload = await uploadBuffer(konver);
411
- //let urel = upload != null ? { url_v2: upload } : null;
412
- let format = ytdl.chooseFormat(data.formats, { filter: 'audioonly', quality: bitrate });
413
-
414
- if (format) {
415
- return {
416
- title: data.videoDetails.title,
417
- description: data.videoDetails.description,
418
- channel: data.videoDetails.ownerChannelName,
419
- views: formatViews(data.videoDetails.viewCount),
420
- publish: data.videoDetails.publishDate,
421
- duration: formatDuration(data.videoDetails.lengthSeconds),
422
- size: format.contentLength ? formatSize(format.contentLength) : 0,
423
- quality: format.audioQuality,
424
- thumb: data.videoDetails.thumbnails[0].url,
425
- dl_url: format.url,
426
- //...urel,
427
- };
428
- } else {
429
- throw new Error('No suitable format found');
430
- }
431
- } catch (error) {
432
- console.error('Error occurred:', error);
433
- return error;
434
- }
435
- }*/
436
-
437
- async function ytmp4(url, quality = 'highestvideo') {
438
- try {
439
- const ID = ytdl.getVideoID(url);
440
- const data = await ytdl.getInfo(ID);
441
-
442
- let format = ytdl.chooseFormat(data.formats, { filter: format => format.hasVideo && format.hasAudio, quality });
443
-
444
- if (format) {
445
- return {
446
- title: data.videoDetails.title,
447
- description: data.videoDetails.description,
448
- channel: data.videoDetails.ownerChannelName,
449
- views: formatViews(data.videoDetails.viewCount),
450
- publish: data.videoDetails.publishDate,
451
- duration: formatDuration(data.videoDetails.lengthSeconds),
452
- size: format.contentLength ? formatSize(format.contentLength) : 0,
453
- quality: format.qualityLabel,
454
- thumb: data.videoDetails.thumbnails[0].url,
455
- dl_url: format.url,
456
- };
457
- } else {
458
- throw new Error('No suitable format found');
459
- }
460
- } catch (error) {
461
- console.error('Error occurred:', error.message);
462
- return { error: error.message };
463
- }
464
- }
465
-
466
- async function ytmp3(url, bitrate = 'highestaudio') {
467
  try {
468
- const ID = ytdl.getVideoID(url);
469
- const data = await ytdl.getInfo(ID);
470
-
471
- let format = ytdl.chooseFormat(data.formats, { filter: 'audioonly', quality: bitrate });
472
-
473
- if (format) {
474
- return {
475
- title: data.videoDetails.title,
476
- description: data.videoDetails.description,
477
- channel: data.videoDetails.ownerChannelName,
478
- views: formatViews(data.videoDetails.viewCount),
479
- publish: data.videoDetails.publishDate,
480
- duration: formatDuration(data.videoDetails.lengthSeconds),
481
- size: format.contentLength ? formatSize(format.contentLength) : 0,
482
- quality: format.audioQuality,
483
- thumb: data.videoDetails.thumbnails[0].url,
484
- dl_url: format.url,
485
- };
486
- } else {
487
- throw new Error('No suitable format found');
488
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  } catch (error) {
490
- console.error('Error occurred:', error.message);
491
- return { error: error.message };
492
  }
493
- }
494
 
495
 
496
  // Fungsi untuk mengkonversi video dari YouTube
@@ -1018,26 +827,13 @@ return res.json({ message: e.message });
1018
  let { url } = req.query;
1019
  if (!ytIdRegex.test(url)) return res.json({ message: 'Invalid URL' });
1020
 
1021
- let video = await ytmp4(url);
1022
- let audio = await ytmp3(url);
1023
- //let any = await ytdlhamster(url)
1024
- let data;
1025
-
1026
- try {
1027
- data = await ytDEEL(url);
1028
- } catch (e) {
1029
- console.log('ytDEEL error:', e.message);
1030
- }
1031
 
1032
  let response = {
1033
- video: {
1034
- ...video,
1035
- ...(data && data.mp4 ? { url_v2: data.mp4 } : {})
1036
- },
1037
- audio: {
1038
- ...audio,
1039
- ...(data && data.mp3 ? { url_v2: data.mp3 } : {})
1040
- }
1041
  };
1042
 
1043
  return res.json(response);
 
228
  }
229
  }
230
 
231
+ async function ytAPI(url) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  try {
233
+ if (!/(?:https?:\/\/)?(?:www\.|music\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=|shorts\/|user\/\S+\/\S+\/)|youtu\.be\/)([\w-]{11})/.test(url)) throw "URL Invalid!!!"
234
+ async function downloadVideoType(url, ftype) {
235
+ // Step #1: Generate Download Hash
236
+ const response1 = await axios.post(
237
+ 'http://www.yt-download.org/api/json',
238
+ {
239
+ ftype,
240
+ url,
241
+ },
242
+ {
243
+ headers: {
244
+ 'Content-Type': 'application/json',
245
+ Accept: 'application/json',
246
+ },
247
+ }
248
+ );
249
+ //console.log(response1.data)
250
+ const { hash } = response1?.data?.tasks[0];
251
+
252
+ // Step #2: Start Download Task
253
+ const response2 = await axios.post(
254
+ 'http://www.yt-download.org/api/json',
255
+ {
256
+ hash,
257
+ },
258
+ {
259
+ headers: {
260
+ 'Content-Type': 'application/json',
261
+ Accept: 'application/json',
262
+ },
263
+ }
264
+ );
265
+
266
+ const { taskId } = response2?.data;
267
+
268
+ // Step #3: Check Download Task Status
269
+ let response3;
270
+ do {
271
+ response3 = await axios.post(
272
+ 'http://www.yt-download.org/api/json/task',
273
+ {
274
+ taskId,
275
+ },
276
+ {
277
+ headers: {
278
+ 'Content-Type': 'application/json',
279
+ Accept: 'application/json',
280
+ },
281
+ }
282
+ );
283
+
284
+ //console.log(response3.data);
285
+
286
+ await new Promise((resolve) => setTimeout(resolve, 5000)); // wait 5 seconds before checking again
287
+ } while (response3.data.status !== 'finished');
288
+
289
+ return response3;
290
+ }
291
+ const mp4Response = await downloadVideoType(url, 'mp4');
292
+ const mp3Response = await downloadVideoType(url, 'mp3');
293
+
294
+ return {
295
+ video: mp4Response?.data,
296
+ audio: mp3Response?.data,
297
+ };
298
  } catch (error) {
299
+ console.error(error);
300
+ throw error;
301
  }
302
+ }
303
 
304
 
305
  // Fungsi untuk mengkonversi video dari YouTube
 
827
  let { url } = req.query;
828
  if (!ytIdRegex.test(url)) return res.json({ message: 'Invalid URL' });
829
 
830
+ let data = await ytAPI(url)
831
+ let dataInfo = await ytdl.getVideoID(url)
832
+ dataInfo = await yts({videoId: dataInfo})
 
 
 
 
 
 
 
833
 
834
  let response = {
835
+ info: dataInfo ? dataInfo : {},
836
+ dl: data ? data : null,
 
 
 
 
 
 
837
  };
838
 
839
  return res.json(response);