mirror of
https://github.com/snobu/destreamer.git
synced 2026-02-14 10:39:41 +00:00
Download a list of videos
This commit is contained in:
@@ -4,13 +4,21 @@ import { terminal as term } from 'terminal-kit';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { BrowserTests } from './BrowserTests';
|
import { BrowserTests } from './BrowserTests';
|
||||||
|
import yargs = require('yargs');
|
||||||
|
|
||||||
// Type in your username here (the one you use to
|
// Type in your username here (the one you use to
|
||||||
// login to Microsoft Stream).
|
// login to Microsoft Stream).
|
||||||
const username: string = 'somebody@example.com';
|
const args: string[] = process.argv.slice(2); // TODO: Remove this
|
||||||
const args: string[] = process.argv.slice(2);
|
|
||||||
const videoUrl: string = args[0];
|
const argv = yargs.options({
|
||||||
const outputDirectory: string = 'videos';
|
videoUrls: { type: 'array', demandOption: true },
|
||||||
|
username: { type: 'string', demandOption: true },
|
||||||
|
outputDirectory: { type: 'string', default: 'videos' }
|
||||||
|
}).argv;
|
||||||
|
|
||||||
|
console.info('Video URLs: %s', argv.videoUrls);
|
||||||
|
console.info('Username: %s', argv.username);
|
||||||
|
console.info('Output Directory: %s', argv.outputDirectory);
|
||||||
|
|
||||||
function sanityChecks() {
|
function sanityChecks() {
|
||||||
try {
|
try {
|
||||||
@@ -31,10 +39,10 @@ function sanityChecks() {
|
|||||||
console.error('FFmpeg is missing. You need a fairly recent release of FFmpeg in $PATH.');
|
console.error('FFmpeg is missing. You need a fairly recent release of FFmpeg in $PATH.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fs.existsSync(outputDirectory)){
|
if (!fs.existsSync(argv.outputDirectory)){
|
||||||
console.log('Creating output directory: ' +
|
console.log('Creating output directory: ' +
|
||||||
process.cwd() + path.sep + outputDirectory);
|
process.cwd() + path.sep + argv.outputDirectory);
|
||||||
fs.mkdirSync(outputDirectory);
|
fs.mkdirSync(argv.outputDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args[0] == null || args[0].length < 10) {
|
if (args[0] == null || args[0].length < 10) {
|
||||||
@@ -44,7 +52,7 @@ function sanityChecks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function rentVideoForLater() {
|
async function rentVideoForLater(videoUrls: string[], username: string, outputDirectory: string) {
|
||||||
console.log('Launching headless Chrome to perform the OpenID Connect dance...');
|
console.log('Launching headless Chrome to perform the OpenID Connect dance...');
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
// Switch to false if you need to login interactively
|
// Switch to false if you need to login interactively
|
||||||
@@ -56,7 +64,7 @@ async function rentVideoForLater() {
|
|||||||
|
|
||||||
// This breaks on slow connections, needs more reliable logic
|
// This breaks on slow connections, needs more reliable logic
|
||||||
//const oidcUrl = "https://login.microsoftonline.com/common/oauth2/authorize?client_id=cf53fce8-def6-4aeb-8d30-b158e7b1cf83&response_mode=form_post&response_type=code+id_token&scope=openid+profile&state=OpenIdConnect.AuthenticationProperties%3d1VtrsKV5QUHtzn8cDWL4wJmacu-VHH_DfpPxMQBhnfbar-_e8X016GGJDPfqfvcyUK3F3vBoiFwUpahR2ANfrzHE469vcw7Mk86wcAqBGXCvAUmv59MDU_OZFHpSL360oVRBo84GfVXAKYdhCjhPtelRHLHEM_ADiARXeMdVTAO3SaTiVQMhw3c9vLWuXqrKKevpI7E5esCQy5V_dhr2Q7kKrlW3gHX0232b8UWAnSDpc-94&nonce=636832485747560726.NzMyOWIyYWQtM2I3NC00MmIyLTg1NTMtODBkNDIwZTI1YjAxNDJiN2JkNDMtMmU5Ni00OTc3LWFkYTQtNTNlNmUwZmM1NTVl&nonceKey=OpenIdConnect.nonce.F1tPks6em0M%2fWMwvatuGWfFM9Gj83LwRKLvbx9rYs5M%3d&site_id=500453&redirect_uri=https%3a%2f%2fmsit.microsoftstream.com%2f&post_logout_redirect_uri=https%3a%2f%2fproducts.office.com%2fmicrosoft-stream&msafed=0";
|
//const oidcUrl = "https://login.microsoftonline.com/common/oauth2/authorize?client_id=cf53fce8-def6-4aeb-8d30-b158e7b1cf83&response_mode=form_post&response_type=code+id_token&scope=openid+profile&state=OpenIdConnect.AuthenticationProperties%3d1VtrsKV5QUHtzn8cDWL4wJmacu-VHH_DfpPxMQBhnfbar-_e8X016GGJDPfqfvcyUK3F3vBoiFwUpahR2ANfrzHE469vcw7Mk86wcAqBGXCvAUmv59MDU_OZFHpSL360oVRBo84GfVXAKYdhCjhPtelRHLHEM_ADiARXeMdVTAO3SaTiVQMhw3c9vLWuXqrKKevpI7E5esCQy5V_dhr2Q7kKrlW3gHX0232b8UWAnSDpc-94&nonce=636832485747560726.NzMyOWIyYWQtM2I3NC00MmIyLTg1NTMtODBkNDIwZTI1YjAxNDJiN2JkNDMtMmU5Ni00OTc3LWFkYTQtNTNlNmUwZmM1NTVl&nonceKey=OpenIdConnect.nonce.F1tPks6em0M%2fWMwvatuGWfFM9Gj83LwRKLvbx9rYs5M%3d&site_id=500453&redirect_uri=https%3a%2f%2fmsit.microsoftstream.com%2f&post_logout_redirect_uri=https%3a%2f%2fproducts.office.com%2fmicrosoft-stream&msafed=0";
|
||||||
await page.goto(videoUrl, { waitUntil: 'networkidle2' });
|
await page.goto(videoUrls[0], { waitUntil: 'networkidle2' });
|
||||||
await page.waitForSelector('input[type="email"]');
|
await page.waitForSelector('input[type="email"]');
|
||||||
await page.keyboard.type(username);
|
await page.keyboard.type(username);
|
||||||
await page.click('input[type="submit"]');
|
await page.click('input[type="submit"]');
|
||||||
@@ -66,40 +74,42 @@ async function rentVideoForLater() {
|
|||||||
await sleep(1500);
|
await sleep(1500);
|
||||||
console.log('Sorry, i mean "you".');
|
console.log('Sorry, i mean "you".');
|
||||||
|
|
||||||
await page.goto(videoUrl, { waitUntil: 'networkidle2' });
|
for (let videoUrl of videoUrls) {
|
||||||
await sleep(2000);
|
await page.goto(videoUrl, { waitUntil: 'networkidle2' });
|
||||||
// try this instead of hardcoding sleep
|
await sleep(2000);
|
||||||
// https://github.com/GoogleChrome/puppeteer/issues/3649
|
// try this instead of hardcoding sleep
|
||||||
|
// https://github.com/GoogleChrome/puppeteer/issues/3649
|
||||||
|
|
||||||
const cookie = await exfiltrateCookie(page);
|
const cookie = await exfiltrateCookie(page);
|
||||||
console.log('Got cookie. Consuming cookie...');
|
console.log('Got cookie. Consuming cookie...');
|
||||||
|
|
||||||
await sleep(4000);
|
await sleep(4000);
|
||||||
console.log('Looking up AMS stream locator...');
|
console.log('Looking up AMS stream locator...');
|
||||||
let amp: any;
|
let amp: any;
|
||||||
const amsUrl = await page.evaluate(
|
const amsUrl = await page.evaluate(
|
||||||
() => { return amp.Player.players["vjs_video_3"].cache_.src }
|
() => { return amp.Player.players["vjs_video_3"].cache_.src }
|
||||||
);
|
);
|
||||||
|
|
||||||
const title = await page.evaluate(
|
const title = await page.evaluate(
|
||||||
// Clear abuse of null assertion operator,
|
// Clear abuse of null assertion operator,
|
||||||
// someone fix this please
|
// someone fix this please
|
||||||
() => { return document!.querySelector(".title")!.textContent!.trim() }
|
() => { return document!.querySelector(".title")!.textContent!.trim() }
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(`Video title is: ${title}`);
|
console.log(`Video title is: ${title}`);
|
||||||
|
|
||||||
|
console.log('Constructing HLS URL...');
|
||||||
|
const hlsUrl = amsUrl.substring(0, amsUrl.lastIndexOf('/')) + '/manifest(format=m3u8-aapl)';
|
||||||
|
|
||||||
|
console.log('Spawning youtube-dl with cookie and HLS URL...');
|
||||||
|
const youtubedlCmd = 'youtube-dl --no-call-home --no-warnings ' +
|
||||||
|
`--output "${outputDirectory}/${title}.mp4" --add-header Cookie:"${cookie}" "${hlsUrl}"`;
|
||||||
|
// console.log(`\n\n[DEBUG] Invoking youtube-dl: ${youtubedlCmd}\n\n`);
|
||||||
|
var result = execSync(youtubedlCmd, { stdio: 'inherit' });
|
||||||
|
}
|
||||||
|
|
||||||
console.log("At this point Chrome's job is done, shutting it down...");
|
console.log("At this point Chrome's job is done, shutting it down...");
|
||||||
await browser.close();
|
await browser.close();
|
||||||
|
|
||||||
console.log('Constructing HLS URL...');
|
|
||||||
const hlsUrl = amsUrl.substring(0, amsUrl.lastIndexOf('/')) + '/manifest(format=m3u8-aapl)';
|
|
||||||
|
|
||||||
console.log('Spawning youtube-dl with cookie and HLS URL...');
|
|
||||||
const youtubedlCmd = 'youtube-dl --no-call-home --no-progress --no-warnings ' +
|
|
||||||
`--output "${outputDirectory}/${title}.mp4" --add-header Cookie:"${cookie}" "${hlsUrl}"`;
|
|
||||||
// console.log(`\n\n[DEBUG] Invoking youtube-dl: ${youtubedlCmd}\n\n`);
|
|
||||||
var result = execSync(youtubedlCmd, { stdio: 'inherit' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sleep(ms: number) {
|
function sleep(ms: number) {
|
||||||
@@ -134,5 +144,5 @@ if (args[0] === 'test')
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
sanityChecks();
|
sanityChecks();
|
||||||
rentVideoForLater();
|
rentVideoForLater(argv.videoUrls as string[], argv.username, argv.outputDirectory);
|
||||||
}
|
}
|
||||||
@@ -18,11 +18,13 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/puppeteer": "^1.20.0",
|
"@types/puppeteer": "^1.20.0",
|
||||||
"@types/terminal-kit": "^1.28.0"
|
"@types/terminal-kit": "^1.28.0",
|
||||||
|
"@types/yargs": "^15.0.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"puppeteer": "^1.20.0",
|
"puppeteer": "^1.20.0",
|
||||||
"terminal-kit": "^1.26.10",
|
"terminal-kit": "^1.26.10",
|
||||||
"typescript": "^3.6.3"
|
"typescript": "^3.6.3",
|
||||||
|
"yargs": "^15.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user