Ability to reduce unnecessary bandwidth usage

This commit is contained in:
RavensRain 2022-09-11 10:41:21 +02:00
parent c3835cb79b
commit f6303c1a6e
10 changed files with 61 additions and 14 deletions

View file

@ -25,7 +25,8 @@ export type CrunchyDownloadOptions = {
mkvmergeOptions: string[],
defaultSub: LanguageItem,
defaultAudio: LanguageItem,
ccTag: string
ccTag: string,
dlVideoOnce: boolean
}
export type CurnchyMultiDownload = {

View file

@ -31,6 +31,7 @@ export type QueueItem = {
season: string
},
q: number,
dlVideoOnce: boolean,
dubLang: string[],
image: string
}
@ -40,6 +41,7 @@ export type ResolveItemsData = {
dubLang: string[],
all: boolean,
but: boolean,
dlVideoOnce: boolean,
e: string,
fileName: string,
q: number,
@ -95,7 +97,7 @@ export type FuniStreamData = { force?: 'Y'|'y'|'N'|'n'|'C'|'c', callbackMaker?:
forceMuxer: AvailableMuxer | undefined, simul: boolean, skipSubMux: boolean, nocleanup: boolean, override: string[], videoTitle: string,
ffmpegOptions: string[], mkvmergeOptions: string[], defaultAudio: LanguageItem, defaultSub: LanguageItem, ccTag: string }
export type FuniSubsData = { nosubs?: boolean, sub: boolean, dlsubs: string[], ccTag: string }
export type DownloadData = { id: string, e: string, dubLang: string[], dlsubs: string[], fileName: string, q: number, novids: boolean, noaudio: boolean }
export type DownloadData = { id: string, e: string, dubLang: string[], dlsubs: string[], fileName: string, q: number, novids: boolean, noaudio: boolean, dlVideoOnce: boolean }
export type AuthResponse = ResponseBase<undefined>;
export type FuniSearchReponse = ResponseBase<FunimationSearch>;

View file

@ -1,4 +1,5 @@
q: 0
nServer: 1
mp4mux: false
noCleanUp: false
noCleanUp: false
dlVideoOnce: true

View file

@ -62,7 +62,7 @@ export default class Crunchy implements ServiceClass {
public async cli() {
console.log(`\n=== Multi Downloader NX ${packageJson.version} ===\n`);
const argv = yargs.appArgv(this.cfg.cli);
// load binaries
this.cfg.bin = await yamlCfg.loadBinCfg();
if (argv.allDubs) {
@ -900,6 +900,7 @@ export default class Crunchy implements ServiceClass {
}
let dlFailed = false;
let dlVideoOnce = false; // Variable to save if best selected video quality was downloaded
for (const mMeta of medias.data) {
console.log(`[INFO] Requesting: [${mMeta.mediaId}] ${mediaName}`);
@ -1030,6 +1031,7 @@ export default class Crunchy implements ServiceClass {
plQuality: {
str: string,
dim: string,
CODECS: string,
RESOLUTION: {
width: number,
height: number
@ -1039,6 +1041,8 @@ export default class Crunchy implements ServiceClass {
// set quality
const plResolution = pl.attributes.RESOLUTION;
const plResolutionText = `${plResolution.width}x${plResolution.height}`;
// set codecs
const plCodecs = pl.attributes.CODECS;
// parse uri
const plUri = new URL(pl.uri);
let plServer = plUri.hostname;
@ -1072,27 +1076,36 @@ export default class Crunchy implements ServiceClass {
plQuality.push({
str: qualityStrAdd,
dim: plResolutionText,
CODECS: plCodecs,
RESOLUTION: plResolution
});
}
}
options.x = options.x > plServerList.length ? 1 : options.x;
const plSelectedServer = plServerList[options.x - 1];
const plSelectedList = plStreams[plSelectedServer];
plQuality.sort((a, b) => {
const aMatch = a.dim.match(/[0-9]+/) || [];
const bMatch = b.dim.match(/[0-9]+/) || [];
const aMatch: RegExpMatchArray | never[] = a.dim.match(/[0-9]+/) || [];
const bMatch: RegExpMatchArray | never[] = b.dim.match(/[0-9]+/) || [];
return parseInt(aMatch[0]) - parseInt(bMatch[0]);
});
let quality = options.q;
if (quality > plQuality.length) {
let quality = options.q === 0 ? plQuality.length : options.q;
if(quality > plQuality.length) {
console.log(`[WARN] The requested quality of ${options.q} is greater than the maximun ${plQuality.length}.\n[WARN] Therefor the maximum will be capped at ${plQuality.length}.`);
quality = plQuality.length;
}
const selPlUrl = quality === 0 ? plSelectedList[plQuality[plQuality.length - 1].dim as string] :
plSelectedList[plQuality.map(a => a.dim)[quality - 1]] ? plSelectedList[plQuality.map(a => a.dim)[quality - 1]] : '';
// When best selected video quality is already downloaded
if(dlVideoOnce && options.dlVideoOnce) {
// Select the lowest resolution with the same codecs
while(quality !=1 && plQuality[quality - 1].CODECS == plQuality[quality - 2].CODECS) {
console.log(quality);
console.log(plQuality[quality - 1].CODECS == plQuality[quality - 2].CODECS);
quality--;
}
}
const selPlUrl = plSelectedList[plQuality.map(a => a.dim)[quality - 1]] ? plSelectedList[plQuality.map(a => a.dim)[quality - 1]] : '';
console.log(`[INFO] Servers available:\n\t${plServerList.join('\n\t')}`);
console.log(`[INFO] Available qualities:\n\t${plQuality.map((a, ind) => `[${ind+1}] ${a.str}`).join('\n\t')}`);
@ -1162,6 +1175,7 @@ export default class Crunchy implements ServiceClass {
path: `${tsFile}.ts`,
lang: lang
});
dlVideoOnce = true;
}
}
else{

View file

@ -120,6 +120,15 @@ For special episodes: S1-4 OR S1,S2,S3,S4 where S is the special letter
| Both | `-q ${qualityLevel}` | `number` | `No`| `NaN` | `0`| `q: ` |
Set the quality level. Use 0 to use the maximum quality.
#### `--dlVideoOnce`
| **Service** | **Usage** | **Type** | **Required** | **Alias** | **Default** |**cli-default Entry**
| --- | --- | --- | --- | --- | --- | ---|
| Both | `--dlVideoOnce ` | `boolean` | `No`| `NaN` | `true`| `dlVideoOnce: ` |
If selected, the best selected quality will be downloaded only for the first language,
then the worst video quality with the same audio quality will be downloaded for every other language.
By the later merge of the videos, no quality difference will be present.
This will speed up the download speed, if multiple languages are selected.
#### `-x`
| **Service** | **Usage** | **Type** | **Required** | **Alias** | **Choices** | **Default** |**cli-default Entry**
| --- | --- | --- | --- | --- | --- | --- | ---|

View file

@ -92,7 +92,7 @@ class CrunchyHandler extends Base implements MessageHandler {
});
if (res.isOk) {
for (const select of res.value) {
if (!(await this.crunchy.downloadEpisode(select, {..._default, skipsubs: false, callbackMaker: this.makeProgressHandler.bind(this), q: data.q, fileName: data.fileName, dlsubs: data.dlsubs, force: 'y',
if (!(await this.crunchy.downloadEpisode(select, {..._default, skipsubs: false, callbackMaker: this.makeProgressHandler.bind(this), q: data.q, fileName: data.fileName, dlsubs: data.dlsubs, dlVideoOnce: data.dlVideoOnce, force: 'y',
novids: data.novids }))) {
const er = new Error(`Unable to download episode ${data.e} from ${data.id}`);
er.name = 'Download error';

View file

@ -27,7 +27,8 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
const subLang = messageHandler?.handleDefault('dlsubs');
const q = messageHandler?.handleDefault('q');
const fileName = messageHandler?.handleDefault('fileName');
const result = await Promise.all([dubLang, subLang, q, fileName]);
const dlVideoOnce = messageHandler?.handleDefault('dlVideoOnce');
const result = await Promise.all([dubLang, subLang, q, fileName, dlVideoOnce]);
dispatch({
type: 'downloadOptions',
payload: {
@ -36,6 +37,7 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
dlsubs: result[1],
q: result[2],
fileName: result[3],
dlVideoOnce: result[4],
}
});
setAvailableDubs(await messageHandler?.availableDubCodes() ?? []);
@ -142,6 +144,7 @@ const DownloadSelector: React.FC<DownloadSelectorProps> = ({ onFinish }) => {
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, but: !store.downloadOptions.but } })} variant={store.downloadOptions.but ? 'contained' : 'outlined'}>Download all but</Button>
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, noaudio: !store.downloadOptions.noaudio } })} variant={store.downloadOptions.noaudio ? 'contained' : 'outlined'}>Skip Audio</Button>
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, novids: !store.downloadOptions.novids } })} variant={store.downloadOptions.novids ? 'contained' : 'outlined'}>Skip Video</Button>
<Button onClick={() => dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, dlVideoOnce: !store.downloadOptions.dlVideoOnce } })} variant={store.downloadOptions.dlVideoOnce ? 'contained' : 'outlined'}>Skip unnecessary Downloads</Button>
</Box>
<Box sx={{ gap: 2, flex: 0, m: 1, mb: 3, display: 'flex', justifyContent: 'center' }}>
<LoadingButton loading={loading} onClick={listEpisodes} variant='contained'>List episodes</LoadingButton>

View file

@ -9,6 +9,7 @@ export type DownloadOptions = {
dubLang: typeof dubLanguageCodes,
dlsubs: string[],
fileName: string,
dlVideoOnce: boolean,
all: boolean,
but: boolean,
novids: boolean,
@ -61,6 +62,7 @@ const initialState: StoreState = {
dubLang: [ 'jpn' ],
dlsubs: [ 'all' ],
fileName: '',
dlVideoOnce: false,
all: false,
but: false,
noaudio: false,

View file

@ -2,7 +2,7 @@ import yargs, { Choices } from 'yargs';
import { args, AvailableMuxer, groups } from './module.args';
import { LanguageItem } from './module.langsData';
let argvC: { [x: string]: unknown; ccTag: string, defaultAudio: LanguageItem, defaultSub: LanguageItem, ffmpegOptions: string[], mkvmergeOptions: string[], force: 'Y'|'y'|'N'|'n'|'C'|'c', skipUpdate: boolean, videoTitle: string, override: string[], fsRetryTime: number, forceMuxer: AvailableMuxer|undefined; username: string|undefined, password: string|undefined, silentAuth: boolean, skipSubMux: boolean, downloadArchive: boolean, addArchive: boolean, but: boolean, auth: boolean | undefined; dlFonts: boolean | undefined; search: string | undefined; 'search-type': string; page: number | undefined; 'search-locale': string; new: boolean | undefined; 'movie-listing': string | undefined; series: string | undefined; s: string | undefined; e: string | undefined; q: number; x: number; kstream: number; partsize: number; hslang: string; dlsubs: string[]; novids: boolean | undefined; noaudio: boolean | undefined; nosubs: boolean | undefined; dubLang: string[]; all: boolean; fontSize: number; allDubs: boolean; timeout: number; simul: boolean; mp4: boolean; skipmux: boolean | undefined; fileName: string; numbers: number; nosess: string; debug: boolean | undefined; nocleanup: boolean; help: boolean | undefined; service: 'funi' | 'crunchy'; update: boolean; fontName: string | undefined; _: (string | number)[]; $0: string; };
let argvC: { [x: string]: unknown; ccTag: string, defaultAudio: LanguageItem, defaultSub: LanguageItem, ffmpegOptions: string[], mkvmergeOptions: string[], force: 'Y'|'y'|'N'|'n'|'C'|'c', skipUpdate: boolean, videoTitle: string, override: string[], fsRetryTime: number, forceMuxer: AvailableMuxer|undefined; username: string|undefined, password: string|undefined, silentAuth: boolean, skipSubMux: boolean, downloadArchive: boolean, addArchive: boolean, but: boolean, auth: boolean | undefined; dlFonts: boolean | undefined; search: string | undefined; 'search-type': string; page: number | undefined; 'search-locale': string; new: boolean | undefined; 'movie-listing': string | undefined; series: string | undefined; s: string | undefined; e: string | undefined; q: number; x: number; kstream: number; partsize: number; hslang: string; dlsubs: string[]; novids: boolean | undefined; noaudio: boolean | undefined; nosubs: boolean | undefined; dubLang: string[]; all: boolean; fontSize: number; allDubs: boolean; timeout: number; simul: boolean; mp4: boolean; skipmux: boolean | undefined; fileName: string; numbers: number; nosess: string; debug: boolean | undefined; nocleanup: boolean; help: boolean | undefined; service: 'funi' | 'crunchy'; update: boolean; fontName: string | undefined; _: (string | number)[]; $0: string; dlVideoOnce: boolean; };
export type ArgvType = typeof argvC;

View file

@ -176,6 +176,21 @@ const args: TAppArg<boolean|number|string|unknown[]>[] = [
type: 'number',
usage: '${qualityLevel}'
},
{
name: 'dlVideoOnce',
describe: 'Download only once the video with the best selected quality',
type: 'boolean',
group: 'dl',
service: 'both',
docDescribe: 'If selected, the best selected quality will be downloaded only for the first language,'
+ '\nthen the worst video quality with the same audio quality will be downloaded for every other language.'
+ '\nBy the later merge of the videos, no quality difference will be present.'
+ '\nThis will speed up the download speed, if multiple languages are selected.',
usage: '',
default: {
default: true
}
},
{
name: 'x',
group: 'dl',