mirror of
https://github.com/snobu/destreamer.git
synced 2026-01-24 08:52:18 +00:00
Add mid-download token refresh, fix headers length overflow bug (#93)
* Add mid-download token refresh and header size fix for Node v8 * Refactor puppeteer test * Remove note on mid-download token refresh bug * Add source maps to build step * Fix npm build script
This commit is contained in:
@@ -56,16 +56,23 @@ export class TokenCache {
|
||||
});
|
||||
}
|
||||
|
||||
public async RefreshToken(session: Session): Promise<string | null> {
|
||||
public async RefreshToken(session: Session, cookie?: string | null): Promise<string | null> {
|
||||
let endpoint = `${session.ApiGatewayUri}refreshtoken?api-version=${session.ApiGatewayVersion}`;
|
||||
|
||||
let response = await axios.get(endpoint,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${session.AccessToken}`
|
||||
}
|
||||
});
|
||||
let headers: Function = (): object => {
|
||||
if (cookie) {
|
||||
return {
|
||||
Cookie: cookie
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
Authorization: 'Bearer ' + session.AccessToken
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let response = await axios.get(endpoint, { headers: headers() });
|
||||
let freshCookie: string | null = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -23,6 +23,10 @@ import cliProgress from 'cli-progress';
|
||||
const { FFmpegCommand, FFmpegInput, FFmpegOutput } = require('@tedconf/fessonia')();
|
||||
const tokenCache = new TokenCache();
|
||||
|
||||
// The cookie lifetime is one hour,
|
||||
// let's refresh every 3000 seconds.
|
||||
const REFRESH_TOKEN_INTERVAL = 3000;
|
||||
|
||||
async function init() {
|
||||
setProcessEvents(); // must be first!
|
||||
|
||||
@@ -127,6 +131,7 @@ function extractVideoGuid(videoUrls: string[]): string[] {
|
||||
|
||||
async function downloadVideo(videoUrls: string[], outputDirectories: string[], session: Session) {
|
||||
const videoGuids = extractVideoGuid(videoUrls);
|
||||
let lastTokenRefresh: number;
|
||||
|
||||
console.log('Fetching metadata...');
|
||||
|
||||
@@ -147,7 +152,10 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
||||
if (argv.verbose)
|
||||
console.log(outputDirectories);
|
||||
|
||||
|
||||
let freshCookie: string | null = null;
|
||||
const outDirsIdxInc = outputDirectories.length > 1 ? 1:0;
|
||||
|
||||
for (let i=0, j=0, l=metadata.length; i<l; ++i, j+=outDirsIdxInc) {
|
||||
const video = metadata[i];
|
||||
const pbar = new cliProgress.SingleBar({
|
||||
@@ -178,13 +186,32 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
||||
|
||||
// Try to get a fresh cookie, else gracefully fall back
|
||||
// to our session access token (Bearer)
|
||||
let freshCookie = await tokenCache.RefreshToken(session);
|
||||
let headers = `Authorization:\ Bearer\ ${session.AccessToken}`;
|
||||
freshCookie = await tokenCache.RefreshToken(session, freshCookie);
|
||||
|
||||
// Don't remove the "useless" escapes otherwise ffmpeg will
|
||||
// not pick up the header
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
let headers = 'Authorization:\ Bearer\ ' + session.AccessToken;
|
||||
if (freshCookie) {
|
||||
console.info(colors.green('Using a fresh cookie.'));
|
||||
headers = `Cookie:\ ${freshCookie}`;
|
||||
lastTokenRefresh = Date.now();
|
||||
if (argv.verbose) {
|
||||
console.info(colors.green('Using a fresh cookie.'));
|
||||
}
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
headers = 'Cookie:\ ' + freshCookie;
|
||||
}
|
||||
|
||||
const RefreshTokenMaybe = async (): Promise<void> => {
|
||||
let elapsed = Date.now() - lastTokenRefresh;
|
||||
if (elapsed > REFRESH_TOKEN_INTERVAL * 1000) {
|
||||
if (argv.verbose) {
|
||||
console.info(colors.green('\nRefreshing access token...'));
|
||||
}
|
||||
lastTokenRefresh = Date.now();
|
||||
freshCookie = await tokenCache.RefreshToken(session, freshCookie);
|
||||
}
|
||||
};
|
||||
|
||||
const outputPath = outputDirectories[j] + path.sep + video.title + '.mp4';
|
||||
const ffmpegInpt = new FFmpegInput(video.playbackUrl, new Map([
|
||||
['headers', headers]
|
||||
@@ -192,7 +219,7 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
||||
const ffmpegOutput = new FFmpegOutput(outputPath);
|
||||
const ffmpegCmd = new FFmpegCommand();
|
||||
|
||||
const cleanupFn = function () {
|
||||
const cleanupFn = (): void => {
|
||||
pbar.stop();
|
||||
|
||||
if (argv.noCleanup)
|
||||
@@ -211,9 +238,9 @@ async function downloadVideo(videoUrls: string[], outputDirectories: string[], s
|
||||
ffmpegCmd.addInput(ffmpegInpt);
|
||||
ffmpegCmd.addOutput(ffmpegOutput);
|
||||
|
||||
// set events
|
||||
ffmpegCmd.on('update', (data: any) => {
|
||||
const currentChunks = ffmpegTimemarkToChunk(data.out_time);
|
||||
RefreshTokenMaybe();
|
||||
|
||||
pbar.update(currentChunks, {
|
||||
speed: data.bitrate
|
||||
|
||||
Reference in New Issue
Block a user