-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscripts.js
More file actions
419 lines (387 loc) · 16.3 KB
/
scripts.js
File metadata and controls
419 lines (387 loc) · 16.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
var UI = function() {
var loadButton = document.getElementById("load");
var playButton = document.getElementById("playButton");
var recordButton = document.getElementById("record");
var generateButton = document.getElementById("generate");
var createFileButton = document.getElementById("create");
var interface = {
loadButton: loadButton,
playButton: playButton,
recordButton: recordButton,
generateButton: generateButton,
createFileButton: createFileButton,
enablePlayButton: enablePlayButton,
addResetButton: addResetButton,
removeResetButton: removeResetButton,
removeAllCaptions: removeAllCaptions,
enableRecord: enableRecord,
disableRecord: disableRecord,
togglePlayPause: playPause
};
function enablePlayButton() {
videoUrl = loadingVideo.isLoaded;
if (!videoUrl) {
playButton.setAttribute("disabled", "");
alert("A url must be entered");
} else {
playButton.removeAttribute("disabled", "");
console.log("The video has been loaded");
}
}
function addResetButton() {
// Check to see if the reset button already exhists
if (captionSection.querySelector("#resetButton")) {} else {
// If it doesnt then add the reset button
console.log("Reset button added");
resetCaptionsButton = document.createElement("button");
// Create reset button
// Set click attribute to call removeAllCaptions function
resetCaptionsButton.setAttribute("onclick", 'UI.removeAllCaptions("")');
// Set the id of the button to be called in other functions
resetCaptionsButton.setAttribute("id", "resetButton");
resetCaptionsButton.appendChild(document.createTextNode("Reset all Captions"));
// Set button text
captionSection.appendChild(resetCaptionsButton);
}
}
// Create a function to remove reset button if no list items exhist
function removeResetButton() {
if (orderedList.childNodes.length === 0) {
// Get the reset button by id and remove it from the dom
var removeResetButton = document.getElementById("resetButton");
captionSection.removeChild(removeResetButton);
}
}
function removeAllCaptions() {
// while the list has a first child remove it (removes all children)
while (orderedList.firstChild) {
orderedList.removeChild(orderedList.firstChild);
}
console.log("Removed all captions & reset button");
UI.removeResetButton();
// Call function to remove the reset button
generateButton.setAttribute("disabled", "");
// Disable generate button
createFileButton.setAttribute("disabled", "");
// Disable create file button
listId = 1;
}
// Enable the record button & set the play/pause button
function enableRecord() {
recordButton.removeAttribute("disabled", "");
if (playButton.innerHTML === "Play") {
playButton.innerHTML = "Pause";
}
}
// Disable the record button & set the play/pause button
function disableRecord() {
recordButton.setAttribute("disabled", "");
if (playButton.innerHTML === "Pause") {
playButton.innerHTML = "Play";
}
}
// Toggle play/pause
function playPause() {
if (playButton.innerHTML === "Play") {
video.play();
playButton.innerHTML = "Pause";
} else if (playButton.innerHTML === "Pause") {
video.pause();
playButton.innerHTML = "Play";
}
}
return interface;
}();
(function() {
var textFile = null, makeTextFile = function(text) {
var data = new Blob([ text ], {
type: "text/vtt"
});
// If we are replacing a previously generated file we need to
// manually revoke the object URL to avoid memory leaks.
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
return textFile;
};
var create = document.getElementById("create"), textbox = document.getElementById("code");
create.addEventListener("click", function() {
var link = document.getElementById("downloadlink");
link.href = makeTextFile(textbox.value);
link.style.display = "inline-block";
}, false);
})();
"use strict";
/*
____ _ _ _
/ ___| __ _ _ _ __ ___ _| | __ / | / |
\___ \ / _` | | | |/ _` \ \ /\ / / |/ / | | | |
___) | (_| | |_| | (_| |\ V V /| < | |_| |
|____/ \__, |\__,_|\__,_| \_/\_/ |_|\_\ |_(_)_|
|_|
*/
// problem: adding subtitles for videos on the web means learning code and takes a lot of time
// solution: create a way to produce the code for somebody to add to there video
// TO DO LIST //
// [x] Think of a way to link youtube videos.
// [x] Mobile support for record button.
// [x] Think of a way to load the output back into the video (subtitle preview).
// [x] Check if caption input contains text.
console.log(" ____ _ _ _ \r\n / ___| __ _ _ _ __ ___ _| | __ / | / |\r\n \\___ \\ / _` | | | |/ _` \\ \\ /\\ / / |/ / | | | |\r\n ___) | (_| | |_| | (_| |\\ V V /| < | |_| |\r\n |____/ \\__, |\\__,_|\\__,_| \\_/\\_/ |_|\\_\\ |_(_)_|\r\n |_| ");
console.log("A PROGRAM FOR CREATING SUBTITLE FILES IN .vtt FORMAT");
// ** VARIABLES **
var videoUrl;
var video = document.getElementById("video");
var buttonDown;
var buttonUp;
var listId = 1;
var captionSection = document.getElementById("captionSection");
var resetCaptionsButton;
var orderedList = document.getElementById("timeList");
var codeOutput = document.getElementById("code");
var loadingVideo = function() {
var isLoaded = false;
function loadVideo() {
videoUrl = document.getElementById("userUrl").value;
video.setAttribute("src", videoUrl);
console.log(videoUrl);
// Call function to check file extension and apply attribute type
_checkVideoType();
}
function _checkVideoType() {
var videoExtension = videoUrl.substr(videoUrl.lastIndexOf(".") + 1);
console.log(videoExtension);
video.setAttribute("type", videoExtension);
if (videoExtension !== "mp4" && videoExtension !== "ogg") {
alert("Squawk does not support this file type and it may not behave as expected. Squawk supports .mp4 and .ogg formats please check your url for typos or find a different format of the video");
}
loadingVideo.isLoaded = true;
}
return {
loadVideo: loadVideo,
isLoaded: isLoaded
};
}();
// Function that logs the time on mouse events
var logTime = function() {
var timeStamp = video.currentTime.toFixed(3);
return timeStamp;
};
// Two functions that update down and up time using logtime function
var logDownTime = function() {
var time = logTime();
buttonDown = time;
console.log("Recording Started at: " + buttonDown);
};
var logUpTime = function() {
var time = logTime();
buttonUp = time;
console.log("Recording stopped at: " + buttonUp);
};
// Function to take the time stamp in seconds and convert it to .webvtt format (hh:mm:ss.sss)
function convertToTimeFormat(time) {
var tick = time;
var hrs = Math.floor(tick / 3600);
tick = tick - 3600 * hrs;
var mins = Math.floor(tick / 60);
tick = tick - 60 * mins;
// Get seconds to 3 decimal places
var secs = tick.toFixed(3);
var tock = (hrs < 10 ? "0" : "") + hrs + ":" + (mins < 10 ? "0" : "") + mins + ":" + (secs < 10 ? "0" : "") + secs;
// Return the output
return tock;
}
// Create a caption list item
var addCaptionHolder = function(down, up) {
console.log("Time stamp added to caption number: " + listId);
var li = document.createElement("li");
// Create li
li.setAttribute("id", "caption" + listId);
// Set unique id
var input = document.createElement("input");
// Create caption input
input.setAttribute("id", "input" + listId);
// Set unique id
input.setAttribute("tabindex", listId);
// Set tab index
input.setAttribute("type", "text");
// Set input type
var saveButton = document.createElement("button");
// Create save button
// Set save button attribute to call function
saveButton.setAttribute("onclick", 'saveEditCaption("' + "input" + listId + '", "save' + listId + '")');
var playSnippetButton = document.createElement("button");
// Create play snippet button
// Set play snippet button attribute to call function and pass the start record time value
playSnippetButton.setAttribute("onclick", 'playSnippet("' + listId + '", "' + down + '")');
var deleteButton = document.createElement("button");
// Create delete button
// Set delete button attribute to call function
deleteButton.setAttribute("onclick", 'deleteCaptionHolder("' + "caption" + listId + '")');
var startSpan = document.createElement("span");
// Create spans for time stamp
var endSpan = document.createElement("span");
// Create spans for time stamp
// Add each aditional list item to the end
orderedList.appendChild(li);
// Add children element to list item
orderedList.lastChild.appendChild(input);
orderedList.lastChild.appendChild(saveButton).innerHTML = "Save";
orderedList.lastChild.appendChild(playSnippetButton).innerHTML = "Play snippet";
orderedList.lastChild.appendChild(deleteButton).innerHTML = "Delete";
orderedList.lastChild.appendChild(startSpan);
orderedList.lastChild.appendChild(endSpan);
// Add id to elements
saveButton.setAttribute("id", "save" + listId);
startSpan.setAttribute("id", "rec_down" + listId);
startSpan.className = "rec_down";
endSpan.setAttribute("id", "rec_up" + listId);
endSpan.className = "rec_up";
playSnippetButton.className = "play";
deleteButton.className = "delete";
// Send the time stamp to the convertToTimeFormat function
// Add start and end time to spans
startSpan.innerHTML = convertToTimeFormat(down);
endSpan.innerHTML = convertToTimeFormat(up);
listId += 1;
// Add 1 to list item for next id
// Disable generate button untill its saved
console.log("not all captions are saved");
UI.generateButton.setAttribute("disabled", "");
UI.createFileButton.setAttribute("disabled", "");
codeOutput.setAttribute("placeholder", "All captions must be saved before you can generate your file.");
};
// Create function to delete caption list item, pass caption id to function
function deleteCaptionHolder(captionID) {
console.log("Deleted: " + captionID);
// Create a variable from element with passed id
var item = document.getElementById(captionID);
// Remove list item with passed id name from the list
orderedList.removeChild(item);
// Cycle through captions and see if they are saved using checkIfAllCaptionsAreComplete function
var countList = orderedList.childNodes.length;
checkIfAllCaptionsAreComplete(countList);
// Call function to see if it was the last li and remove reset button if
UI.removeResetButton();
}
// Create a function to disable/enable caption input
function saveEditCaption(inputID, buttonID) {
// Get elements by id supplied through the function values
var item = document.getElementById(inputID);
var item2 = document.getElementById(buttonID);
// When user clicks button check if the disabled attribute is set
// If it is already set remove it and change the button to save
if (item.hasAttribute("disabled")) {
item.removeAttribute("disabled");
item2.innerHTML = "Save";
console.log(inputID + " can be edited");
if (item.parentElement.querySelector(".saveTick")) {
var getSaveTick = item.parentElement.getElementsByClassName("saveTick");
item.parentElement.removeChild(getSaveTick[0]);
console.log("not all captions are saved");
UI.generateButton.setAttribute("disabled", "");
UI.createFileButton.setAttribute("disabled", "");
codeOutput.setAttribute("placeholder", "All captions must be saved before you can generate your file.");
} else {}
} else {
// if it is not set set it to disabled and change the button to edit
item.setAttribute("disabled", "");
item2.innerHTML = "Edit";
console.log(inputID + " has been saved");
if (item.parentElement.querySelector(".saveTick")) {} else {
var saveCheck = document.createElement("div");
saveCheck.className = "saveTick";
saveCheck.appendChild(document.createTextNode("✔"));
item.parentElement.appendChild(saveCheck);
}
// Cycle through captions and see if they are saved using checkIfAllCaptionsAreComplete function
var countList = orderedList.childNodes.length;
checkIfAllCaptionsAreComplete(countList);
}
}
// Function to run through list items and see if they are saved, if they are enable generate button!
function checkIfAllCaptionsAreComplete(numberOfCaptionsToCheck) {
for (var i = 1; i <= numberOfCaptionsToCheck; i += 1) {
var checkForCompleteCaption = document.getElementById("caption" + i);
if (checkForCompleteCaption === null) {
numberOfCaptionsToCheck += 1;
} else if (checkForCompleteCaption.querySelector(".saveTick")) {
console.log(i + " is saved");
} else {
break;
}
if (i === numberOfCaptionsToCheck) {
console.log("All captions are saved!");
UI.generateButton.removeAttribute("disabled");
codeOutput.setAttribute("placeholder", "Press generate to preview your code here.");
} else {}
}
}
function playSnippet(captionID, startTime) {
console.log("Play snippet " + captionID + " from: " + startTime);
video.currentTime = startTime;
console.log(video.currentTime);
video.play();
}
// Function to grab data from each element
var getDataFromCaptions = function() {
console.log("generate called");
// Create a way to put data to text area
codeOutput.innerHTML = "";
// Add header to webvtt
codeOutput.appendChild(document.createTextNode("WEBVTT" + "\n"));
// Create a loop to go through each caption
var captionCount = orderedList.childNodes.length;
for (var i = 1; i <= captionCount; i += 1) {
console.log("getting data from caption " + i);
// Get input data
var input = document.getElementById("input" + i);
// If the input is missing (has been deleted) increase the captionCount to compensate
if (input === null) {
captionCount += 1;
} else {
input = "- " + input.value;
// log it
console.log(input);
// Get time stamp data
var startTime = document.getElementById("rec_down" + i);
startTime = startTime.textContent;
var endTime = document.getElementById("rec_up" + i);
endTime = endTime.textContent;
// log it
console.log(startTime + " --> " + endTime);
// Unicode - u000a line feed, u000d carriage return
codeOutput.appendChild(document.createTextNode("\r" + i + "\n"));
codeOutput.appendChild(document.createTextNode(startTime + " --> " + endTime + "\n"));
codeOutput.appendChild(document.createTextNode(input + "\r"));
}
}
};
// ** RUN PROGRAM **
// Load video button
UI.loadButton.onclick = function() {
loadingVideo.loadVideo();
if (loadingVideo.isLoaded === true) {
UI.enablePlayButton();
}
};
// Play button
UI.playButton.onclick = UI.togglePlayPause;
// Record button
UI.recordButton.onmousedown = logDownTime;
UI.recordButton.onmouseup = function() {
logUpTime();
// generate list item
addCaptionHolder(buttonDown, buttonUp);
// call addResetButton function
UI.addResetButton();
};
// Generate button
UI.generateButton.onclick = function() {
getDataFromCaptions();
UI.createFileButton.removeAttribute("disabled");
};
video.addEventListener("play", UI.enableRecord);
video.addEventListener("pause", UI.disableRecord);
video.addEventListener("ended", UI.disableRecord);