improved ass resampler
This commit is contained in:
parent
17de9416d0
commit
76d8ab5f39
@ -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
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user