diff options
Diffstat (limited to 'youtube/static/js')
-rw-r--r-- | youtube/static/js/av-merge.js | 107 | ||||
-rw-r--r-- | youtube/static/js/comments.js | 4 | ||||
-rw-r--r-- | youtube/static/js/common.js | 24 | ||||
-rw-r--r-- | youtube/static/js/playlistadd.js | 6 | ||||
-rw-r--r-- | youtube/static/js/plyr-start.js | 8 | ||||
-rw-r--r-- | youtube/static/js/sponsorblock.js | 2 | ||||
-rw-r--r-- | youtube/static/js/watch.js | 20 |
7 files changed, 87 insertions, 84 deletions
diff --git a/youtube/static/js/av-merge.js b/youtube/static/js/av-merge.js index bbe3e35..e7d5c25 100644 --- a/youtube/static/js/av-merge.js +++ b/youtube/static/js/av-merge.js @@ -41,7 +41,7 @@ function AVMerge(video, srcInfo, startTime){ } // Find supported video and audio sources - for (var src of srcInfo['videos']) { + for (let src of srcInfo['videos']) { if (MediaSource.isTypeSupported(src['mime_codec'])) { reportDebug('Using video source', src['mime_codec'], src['quality_string'], 'itag', src['itag']); @@ -49,7 +49,7 @@ function AVMerge(video, srcInfo, startTime){ break; } } - for (var src of srcInfo['audios']) { + for (let src of srcInfo['audios']) { if (MediaSource.isTypeSupported(src['mime_codec'])) { reportDebug('Using audio source', src['mime_codec'], src['quality_string'], 'itag', src['itag']); @@ -205,9 +205,9 @@ Stream.prototype.setup = async function(){ this.initRange.start, this.indexRange.end, (buffer) => { - var init_end = this.initRange.end - this.initRange.start + 1; - var index_start = this.indexRange.start - this.initRange.start; - var index_end = this.indexRange.end - this.initRange.start + 1; + let init_end = this.initRange.end - this.initRange.start + 1; + let index_start = this.indexRange.start - this.initRange.start; + let index_end = this.indexRange.end - this.initRange.start + 1; this.setupInitSegment(buffer.slice(0, init_end)); this.setupSegmentIndex(buffer.slice(index_start, index_end)); } @@ -247,7 +247,7 @@ Stream.prototype.setupSegmentIndex = async function(indexSegment){ entry.referencedSize = entry.end - entry.start + 1; } } else { - var box = unbox(indexSegment); + let box = unbox(indexSegment); this.sidx = sidx_parse(box.data, this.indexRange.end+1); } this.fetchSegmentIfNeeded(this.getSegmentIdx(this.startTime)); @@ -289,8 +289,8 @@ Stream.prototype.appendSegment = function(segmentIdx, chunk) { // Count how many bytes are in buffer to update buffering target, // updating .have as well for when we need to delete segments - var bytesInBuffer = 0; - for (var i = 0; i < this.sidx.entries.length; i++) { + let bytesInBuffer = 0; + for (let i = 0; i < this.sidx.entries.length; i++) { if (this.segmentInBuffer(i)) bytesInBuffer += this.sidx.entries[i].referencedSize; else if (this.sidx.entries[i].have) { @@ -306,11 +306,11 @@ Stream.prototype.appendSegment = function(segmentIdx, chunk) { // Delete 10 segments (arbitrary) from buffer, making sure // not to delete current one - var currentSegment = this.getSegmentIdx(this.video.currentTime); - var numDeleted = 0; - var i = 0; + let currentSegment = this.getSegmentIdx(this.video.currentTime); + let numDeleted = 0; + let i = 0; const DELETION_TARGET = 10; - var toDelete = []; // See below for why we have to schedule it + let toDelete = []; // See below for why we have to schedule it this.reportDebug('Deleting segments from beginning of buffer.'); while (numDeleted < DELETION_TARGET && i < currentSegment) { if (this.sidx.entries[i].have) { @@ -334,9 +334,9 @@ Stream.prototype.appendSegment = function(segmentIdx, chunk) { // When calling .remove, the sourceBuffer will go into updating=true // state, and remove cannot be called until it is done. So we have // to delete on the updateend event for subsequent ones. - var removeFinishedEvent; - var deletedStuff = (toDelete.length !== 0) - var deleteSegment = () => { + let removeFinishedEvent; + let deletedStuff = (toDelete.length !== 0) + let deleteSegment = () => { if (toDelete.length === 0) { removeFinishedEvent.remove(); // If QuotaExceeded happened for current segment, retry the @@ -370,19 +370,19 @@ Stream.prototype.appendSegment = function(segmentIdx, chunk) { } Stream.prototype.getSegmentIdx = function(videoTime) { // get an estimate - var currentTick = videoTime * this.sidx.timeScale; - var firstSegmentDuration = this.sidx.entries[0].subSegmentDuration; - var index = 1 + Math.floor(currentTick / firstSegmentDuration); - var index = clamp(index, 0, this.sidx.entries.length - 1); + let currentTick = videoTime * this.sidx.timeScale; + let firstSegmentDuration = this.sidx.entries[0].subSegmentDuration; + let index = 1 + Math.floor(currentTick / firstSegmentDuration); + index = clamp(index, 0, this.sidx.entries.length - 1); - var increment = 1; + let increment = 1; if (currentTick < this.sidx.entries[index].tickStart){ increment = -1; } // go up or down to find correct index while (index >= 0 && index < this.sidx.entries.length) { - var entry = this.sidx.entries[index]; + let entry = this.sidx.entries[index]; if (entry.tickStart <= currentTick && (entry.tickEnd+1) > currentTick){ return index; } @@ -396,11 +396,11 @@ Stream.prototype.checkBuffer = async function() { return; } // Find the first unbuffered segment, i - var currentSegmentIdx = this.getSegmentIdx(this.video.currentTime); - var bufferedBytesAhead = 0; - var i; + let currentSegmentIdx = this.getSegmentIdx(this.video.currentTime); + let bufferedBytesAhead = 0; + let i; for (i = currentSegmentIdx; i < this.sidx.entries.length; i++) { - var entry = this.sidx.entries[i]; + let entry = this.sidx.entries[i]; // check if we had it before, but it was deleted by the browser if (entry.have && !this.segmentInBuffer(i)) { this.reportDebug('segment', i, 'deleted by browser'); @@ -428,9 +428,9 @@ Stream.prototype.checkBuffer = async function() { } } Stream.prototype.segmentInBuffer = function(segmentIdx) { - var entry = this.sidx.entries[segmentIdx]; + let entry = this.sidx.entries[segmentIdx]; // allow for 0.01 second error - var timeStart = entry.tickStart/this.sidx.timeScale + 0.01; + let timeStart = entry.tickStart/this.sidx.timeScale + 0.01; /* Some of YouTube's mp4 fragments are malformed, with half-frame playback gaps. In this video at 240p (timeScale = 90000 ticks/second) @@ -457,14 +457,15 @@ Stream.prototype.segmentInBuffer = function(segmentIdx) { quality switching, YouTube likely encodes their formats to line up nicely. Either there is a bug in their encoder, or this is intentional. Allow for up to 1 frame-time of error to work around this issue. */ + let endError; if (this.streamType == 'video') - var endError = 1/(this.avMerge.videoSource.fps || 30); + endError = 1/(this.avMerge.videoSource.fps || 30); else - var endError = 0.01 - var timeEnd = (entry.tickEnd+1)/this.sidx.timeScale - endError; + endError = 0.01 + let timeEnd = (entry.tickEnd+1)/this.sidx.timeScale - endError; - var timeRanges = this.sourceBuffer.buffered; - for (var i=0; i < timeRanges.length; i++) { + let timeRanges = this.sourceBuffer.buffered; + for (let i=0; i < timeRanges.length; i++) { if (timeRanges.start(i) <= timeStart && timeEnd <= timeRanges.end(i)) { return true; } @@ -505,7 +506,7 @@ Stream.prototype.fetchSegmentIfNeeded = function(segmentIdx) { this.fetchSegment(segmentIdx); } Stream.prototype.handleSeek = function() { - var segmentIdx = this.getSegmentIdx(this.video.currentTime); + let segmentIdx = this.getSegmentIdx(this.video.currentTime); this.fetchSegmentIfNeeded(segmentIdx); } Stream.prototype.reportDebug = function(...args) { @@ -523,7 +524,7 @@ Stream.prototype.reportError = function(...args) { function fetchRange(url, start, end, cb) { return new Promise((resolve, reject) => { - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); xhr.open('get', url); xhr.responseType = 'arraybuffer'; xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end); @@ -536,15 +537,15 @@ function fetchRange(url, start, end, cb) { } function debounce(func, wait, immediate) { - var timeout; + let timeout; return function() { - var context = this; - var args = arguments; - var later = function() { + let context = this; + let args = arguments; + let later = function() { timeout = null; if (!immediate) func.apply(context, args); }; - var callNow = immediate && !timeout; + let callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); @@ -580,7 +581,7 @@ function reportDebug(...args){ } function byteArrayToIntegerLittleEndian(unsignedByteArray){ - var result = 0; + let result = 0; for (byte of unsignedByteArray){ result = result*256; result += byte @@ -588,7 +589,7 @@ function byteArrayToIntegerLittleEndian(unsignedByteArray){ return result; } function byteArrayToFloat(byteArray) { - var view = new DataView(byteArray.buffer); + let view = new DataView(byteArray.buffer); if (byteArray.length == 4) return view.getFloat32(byteArray.byteOffset); else @@ -599,14 +600,14 @@ function ByteParser(data){ this.data = new Uint8Array(data); } ByteParser.prototype.readInteger = function(nBytes){ - var result = byteArrayToIntegerLittleEndian( + let result = byteArrayToIntegerLittleEndian( this.data.slice(this.curIndex, this.curIndex + nBytes) ); this.curIndex += nBytes; return result; } ByteParser.prototype.readBufferBytes = function(nBytes){ - var result = this.data.slice(this.curIndex, this.curIndex + nBytes); + let result = this.data.slice(this.curIndex, this.curIndex + nBytes); this.curIndex += nBytes; return result; } @@ -635,7 +636,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ function sidx_parse (data, offset) { - var bp = new ByteParser(data), + let bp = new ByteParser(data), version = bp.readInteger(1), flags = bp.readInteger(3), referenceId = bp.readInteger(4), @@ -646,9 +647,9 @@ function sidx_parse (data, offset) { entryCount = bp.readInteger(2), entries = []; - var totalBytesOffset = firstOffset + offset; - var totalTicks = 0; - for (var i = entryCount; i > 0; i=i-1 ) { + let totalBytesOffset = firstOffset + offset; + let totalTicks = 0; + for (let i = entryCount; i > 0; i=i-1 ) { let referencedSize = bp.readInteger(4), subSegmentDuration = bp.readInteger(4), unused = bp.readBufferBytes(4) @@ -681,7 +682,7 @@ function sidx_parse (data, offset) { // BEGIN iso-bmff-parser-stream/lib/unbox.js (same license), modified function unbox(buf) { - var bp = new ByteParser(buf), + let bp = new ByteParser(buf), bufferLength = buf.length, length, typeData, @@ -712,7 +713,7 @@ function unbox(buf) { function extractWebmInitializationInfo(initializationSegment) { - var result = { + let result = { timeScale: null, cuesOffset: null, duration: null, @@ -740,9 +741,9 @@ function extractWebmInitializationInfo(initializationSegment) { return result; } function parseWebmCues(indexSegment, initInfo) { - var entries = []; - var currentEntry = {}; - var cuesOffset = initInfo.cuesOffset; + let entries = []; + let currentEntry = {}; + let cuesOffset = initInfo.cuesOffset; (new EbmlDecoder()).readTags(indexSegment, (tagType, tag) => { if (tag.name == 'CueTime') { const tickStart = byteArrayToIntegerLittleEndian(tag.data); @@ -818,7 +819,7 @@ EbmlDecoder.prototype.readTags = function(chunk, onParsedTag) { } EbmlDecoder.prototype.getSchemaInfo = function(tag) { if (Number.isInteger(tag) && schema.has(tag)) { - var name, type; + let name, type; [name, type] = schema.get(tag); return {name, type}; } diff --git a/youtube/static/js/comments.js b/youtube/static/js/comments.js index fdd089f..14ba0c0 100644 --- a/youtube/static/js/comments.js +++ b/youtube/static/js/comments.js @@ -1,9 +1,9 @@ function onClickReplies(e) { - var details = e.target.parentElement; + let details = e.target.parentElement; // e.preventDefault(); console.log("loading replies .."); doXhr(details.getAttribute("data-src") + "&slim=1", (html) => { - var div = details.querySelector(".comment_page"); + let div = details.querySelector(".comment_page"); div.innerHTML = html; }); details.removeEventListener('click', onClickReplies); diff --git a/youtube/static/js/common.js b/youtube/static/js/common.js index c15921c..79f8834 100644 --- a/youtube/static/js/common.js +++ b/youtube/static/js/common.js @@ -1,16 +1,19 @@ const Q = document.querySelector.bind(document); const QA = document.querySelectorAll.bind(document); const QId = document.getElementById.bind(document); +let seconds, + minutes, + hours; function text(msg) { return document.createTextNode(msg); } function clearNode(node) { while (node.firstChild) node.removeChild(node.firstChild); } function toTimestamp(seconds) { - var seconds = Math.floor(seconds); + seconds = Math.floor(seconds); - var minutes = Math.floor(seconds/60); - var seconds = seconds % 60; + minutes = Math.floor(seconds/60); + seconds = seconds % 60; - var hours = Math.floor(minutes/60); - var minutes = minutes % 60; + hours = Math.floor(minutes/60); + minutes = minutes % 60; if (hours) { return `0${hours}:`.slice(-3) + `0${minutes}:`.slice(-3) + `0${seconds}`.slice(-2); @@ -18,8 +21,7 @@ function toTimestamp(seconds) { return `0${minutes}:`.slice(-3) + `0${seconds}`.slice(-2); } - -var cur_track_idx = 0; +let cur_track_idx = 0; function getActiveTranscriptTrackIdx() { let textTracks = QId("js-video-player").textTracks; if (!textTracks.length) return; @@ -39,7 +41,7 @@ function getDefaultTranscriptTrackIdx() { } function doXhr(url, callback=null) { - var xhr = new XMLHttpRequest(); + let xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = (e) => { callback(e.currentTarget.response); @@ -50,7 +52,7 @@ function doXhr(url, callback=null) { // https://stackoverflow.com/a/30810322 function copyTextToClipboard(text) { - var textArea = document.createElement("textarea"); + let textArea = document.createElement("textarea"); // // *** This styling is an extra step which is likely not required. *** @@ -97,8 +99,8 @@ function copyTextToClipboard(text) { textArea.select(); try { - var successful = document.execCommand('copy'); - var msg = successful ? 'successful' : 'unsuccessful'; + let successful = document.execCommand('copy'); + let msg = successful ? 'successful' : 'unsuccessful'; console.log('Copying text command was ' + msg); } catch (err) { console.log('Oops, unable to copy'); diff --git a/youtube/static/js/playlistadd.js b/youtube/static/js/playlistadd.js index 0a2a027..4b76ce1 100644 --- a/youtube/static/js/playlistadd.js +++ b/youtube/static/js/playlistadd.js @@ -37,7 +37,7 @@ } // https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript function sendData(event){ - var clicked_button = document.activeElement; + let clicked_button = document.activeElement; if(clicked_button === null || clicked_button.getAttribute('type') !== 'submit' || clicked_button.parentElement != event.target){ console.log('ERROR: clicked_button not valid'); return; @@ -46,8 +46,8 @@ return; // video(s) are being removed from playlist, just let it refresh the page } event.preventDefault(); - var XHR = new XMLHttpRequest(); - var FD = new FormData(playlistAddForm); + let XHR = new XMLHttpRequest(); + let FD = new FormData(playlistAddForm); if(FD.getAll('video_info_list').length === 0){ displayMessage('Error: No videos selected', true); diff --git a/youtube/static/js/plyr-start.js b/youtube/static/js/plyr-start.js index 763a492..86840e9 100644 --- a/youtube/static/js/plyr-start.js +++ b/youtube/static/js/plyr-start.js @@ -16,10 +16,10 @@ let qualityOptions = []; let qualityDefault; - for (var src of data['uni_sources']) { + for (let src of data['uni_sources']) { qualityOptions.push(src.quality_string) } - for (var src of data['pair_sources']) { + for (let src of data['pair_sources']) { qualityOptions.push(src.quality_string) } if (data['using_pair_sources']) @@ -100,14 +100,14 @@ onChange: function(quality) { if (quality == 'None') {return;} if (quality.includes('(integrated)')) { - for (var i=0; i < data['uni_sources'].length; i++) { + for (let i=0; i < data['uni_sources'].length; i++) { if (data['uni_sources'][i].quality_string == quality) { changeQuality({'type': 'uni', 'index': i}); return; } } } else { - for (var i=0; i < data['pair_sources'].length; i++) { + for (let i=0; i < data['pair_sources'].length; i++) { if (data['pair_sources'][i].quality_string == quality) { changeQuality({'type': 'pair', 'index': i}); return; diff --git a/youtube/static/js/sponsorblock.js b/youtube/static/js/sponsorblock.js index a2fd094..a929fc5 100644 --- a/youtube/static/js/sponsorblock.js +++ b/youtube/static/js/sponsorblock.js @@ -2,7 +2,7 @@ // from: https://git.gir.st/subscriptionfeed.git/blob/59a590d:/app/youtube/templates/watch.html.j2#l28 -var sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i}; /*https://geraintluff.github.io/sha256/sha256.min.js (public domain)*/ +let sha256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i}; /*https://geraintluff.github.io/sha256/sha256.min.js (public domain)*/ window.addEventListener("load", load_sponsorblock); document.addEventListener('DOMContentLoaded', ()=>{ diff --git a/youtube/static/js/watch.js b/youtube/static/js/watch.js index acc6b28..95d9fa7 100644 --- a/youtube/static/js/watch.js +++ b/youtube/static/js/watch.js @@ -1,10 +1,10 @@ const video = document.getElementById('js-video-player'); function changeQuality(selection) { - var currentVideoTime = video.currentTime; - var videoPaused = video.paused; - var videoSpeed = video.playbackRate; - var srcInfo; + let currentVideoTime = video.currentTime; + let videoPaused = video.paused; + let videoSpeed = video.playbackRate; + let srcInfo; if (avMerge) avMerge.close(); if (selection.type == 'uni'){ @@ -22,9 +22,9 @@ function changeQuality(selection) { } // Initialize av-merge -var avMerge; +let avMerge; if (data.using_pair_sources) { - var srcPair = data['pair_sources'][data['pair_idx']]; + let srcPair = data['pair_sources'][data['pair_idx']]; // Do it dynamically rather than as the default in jinja // in case javascript is disabled avMerge = new AVMerge(video, srcPair, 0); @@ -42,10 +42,10 @@ if (qs) { if (data.time_start != 0 && video) {video.currentTime = data.time_start}; // External video speed control -var speedInput = document.getElementById('speed-control'); +let speedInput = document.getElementById('speed-control'); speedInput.addEventListener('keyup', (event) => { if (event.key === 'Enter') { - var speed = parseFloat(speedInput.value); + let speed = parseFloat(speedInput.value); if(!isNaN(speed)){ video.playbackRate = speed; } @@ -61,7 +61,7 @@ if (data.playlist && data.playlist['id'] !== null) { // IntersectionObserver isn't supported in pre-quantum // firefox versions, but the alternative of making it // manually is a performance drain, so oh well - var observer = new IntersectionObserver(lazyLoad, { + let observer = new IntersectionObserver(lazyLoad, { // where in relation to the edge of the viewport, we are observing rootMargin: "100px", @@ -86,7 +86,7 @@ if (data.playlist && data.playlist['id'] !== null) { }; // Tell our observer to observe all img elements with a "lazy" class - var lazyImages = document.querySelectorAll('img.lazy'); + let lazyImages = document.querySelectorAll('img.lazy'); lazyImages.forEach(img => { observer.observe(img); }); |