Skip to content

Instantly share code, notes, and snippets.

@H1D
Last active March 4, 2021 03:51
Show Gist options
  • Save H1D/4f95e5cf50d656bf010b5ceaf45b04cf to your computer and use it in GitHub Desktop.
Save H1D/4f95e5cf50d656bf010b5ceaf45b04cf to your computer and use it in GitHub Desktop.
microsoft stream transcript grabber
/*! https://gist.github.com/H1D/4f95e5cf50d656bf010b5ceaf45b04cf | (c) Artem Sushchev | opensource.org/licenses/MIT */
const speed = 20;//1 - 100
const scrollCont = document.querySelector('.transcript .virtual-list');
const lines = new Set();
let statusSpan;
let linesCountBefore = lines.size;
let scrollTimer;
let grabTimer;
let checkFinishedTimer;
showOverlay()
if (validateDocument()) {
scrollTimer = setInterval(scrollLines,(101-speed)*2);
grabTimer = setInterval(grabVisible,(101-speed)*2);
checkFinishedTimer = setInterval(checkFinished,(101-speed)*10);
}
////////////////////////
async function scrollLines() {
const currentScrollTop = scrollCont.scrollTop;
const contentHeight = scrollCont.getBoundingClientRect().height;
scrollCont.scroll(0, currentScrollTop + contentHeight);
}
function grabVisible() {
const linesElems = Array.from(document.querySelectorAll('.transcript-line-wrapper'));
linesElems.forEach((lineElem)=>{
const ts = lineElem.querySelector('.transcript-timestamp').textContent;
const text = lineElem.querySelector('.transcript-text').textContent;
lines.add(`${ts}\n${text}`);
});
}
const saveTextFile = (function saveData() {
const a = document.createElement("a");
a.classList.add('bkmrkltFileLink');
return function (text, fileName) {
const blob = new Blob([text], {type: "octet/stream"});
const url = window.URL.createObjectURL(blob);
statusSpan.innerHTML = `Done!<br>`;
statusSpan.appendChild(a);
a.textContent = fileName;
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());
function checkFinished() {
if (linesCountBefore === lines.size) {
clearInterval(scrollTimer);
clearInterval(grabTimer);
clearInterval(checkFinishedTimer);
const text = Array.from(lines).join('\n\n');
saveTextFile(text,`${document.title}.txt`)
} else {
linesCountBefore = lines.size
}
}
/// foolproofing
function validateDocument() {
if (!scrollCont) {
statusSpan.style = 'text-transform:none;font-size:x-large;'
statusSpan.innerHTML = `
🤷‍♂️ <br>
Can't find transcript here. <br>
Are you sure you invoked bookmarklet after opening correct page?
`;
statusSpan
return false;
}
return true;
}
/// overlay
function showOverlay() {
const style = document.createElement('style');
const overlay = document.createElement('div');
style.innerHTML = `
.bkmrkltGrabberOverlay {
height: 100vh;
width: 100%;
background: rgba(255,255,255,0.8);
backdrop-filter: blur(4px);
position: fixed;
top: 0;
z-index: 2147483648;
font-family: sans-serif;
font-weight: 900;
font-size: xxx-large;
display: flex;
align-items: center;
justify-content: center;
line-height: 1.2;
text-transform: uppercase;
text-align: center;
}
.bkmrkltFileLink {
text-transform: none;
color: blue !important;
text-decoration: underline !important;
font-size: small;
}
.bkmrkltGrabberContacts {
position: absolute;
bottom: 30px;
text-transform: none;
color: blue !important;
text-decoration: underline !important;
font-size: large;
}
`;
overlay.innerHTML = `
<span>In progress…</span>
<a class="bkmrkltGrabberContacts" target="_blank" href="https://gist.github.com/H1D/4f95e5cf50d656bf010b5ceaf45b04cf">
Contact & questions
</a>
`;
statusSpan = overlay.querySelector('span');
overlay.classList.add("bkmrkltGrabberOverlay");
document.body.appendChild(overlay);
document.head.appendChild(style);
}
@nicoborghi
Copy link

Thank you! Very useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment