Ability to reduce unnecessary bandwidth usage
This commit is contained in:
parent
c3835cb79b
commit
f6303c1a6e
10 changed files with 61 additions and 14 deletions
3
@types/crunchyTypes.d.ts
vendored
3
@types/crunchyTypes.d.ts
vendored
|
|
@ -25,7 +25,8 @@ export type CrunchyDownloadOptions = {
|
|||
mkvmergeOptions: string[],
|
||||
defaultSub: LanguageItem,
|
||||
defaultAudio: LanguageItem,
|
||||
ccTag: string
|
||||
ccTag: string,
|
||||
dlVideoOnce: boolean
|
||||
}
|
||||
|
||||
export type CurnchyMultiDownload = {
|
||||
|
|
|
|||
4
@types/messageHandler.d.ts
vendored
4
@types/messageHandler.d.ts
vendored
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
q: 0
|
||||
nServer: 1
|
||||
mp4mux: false
|
||||
noCleanUp: false
|
||||
noCleanUp: false
|
||||
dlVideoOnce: true
|
||||
30
crunchy.ts
30
crunchy.ts
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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**
|
||||
| --- | --- | --- | --- | --- | --- | --- | ---|
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
Loading…
Reference in a new issue