1
0
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:
Adrian Calinescu
2020-04-26 22:54:05 +03:00
committed by GitHub
parent 67cb62ce3c
commit 042e79d57f
12 changed files with 94 additions and 46 deletions

View File

@@ -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 {

View File

@@ -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