2024-03-29 17:48:59 +00:00
const wget = require ( 'wget-improved' )
2023-09-30 15:32:32 +00:00
const DOMPurify = require ( 'isomorphic-dompurify' )
2024-03-29 14:32:12 +00:00
const metadata = require ( './metadata.js' )
2024-03-29 17:48:59 +00:00
const hr = require ( '@tsmx/human-readable' )
2023-03-03 16:44:40 +00:00
2024-03-29 14:32:12 +00:00
async function downloadVideo ( url , ws , id ) {
return new Promise ( async ( resolve , reject ) => {
2024-03-30 17:04:00 +00:00
let quality = '720'
2024-03-29 14:32:12 +00:00
const video = await metadata . getVideoMetadata ( id )
2024-03-30 10:11:49 +00:00
if ( video . error ) {
2024-03-30 13:32:37 +00:00
return resolve ( {
2024-03-30 10:11:49 +00:00
message : ` Failed to request Youtube with error ${ video . error } . Please retry... ` ,
fail : true
} )
}
2024-03-30 17:04:00 +00:00
if ( video . basic _info . duration >= 900 ) quality = '360' // 15 minutes
2024-03-30 10:11:49 +00:00
2024-03-29 17:48:59 +00:00
const downloadJson = await metadata . getVideoDownload ( url , quality )
2024-03-29 18:30:04 +00:00
if ( downloadJson . status == 'error' ) {
2024-03-30 13:32:37 +00:00
return resolve ( {
2024-06-07 16:13:45 +00:00
message : ` Failed to request Youtube with error ${ downloadJson . text } . Please retry... ` ,
2024-03-29 18:30:04 +00:00
fail : true
} )
}
2024-03-29 14:32:12 +00:00
2024-03-29 17:48:59 +00:00
let size = ''
2024-03-29 18:30:04 +00:00
let startTime = Date . now ( )
let prevBytes = 0
let speed = 0
2024-03-29 17:48:59 +00:00
const alreadyPrecentages = [ ]
2024-06-10 18:05:37 +00:00
const target = Array . isArray ( downloadJson . url ) ? downloadJson . url [ 0 ] : downloadJson . url
2024-06-28 17:59:56 +00:00
const download = wget . download ( target , ` ./videos/ ${ id } .mp4 ` )
2023-03-03 16:44:40 +00:00
2024-03-29 17:48:59 +00:00
download . on ( 'start' , fileSize => {
size = fileSize
2024-03-30 17:12:30 +00:00
if ( ws ) ws . send ( ` DATA - Download has started in ${ quality } p ` )
2023-03-03 16:44:40 +00:00
} )
2024-03-29 17:48:59 +00:00
download . on ( 'progress' , progress => {
if ( alreadyPrecentages . includes ( ( progress * 100 ) . toFixed ( 0 ) ) ) return
alreadyPrecentages . push ( ( progress * 100 ) . toFixed ( 0 ) )
2024-03-29 18:30:04 +00:00
const currentTime = Date . now ( )
const elapsedTime = ( currentTime - startTime ) / 1000
const currentBytes = progress * size
const bytesDownloaded = currentBytes - prevBytes
speed = bytesDownloaded / elapsedTime
prevBytes = currentBytes
const speedInMBps = speed / 1048576
const remainingBytes = size - currentBytes
const remainingTime = remainingBytes / speed
if ( ws ) ws . send ( ` DATA - [download] ${ ( progress * 100 ) . toFixed ( 2 ) } % of ${ hr . fromBytes ( size ) } at ${ speedInMBps . toFixed ( 2 ) } MB/s ETA ${ secondsToTime ( remainingTime . toFixed ( 0 ) ) } ` )
2024-03-29 14:32:12 +00:00
} )
2024-03-29 17:48:59 +00:00
download . on ( 'error' , err => {
if ( ws ) ws . send ( ` DATA - ${ DOMPurify . sanitize ( err ) } ` )
2024-03-29 14:32:12 +00:00
} )
2024-03-29 17:48:59 +00:00
download . on ( 'end' , output => {
if ( output == 'Finished writing to disk' ) {
ws . send ( ` DATA - Download has finished ` )
2024-03-30 13:32:37 +00:00
return resolve ( {
2024-03-29 17:48:59 +00:00
fail : false
} )
} else {
2024-03-30 13:32:37 +00:00
return resolve ( {
2024-03-29 14:32:12 +00:00
fail : true
} )
}
} )
} )
}
2024-03-29 18:30:04 +00:00
function secondsToTime ( seconds ) {
const minutes = Math . floor ( seconds / 60 ) ;
const remainingSeconds = seconds % 60 ;
const formattedSeconds = remainingSeconds < 10 ? '0' + remainingSeconds : remainingSeconds ;
return ` ${ minutes } : ${ formattedSeconds } ` ;
}
2023-03-03 16:44:40 +00:00
module . exports = { downloadVideo }