diff --git a/src/api/routes/service/service.service.ts b/src/api/routes/service/service.service.ts index a26bc53..d3b5794 100644 --- a/src/api/routes/service/service.service.ts +++ b/src/api/routes/service/service.service.ts @@ -404,7 +404,7 @@ export async function downloadCrunchyrollPlaylist( const subDownload = async () => { const sbs: Array = [] for (const sub of subDownloadList) { - const name = await downloadCRSub(sub, subFolder) + const name = await downloadCRSub(sub, subFolder, quality) sbs.push(name) } return sbs diff --git a/src/api/services/subs.ts b/src/api/services/subs.ts index 11a2250..3ff51fe 100644 --- a/src/api/services/subs.ts +++ b/src/api/services/subs.ts @@ -11,34 +11,59 @@ export async function downloadCRSub( url: string isDub: boolean }, - dir: string + dir: string, + qual: 1080 | 720 | 480 | 360 | 240 ) { const path = `${dir}/${sub.language}${sub.isDub ? `-FORCED` : ''}.${sub.format}` + var qualX; + var qualY; + + switch (qual) { + case 1080: + qualX = 1920 + qualY = 1080 + break; + case 720: + qualX = 1280 + qualY = 720 + break; + case 480: + qualX = 720 + qualY = 480 + break; + case 360: + qualX = 640 + qualY = 360 + break; + case 240: + qualX = 426 + qualY = 240 + break; + } const stream = fs.createWriteStream(path) const response = await fetch(sub.url) - var resampledSubs = resamplePOSSubtitle(await response.text()) - - var parsedASS = parse(resampledSubs) + var parsedASS = parse(await response.text()) parsedASS.info['Original Script'] = 'crd [https://github.com/stratuma/]' - parsedASS.info.PlayResX = "1920"; - parsedASS.info.PlayResY = "1080"; - for (const s of parsedASS.styles.style) { - if (s.Fontname === 'Arial') { - (s.Fontsize = "54"), (s.Outline = "4"), (s.MarginV = "60"); - } - if (s.Name === 'TypePlaceholder') { - (s.Fontsize = "57"), (s.Outline = "4"), (s.MarginL = "30"), (s.MarginR = "30"), (s.MarginV = "60"); - } + ;(s.Fontsize = String(Math.round((parseInt(s.Fontsize) / parseInt(parsedASS.info.PlayResY)) * qualY))), + (s.Outline = String(Math.round((parseInt(s.Outline) / parseInt(parsedASS.info.PlayResY)) * qualY))), + (s.MarginL = String(Math.round((parseInt(s.MarginL) / parseInt(parsedASS.info.PlayResY)) * qualY))), + (s.MarginR = String(Math.round((parseInt(s.MarginR) / parseInt(parsedASS.info.PlayResY)) * qualY))), + (s.MarginV = String(Math.round((parseInt(s.MarginV) / parseInt(parsedASS.info.PlayResY)) * qualY))) } + parsedASS.info.PlayResX = String(qualX) + parsedASS.info.PlayResY = String(qualY) + const fixed = stringify(parsedASS) - const readableStream = Readable.from([fixed]) + const resampledSubs = resamplePOSSubtitle(fixed,parseInt(parsedASS.info.PlayResX), parseInt(parsedASS.info.PlayResY), qualX, qualY) + + const readableStream = Readable.from([resampledSubs]) await finished(readableStream.pipe(stream)) console.log(`Sub ${sub.language}.${sub.format} downloaded`) @@ -46,30 +71,30 @@ export async function downloadCRSub( return path } -function resamplePOSSubtitle(subtitle: string) { - let lines = subtitle.split('\n'); +function resamplePOSSubtitle(subtitle: string, ox: number, oy: number, nx: number, ny: number) { + let lines = subtitle.split('\n') for (let i = 0; i < lines.length; i++) { - let line = lines[i]; + let line = lines[i] - if (line.includes("\\pos(")) { - let posMatch = line.match(/\\pos\((\d+),(\d+)\)/); - if (posMatch) { - let oldX = parseInt(posMatch[1]); - let oldY = parseInt(posMatch[2]); + if (line.includes('\\pos(')) { + let posMatch = line.match(/\\pos\((\d+),(\d+)\)/) + if (posMatch) { + let oldX = parseInt(posMatch[1]) + let oldY = parseInt(posMatch[2]) - let newX = Math.round((oldX / 640) * 1920); - let newY = Math.round((oldY / 360) * 1080); + let newX = Math.round((oldX / ox) * nx) + let newY = Math.round((oldY / oy) * ny) - let newPos = `\\pos(${newX},${newY})`; + let newPos = `\\pos(${newX},${newY})` - line = line.replace(/\\pos\(\d+,\d+\)/, newPos); - lines[i] = line; - } + line = line.replace(/\\pos\(\d+,\d+\)/, newPos) + lines[i] = line } + } } - return lines.join('\n'); + return lines.join('\n') } export async function downloadADNSub(link: string, dir: string, secret: string) { @@ -118,22 +143,23 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\ positionAligh: string lineAlign: string text: string - }>, + }> vostde: Array<{ startTime: number endTime: number positionAligh: string lineAlign: string text: string - }>, + }> } = await JSON.parse(subs) if (parsedSubs.vde) { for (const s of parsedSubs.vde) { const convertedStart = convertToTimeFormat(s.startTime) const convertedEnd = convertToTimeFormat(s.endTime) - - templateASS = templateASS + `Dialogue: 0,${convertedStart},${convertedEnd},Default,,0,0,0,,${s.text.replace('\n', '\\N').replace('', '{\\i1}').replace('', '{\\i0}')}\n` + + templateASS = + templateASS + `Dialogue: 0,${convertedStart},${convertedEnd},Default,,0,0,0,,${s.text.replace('\n', '\\N').replace('', '{\\i1}').replace('', '{\\i0}')}\n` } } @@ -141,8 +167,9 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\ for (const s of parsedSubs.vostde) { const convertedStart = convertToTimeFormat(s.startTime) const convertedEnd = convertToTimeFormat(s.endTime) - - templateASS = templateASS + `Dialogue: 0,${convertedStart},${convertedEnd},Default,,0,0,0,,${s.text.replace('\n', '\\N').replace('', '{\\i1}').replace('', '{\\i0}')}\n` + + templateASS = + templateASS + `Dialogue: 0,${convertedStart},${convertedEnd},Default,,0,0,0,,${s.text.replace('\n', '\\N').replace('', '{\\i1}').replace('', '{\\i0}')}\n` } } @@ -166,23 +193,23 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\ } function convertToTimeFormat(time: number) { - var seconds: number | string = Math.floor(time); - var milliseconds = Math.round((time - seconds) * 1000); + var seconds: number | string = Math.floor(time) + var milliseconds = Math.round((time - seconds) * 1000) - var hours: number | string = Math.floor(seconds / 3600); - var minutes: number | string = Math.floor((seconds % 3600) / 60); - seconds = seconds % 60; + var hours: number | string = Math.floor(seconds / 3600) + var minutes: number | string = Math.floor((seconds % 3600) / 60) + seconds = seconds % 60 - hours = String(hours).padStart(2, '0'); - minutes = String(minutes).padStart(2, '0'); - seconds = String(seconds).padStart(2, '0'); + hours = String(hours).padStart(2, '0') + minutes = String(minutes).padStart(2, '0') + seconds = String(seconds).padStart(2, '0') - milliseconds = Math.round(milliseconds / 10); + milliseconds = Math.round(milliseconds / 10) - var formattedMilliseconds = milliseconds < 10 ? '0' + milliseconds : milliseconds; + var formattedMilliseconds = milliseconds < 10 ? '0' + milliseconds : milliseconds - var formattedTime = hours + ':' + minutes + ':' + seconds + '.' + formattedMilliseconds; - return formattedTime; + var formattedTime = hours + ':' + minutes + ':' + seconds + '.' + formattedMilliseconds + return formattedTime } export async function ADNparseSub(raw: string, secret: string) {