2024-01-14 13:45:48 -06:00
const fs = require ( 'fs' ) ,
2023-08-21 11:46:48 -05:00
path = require ( 'path' ) ,
express = require ( 'express' ) ,
2024-01-17 19:48:08 -06:00
cp = require ( "child_process" ) ,
ffmpeg = require ( "ffmpeg-static" )
2024-01-25 19:38:25 -06:00
const { stringify } = require ( 'querystring' )
2023-05-05 11:15:22 -05:00
const PORT = process . env . PORT || 8080
const app = express ( )
2023-10-23 10:57:35 -05:00
2024-01-17 19:48:08 -06:00
const MAX _FILESIZE = process . env . MAX _FILESIZE || 500
2024-01-17 19:52:18 -06:00
var formats = {
"mkv" : "matroska"
}
2024-01-17 19:48:08 -06:00
app . get ( "/convert" , async ( req , res ) => {
var file = req . query . file || ""
var format = req . query . format
2024-01-17 22:17:27 -06:00
var url = req . query . url
2024-01-17 19:48:08 -06:00
var filePath = path . join ( _ _dirname , 'downloads' , file )
2024-01-17 22:17:27 -06:00
2024-01-19 18:30:25 -06:00
console . log ( filePath )
2024-01-17 19:48:08 -06:00
if ( fs . existsSync ( filePath ) ) {
2024-01-17 22:17:27 -06:00
var ytdlpProcess = cp . spawnSync ( 'yt-dlp' , [ '--get-filename' , url ] )
var name = ytdlpProcess . stdout . toString ( )
name = name . substring ( 0 , name . lastIndexOf ( "[" ) - 1 )
res . setHeader ( 'Content-Disposition' , ` attachment; filename=" ${ encodeURIComponent ( name ) } . ${ format } " ` ) ;
2024-01-17 19:48:08 -06:00
const ffmpegProcess = cp . spawn ( ffmpeg , [
'-i' , filePath ,
2024-01-17 19:52:18 -06:00
'-f' , formats [ format ] || format ,
'-movflags' , 'frag_keyframe+empty_moov' ,
2024-01-18 20:59:21 -06:00
'-c' , 'copy' ,
2024-01-17 19:48:08 -06:00
'-'
] , {
stdio : [
'pipe' , 'pipe' , 'pipe' , 'pipe' , 'pipe' ,
] ,
} )
2024-01-18 18:05:00 -06:00
// ffmpegProcess.stderr.setEncoding('utf-8')
// ffmpegProcess.stderr.on('data', (data) => {
// console.log(data)
// })
2024-01-17 19:48:08 -06:00
// These are debugging lines to watch FFMPEG output :3
2024-01-18 18:05:00 -06:00
ffmpegProcess . stdio [ 1 ] . pipe ( res )
. on ( 'close' , ( ) => {
fs . rmSync ( filePath )
} )
2024-01-17 19:48:08 -06:00
}
} )
2023-10-23 10:57:35 -05:00
2023-11-20 14:39:04 -06:00
app . get ( "/download" , async ( req , res ) => {
2023-05-08 12:52:41 -05:00
const url = req . query . url
2023-12-09 12:10:50 -06:00
const format = req . query . format || 'mp4'
2024-01-25 19:38:25 -06:00
const quality = req . query . quality || '720'
2023-05-10 12:36:26 -05:00
2023-10-25 22:07:48 -05:00
res . setHeader ( "X-Accel-Buffering" , "no" )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
var fileName = Math . ceil ( Math . random ( ) * 100_000_000_000 ) . toString ( )
console . log ( fileName )
var videoName = cp . spawnSync ( 'yt-dlp' , [ '-S' , 'res:' + quality , '--get-filename' , url ] ) . stdout . toString ( )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
videoName = videoName . substring ( 0 , videoName . lastIndexOf ( '.' ) )
videoName = videoName . substring ( 0 , videoName . lastIndexOf ( '[' ) )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
if ( ! [ "mp3" , "wav" , "ogx" ] . includes ( format ) && Number ( quality ) > 720 ) {
res . setHeader ( "Content-Type" , "text/html" )
2024-01-18 18:05:00 -06:00
2024-01-25 19:38:25 -06:00
var downloadHTML = fs . readFileSync ( path . join ( _ _dirname , 'resources/downloading.html' ) ) . toString ( )
res . write ( downloadHTML . substring ( 0 , downloadHTML . indexOf ( "{CONTENT}" ) ) )
var filePath = path . join ( _ _dirname , 'downloads' , fileName )
2024-01-17 20:22:19 -06:00
var ytdlpProcess = cp . spawn ( 'yt-dlp' , [
url ,
2024-01-25 19:38:25 -06:00
'-o' , filePath ,
2024-01-17 20:39:08 -06:00
'--max-filesize' , MAX _FILESIZE + 'm' ,
2024-01-18 18:05:00 -06:00
'-S' , 'res:' + quality ,
'--no-playlist' ,
2024-01-17 20:22:19 -06:00
] )
2024-01-25 19:38:25 -06:00
var lastDownload = 0
ytdlpProcess . stderr . setEncoding ( 'utf-8' )
ytdlpProcess . stderr . on ( 'data' , ( data ) => {
console . log ( data )
res . write ( ` <div class="error"><p> ` + data + ` </p></div> ` )
} )
var debounce = false
ytdlpProcess . stdout . setEncoding ( 'utf-8' )
ytdlpProcess . stdout . on ( 'data' , ( data ) => {
if ( ! debounce ) {
if ( data . includes ( "max-filesize" ) ) {
debounce = true
res . write ( ` <p>Uh oh! The video you're trying to download is too large for this server's current settings ${ MAX _FILESIZE } . Please try another server? (Visit main page and go to the codeberg for a list of instances!)</p> ` )
}
else if ( data . includes ( "[download]" ) ) {
res . write ( ` <style>#downloading ${ lastDownload } { display: none; }</style> ` )
lastDownload += 1
res . write ( ` <p id="downloading ${ lastDownload } "> ` + data . substring ( 12 ) + ` </p> ` )
}
}
} )
var exited = false
ytdlpProcess . on ( 'close' , ( ) => {
var files = fs . readdirSync ( path . join ( _ _dirname , 'downloads' ) )
for ( let index = 0 ; index < files . length ; index ++ ) {
const file = files [ index ] ;
console . log ( file )
if ( file . includes ( fileName ) ) {
fileName = file
filePath = path . join ( _ _dirname , 'downloads' , fileName )
}
}
if ( exited ) {
if ( fs . existsSync ( filePath ) ) {
fs . rmSync ( filePath )
}
}
else if ( fs . existsSync ( filePath ) ) {
res . write ( ` <iframe src="/convert?file= ${ fileName } &format= ${ format } &url= ${ url } "></iframe>" ` )
res . write ( downloadHTML . substring ( downloadHTML . indexOf ( "{CONTENT}" ) + 9 ) + ` <meta http-equiv="Refresh" content="0; url='/'" /> ` , ( ) => { res . end ( ) } )
} else {
res . write ( "<p>An error has occured!!! We're not exactly sure what the error is, but we cant seem to find the download file. Double check the URL, and if the URL is fine, then file an issue on codeberg. </p>" )
}
} )
res . on ( "error" , ( ) => {
if ( fs . existsSync ( filePath ) ) {
fs . rmSync ( filePath )
}
exited = true
} )
} else if ( [ "mp3" , "wav" , "ogx" ] . includes ( format ) ) {
res . setHeader ( 'Content-Disposition' , ` attachment; filename=" ${ encodeURIComponent ( videoName ) } . ${ format } " ` ) ;
2024-01-19 18:30:25 -06:00
2024-01-17 20:22:19 -06:00
var ytdlpProcess = cp . spawn ( 'yt-dlp' , [
url ,
'-x' ,
2024-01-25 19:38:25 -06:00
'-o' , '-' ,
2024-01-17 20:22:19 -06:00
'--max-filesize' , MAX _FILESIZE + 'm' ,
2024-01-19 18:30:25 -06:00
'--audio-format' , 'mp3' ,
2024-01-25 19:38:25 -06:00
'--no-playlist' ,
2024-01-17 20:22:19 -06:00
] )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
const ffmpegProcess = cp . spawn ( ffmpeg , [
'-i' , 'pipe:3' ,
'-f' , formats [ format ] || format ,
'-movflags' , 'frag_keyframe+empty_moov' ,
'-c:a' , 'libmp3lame' ,
'-preset' , 'ultrafast' ,
'-crf' , '23' ,
'-loglevel' , 'error' ,
'-'
] , {
stdio : [
'pipe' , 'pipe' , 'pipe' , 'pipe' , 'pipe' ,
] ,
} )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
ytdlpProcess . stdout . pipe ( ffmpegProcess . stdio [ 3 ] )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
ytdlpProcess . stderr . setEncoding ( 'utf-8' )
ytdlpProcess . stderr . on ( 'data' , ( data ) => {
console . log ( data )
} )
2024-01-17 19:48:08 -06:00
2024-01-25 19:38:25 -06:00
ffmpegProcess . stdio [ 1 ] . pipe ( res )
} else {
res . setHeader ( 'Content-Disposition' , ` attachment; filename=" ${ encodeURIComponent ( videoName ) } . ${ format } " ` ) ;
var ytdlpProcess = cp . spawn ( 'yt-dlp' , [
url ,
'-o' , '-' ,
'--max-filesize' , MAX _FILESIZE + 'm' ,
'--no-playlist' ,
] )
2023-10-25 22:07:48 -05:00
2024-01-25 19:38:25 -06:00
const ffmpegProcess = cp . spawn ( ffmpeg , [
'-i' , 'pipe:3' ,
'-f' , formats [ format ] || format ,
'-movflags' , 'frag_keyframe+empty_moov' ,
'-c:a' , 'libmp3lame' ,
'-preset' , 'ultrafast' ,
'-crf' , '23' ,
'-loglevel' , 'error' ,
'-'
] , {
stdio : [
'pipe' , 'pipe' , 'pipe' , 'pipe' , 'pipe' ,
] ,
} )
2024-01-18 18:05:00 -06:00
2024-01-25 19:38:25 -06:00
ytdlpProcess . stdout . pipe ( ffmpegProcess . stdio [ 3 ] )
2024-01-07 16:37:37 -06:00
2024-01-25 19:38:25 -06:00
ytdlpProcess . stderr . setEncoding ( 'utf-8' )
ytdlpProcess . stderr . on ( 'data' , ( data ) => {
console . log ( data )
} )
2024-01-17 20:39:08 -06:00
2024-01-25 19:38:25 -06:00
ffmpegProcess . stdio [ 1 ] . pipe ( res )
}
2024-01-17 20:39:08 -06:00
2023-10-20 18:03:54 -05:00
} )
2023-05-05 11:15:22 -05:00
app . use ( express . static ( path . join ( _ _dirname , 'static' ) ) )
2023-05-10 12:36:26 -05:00
app . listen ( PORT , function ( ) {
2023-05-05 11:15:22 -05:00
console . log ( "Hosted on port " + PORT )
} )