aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md9
-rw-r--r--index.html56
-rw-r--r--main.js65
3 files changed, 104 insertions, 26 deletions
diff --git a/README.md b/README.md
index 5267572..2c8aed4 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,9 @@
# yt-frame-timer
-A JavaScript-based program to determine the time between start and end points of a YouTube video down to the frame. Based on [https://github.com/Slush0Puppy/retime](https://github.com/Slush0Puppy/retime) by Slush Puppy (big thanks to them for their work). Formatting done by [StackEdit](https://stackedit.io/). \ No newline at end of file
+A JavaScript-based program to determine the time between start and end points of a YouTube video down to the frame. The tool was originally created to help moderators retime speedruns on [speedrun.com](https://www.speedrun.com). Based on [Slush Puppy's Retime Tool (SPRT)](https://github.com/Slush0Puppy/retime) by Slush Puppy (big thanks to them for their work).
+
+## Contributors
+* [SlushPuppy](https://www.speedrun.com/user/SlushPuppy) - Created [Slush Puppy's Retime Tool (SPRT)](https://github.com/Slush0Puppy/retime) in Python
+* [dadinfinitum](https://www.speedrun.com/user/dadinfinitum) - Rewrote SPRT into web-hosted JavaScript / yt-frame-retimer lead
+* [Oxknifer](https://www.speedrun.com/user/Oxknifer) - Original idea / beta tester on SPRT / yt-frame-retimer contributor
+
+Interested in contributing? Message @dadinfinitum or @Oxknifer
diff --git a/index.html b/index.html
index 932267e..978e6ee 100644
--- a/index.html
+++ b/index.html
@@ -1,27 +1,53 @@
<!DOCTYPE html>
<html>
+
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <version>1.1.0</version>
<title>YouTube Frame Timer</title>
<link rel="stylesheet" href="https://stackedit.io/style.css" />
- <script src="main.js"></script>
+ <script src="main.js"></script>
</head>
<body class="stackedit">
- <div class="stackedit__html"><h1 id="youtube-interval-timer">YouTube Interval Timer</h1>
-<h3 id="about">About</h3>
-<p>Takes start and stop points of a YouTube video, down to the frame, and gives the time between them in the format <code>1h 23m 45s 678ms</code>. Source code is <a href="https://github.com/slashinfty/yt-frame-timer">available</a>.</p>
-<h3 id="video-framerate">Video Framerate</h3>
-<p>Right click the YouTube video and select “Stats for nerds.” The third line is “Current / Optimal Res” - find the two numbers after the @ and enter them for framerate.</p>
-<p><label for="framerate">Framerate: </label><input type="text" id="framerate" size="3" /></p>
-<h3 id="video-endpoints">Video Endpoints</h3>
-<p>Find the starting point (you can use the <code>,</code> and <code>.</code> keys to find the exact frame). Right click the video and select “Copy debug info” and paste it for starting frame. Repeat for ending frame.</p>
-<p><label for="startobj">Starting frame: </label><input type="text" id="startobj" style='width:100%'/></p>
-<p><label for="endobj">Ending frame: </label><input type="text" id="endobj" style='width:100%'/></p>
-<h3 id="video-time">Video Time</h3>
-<p><button onclick="compute()">Compute time</button>&nbsp;<input type="text" id="time" readonly size="20" /></p>
-</div>
+ <div class="stackedit__html">
+ <h1 id="youtube-interval-timer">YouTube Interval Timer</h1>
+ <h3 id="about">About</h3>
+ <p>Takes start and stop points of a YouTube video, down to the frame, and gives the time between them in the format
+ <code>1h 23m 45s 678ms</code>. Source code is <a
+ href="https://github.com/slashinfty/yt-frame-timer">available</a>.
+ </p>
+ <h3 id="video-framerate">Video Framerate</h3>
+ <p>Right click the YouTube video and select “Stats for nerds.” The third line is “Current / Optimal Res” - find the
+ two numbers after the @ and enter them for framerate.</p>
+ <p>
+ <label for="framerate">Framerate: </label>
+ <input type="text" id="framerate" size="3" value="60" onchange='validateFPS(event)' />
+ </p>
+ <h3 id="video-endpoints">Video Endpoints</h3>
+ <p>
+ Find the starting point (you can use the <code>,</code> and <code>.</code> keys to find the exact frame). Right
+ click the video and select “Copy debug info” and paste it for starting frame. Repeat for ending frame.
+ </p>
+ <p>
+ <label for="startobj">Starting frame: </label>
+ <input type="text" id="startobj" style='width:100%' onchange='parseForTime(event)' />
+ </p>
+ <p>
+ <label for="endobj">Ending frame: </label>
+ <input type="text" id="endobj" style='width:100%' onchange='parseForTime(event)' />
+ </p>
+ <h3 id="video-time">Video Time</h3>
+ <p>
+ <button id="computeButton" onclick="compute()">Compute time</button>&nbsp;<input type="text" id="time" readonly
+ size="20" />
+ </p>
+ <p id="modMessage"></p>
+ <b>
+ <p id="postModMessage"></p>
+ </b>
+ </div>
</body>
-</html>
+</html> \ No newline at end of file
diff --git a/main.js b/main.js
index 1deac10..f84be0b 100644
--- a/main.js
+++ b/main.js
@@ -1,16 +1,21 @@
function compute() {
- let startObj = JSON.parse(document.getElementById('startobj').value);
- let endObj = JSON.parse(document.getElementById('endobj').value);
- let framerate = document.getElementById('framerate').value;
- if (startObj == undefined || endObj == undefined || framerate == undefined) return;
+
+ // Initiate basic time variables
let hours = 0;
let minutes = 0;
let seconds = 0;
let milliseconds = 0;
- let frameRate = parseInt(framerate);
- let frameFromObj = (time, fps) => Math.floor(time * fps) / fps; //round to the nearest frame
- let startFrame = frameFromObj(startObj.lct, frameRate);
- let endFrame = frameFromObj(endObj.lct, frameRate);
+
+ // Get framerate, start frame, and end frame from corresponding elements
+ // Double check they all have a value
+ let frameRate = parseInt(document.getElementById('framerate').value);
+ let startFrame = document.getElementById('startobj').value;
+ let endFrame = document.getElementById('endobj').value;
+ if (typeof (startFrame) === 'undefined' || endFrame === 'undefined' || framerate === 'undefined') {
+ return
+ };
+
+ // Calculate framerate
let frames = (endFrame - startFrame) * frameRate;
if (frames >= frameRate) {
seconds = Math.floor(frames / frameRate);
@@ -39,6 +44,46 @@ function compute() {
milliseconds = '0' + milliseconds;
}
}
- let print = hours.toString() + 'h ' + minutes.toString() + 'm ' + seconds.toString() + 's ' + milliseconds.toString() + 'ms';
- document.getElementById('time').value = print;
+
+ // Show the time and mod message in the DOM
+ let finalTime = hours.toString() + 'h ' + minutes.toString() + 'm ' + seconds.toString() + 's ' + milliseconds.toString() + 'ms';
+ let modMessage = `Mod Message: Time starts at ${parseFloat(startFrame).toFixed(3)} and ends at ${parseFloat(endFrame).toFixed(3)} at ${frameRate} fps to get a final time of ${finalTime}.`;
+ let credits = `Retimed using [yt-frame-timer](https://mattbraddock.com/yt-frame-timer)`;
+ document.getElementById('time').value = finalTime;
+ document.getElementById('postModMessage').innerHTML = "The mod message has been copied to clipboard! Please paste the it into the comment of the run you are verifying.";
+ document.getElementById('modMessage').innerHTML = modMessage + ' ' + credits;
+
+ // Copy mod message to clipboard
+ navigator.clipboard.writeText(modMessage)
+ .then(() => { alert(`Copied to clipboard!`) })
+ .catch((error) => { alert(`Copy failed! ${error}`) })
+}
+
+const validateFPS = (event) => {
+ // If framerate is invalid, show an error message and disable start and end frame fields
+ if (event.target.value === '' || parseInt(event.target.value) <= 0 || isNaN(parseInt(event.target.value))) {
+ document.getElementById('framerate').setCustomValidity('Please enter a valid framerate.');
+ document.getElementById('framerate').reportValidity();
+ document.getElementById('startobj').disabled = true;
+ document.getElementById('endobj').disabled = true;
+ document.getElementById('computeButton').disabled = true;
+ } else {
+ document.getElementById('startobj').disabled = false;
+ document.getElementById('endobj').disabled = false;
+ document.getElementById('computeButton').disabled = false;
+ }
+}
+
+const parseForTime = (event) => {
+ // Get current frame from input field (either start time or end time)
+ let frameFromInputText = (JSON.parse(event.target.value)).lct;
+ if (typeof frameFromInputText !== 'undefined') {
+ // Get the framerate
+ let frameRate = parseInt(document.getElementById('framerate').value);
+ // Calculate the frame
+ let frameFromObj = (time, fps) => Math.floor(time * fps) / fps; //round to the nearest frame
+ let finalFrame = frameFromObj(frameFromInputText, frameRate);
+ // Update the DOM
+ document.getElementById(event.target.id).value = `${finalFrame}`;
+ }
} \ No newline at end of file