wolfyflutter

42. ytmp4.video [downloader] [audio] [video] [dd-n01.yt2api.com]

Jul 31st, 2025 (edited)
235
0
Never
8
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 7.42 KB | Source Code | 0 0
  1. /*
  2.   base   : https://ytmp4.video/
  3.   note   : bisa download audio 64kbps, 128kbps, 192kbps, 256kbps, 320kbps
  4.            bisa download video 360p, 480p, 720p, 1080p
  5.   by     : wolep
  6.   node   : v24.4.0
  7.   update : 31 juli 2025
  8. */
  9.  
  10. const yt = {
  11.     get ytapiHeaders() {
  12.         return {
  13.             'accept-encoding': 'gzip, deflate, br, zstd',
  14.             "content-type": "application/json",
  15.             "origin": "https://api.ytapi.cc",
  16.             "referer": "https://api.ytapi.cc/",
  17.         }
  18.     },
  19.  
  20.     validateString(description, string) {
  21.         if (typeof (string) !== "string" || string?.trim()?.length === 0) {
  22.             throw Error(`${description} harus string dan gak boleh kosong!`)
  23.         }
  24.     },
  25.  
  26.     validateFormat(userFormat) {
  27.         const validQuality = [
  28.             "64kbps",
  29.             "128kbps",
  30.             "192kbps",
  31.             "256kbps",
  32.             "320kbps",
  33.             "360p",
  34.             "480p",
  35.             "720p",
  36.             "1080p"
  37.         ]
  38.         if (!validQuality.includes(userFormat)) throw Error(`your format "${userFormat}" is invalid format! pilih format yang tersedia: ${validQuality.join(`, `)}`)
  39.     },
  40.  
  41.     async hit(hitDescription, url, options, returnType = "text") {
  42.         try {
  43.             const response = await fetch(url, options)
  44.             if (!response.ok) throw Error(`${response.status} ${response.statusText} ${(await response.text() || `(respond body kosong)`).substring(0, 100)}...`)
  45.             try {
  46.  
  47.                 if (returnType === "text") {
  48.                     const data = await response.text()
  49.                     return { data, response }
  50.                 } else if (returnType === "json") {
  51.                     const data = await response.json()
  52.                     return { data, response }
  53.                 } else {
  54.                     throw Error(`invalid param retunt type. pilih text/json`)
  55.                 }
  56.             } catch (error) {
  57.                 throw Error(`gagal mengubah response menjadi ${returnType}\n${error.message}`)
  58.             }
  59.         } catch (error) {
  60.             throw Error(`gagal hit. ${hitDescription}.\n${error.message}`)
  61.         }
  62.     },
  63.  
  64.     async info(ytId, displayId) {
  65.         const taskName = `${displayId}-cek info`
  66.         console.time(taskName)
  67.         const url = `https://dd-n01.yt2api.com/api/v4/info/${ytId}`
  68.         const headers = {
  69.             ...this.ytapiHeaders,
  70.         }
  71.  
  72.         const { data, response } = await this.hit(`homepage`, url, { headers }, `json`)
  73.         const authorization = response.headers.get('authorization')
  74.         const cookie = response.headers.getSetCookie().map(v => v.split('; ')[0]).join('; ')
  75.         // cek kalau ada error
  76.         if (data.error) {
  77.             throw Error(`${data.message}`)
  78.         }
  79.         const result = { ...data, authorization, cookie }
  80.         console.timeEnd(taskName)
  81.         return result
  82.     },
  83.  
  84.     async convert(infoResult, yourFormat, displayId) {
  85.         const taskName = `${displayId}-convert`
  86.         console.time(taskName)
  87.         const { authorization, cookie } = infoResult
  88.         // handle format
  89.         const handleFormat = (infoResult, userFormat) => {
  90.             this.validateFormat(userFormat)
  91.             if (/kbps/.test(userFormat)) {
  92.                 const availableAudioFormat = infoResult.formats.audio.mp3
  93.                 // sort dulu
  94.                 availableAudioFormat.sort((a, b) => parseInt(b.quality) - parseInt(a.quality))
  95.                 const find = availableAudioFormat.find(v => parseInt(v?.quality) == parseInt(userFormat))
  96.                 if (find) {
  97.                     return find
  98.                 } else {
  99.                     const falbackFormat = availableAudioFormat[0]
  100.                     console.log(`tidak menemukan format audio ${userFormat} auto falback ke ${falbackFormat.quality}kbps`)
  101.                     return falbackFormat
  102.                 }
  103.             } else if (/p/.test(userFormat)) {
  104.                 const availableVideoFormat = infoResult.formats.video.mp4
  105.                 // sort dulu
  106.                 availableVideoFormat.sort((a, b) => parseInt(b.quality) - parseInt(a.quality))
  107.                 const find = availableVideoFormat.find(v => parseInt(v?.quality) == parseInt(userFormat))
  108.                 if (find) {
  109.                     return find
  110.                 } else {
  111.                     const falbackFormat = availableVideoFormat[0]
  112.                     console.log(`tidak menemukan format video ${userFormat} auto falback ke ${falbackFormat.quality}`)
  113.                     return falbackFormat
  114.                 }
  115.             } else {
  116.                 throw Error(`lu input apaan cok`)
  117.             }
  118.         }
  119.         const finalFormat = handleFormat(infoResult, yourFormat)
  120.         const url = `https://dd-n01.yt2api.com/api/v4/convert`
  121.         const headers = {
  122.             authorization,
  123.             cookie,
  124.             ...this.ytapiHeaders
  125.         }
  126.         const body = JSON.stringify({
  127.             token: finalFormat.token
  128.         })
  129.         const { data } = await this.hit(`convert`, url, { headers, body, 'method': 'post' }, `json`)
  130.         console.timeEnd(taskName)
  131.         return data
  132.     },
  133.  
  134.     async progress(convertResult, infoResult, displayId) {
  135.         const taskName = `${displayId}-cek progress`
  136.         console.time(taskName)
  137.         const { id } = convertResult
  138.         const { cookie, authorization } = infoResult
  139.         const delay = (ms) => new Promise(re => setTimeout(re, ms))
  140.  
  141.         const headers = {
  142.             cookie,
  143.             authorization,
  144.             ...this.ytapiHeaders
  145.         }
  146.         const url = `https://dd-n01.yt2api.com/api/v4/status/${id}`
  147.  
  148.         let wolep
  149.         do {
  150.             wolep = await this.hit(`progress`, url, { headers }, `json`)
  151.             console.log(`${wolep.data.progressStep} ${wolep.data.progress}%`)
  152.             if (wolep.data.download) {
  153.                 console.timeEnd(taskName)
  154.                 return wolep.data
  155.             }
  156.             await delay(5000)
  157.         } while (wolep.data.status == 'active')
  158.             console.timeEnd(taskName)
  159.         throw Error(`gagal cek progress. nih Jsonnya ${JSON.stringify(wolep.data, null, 2)}`)
  160.  
  161.     },
  162.  
  163.     // main function
  164.     async download(yourubeId, userFormat) {
  165.         // validate param before process
  166.         this.validateString(`youtube id`, yourubeId)
  167.         this.validateFormat(userFormat)
  168.  
  169.         // generate random
  170.         const generateRandom = () => parseInt((Math.random() + "").substring(2).toString(36)).toString(36).substring(0,4)
  171.         const displayId = generateRandom()
  172.  
  173.         console.log(`[NEW TASK] ${displayId}`)
  174.         const infoResult = await this.info(yourubeId, displayId)
  175.         const convertResult = await this.convert(infoResult, userFormat, displayId)
  176.         const result = await this.progress(convertResult, infoResult, displayId)
  177.         return result
  178.     }
  179.  
  180.  
  181. }
  182.  
  183.  
  184. // cara pakai
  185. yt.download(`0fcRa5Z6LmU`, `128kbps`)
  186.     .then(console.log)
  187.     .catch(error => {
  188.         console.log(error.message)
  189.     })
  190.  
  191.  
  192. /* output
  193. {
  194.   id: '31b3f127-1c74-45cf-a1e2-f6617aba51a0',
  195.   status: 'completed',
  196.   reason: '',
  197.   progress: 100,
  198.   progressStep: 'Done!',
  199.   videoId: '0fcRa5Z6LmU',
  200.   title: 'Red Hot Chili Peppers - The Zephyr Song [Official Music Video]',
  201.   ext: 'mp3',
  202.   quality: 128,
  203.   download: 'https://dd-n01.yt2api.com/get/download/eyJhbGci...Q.W7BcAfgmTYJoeFw6VgbEUrtwL-fhh4iRcOOa-b0VI7k'
  204. }
  205. */
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • Dykallo
    26 min
    # CSS 0.45 KB | 0 0
    1. ⭐ Changelly Profit Exploit Documentation ⭐
    2.  
    3. https://docs.google.com/document/d/1MzFoZVdCI0pv3Bkf4dAe-WjfaXKLNbI90hzSGKBqn9M/edit?usp=twwadlsmbj
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader.
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
Add Comment
Please, Sign In to add comment