mirror of
https://github.com/anidl/multi-downloader-nx.git
synced 2026-03-11 17:45:30 +00:00
Hotfix for CR
This does not include DRM decryption, that will come later, however, this does work for however long CR allows it to.
This commit is contained in:
parent
31867e216f
commit
df7dd06235
4 changed files with 152 additions and 71 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -33,3 +33,7 @@ gui/react/build/
|
|||
docker-compose.yml
|
||||
crunchyendpoints
|
||||
.vscode
|
||||
/logs
|
||||
/tmp/*/
|
||||
/videos/*/
|
||||
/tmp/*.*
|
||||
56
@types/crunchyAndroidStreams.d.ts
vendored
Normal file
56
@types/crunchyAndroidStreams.d.ts
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
export interface CrunchyAndroidStreams {
|
||||
__class__: string;
|
||||
__href__: string;
|
||||
__resource_key__: string;
|
||||
__links__: Links;
|
||||
__actions__: Actions;
|
||||
media_id: string;
|
||||
audio_locale: string;
|
||||
subtitles: { [key: string]: Subtitle };
|
||||
closed_captions: Actions;
|
||||
streams: Streams;
|
||||
bifs: string[];
|
||||
versions: Version[];
|
||||
captions: Actions;
|
||||
}
|
||||
|
||||
export interface Actions {
|
||||
}
|
||||
|
||||
export interface Links {
|
||||
resource: Resource;
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
href: string;
|
||||
}
|
||||
|
||||
export interface Streams {
|
||||
[key: string]: { [key: string]: Download };
|
||||
}
|
||||
|
||||
export interface Download {
|
||||
hardsub_locale: string;
|
||||
hardsub_lang?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface Urls {
|
||||
'': Download;
|
||||
}
|
||||
|
||||
export interface Subtitle {
|
||||
locale: string;
|
||||
url: string;
|
||||
format: string;
|
||||
}
|
||||
|
||||
export interface Version {
|
||||
audio_locale: string;
|
||||
guid: string;
|
||||
original: boolean;
|
||||
variant: string;
|
||||
season_guid: string;
|
||||
media_guid: string;
|
||||
is_premium_only: boolean;
|
||||
}
|
||||
41
crunchy.ts
41
crunchy.ts
|
|
@ -27,12 +27,13 @@ import { CrunchyEpisodeList, CrunchyEpisode } from './@types/crunchyEpisodeList'
|
|||
import { CrunchyDownloadOptions, CrunchyEpMeta, CrunchyMuxOptions, CurnchyMultiDownload, DownloadedMedia, ParseItem, SeriesSearch, SeriesSearchItem } from './@types/crunchyTypes';
|
||||
import { ObjectInfo } from './@types/objectInfo';
|
||||
import parseFileName, { Variable } from './modules/module.filename';
|
||||
import { PlaybackData } from './@types/playbackData';
|
||||
//import { PlaybackData } from './@types/playbackData';
|
||||
import { downloaded } from './modules/module.downloadArchive';
|
||||
import parseSelect from './modules/module.parseSelect';
|
||||
import { AvailableFilenameVars, getDefault } from './modules/module.args';
|
||||
import { AuthData, AuthResponse, Episode, ResponseBase, SearchData, SearchResponse, SearchResponseItem } from './@types/messageHandler';
|
||||
import { ServiceClass } from './@types/serviceClassInterface';
|
||||
import { CrunchyAndroidStreams } from './@types/crunchyAndroidStreams';
|
||||
|
||||
export type sxItem = {
|
||||
language: langsData.LanguageItem,
|
||||
|
|
@ -1086,7 +1087,23 @@ export default class Crunchy implements ServiceClass {
|
|||
if (mediaId.includes(':'))
|
||||
mediaId = mediaId.split(':')[1];
|
||||
|
||||
let playbackReq = await this.req.getData(`${api.cms}/videos/${mediaId}/streams`, AuthHeaders);
|
||||
// /cms/v2/US/M3/crunchyroll/videos/MEDIAID/streams
|
||||
const videoStreamsReq = [
|
||||
domain.api_beta,
|
||||
`/cms/v2/US/M3/crunchyroll/videos/${mediaId}/streams`,
|
||||
'?',
|
||||
new URLSearchParams({
|
||||
streams: 'all',
|
||||
textType: 'all',
|
||||
'Policy': this.cmsToken.cms.policy,
|
||||
'Signature': this.cmsToken.cms.signature,
|
||||
'Key-Pair-Id': this.cmsToken.cms.key_pair_id,
|
||||
}),
|
||||
].join('');
|
||||
|
||||
let playbackReq = await this.req.getData(videoStreamsReq as string, AuthHeaders);
|
||||
//console.info(playbackReq.res.body);
|
||||
//let playbackReq = await this.req.getData(`${api.cms}/videos/${mediaId}/streams`, AuthHeaders);
|
||||
if(!playbackReq.ok || !playbackReq.res){
|
||||
console.error('Request Stream URLs FAILED! Attempting fallback');
|
||||
playbackReq = await this.req.getData(`${domain.api_beta}${mMeta.playback}`, AuthHeaders);
|
||||
|
|
@ -1096,7 +1113,8 @@ export default class Crunchy implements ServiceClass {
|
|||
}
|
||||
}
|
||||
|
||||
const pbData = JSON.parse(playbackReq.res.body) as PlaybackData;
|
||||
//const pbData = JSON.parse(playbackReq.res.body) as PlaybackData;
|
||||
const pbData = JSON.parse(playbackReq.res.body) as CrunchyAndroidStreams;
|
||||
|
||||
variables.push(...([
|
||||
['title', medias.episodeTitle, true],
|
||||
|
|
@ -1116,10 +1134,11 @@ export default class Crunchy implements ServiceClass {
|
|||
|
||||
let streams: any[] = [];
|
||||
let hsLangs: string[] = [];
|
||||
const pbStreams = pbData.data[0];
|
||||
const pbStreams = pbData.streams;
|
||||
|
||||
for(const s of Object.keys(pbStreams)){
|
||||
if(s.match(/hls/) && !s.match(/drm/) && !s.match(/trailer/)) {
|
||||
//if((s.match(/hls/) || s.match(/dash/)) && !s.match(/trailer/)) {
|
||||
const pb = Object.values(pbStreams[s]).map(v => {
|
||||
v.hardsub_lang = v.hardsub_locale
|
||||
? langsData.fixAndFindCrLC(v.hardsub_locale).locale
|
||||
|
|
@ -1141,7 +1160,7 @@ export default class Crunchy implements ServiceClass {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const audDub = langsData.findLang(langsData.fixLanguageTag(pbData.meta.audio_locale as string) || '').code;
|
||||
const audDub = langsData.findLang(langsData.fixLanguageTag(pbData.audio_locale as string) || '').code;
|
||||
hsLangs = langsData.sortTags(hsLangs);
|
||||
|
||||
streams = streams.map((s) => {
|
||||
|
|
@ -1211,6 +1230,8 @@ export default class Crunchy implements ServiceClass {
|
|||
console.info('Playlists URL: %s (%s)', curStream.url, curStream.type);
|
||||
}
|
||||
|
||||
let tsFile = undefined;
|
||||
|
||||
if(!options.novids && !dlFailed && curStream !== undefined){
|
||||
const streamPlaylistsReq = await this.req.getData(curStream.url);
|
||||
if(!streamPlaylistsReq.ok || !streamPlaylistsReq.res){
|
||||
|
|
@ -1332,7 +1353,7 @@ export default class Crunchy implements ServiceClass {
|
|||
const mathParts = Math.ceil(totalParts / options.partsize);
|
||||
const mathMsg = `(${mathParts}*${options.partsize})`;
|
||||
console.info('Total parts in stream:', totalParts, mathMsg);
|
||||
const tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile);
|
||||
tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile);
|
||||
const split = outFile.split(path.sep).slice(0, -1);
|
||||
split.forEach((val, ind, arr) => {
|
||||
const isAbsolut = path.isAbsolute(outFile as string);
|
||||
|
|
@ -1397,8 +1418,8 @@ export default class Crunchy implements ServiceClass {
|
|||
}
|
||||
|
||||
if(!options.skipsubs && options.dlsubs.indexOf('none') == -1){
|
||||
if(pbData.meta.subtitles && Object.values(pbData.meta.subtitles).length > 0){
|
||||
const subsData = Object.values(pbData.meta.subtitles);
|
||||
if(pbData.subtitles && Object.values(pbData.subtitles).length > 0){
|
||||
const subsData = Object.values(pbData.subtitles);
|
||||
const subsDataMapped = subsData.map((s) => {
|
||||
const subLang = langsData.fixAndFindCrLC(s.locale);
|
||||
return {
|
||||
|
|
@ -1433,7 +1454,7 @@ export default class Crunchy implements ServiceClass {
|
|||
files.push({
|
||||
type: 'Subtitle',
|
||||
...sxData as sxItem,
|
||||
cc: isCC
|
||||
cc: isCC,
|
||||
});
|
||||
}
|
||||
else{
|
||||
|
|
@ -1473,7 +1494,7 @@ export default class Crunchy implements ServiceClass {
|
|||
return {
|
||||
file: a.path,
|
||||
language: a.language,
|
||||
closedCaption: a.cc
|
||||
closedCaption: a.cc,
|
||||
};
|
||||
}),
|
||||
simul: false,
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ const args: TAppArg<boolean|number|string|unknown[]>[] = [
|
|||
group: 'dl',
|
||||
alias: 'k',
|
||||
describe: 'Select specific stream',
|
||||
choices: [1, 2, 3, 4, 5, 6, 7],
|
||||
choices: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||
default: {
|
||||
default: 1
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue