1
0
mirror of https://github.com/snobu/destreamer.git synced 2026-02-02 13:22:18 +00:00

Fixes and refactoring (#59)

* Input url list: Fix bad Windows behavior

* Minor output fix

* Fix all download issues
  - downloads are synchronous again
  - fix progress bar (fix #39)
  - nuke fluent and switch to a bug-free ffmpeg module (fessonia)

* Move destreamer process events to a new file, we may add more in the future, lets give them their own space

* Destreamer: Release packages and builder script

ETA when? :P

* Clean up

* Implement yargs checks and add --videoUrlsFile option

* Refactor error handling
  - Human readable
  - No magic numbers

* Handle mkdir error
  - remove reduntant message

* gitignore: don't add hidden files

* Implement --outputDirectories

This gives us more flexibility on where to save videos

..especially if your videos have all the same name <.<

* Rename utils -> Utils

* Fix tests

don't import yargs on files other than main

* Create scripts directory

* Update make_release path

* Fix typo

* Create CONTRIBUTING.md

Co-authored-by: kylon <kylonux@gmail.com>
This commit is contained in:
kylon
2020-04-14 14:59:14 +02:00
committed by GitHub
parent 05c36fe718
commit 176fa6e214
15 changed files with 709 additions and 208 deletions

141
src/Utils.ts Normal file
View File

@@ -0,0 +1,141 @@
import { ERROR_CODE } from './Errors';
import { execSync } from 'child_process';
import colors from 'colors';
import fs from 'fs';
import path from 'path';
function sanitizeUrls(urls: string[]) {
const rex = new RegExp(/(?:https:\/\/)?.*\/video\/[a-z0-9]{8}-(?:[a-z0-9]{4}\-){3}[a-z0-9]{12}$/, 'i');
const sanitized: string[] = [];
for (let i=0, l=urls.length; i<l; ++i) {
const urlAr = urls[i].split('?');
const query = urlAr.length === 2 && urlAr[1] !== '' ? '?'+urlAr[1] : '';
let url = urlAr[0];
if (!rex.test(url)) {
if (url !== '')
console.warn(colors.yellow('Invalid URL at line ' + (i+1) + ', skip..'));
continue;
}
if (url.substring(0, 8) !== 'https://')
url = 'https://'+url;
sanitized.push(url+query);
}
if (!sanitized.length)
process.exit(ERROR_CODE.INVALID_INPUT_URLS);
return sanitized;
}
function sanitizeOutDirsList(dirsList: string[]) {
const sanitized: string[] = [];
dirsList.forEach(dir => {
if (dir !== '')
sanitized.push(dir);
});
return sanitized;
}
function readFileToArray(path: string) {
return fs.readFileSync(path).toString('utf-8').split(/[\r\n]/);
}
export function parseVideoUrls(videoUrls: any) {
let t = videoUrls[0] as string;
const isPath = t.substring(t.length-4) === '.txt';
let urls: string[];
if (isPath)
urls = readFileToArray(t);
else
urls = videoUrls as string[];
return sanitizeUrls(urls);
}
export function getOutputDirectoriesList(outDirArg: string) {
const isList = outDirArg.substring(outDirArg.length-4) === '.txt';
let dirsList: string[];
if (isList)
dirsList = sanitizeOutDirsList(readFileToArray(outDirArg));
else
dirsList = [outDirArg];
return dirsList;
}
export function makeOutputDirectories(dirsList: string[]) {
dirsList.forEach(dir => {
if (!fs.existsSync(dir)) {
console.info(colors.yellow('Creating output directory:'));
console.info(colors.green(dir)+'\n');
try {
fs.mkdirSync(dir, { recursive: true });
} catch(e) {
process.exit(ERROR_CODE.INVALID_OUTPUT_DIR);
}
}
});
}
export function checkOutDirsUrlsMismatch(dirsList: string[], urlsList: string[]) {
const dirsListL = dirsList.length;
const urlsListL = urlsList.length;
if (dirsListL == 1) // one out dir, treat this as the chosen one for all
return;
else if (dirsListL != urlsListL)
process.exit(ERROR_CODE.OUTDIRS_URLS_MISMATCH);
}
export function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function checkRequirements() {
try {
const ffmpegVer = execSync('ffmpeg -version').toString().split('\n')[0];
console.info(colors.green(`Using ${ffmpegVer}\n`));
} catch (e) {
process.exit(ERROR_CODE.MISSING_FFMPEG);
}
}
export function makeUniqueTitle(title: string, outDir: string) {
let ntitle = title;
let k = 0;
while (fs.existsSync(outDir + path.sep + ntitle + '.mp4'))
ntitle = title + ' - ' + (++k).toString();
return ntitle;
}
export function ffmpegTimemarkToChunk(timemark: string) {
const timeVals: string[] = timemark.split(':');
const hrs = parseInt(timeVals[0]);
const mins = parseInt(timeVals[1]);
const secs = parseInt(timeVals[2]);
return hrs * 1000 + mins * 100 + secs;
}