Teleprompter
Download
Recording Time: 0s

Teleprompter - Copy text here...

...

‣

Your teleprompter text here...

'); iframe.contentDocument.write(quill.root.innerHTML); iframe.contentDocument.write(''); iframe.contentDocument.close(); var content = iframe.contentDocument.documentElement.outerHTML; var asBlob = true; var converted = htmlDocx.asBlob(content, {orientation: 'portrait'}); var link = document.createElement('a'); link.href = URL.createObjectURL(converted); link.download = 'document.docx'; link.click(); document.body.removeChild(iframe); }); // functions toolbar// //miror text// document.getElementById("mirrorButton").addEventListener("click", function() { document.getElementById("teleprompter").classList.toggle("mirrored"); }); //cue position// document.getElementById('toggleCuePosition').addEventListener('click', function() { var cueMarker = document.getElementById('cueMarker'); if (cueMarker.style.left !== '0px') { cueMarker.style.left = '0px'; cueMarker.style.right = 'auto'; } else { cueMarker.style.left = 'auto'; cueMarker.style.right = '0px'; cueMarker.style.transform = 'rotate(180deg)'; } }); //edit text// document.getElementById('edit-toggle').addEventListener('click', function() { let contentEditable = document.getElementById('text').getAttribute('contentEditable'); if(contentEditable == 'true') { document.getElementById('text').setAttribute('contentEditable', 'false'); document.getElementById('edit-toggle').innerText = 'Edit Text'; document.getElementById('text').style.backgroundColor = "transparent"; // reset background color after editing } else { document.getElementById('text').setAttribute('contentEditable', 'true'); document.getElementById('edit-toggle').innerText = 'Save Text'; } }); //full screen// document.getElementById('toggleFullscreen').addEventListener('click', function() { if (!document.fullscreenElement) { // if not in fullscreen mode // Enter fullscreen mode if (document.documentElement.requestFullscreen) { document.documentElement.requestFullscreen(); } else if (document.documentElement.mozRequestFullScreen) { // Mozilla document.documentElement.mozRequestFullScreen(); } else if (document.documentElement.webkitRequestFullscreen) { // Webkit document.documentElement.webkitRequestFullscreen(); } else if (document.documentElement.msRequestFullscreen) { // MS document.documentElement.msRequestFullscreen(); } } else { // if in fullscreen mode // Exit fullscreen mode if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { // Mozilla document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { // Webkit document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { // MS document.msExitFullscreen(); } } }); // hide controls// document.getElementById('toggle-controls').addEventListener('click', function() { var controls = document.getElementById('controls'); if (controls.style.display === "none") { controls.style.display = "block"; this.innerText = "Hide Controls"; } else { controls.style.display = "none"; this.innerText = "Unhide Controls"; } }); var teleprompter = document.getElementById('teleprompter'); var text = document.getElementById('text'); var updateText = document.getElementById('update-text'); var scrollSpeedControl = document.getElementById('scroll-speed'); var fontSizeControl = document.getElementById('font-size'); var fontFamilyControl = document.getElementById('font-family'); var textDirectionControl = document.getElementById('text-direction'); var scrolling; var scrollSpeed = 100 - scrollSpeedControl.value; // Inverse the value so that higher means faster fontSizeControl.addEventListener('change', function() { text.style.fontSize = this.value + 'px'; }); fontFamilyControl.addEventListener('change', function() { text.style.fontFamily = this.value; }); scrollSpeedControl.addEventListener('input', function() { scrollSpeed = 100 - this.value; if (scrolling) { // if scrolling, restart it with new speed stopAutoScroll(); startAutoScroll(); } }); function startAutoScroll() { stopAutoScroll(); scrolling = setInterval(function() { teleprompter.scrollTop += 1; }, scrollSpeed); } function stopAutoScroll() { clearInterval(scrolling); } textDirectionControl.addEventListener('change', function() { text.style.direction = this.value; }); updateText.addEventListener('click', function() { var html = quill.root.innerHTML; text.innerHTML = html; }); document.getElementById('returnToStart').addEventListener('click', function() { document.getElementById('teleprompter').scrollTop = 0; }); teleprompter.addEventListener('scroll', function() { localStorage.setItem('teleprompterScrollTop', teleprompter.scrollTop.toString()); }); window.addEventListener('storage', function(e) { if (e.key === 'teleprompterScrollTop') { var newScrollTop = parseInt(e.newValue, 10); // Mirror the scrolling teleprompter.scrollTop = newScrollTop; } }); const toggleScrollBtn = document.getElementById('toggleScroll'); let isScrolling = false; toggleScrollBtn.addEventListener('click', toggleScrollingState); document.addEventListener('keydown', function(event) { if (event.key === " ") { event.preventDefault(); toggleScrollingState(); } }); function toggleScrollingState() { if (isScrolling) { stopAutoScroll(); toggleScrollBtn.textContent = "Start"; exitFullscreen(); toggleControlsVisibility(true); } else { startAutoScroll(); toggleScrollBtn.textContent = "Stop"; enterFullscreen(); toggleControlsVisibility(false); } toggleScrollBtn.blur(); isScrolling = !isScrolling; } function enterFullscreen() { if (!document.fullscreenElement) { if (document.documentElement.requestFullscreen) { document.documentElement.requestFullscreen(); } else if (document.documentElement.mozRequestFullScreen) { document.documentElement.mozRequestFullScreen(); } else if (document.documentElement.webkitRequestFullscreen) { document.documentElement.webkitRequestFullscreen(); } else if (document.documentElement.msRequestFullscreen) { document.documentElement.msRequestFullscreen(); } } } function exitFullscreen() { if (document.fullscreenElement) { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } } } function toggleControlsVisibility(shouldShow) { const controls = document.getElementById('controls'); if (shouldShow) { controls.style.display = "block"; } else { controls.style.display = "none"; } } //keyboard shortcuts// document.addEventListener('keydown', function(event) { if (event.key === "ArrowUp") { // Speed up by decreasing the scrollSpeed if (scrollSpeed > 10) { // This is a minimum threshold, adjust as needed scrollSpeed -= 5; // Decrease by 5, adjust as desired for sensitivity } } else if (event.key === "ArrowDown") { // Slow down by increasing the scrollSpeed if (scrollSpeed < 200) { // This is a maximum threshold, adjust as needed scrollSpeed += 5; // Increase by 5, adjust as desired for sensitivity } } else if (event.key === "") { // Stop the auto-scrolling stopAutoScroll(); // Update the button's text to "Start" if you have a button for that if (toggleScrollBtn) { toggleScrollBtn.textContent = "Start"; isScrolling = false; // Reset the scrolling state } } if (scrolling && (event.key === "ArrowUp" || event.key === "ArrowDown")) { // If scrolling, restart with the new speed stopAutoScroll(); startAutoScroll(); } }); // Add handler for paste event quill.clipboard.addMatcher(Node.TEXT_NODE, function(node, delta) { delta.ops = delta.ops.map(op => { if (op.insert && typeof op.insert === 'string') { let attributes = op.attributes || {}; // If color is not defined, set it to white if (!attributes.color) attributes.color = 'white'; return { insert: op.insert, attributes: attributes }; } else { return op; } }); return delta; }); //story box highlightsBox// document.getElementById('copyHighlights').addEventListener('click', function() { var range = quill.getSelection(); var teleprompter = document.getElementById('teleprompter'); // Adjust this line to match the id of your teleprompter if (range) { if (range.length != 0) { var text = quill.getText(range.index, range.length).substring(0, 10); // Limit to first 10 characters var row = document.createElement('tr'); row.dataset.startIndex = range.index; var noCell = document.createElement('td'); var textCell = document.createElement('td'); var actionsCell = document.createElement('td'); noCell.textContent = document.getElementById('highlightsBox').getElementsByTagName('tr').length; // Set the number var textLink = document.createElement('a'); // create an anchor tag textLink.href = "#"; textLink.textContent = text; textCell.appendChild(textLink); // append the anchor tag to the cell var deleteIcon = document.createElement('i'); deleteIcon.className = 'fas fa-trash delete-icon'; var moveUpButton = document.createElement('button'); moveUpButton.textContent = '+'; moveUpButton.className = 'move-up'; var moveDownButton = document.createElement('button'); moveDownButton.textContent = '-'; moveDownButton.className = 'move-down'; actionsCell.appendChild(deleteIcon); actionsCell.appendChild(moveUpButton); actionsCell.appendChild(moveDownButton); row.appendChild(noCell); row.appendChild(textCell); row.appendChild(actionsCell); document.getElementById('highlightsBox').getElementsByTagName('tbody')[0].appendChild(row); deleteIcon.addEventListener('click', function(e) { e.preventDefault(); var tbody = document.getElementById('highlightsBox').getElementsByTagName('tbody')[0]; tbody.removeChild(row); }); // Event listener for moving a row up moveUpButton.addEventListener('click', function(e) { e.preventDefault(); var prevSibling = row.previousElementSibling; if (prevSibling) { row.parentNode.insertBefore(row, prevSibling); } }); // Event listener for moving a row down moveDownButton.addEventListener('click', function(e) { e.preventDefault(); var nextSibling = row.nextElementSibling; if (nextSibling) { row.parentNode.insertBefore(nextSibling, row); } }); document.getElementById('highlightsBox').addEventListener('click', function(event) { var clickedElement = event.target; if (clickedElement.tagName.toLowerCase() === 'a') { var searchText = clickedElement.textContent; var range = document.createRange(); var teleprompterNode = document.getElementById("text"); if (!teleprompterNode) { console.warn('Teleprompter paragraph not found!'); return; } // Utility function to retrieve all text nodes from a parent node function getTextNodes(node) { var textNodes = []; function retrieveTextNodes(subNode) { if (subNode.nodeType === Node.TEXT_NODE) { textNodes.push(subNode); } else { for (var i = 0; i < subNode.childNodes.length; i++) { retrieveTextNodes(subNode.childNodes[i]); } } } retrieveTextNodes(node); return textNodes; } var textNodes = getTextNodes(teleprompterNode); for (var i = 0; i < textNodes.length; i++) { var pos = textNodes[i].nodeValue.indexOf(searchText); if (pos > -1) { range.setStart(textNodes[i], pos); range.setEnd(textNodes[i], pos + searchText.length); var rect = range.getBoundingClientRect(); var teleprompter = document.getElementById('teleprompter'); var scrollOffset = rect.top + teleprompter.scrollTop - teleprompter.getBoundingClientRect().top; teleprompter.scrollTop = scrollOffset; return; } } console.warn('Search text not found within teleprompter!'); } }); } } }); //sidebar code: document.getElementById('toggleSidebar').addEventListener('click', function() { const sidebar = document.getElementById('sidebar'); const arrowButton = document.getElementById('toggleSidebar'); if (sidebar.style.right === '0px') { sidebar.style.right = '-400px'; arrowButton.innerHTML = "→"; // Change arrow to pointing right } else { sidebar.style.right = '0px'; arrowButton.innerHTML = "←"; // Change arrow to pointing left } }); // story box end highlights// //video let video = document.querySelector("#videoElement"); let cameraSelect = document.querySelector("#cameraSelect"); let micSelect = document.querySelector("#micSelect"); let toggleRecord = document.querySelector("#toggleRecord"); let recordingTime = document.querySelector("#recordingTime"); let downloadLink = document.querySelector("#downloadLink"); let audioPlayer = document.querySelector("#audioPlayer"); let recordedBlobs; let sourceBuffer; let recordingInterval; let audioContext; let analyser; let dataArray; video.muted = true; // Mute the video element if (navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.enumerateDevices() .then(function (devices) { devices.forEach(function (device) { var option = document.createElement("option"); option.value = device.deviceId; if (device.kind === "videoinput") { option.text = device.label || "Camera " + (cameraSelect.length + 1); cameraSelect.appendChild(option); } else if (device.kind === "audioinput") { option.text = device.label || "Microphone " + (micSelect.length + 1); micSelect.appendChild(option); } }); // Select the first camera and microphone by default cameraSelect.value = devices.find(device => device.kind === "videoinput").deviceId; micSelect.value = devices.find(device => device.kind === "audioinput").deviceId; // Start streaming with the selected camera startCameraStream(); }) .catch(function (error) { console.log("Error retrieving media devices: ", error); }); } cameraSelect.addEventListener("change", startCameraStream); micSelect.addEventListener("change", startCameraStream); toggleRecord.addEventListener("click", toggleRecording); function startCameraStream() { var selectedCameraId = cameraSelect.value; var selectedMicId = micSelect.value; var constraints = { video: { deviceId: selectedCameraId }, audio: { deviceId: selectedMicId } }; navigator.mediaDevices.getUserMedia(constraints) .then(function (stream) { video.srcObject = stream; initRecorder(stream); }) .catch(function (error) { console.log("Error accessing camera stream: ", error); }); } function initRecorder(stream) { audioContext = new AudioContext(); var input = audioContext.createMediaStreamSource(stream); recorder = new Recorder(input); // Create an analyser node analyser = audioContext.createAnalyser(); analyser.fftSize = 2048; var bufferLength = analyser.frequencyBinCount; dataArray = new Uint8Array(bufferLength); // Connect the analyser node to our input input.connect(analyser); } // Initialize wavesurfer.js var wavesurfer = WaveSurfer.create({ container: '#waveform', waveColor: 'violet', progressColor: 'purple' }); function toggleRecording() { if (!recorder || recorder.recording) { recorder && recorder.stop(); clearInterval(recordingInterval); toggleRecord.textContent = 'Start Recording'; recorder && recorder.exportWAV(function(blob) { let url = URL.createObjectURL(blob); downloadLink.href = url; downloadLink.download = 'test.wav'; downloadLink.innerHTML = 'Download sound file'; // Load the recorded blob into wavesurfer wavesurfer.loadBlob(blob); }); } else { recorder.record(); recordingTime.innerText = "Recording Time: 0s"; // Reset counter toggleRecord.textContent = 'Stop Recording'; recordingInterval = setInterval(updateRecordingTime, 1000); } } // Add this to your script to handle the play/pause button functionality document.getElementById('playButton').onclick = function() { wavesurfer.playPause(); }; // This will enable the play button once wavesurfer is ready to play the file wavesurfer.on('ready', function() { document.getElementById('playButton').disabled = false; }); function updateRecordingTime() { let time = parseInt(recordingTime.innerText.split(" ")[2]); recordingTime.innerText = `Recording Time: ${++time}s`; } function updateRecordingTime() { let time = parseInt(recordingTime.innerText.split(" ")[2]); recordingTime.innerText = `Recording Time: ${++time}s`; } // file load document.getElementById('file-input').addEventListener('change', function(e) { var file = e.target.files[0]; if (!file) { return; } if (file.name.endsWith(".txt")) { var reader = new FileReader(); reader.onload = function(e) { var contents = e.target.result; quill.setContents([]); quill.clipboard.dangerouslyPasteHTML(0, contents); }; reader.readAsText(file); } else if (file.name.endsWith(".docx") || file.name.endsWith(".doc")) { convertToHtml(file).then(function(html){ quill.setContents([]); quill.clipboard.dangerouslyPasteHTML(0, html); }); } }); function convertToHtml(file) { return new Promise(function(resolve, reject){ var reader = new FileReader(); reader.onload = function(e) { var arrayBuffer = e.target.result; mammoth.convertToHtml({arrayBuffer: arrayBuffer}) .then(function(resultHtml) { resolve(resultHtml.value); }).done(); }; reader.readAsArrayBuffer(file); }); } //dual screen fontSizeControl.addEventListener('change', function() { text.style.fontSize = this.value + 'px'; mirroredTeleprompterElement.style.fontSize = this.value + 'px'; // Update dual screen }); fontFamilyControl.addEventListener('change', function() { text.style.fontFamily = this.value; mirroredTeleprompterElement.style.fontFamily = this.value; // Update dual screen }); document.getElementById('dualScreenBtn').addEventListener('click', function() { var teleprompterContent = document.getElementById('teleprompter').innerHTML; var newWindow = window.open('', '_blank'); newWindow.document.write(` Mirrored Teleprompter ‣
${teleprompterContent}
`); newWindow.document.close(); var teleprompterElement = document.getElementById('teleprompter'); var mirroredTeleprompterElement = newWindow.document.getElementById('teleprompterContent'); // Synchronize the initial styles mirroredTeleprompterElement.style.fontSize = fontSizeControl.value + 'px'; mirroredTeleprompterElement.style.fontFamily = fontFamilyControl.value; teleprompterElement.addEventListener('scroll', function() { mirroredTeleprompterElement.scrollTop = this.scrollTop; }); mirroredTeleprompterElement.addEventListener('scroll', function() { teleprompterElement.scrollTop = this.scrollTop; }); // Update the dual screen when the text is updated updateText.addEventListener('click', function() { var html = quill.root.innerHTML; text.innerHTML = html; mirroredTeleprompterElement.innerHTML = html; // Update the dual screen }); }); // save to PDF document.querySelector("#saveAsPDF").addEventListener("click", function() { var element = quill.container.firstChild; var opt = { margin: 1, filename: 'teleprompter.pdf', image: { type: 'jpeg', quality: 0.98 }, html2canvas: { scale: 2 }, jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' } }; // New Promise-based usage: html2pdf().set(opt).from(element).save(); }); // save to text document.getElementById('save-text-file').addEventListener('click', function() { // Get Quill editor content let quillContent = quill.container.firstChild.innerHTML; // Remove HTML tags using a regular expression let cleanedContent = quillContent.replace(/<[^>]*>?/gm, ''); // Remove HTML entities cleanedContent = cleanedContent.replace(/ /g, ' '); // Create a blob from the cleaned content let blob = new Blob([cleanedContent], {type: "text/plain;charset=utf-8"}); // Create a link element let downloadLink = document.createElement("a"); // Create a data URL for the blob let url = window.URL.createObjectURL(blob); downloadLink.href = url; // Set the download attribute of the link to the text file name downloadLink.download = "teleprompter_content.txt"; // Append the link to the document body document.body.appendChild(downloadLink); // Simulate a click of the download link downloadLink.click(); // Remove the link from the document body document.body.removeChild(downloadLink); });