UNPKG

vivo-dl

Version:

download videos from vivo.sx

119 lines (118 loc) 5.21 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.vivodl = void 0; const fs = __importStar(require("fs")); const node_fetch_1 = __importDefault(require("node-fetch")); const puppeteer_extra_plugin_stealth_1 = __importDefault(require("puppeteer-extra-plugin-stealth")); const cheerio_1 = __importDefault(require("cheerio")); const video_1 = require("./models/video"); const puppeteer_extra_1 = __importDefault(require("puppeteer-extra")); const mkdirp_1 = __importDefault(require("mkdirp")); async function vivodl(destinationFolder = "", vivoUrls = []) { let videos = []; try { if (!fs.existsSync(destinationFolder)) { await mkdirp_1.default(destinationFolder); } videos = await fetchVideoSources(vivoUrls); await downloadVideos(videos, destinationFolder); fs.writeFileSync(destinationFolder + "/resources.json", JSON.stringify(videos, null, 2)); } catch (error) { console.error(`❌ It seems like something went wrong: ${error}`); } return videos; } exports.vivodl = vivodl; async function fetchVideoSources(vivoUrls) { console.log("▶ Fetching all video sources"); const videos = []; puppeteer_extra_1.default.use(puppeteer_extra_plugin_stealth_1.default()); const browser = await puppeteer_extra_1.default.launch({ headless: true }); const context = await browser.createIncognitoBrowserContext(); await Promise.all(vivoUrls.map(async (vivoUrl) => { const page = await context.newPage(); intercept(page); if (!vivoUrl.includes("vivo.sx")) { console.log(`⚠ Skipping ${vivoUrl} because it is not a valid vivo url.`); return; } await page.goto(vivoUrl); try { await Promise.all([ page.waitForSelector("div.stream-content", { timeout: 60000 }), page.waitForSelector("source", { timeout: 60000 }), ]); } catch (error) { console.log(`⚠ Skipping ${vivoUrl} because the video could not be found.`); return; } const $ = cheerio_1.default.load(await page.evaluate(() => document.body.innerHTML)); await page.close(); const extractedName = $("div.stream-content").attr("data-name"); const extractedUrl = $("source").attr("src"); videos.push(new video_1.Video(extractedName, extractedUrl, vivoUrl)); })); await browser.close(); console.log(`✔ Fetched ${videos.length} video sources`); return videos; } async function downloadVideos(videos, destinationFolder = "") { if (destinationFolder == "") { console.log("✨ Fetched the video URIs}"); return; } console.log("▶ Starting video downloads"); destinationFolder = stripPath(destinationFolder); let downloadedVideos = 0; await Promise.all(videos.map(async (video) => { console.log(`▶ Downloading video ${video.filename} from ${video.vivoUrl}`); const dest = `${destinationFolder}/${video.filename}`; const response = await node_fetch_1.default(video.videoUrl); try { await fs.promises.writeFile(dest, await response.buffer()); console.log(`✔ Downloaded video (${++downloadedVideos}/${videos.length}) ${video.filename} from ${video.vivoUrl}`); } catch (error) { console.error(`❌ Failed to download video (${++downloadedVideos}/${videos.length}) ${video.filename} from ${video.vivoUrl}: ${error}`); } })); console.log(`✨ Downloaded ${downloadedVideos} of ${videos.length} videos to ${destinationFolder}`); } function stripPath(path) { return path.replace(/\/$/, ""); } async function intercept(page) { await page.setRequestInterception(true); page.on('request', request => { if (request.resourceType() === 'font' || request.resourceType() === 'image' || request.resourceType() === 'stylesheet') { request.abort(); return; } request.continue(); return; }); }