mirror of
https://github.com/anidl/multi-downloader-nx.git
synced 2026-03-11 17:45:30 +00:00
hotfix crunchyroll 192 audio + cbr video dl
This commit is contained in:
parent
dedf284844
commit
ec1f4e6ba9
6 changed files with 50 additions and 38 deletions
8
@types/crunchyTypes.d.ts
vendored
8
@types/crunchyTypes.d.ts
vendored
|
|
@ -2,14 +2,14 @@ import { HLSCallback } from 'hls-download';
|
|||
import { sxItem } from '../crunchy';
|
||||
import { LanguageItem } from '../modules/module.langsData';
|
||||
import { DownloadInfo } from './messageHandler';
|
||||
import { CrunchyPlayStreams } from './enums';
|
||||
import { CrunchyVideoPlayStreams, CrunchyAudioPlayStreams } from './enums';
|
||||
|
||||
export type CrunchyDownloadOptions = {
|
||||
hslang: string,
|
||||
// kstream: number,
|
||||
cstream: keyof typeof CrunchyPlayStreams,
|
||||
vstream: keyof typeof CrunchyPlayStreams,
|
||||
astream: keyof typeof CrunchyPlayStreams,
|
||||
cstream: keyof typeof CrunchyVideoPlayStreams,
|
||||
vstream: keyof typeof CrunchyVideoPlayStreams,
|
||||
astream: keyof typeof CrunchyAudioPlayStreams,
|
||||
tsd?: boolean,
|
||||
novids?: boolean,
|
||||
noaudio?: boolean,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,8 @@
|
|||
export enum CrunchyPlayStreams {
|
||||
'chrome' = 'web/chrome',
|
||||
'firefox' = 'web/firefox',
|
||||
'safari' = 'web/safari',
|
||||
'edge' = 'web/edge',
|
||||
'fallback' = 'web/fallback',
|
||||
'ps4' = 'console/ps4',
|
||||
'ps5' = 'console/ps5',
|
||||
'switch' = 'console/switch',
|
||||
'xboxone' = 'console/xbox_one',
|
||||
'vidaa' = 'tv/vidaa',
|
||||
'samsungtv' = 'tv/samsung',
|
||||
'lgtv' = 'tv/lg',
|
||||
'rokutv' = 'tv/roku',
|
||||
'chromecast'= 'tv/chromecast',
|
||||
'firetv' = 'tv/fire_tv',
|
||||
export enum CrunchyVideoPlayStreams {
|
||||
'androidtv' = 'tv/android_tv'
|
||||
}
|
||||
|
||||
export enum CrunchyAudioPlayStreams {
|
||||
'androidtv' = 'tv/android_tv',
|
||||
'android' = 'android/phone',
|
||||
'androidtab'= 'android/tablet'
|
||||
|
|
|
|||
37
crunchy.ts
37
crunchy.ts
|
|
@ -43,7 +43,7 @@ import { CrunchyAndroidObject } from './@types/crunchyAndroidObject';
|
|||
import { CrunchyChapters, CrunchyChapter, CrunchyOldChapter } from './@types/crunchyChapters';
|
||||
import vtt2ass from './modules/module.vtt2ass';
|
||||
import { CrunchyPlayStream } from './@types/crunchyPlayStreams';
|
||||
import { CrunchyPlayStreams } from './@types/enums';
|
||||
import { CrunchyVideoPlayStreams, CrunchyAudioPlayStreams } from './@types/enums';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
export type sxItem = {
|
||||
|
|
@ -1434,6 +1434,20 @@ export default class Crunchy implements ServiceClass {
|
|||
return selectedMedia;
|
||||
}
|
||||
|
||||
private convertDownloadToPlayback(audioUrl: string, videoUrl: string): string {
|
||||
try {
|
||||
const url = new URL(audioUrl);
|
||||
const urla = new URL(videoUrl);
|
||||
url.pathname = url.pathname.replace('/manifest/download/', '/manifest/');
|
||||
url.searchParams.delete('downloadGuid');
|
||||
url.searchParams.set('playbackGuid', urla.searchParams.get('playbackGuid') as string);
|
||||
|
||||
return url.toString();
|
||||
} catch (err) {
|
||||
return audioUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public async downloadMediaList(medias: CrunchyEpMeta, options: CrunchyDownloadOptions) : Promise<{
|
||||
data: DownloadedMedia[],
|
||||
fileName: string,
|
||||
|
|
@ -1637,6 +1651,7 @@ export default class Crunchy implements ServiceClass {
|
|||
|
||||
let videoStream: CrunchyPlayStream | null = null;
|
||||
let audioStream: CrunchyPlayStream | null = null;
|
||||
const isDLBypass: boolean = options.astream === 'android' || options.astream === 'androidtab' ? true : false;
|
||||
|
||||
if (options.tsd) {
|
||||
console.warn('Total Session Death Active');
|
||||
|
|
@ -1650,7 +1665,7 @@ export default class Crunchy implements ServiceClass {
|
|||
}
|
||||
}
|
||||
|
||||
const videoPlaybackReq = await this.req.getData(`https://www.crunchyroll.com/playback/v3/${currentVersion ? currentVersion.guid : currentMediaId}/${CrunchyPlayStreams[options.vstream]}/play`, AuthHeaders);
|
||||
const videoPlaybackReq = await this.req.getData(`https://www.crunchyroll.com/playback/v3/${currentVersion ? currentVersion.guid : currentMediaId}/${CrunchyVideoPlayStreams[options.vstream]}/play`, AuthHeaders);
|
||||
if (!videoPlaybackReq.ok || !videoPlaybackReq.res) {
|
||||
console.warn('Request Video Stream URLs FAILED!');
|
||||
} else {
|
||||
|
|
@ -1681,8 +1696,8 @@ export default class Crunchy implements ServiceClass {
|
|||
};
|
||||
}
|
||||
|
||||
if (!options.cstream && (options.vstream !== options.astream)) {
|
||||
const audioPlaybackReq = await this.req.getData(`https://www.crunchyroll.com/playback/v3/${currentVersion ? currentVersion.guid : currentMediaId}/${CrunchyPlayStreams[options.astream]}/play`, AuthHeaders);
|
||||
if (!options.cstream && (options.vstream !== options.astream) && videoStream) {
|
||||
const audioPlaybackReq = await this.req.getData(`https://www.crunchyroll.com/playback/v3/${currentVersion ? currentVersion.guid : currentMediaId}/${CrunchyAudioPlayStreams[options.astream]}/${isDLBypass ? 'download' : 'play'}`, AuthHeaders);
|
||||
if (!audioPlaybackReq.ok || !audioPlaybackReq.res) {
|
||||
console.warn('Request Audio Stream URLs FAILED!');
|
||||
} else {
|
||||
|
|
@ -1695,9 +1710,17 @@ export default class Crunchy implements ServiceClass {
|
|||
'hardsub_locale': stream.hlang
|
||||
};
|
||||
}
|
||||
derivedPlaystreams[''] = {
|
||||
url: audioStream.url,
|
||||
hardsub_locale: ''
|
||||
if (isDLBypass) {
|
||||
audioStream.token = videoStream.token;
|
||||
derivedPlaystreams[''] = {
|
||||
url: this.convertDownloadToPlayback(audioStream.url, videoStream.url),
|
||||
hardsub_locale: ''
|
||||
};
|
||||
} else {
|
||||
derivedPlaystreams[''] = {
|
||||
url: audioStream.url,
|
||||
hardsub_locale: ''
|
||||
};
|
||||
};
|
||||
pbData.meta = {
|
||||
audio_locale: audioStream.audioLocale,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const api: APIType = {
|
|||
bundlejs: 'https://static.crunchyroll.com/vilos-v2/web/vilos/js/bundle.js',
|
||||
//
|
||||
// Crunchyroll API
|
||||
basic_auth_token: 'Ym1icmt4eXgzZDd1NmpzZnlsYTQ6QUlONEQ1VkVfY3Awd1Z6Zk5vUDBZcUhVcllGcDloU2c=',
|
||||
basic_auth_token: 'cHVnMG43eW11YW9sa2tnaTNsYmo6WGlraXNhQ2FYRllCY1hxb09sa1NUMWg2b1pYbHdESk4=',
|
||||
auth: `${domain.cr_www}/auth/v1/token`,
|
||||
profile: `${domain.cr_www}/accounts/v1/me/profile`,
|
||||
search: `${domain.cr_www}/content/v2/discover/search`,
|
||||
|
|
@ -64,7 +64,7 @@ const api: APIType = {
|
|||
cms_auth: `${domain.cr_www}/index/v2`,
|
||||
//
|
||||
// Crunchyroll Headers
|
||||
crunchyDefUserAgent: 'Crunchyroll/ANDROIDTV/3.42.1_22267 (Android 16; en-US; sdk_gphone64_x86_64)',
|
||||
crunchyDefUserAgent: 'Crunchyroll/ANDROIDTV/3.45.0_22272 (Android 16; en-US; sdk_gphone64_x86_64)',
|
||||
crunchyDefHeader: {},
|
||||
crunchyAuthHeader: {},
|
||||
//
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { DownloadInfo } from '../@types/messageHandler';
|
|||
import { HLSCallback } from './hls-download';
|
||||
import leven from 'leven';
|
||||
import { console } from './log';
|
||||
import { CrunchyPlayStreams } from '../@types/enums';
|
||||
import { CrunchyVideoPlayStreams, CrunchyAudioPlayStreams } from '../@types/enums';
|
||||
|
||||
let argvC: {
|
||||
[x: string]: unknown;
|
||||
|
|
@ -46,9 +46,9 @@ let argvC: {
|
|||
q: number;
|
||||
x: number;
|
||||
// kstream: number;
|
||||
cstream: keyof typeof CrunchyPlayStreams;
|
||||
vstream: keyof typeof CrunchyPlayStreams;
|
||||
astream: keyof typeof CrunchyPlayStreams;
|
||||
cstream: keyof typeof CrunchyVideoPlayStreams;
|
||||
vstream: keyof typeof CrunchyVideoPlayStreams;
|
||||
astream: keyof typeof CrunchyAudioPlayStreams;
|
||||
tsd: boolean | undefined;
|
||||
partsize: number;
|
||||
hslang: string;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { aoSearchLocales, dubLanguageCodes, languages, searchLocales, subtitleLanguagesFilter } from './module.langsData';
|
||||
import { CrunchyPlayStreams } from '../@types/enums';
|
||||
import { CrunchyVideoPlayStreams, CrunchyAudioPlayStreams } from '../@types/enums';
|
||||
|
||||
const groups = {
|
||||
'auth': 'Authentication:',
|
||||
|
|
@ -332,7 +332,7 @@ const args: TAppArg<boolean|number|string|unknown[]>[] = [
|
|||
service: ['crunchy'],
|
||||
type: 'string',
|
||||
describe: '(Please use --vstream and --astream instead, this will deprecate soon) Select a specific Crunchyroll playback endpoint by device. Since Crunchyroll has started rolling out their new VBR encodes, we highly recommend using a TV endpoint (e.g. vidaa, samsungtv, lgtv, rokutv, chromecast, firetv, androidtv) to access the old CBR encodes. Please note: The older encodes do not include the new 192 kbps audio, the new audio is only available with the new VBR encodes.',
|
||||
choices: [...Object.keys(CrunchyPlayStreams), 'none'],
|
||||
choices: [...Object.keys(CrunchyVideoPlayStreams), 'none'],
|
||||
docDescribe: true,
|
||||
usage: '${device}'
|
||||
},
|
||||
|
|
@ -343,7 +343,7 @@ const args: TAppArg<boolean|number|string|unknown[]>[] = [
|
|||
service: ['crunchy'],
|
||||
type: 'string',
|
||||
describe: 'Select a specific Crunchyroll video playback endpoint by device.',
|
||||
choices: [...Object.keys(CrunchyPlayStreams), 'none'],
|
||||
choices: [...Object.keys(CrunchyVideoPlayStreams), 'none'],
|
||||
default: {
|
||||
default: 'androidtv'
|
||||
},
|
||||
|
|
@ -357,9 +357,9 @@ const args: TAppArg<boolean|number|string|unknown[]>[] = [
|
|||
service: ['crunchy'],
|
||||
type: 'string',
|
||||
describe: 'Select a specific Crunchyroll audio playback endpoint by device.',
|
||||
choices: [...Object.keys(CrunchyPlayStreams), 'none'],
|
||||
choices: [...Object.keys(CrunchyAudioPlayStreams), 'none'],
|
||||
default: {
|
||||
default: 'androidtv'
|
||||
default: 'android'
|
||||
},
|
||||
docDescribe: true,
|
||||
usage: '${device}'
|
||||
|
|
|
|||
Loading…
Reference in a new issue