diff --git a/adn.ts b/adn.ts index d4592e8..a85a06f 100644 --- a/adn.ts +++ b/adn.ts @@ -56,6 +56,11 @@ export default class AnimationDigitalNetwork implements ServiceClass { private polSubStrings: string[] = ['vpl', 'vostpl']; private deuSubStrings: string[] = ['vde', 'vostde']; private fraSubStrings: string[] = ['vf', 'vostf']; + private regions = [ + { code: 'de', vost: 'vostde', dub: 'vde' }, + { code: 'fr', vost: 'vostf', dub: 'vf' }, + { code: 'pl', vost: 'vostpl', dub: 'vpl' } + ] as const; constructor(private debug = false) { this.cfg = yamlCfg.loadCfg(); @@ -284,11 +289,31 @@ export default class AnimationDigitalNetwork implements ServiceClass { episodeIndex--; } else { console.info(` (${episode.id}) [E${episode.shortNumber}] ${episode.number} - ${episode.name}`); + const langs = episode.languages ?? []; + const audios: string[] = []; + const subs: string[] = []; + if (this.regions.some((r) => langs.includes(r.vost))) audios.push('ja'); + for (const r of this.regions) { + if (langs.includes(r.dub)) audios.push(r.code); + if (langs.includes(r.vost) || langs.includes(r.dub)) subs.push(r.code); + } + if (audios.length > 0) console.info(` - Versions: ${audios.join(', ')}`); + if (subs.length > 0) console.info(` - Subtitles: ${subs.join(', ')}`); } episodeIndex++; } for (const special of specials) { console.info(` (Special) (${special.id}) [${special.shortNumber}] ${special.number} - ${special.name}`); + const langs = special.languages ?? []; + const audios: string[] = []; + const subs: string[] = []; + if (this.regions.some((r) => langs.includes(r.vost))) audios.push('ja'); + for (const r of this.regions) { + if (langs.includes(r.dub)) audios.push(r.code); + if (langs.includes(r.vost) || langs.includes(r.dub)) subs.push(r.code); + } + if (audios.length > 0) console.info(` - Versions: ${audios.join(', ')}`); + if (subs.length > 0) console.info(` - Subtitles: ${subs.join(', ')}`); show.value.videos.splice( show.value.videos.findIndex((i) => i.id === special.id), 1 @@ -296,6 +321,16 @@ export default class AnimationDigitalNetwork implements ServiceClass { } for (const nc of ncs) { console.info(` (NC) (${nc.id}) [${nc.shortNumber}] ${nc.number} - ${nc.name}`); + const langs = nc.languages ?? []; + const audios: string[] = []; + const subs: string[] = []; + if (this.regions.some((r) => langs.includes(r.vost))) audios.push('ja'); + for (const r of this.regions) { + if (langs.includes(r.dub)) audios.push(r.code); + if (langs.includes(r.vost) || langs.includes(r.dub)) subs.push(r.code); + } + if (audios.length > 0) console.info(` - Versions: ${audios.join(', ')}`); + if (subs.length > 0) console.info(` - Subtitles: ${subs.join(', ')}`); show.value.videos.splice( show.value.videos.findIndex((i) => i.id === nc.id), 1 diff --git a/hidive.ts b/hidive.ts index da588ca..0c74322 100644 --- a/hidive.ts +++ b/hidive.ts @@ -415,6 +415,26 @@ export default class Hidive implements ServiceClass { season.value.paging.lastSeen = seasonPage.value.paging.lastSeen; season.value.paging.moreDataAvailable = seasonPage.value.paging.moreDataAvailable; } + let subLocales: string[] = []; + const sampleEp = season.value.episodes[0]; + if (sampleEp) { + const epReq = await this.apiReq(`/v4/vod/${sampleEp.id}?includePlaybackDetails=URL`, '', 'auth', 'GET'); + const epData = epReq.ok && epReq.res ? (JSON.parse(await epReq.res.text()) as NewHidiveEpisode) : undefined; + const pbReq = epData?.playerUrlCallback ? await this.req.getData(epData.playerUrlCallback) : undefined; + if (pbReq?.ok && pbReq.res) { + const pbData = JSON.parse(await pbReq.res.text()) as NewHidivePlayback; + subLocales = [ + ...new Set( + (pbData.dash?.[0]?.subtitles ?? []) + .filter((s) => s.format === 'vtt') + .map((s) => langsData.languages.find((l) => l.new_hd_locale == s.language)?.hd_locale) + .filter((l): l is string => typeof l === 'string') + ) + ]; + } else { + console.warn(`Failed to sample subtitles for season ${season.value.id}`); + } + } for (const episode of season.value.episodes) { const datePattern = /\d{1,2}\/\d{1,2}\/\d{2,4} \d{1,2}:\d{2} UTC/; if (episode.title.includes(' - ')) { @@ -426,6 +446,15 @@ export default class Hidive implements ServiceClass { episodes.push(episode); } console.info(` [E.${episode.id}] ${episode.title}`); + const audioLocales = (episode.offlinePlaybackLanguages ?? []) + .map((c) => langsData.languages.find((l) => l.code == c)?.hd_locale) + .filter((l): l is string => typeof l === 'string'); + if (audioLocales.length > 0) { + console.info(` - Versions: ${audioLocales.join(', ')}`); + } + if (subLocales.length > 0) { + console.info(` - Subtitles: ${subLocales.join(', ')}`); + } } } return { isOk: true, value: episodes, series: series.value }; @@ -445,6 +474,26 @@ export default class Hidive implements ServiceClass { season.value.paging.lastSeen = seasonPage.value.paging.lastSeen; season.value.paging.moreDataAvailable = seasonPage.value.paging.moreDataAvailable; } + let subLocales: string[] = []; + const sampleEp = season.value.episodes[0]; + if (sampleEp) { + const epReq = await this.apiReq(`/v4/vod/${sampleEp.id}?includePlaybackDetails=URL`, '', 'auth', 'GET'); + const epData = epReq.ok && epReq.res ? (JSON.parse(await epReq.res.text()) as NewHidiveEpisode) : undefined; + const pbReq = epData?.playerUrlCallback ? await this.req.getData(epData.playerUrlCallback) : undefined; + if (pbReq?.ok && pbReq.res) { + const pbData = JSON.parse(await pbReq.res.text()) as NewHidivePlayback; + subLocales = [ + ...new Set( + (pbData.dash?.[0]?.subtitles ?? []) + .filter((s) => s.format === 'vtt') + .map((s) => langsData.languages.find((l) => l.new_hd_locale == s.language)?.hd_locale) + .filter((l): l is string => typeof l === 'string') + ) + ]; + } else { + console.warn(`Failed to sample subtitles for season ${season.value.id}`); + } + } const episodes: Episode[] = []; for (const episode of season.value.episodes) { const datePattern = /\d{1,2}\/\d{1,2}\/\d{2,4} \d{1,2}:\d{2} UTC/; @@ -457,6 +506,15 @@ export default class Hidive implements ServiceClass { episodes.push(episode); } console.info(` [E.${episode.id}] ${episode.title}`); + const audioLocales = (episode.offlinePlaybackLanguages ?? []) + .map((c) => langsData.languages.find((l) => l.code == c)?.hd_locale) + .filter((l): l is string => typeof l === 'string'); + if (audioLocales.length > 0) { + console.info(` - Versions: ${audioLocales.join(', ')}`); + } + if (subLocales.length > 0) { + console.info(` - Subtitles: ${subLocales.join(', ')}`); + } } const series: NewHidiveSeriesExtra = { ...season.value.series, season: season.value }; return { isOk: true, value: episodes, series: series };