improved ass resampler

This commit is contained in:
Daniel Haller 2024-04-24 05:25:39 +02:00
parent 17de9416d0
commit 76d8ab5f39
2 changed files with 75 additions and 48 deletions

View File

@ -404,7 +404,7 @@ export async function downloadCrunchyrollPlaylist(
const subDownload = async () => {
const sbs: Array<string> = []
for (const sub of subDownloadList) {
const name = await downloadCRSub(sub, subFolder)
const name = await downloadCRSub(sub, subFolder, quality)
sbs.push(name)
}
return sbs

View File

@ -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('<i>', '{\\i1}').replace('</i>', '{\\i0}')}\n`
templateASS =
templateASS + `Dialogue: 0,${convertedStart},${convertedEnd},Default,,0,0,0,,${s.text.replace('\n', '\\N').replace('<i>', '{\\i1}').replace('</i>', '{\\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('<i>', '{\\i1}').replace('</i>', '{\\i0}')}\n`
templateASS =
templateASS + `Dialogue: 0,${convertedStart},${convertedEnd},Default,,0,0,0,,${s.text.replace('\n', '\\N').replace('<i>', '{\\i1}').replace('</i>', '{\\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) {