diff --git a/@types/crunchyAndroidStreams.d.ts b/@types/crunchyAndroidStreams.d.ts index c1e56c3..c5e9889 100644 --- a/@types/crunchyAndroidStreams.d.ts +++ b/@types/crunchyAndroidStreams.d.ts @@ -3,15 +3,15 @@ export interface CrunchyAndroidStreams { __href__: string; __resource_key__: string; __links__: Links; - __actions__: Actions; + __actions__: Record; media_id: string; audio_locale: Locale; subtitles: Subtitles; - closed_captions: Actions; + closed_captions: Subtitles; streams: Streams; bifs: string[]; versions: Version[]; - captions: Actions; + captions: Record; } export interface Subtitles { @@ -34,9 +34,6 @@ export interface Subtitles { 'ja-JP'?: Subtitle; } -export interface Actions { -} - export interface Links { resource: Resource; } diff --git a/@types/crunchyTypes.d.ts b/@types/crunchyTypes.d.ts index 13ceee4..7de374e 100644 --- a/@types/crunchyTypes.d.ts +++ b/@types/crunchyTypes.d.ts @@ -32,7 +32,9 @@ export type CrunchyDownloadOptions = { skipmux?: boolean, syncTiming: boolean, nocleanup: boolean, - chapters: boolean + chapters: boolean, + fontName: string | undefined, + fontSize: number, } export type CrunchyMultiDownload = { diff --git a/@types/playbackData.d.ts b/@types/playbackData.d.ts index 3374c3e..1b6548e 100644 --- a/@types/playbackData.d.ts +++ b/@types/playbackData.d.ts @@ -56,7 +56,7 @@ export interface Meta { bifs: string[]; versions: Version[]; audio_locale: Locale; - closed_captions: Record; + closed_captions: Subtitles; captions: Record; } diff --git a/crunchy.ts b/crunchy.ts index 7805640..edc431b 100644 --- a/crunchy.ts +++ b/crunchy.ts @@ -19,6 +19,7 @@ import * as yamlCfg from './modules/module.cfg-loader'; import * as yargs from './modules/module.app-args'; import Merger, { Font, MergerInput, SubtitleInput } from './modules/module.merger'; import getKeys, { canDecrypt } from './modules/cr_widevine'; +//import vttConvert from './modules/module.vttconvert'; // args @@ -1935,22 +1936,35 @@ 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); + const capsData = Object.values(pbData.meta.closed_captions); const subsDataMapped = subsData.map((s) => { const subLang = langsData.fixAndFindCrLC(s.locale); return { ...s, + isCC: false, locale: subLang, language: subLang.locale }; - }); + }).concat( + capsData.map((s) => { + const subLang = langsData.fixAndFindCrLC(s.locale); + return { + ...s, + isCC: true, + locale: subLang, + language: subLang.locale + }; + }) + ); const subsArr = langsData.sortSubtitles(subsDataMapped, 'language'); for(const subsIndex in subsArr){ const subsItem = subsArr[subsIndex]; const langItem = subsItem.locale; const sxData: Partial = {}; sxData.language = langItem; - const isCC = langItem.code === audDub; - sxData.file = langsData.subsFile(fileName as string, subsIndex, langItem, isCC, options.ccTag); + const isSigns = langItem.code === audDub && !subsItem.isCC; + const isCC = subsItem.isCC; + sxData.file = langsData.subsFile(fileName as string, subsIndex, langItem, isCC, options.ccTag, isSigns, subsItem.format); sxData.path = path.join(this.cfg.dir.content, sxData.file); const split = sxData.path.split(path.sep).slice(0, -1); split.forEach((val, ind, arr) => { @@ -1963,13 +1977,22 @@ export default class Crunchy implements ServiceClass { if(options.dlsubs.includes('all') || options.dlsubs.includes(langItem.locale)){ const subsAssReq = await this.req.getData(subsItem.url); if(subsAssReq.ok && subsAssReq.res){ - let sBody = '\ufeff' + subsAssReq.res.body; - const sBodySplit = sBody.split('\r\n'); - sBodySplit.splice(2, 0, 'ScaledBorderAndShadow: yes'); - sBody = sBodySplit.join('\r\n'); - sxData.title = sBody.split('\r\n')[1].replace(/^Title: /, ''); - sxData.title = `${langItem.language} / ${sxData.title}`; - sxData.fonts = fontsData.assFonts(sBody) as Font[]; + let sBody; + if (subsItem.format == 'vtt') { + //TODO: look into converting downloaded vtt into ASS + //sBody = vttConvert(subsAssReq.res.body, false, langItem.language, options.fontSize, options.fontName); + sBody = subsAssReq.res.body; + //TODO: look into parsing the fonts from the styles field in the VTT + sxData.fonts = options.fontName ? [options.fontName] as Font[] : []; + } else { + sBody = '\ufeff' + subsAssReq.res.body; + const sBodySplit = sBody.split('\r\n'); + sBodySplit.splice(2, 0, 'ScaledBorderAndShadow: yes'); + sBody = sBodySplit.join('\r\n'); + sxData.title = sBody.split('\r\n')[1].replace(/^Title: /, ''); + sxData.title = `${langItem.language} / ${sxData.title}`; + sxData.fonts = fontsData.assFonts(sBody) as Font[]; + } fs.writeFileSync(sxData.path, sBody); console.info(`Subtitle downloaded: ${sxData.file}`); files.push({ diff --git a/modules/module.langsData.ts b/modules/module.langsData.ts index c4ffbf1..e6453ef 100644 --- a/modules/module.langsData.ts +++ b/modules/module.langsData.ts @@ -142,9 +142,9 @@ const sortTags = (data: string[]) => { return sort.map(e => e.locale as string); }; -const subsFile = (fnOutput:string, subsIndex: string, langItem: LanguageItem, isCC: boolean, ccTag: string) => { +const subsFile = (fnOutput:string, subsIndex: string, langItem: LanguageItem, isCC: boolean, ccTag: string, isSigns?: boolean, format?: string) => { subsIndex = (parseInt(subsIndex) + 1).toString().padStart(2, '0'); - return `${fnOutput}.${subsIndex}.${langItem.code}.${langItem.language}${isCC ? `.${ccTag}` : ''}.ass`; + return `${fnOutput}.${subsIndex}.${langItem.code}.${langItem.language}${isCC ? `.${ccTag}` : ''}${isSigns ? '.signs' : ''}.${format ? format : 'ass'}`; }; // construct dub langs const