|
(() => { |
|
const a = document.createElement('audio'); |
|
a.style.display = 'none'; |
|
const discPart = 'https://cdn.discordapp.com/attachments/500416964620189706/'; |
|
a.src = discPart + '820290793691545641/aot1.mp3'; |
|
a.volume = 0.4; |
|
document.body.append(a); |
|
a.addEventListener('canplay', () => { |
|
a.pause(); |
|
const srtSources = [ |
|
discPart + '820438470375374878/aot0.srt', |
|
discPart + '820438471436795915/aot1.srt', |
|
discPart + '820438474153787412/aot2.srt', |
|
discPart + '820438466012905513/aot3.srt', |
|
discPart + '820438464113410088/aot4.srt', |
|
] |
|
let chunkIndex = 0; |
|
const getFrames = async () => { |
|
return fetch(srtSources.shift()).then(async (r) => { |
|
const reader = await r.body.getReader(); |
|
chunkIndex++; |
|
const utf8Decoder = new TextDecoder('utf-8'); |
|
console.log('Starting download of chunk', chunkIndex); |
|
let chunks = []; |
|
let { value: chunk, done: readerDone } = await reader.read(); |
|
chunk = chunk ? utf8Decoder.decode(chunk, { stream: true }) : ''; |
|
const re = /^\n$/gm; |
|
let startIndex = 0; |
|
let result; |
|
for (; ;) { |
|
result = re.exec(chunk); |
|
if (!result) { |
|
if (readerDone) { |
|
break; |
|
} |
|
let remainder = chunk.substr(startIndex); |
|
({ value: chunk, done: readerDone } = await reader.read()); |
|
chunk = remainder + (chunk ? utf8Decoder.decode(chunk, { stream: true }) : ''); |
|
startIndex = re.lastIndex = 0; |
|
continue; |
|
} |
|
chunks.push(chunk.substring(startIndex, result.index)); |
|
startIndex = re.lastIndex; |
|
} |
|
console.log(`Chunk ${chunkIndex} downloaded and processed!`); |
|
return chunks; |
|
}); |
|
}; |
|
|
|
let m = Array.from(document.querySelectorAll('.markup-eYLPri.messageContent-2t3eCI')).filter((e) => e.textContent === 'START'); |
|
if (!m || m.length === 0) return console.warn('START NOT FOUND!'); |
|
m = m[m.length - 1]; |
|
|
|
let gettingFrames = false; |
|
let frames = []; |
|
const run = () => { |
|
console.log('RUNNING VIDEO'); |
|
const startTime = Date.now(); |
|
let timeStep = frames[frames.length - 2].trim().split(/\n/gm, 2)[1].split('-->')[1].split(':'); |
|
timeStep = Number(timeStep[timeStep.length - 1].replace(',', '.')) + Number(timeStep[0]) * 3600 + Number(timeStep[1]) * 60; |
|
timeStep = timeStep / (frames.length - 1); |
|
const c = () => { |
|
if (frames.length > 0) drawFrame(frames.shift()) |
|
else { |
|
document.body.removeChild(a); |
|
console.log('ENDED'); |
|
m.textContent = 'START'; |
|
delete frames; |
|
} |
|
}; |
|
let i = 0; |
|
|
|
const drawFrame = (frame) => { |
|
let targetTime = i * timeStep * 1000.0; |
|
let fromLast = Date.now() - startTime; |
|
const t = Math.max(targetTime - fromLast, 0); |
|
if (!frame || frame.length < 10) return c(); |
|
i++ |
|
if (t === 0) return c(); |
|
let f = frame.split(/\d$/gm); |
|
if (f.length < 3) return c(); |
|
|
|
if (srtSources.length > 0 && frames.length < 600 && !gettingFrames) { |
|
gettingFrames = true; |
|
getFrames().then(f => frames = frames.concat(f)).finally(() => gettingFrames = false); |
|
} |
|
|
|
let txt = ['<div style="font-family: monospace;font-size: 15px; line-height: 9px; letter-spacing: 0em;">']; |
|
const rows = f[2].split('\n'); |
|
for (let r of rows) { |
|
const spans = r.split('S'); |
|
for (let line of spans) { |
|
if (!line) continue |
|
const c = line.slice(0, 6); |
|
const l = line.slice(6); |
|
txt.push(`<span style="color: #${c};">${l}</span>`); |
|
} |
|
txt.push('<br>') |
|
} |
|
txt.push('</div>'); |
|
m.innerHTML = txt.join(''); |
|
setTimeout(() => { |
|
c(); |
|
}, t); |
|
}; |
|
a.addEventListener('play', () => { |
|
drawFrame(frames.shift()); |
|
}); |
|
} |
|
|
|
getFrames().then(f => frames = frames.concat(f)).finally(() => { a.play(); run(); }) |
|
}); |
|
})() |