zenmdl
Version:
106 lines (83 loc) • 3.34 kB
JavaScript
const fs = require('fs')
const os = require('os');
const path = require('path')
const ytdl = require('@distube/ytdl-core')
const yts = require('yt-search')
const ytdlcore = require('ytdl-core')
function ensureDownloadDirs(basePath) {
if (!fs.existsSync(basePath)) {
fs.mkdirSync(basePath, { recursive: true })
}
return basePath
}
const sanitizeFilename = (filename) => {
return filename.replace(/[<>:"/\\|?*]+/g, '').replace(/\s+/g, '_').toLowerCase()
}
const user = os.userInfo().username
async function downloadYouTube(query, type = 'video', downloadPath = `C:/Users/${user}/Downloads`, codec = 'avc1') {
try {
console.log(`\n🔎 Buscando: ${query}...`)
const resultados = await yts(query)
if (resultados.videos.length === 0) {
console.log("❌ Nenhum vídeo encontrado.")
return
}
const url = resultados.videos[0].url
console.log(`🎯 Vídeo encontrado: ${url}`)
const downloadDir = ensureDownloadDirs(downloadPath)
// Configura as opções com o codec H.264 (avc1)
const options = {
quality: type === 'audio' ? 'highestaudio' : 'highestvideo',
filter: (format) => {
if (type === 'audio') return format.audioQuality
return format.container === 'mp4' && format.codecs.includes(codec)
}
}
const fileExtension = type === 'audio' ? 'mp3' : 'mp4'
const sanitizedQuery = sanitizeFilename(resultados.videos[0].title) + `.${fileExtension}`
const filePath = path.join(downloadDir, sanitizedQuery)
let downloaded = 0
const stream = ytdl(url, options)
const fileStream = fs.createWriteStream(filePath)
stream.on('progress', (_, downloadedBytes, totalBytes) => {
downloaded = downloadedBytes
const percent = ((downloaded / totalBytes) * 100).toFixed(2)
process.stdout.write('\r' + `📥 Progresso: ${percent}% (${(downloaded / 1024 / 1024).toFixed(2)} MB)`)
})
return new Promise((resolve, reject) => {
stream.pipe(fileStream)
stream.on('end', () => {
console.log(`\n✅ Download concluído: ${filePath} (${(downloaded / 1024 / 1024).toFixed(2)} MB)`)
resolve(filePath)
})
stream.on('error', err => {
console.error('❌ Erro no download:', err.message)
reject(err)
})
})
} catch (error) {
console.error('❌ Erro geral:', error.message)
throw error
}
}
async function search(query) {
try {
const resultados = await yts(query)
const url = resultados.videos[0].url
const title = resultados.videos[0].title;
const description = resultados.videos[0].description;
const channel = {
name: resultados.videos[0].author.name,
url: resultados.videos[0].author.url,
};
const views = resultados.videos[0].views;
const duration = resultados.videos[0].duration;
const thumbnail = resultados.videos[0].image;
const videoId = resultados.videos[0].videoId;
return { title, description, channel, views, duration, thumbnail, videoId, url };
} catch (error) {
console.error('Erro ao obter informações do vídeo:', error.message);
return null;
}
}
module.exports = { downloadYouTube, search }