[frontend]: fix global scope, change var to let
This commit is contained in:
parent
dd498e63d9
commit
df7e41b61a
@ -41,7 +41,7 @@ function AVMerge(video, srcInfo, startTime){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find supported video and audio sources
|
// Find supported video and audio sources
|
||||||
for (var src of srcInfo['videos']) {
|
for (let src of srcInfo['videos']) {
|
||||||
if (MediaSource.isTypeSupported(src['mime_codec'])) {
|
if (MediaSource.isTypeSupported(src['mime_codec'])) {
|
||||||
reportDebug('Using video source', src['mime_codec'],
|
reportDebug('Using video source', src['mime_codec'],
|
||||||
src['quality_string'], 'itag', src['itag']);
|
src['quality_string'], 'itag', src['itag']);
|
||||||
@ -49,7 +49,7 @@ function AVMerge(video, srcInfo, startTime){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var src of srcInfo['audios']) {
|
for (let src of srcInfo['audios']) {
|
||||||
if (MediaSource.isTypeSupported(src['mime_codec'])) {
|
if (MediaSource.isTypeSupported(src['mime_codec'])) {
|
||||||
reportDebug('Using audio source', src['mime_codec'],
|
reportDebug('Using audio source', src['mime_codec'],
|
||||||
src['quality_string'], 'itag', src['itag']);
|
src['quality_string'], 'itag', src['itag']);
|
||||||
@ -205,9 +205,9 @@ Stream.prototype.setup = async function(){
|
|||||||
this.initRange.start,
|
this.initRange.start,
|
||||||
this.indexRange.end,
|
this.indexRange.end,
|
||||||
(buffer) => {
|
(buffer) => {
|
||||||
var init_end = this.initRange.end - this.initRange.start + 1;
|
let init_end = this.initRange.end - this.initRange.start + 1;
|
||||||
var index_start = this.indexRange.start - this.initRange.start;
|
let index_start = this.indexRange.start - this.initRange.start;
|
||||||
var index_end = this.indexRange.end - this.initRange.start + 1;
|
let index_end = this.indexRange.end - this.initRange.start + 1;
|
||||||
this.setupInitSegment(buffer.slice(0, init_end));
|
this.setupInitSegment(buffer.slice(0, init_end));
|
||||||
this.setupSegmentIndex(buffer.slice(index_start, index_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;
|
entry.referencedSize = entry.end - entry.start + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var box = unbox(indexSegment);
|
let box = unbox(indexSegment);
|
||||||
this.sidx = sidx_parse(box.data, this.indexRange.end+1);
|
this.sidx = sidx_parse(box.data, this.indexRange.end+1);
|
||||||
}
|
}
|
||||||
this.fetchSegmentIfNeeded(this.getSegmentIdx(this.startTime));
|
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,
|
// Count how many bytes are in buffer to update buffering target,
|
||||||
// updating .have as well for when we need to delete segments
|
// updating .have as well for when we need to delete segments
|
||||||
var bytesInBuffer = 0;
|
let bytesInBuffer = 0;
|
||||||
for (var i = 0; i < this.sidx.entries.length; i++) {
|
for (let i = 0; i < this.sidx.entries.length; i++) {
|
||||||
if (this.segmentInBuffer(i))
|
if (this.segmentInBuffer(i))
|
||||||
bytesInBuffer += this.sidx.entries[i].referencedSize;
|
bytesInBuffer += this.sidx.entries[i].referencedSize;
|
||||||
else if (this.sidx.entries[i].have) {
|
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
|
// Delete 10 segments (arbitrary) from buffer, making sure
|
||||||
// not to delete current one
|
// not to delete current one
|
||||||
var currentSegment = this.getSegmentIdx(this.video.currentTime);
|
let currentSegment = this.getSegmentIdx(this.video.currentTime);
|
||||||
var numDeleted = 0;
|
let numDeleted = 0;
|
||||||
var i = 0;
|
let i = 0;
|
||||||
const DELETION_TARGET = 10;
|
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.');
|
this.reportDebug('Deleting segments from beginning of buffer.');
|
||||||
while (numDeleted < DELETION_TARGET && i < currentSegment) {
|
while (numDeleted < DELETION_TARGET && i < currentSegment) {
|
||||||
if (this.sidx.entries[i].have) {
|
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
|
// When calling .remove, the sourceBuffer will go into updating=true
|
||||||
// state, and remove cannot be called until it is done. So we have
|
// state, and remove cannot be called until it is done. So we have
|
||||||
// to delete on the updateend event for subsequent ones.
|
// to delete on the updateend event for subsequent ones.
|
||||||
var removeFinishedEvent;
|
let removeFinishedEvent;
|
||||||
var deletedStuff = (toDelete.length !== 0)
|
let deletedStuff = (toDelete.length !== 0)
|
||||||
var deleteSegment = () => {
|
let deleteSegment = () => {
|
||||||
if (toDelete.length === 0) {
|
if (toDelete.length === 0) {
|
||||||
removeFinishedEvent.remove();
|
removeFinishedEvent.remove();
|
||||||
// If QuotaExceeded happened for current segment, retry the
|
// If QuotaExceeded happened for current segment, retry the
|
||||||
@ -370,19 +370,19 @@ Stream.prototype.appendSegment = function(segmentIdx, chunk) {
|
|||||||
}
|
}
|
||||||
Stream.prototype.getSegmentIdx = function(videoTime) {
|
Stream.prototype.getSegmentIdx = function(videoTime) {
|
||||||
// get an estimate
|
// get an estimate
|
||||||
var currentTick = videoTime * this.sidx.timeScale;
|
let currentTick = videoTime * this.sidx.timeScale;
|
||||||
var firstSegmentDuration = this.sidx.entries[0].subSegmentDuration;
|
let firstSegmentDuration = this.sidx.entries[0].subSegmentDuration;
|
||||||
var index = 1 + Math.floor(currentTick / firstSegmentDuration);
|
let index = 1 + Math.floor(currentTick / firstSegmentDuration);
|
||||||
var index = clamp(index, 0, this.sidx.entries.length - 1);
|
index = clamp(index, 0, this.sidx.entries.length - 1);
|
||||||
|
|
||||||
var increment = 1;
|
let increment = 1;
|
||||||
if (currentTick < this.sidx.entries[index].tickStart){
|
if (currentTick < this.sidx.entries[index].tickStart){
|
||||||
increment = -1;
|
increment = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// go up or down to find correct index
|
// go up or down to find correct index
|
||||||
while (index >= 0 && index < this.sidx.entries.length) {
|
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){
|
if (entry.tickStart <= currentTick && (entry.tickEnd+1) > currentTick){
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
@ -396,11 +396,11 @@ Stream.prototype.checkBuffer = async function() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Find the first unbuffered segment, i
|
// Find the first unbuffered segment, i
|
||||||
var currentSegmentIdx = this.getSegmentIdx(this.video.currentTime);
|
let currentSegmentIdx = this.getSegmentIdx(this.video.currentTime);
|
||||||
var bufferedBytesAhead = 0;
|
let bufferedBytesAhead = 0;
|
||||||
var i;
|
let i;
|
||||||
for (i = currentSegmentIdx; i < this.sidx.entries.length; 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
|
// check if we had it before, but it was deleted by the browser
|
||||||
if (entry.have && !this.segmentInBuffer(i)) {
|
if (entry.have && !this.segmentInBuffer(i)) {
|
||||||
this.reportDebug('segment', i, 'deleted by browser');
|
this.reportDebug('segment', i, 'deleted by browser');
|
||||||
@ -428,9 +428,9 @@ Stream.prototype.checkBuffer = async function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Stream.prototype.segmentInBuffer = function(segmentIdx) {
|
Stream.prototype.segmentInBuffer = function(segmentIdx) {
|
||||||
var entry = this.sidx.entries[segmentIdx];
|
let entry = this.sidx.entries[segmentIdx];
|
||||||
// allow for 0.01 second error
|
// 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
|
/* Some of YouTube's mp4 fragments are malformed, with half-frame
|
||||||
playback gaps. In this video at 240p (timeScale = 90000 ticks/second)
|
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.
|
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
|
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. */
|
up to 1 frame-time of error to work around this issue. */
|
||||||
|
let endError;
|
||||||
if (this.streamType == 'video')
|
if (this.streamType == 'video')
|
||||||
var endError = 1/(this.avMerge.videoSource.fps || 30);
|
endError = 1/(this.avMerge.videoSource.fps || 30);
|
||||||
else
|
else
|
||||||
var endError = 0.01
|
endError = 0.01
|
||||||
var timeEnd = (entry.tickEnd+1)/this.sidx.timeScale - endError;
|
let timeEnd = (entry.tickEnd+1)/this.sidx.timeScale - endError;
|
||||||
|
|
||||||
var timeRanges = this.sourceBuffer.buffered;
|
let timeRanges = this.sourceBuffer.buffered;
|
||||||
for (var i=0; i < timeRanges.length; i++) {
|
for (let i=0; i < timeRanges.length; i++) {
|
||||||
if (timeRanges.start(i) <= timeStart && timeEnd <= timeRanges.end(i)) {
|
if (timeRanges.start(i) <= timeStart && timeEnd <= timeRanges.end(i)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -505,7 +506,7 @@ Stream.prototype.fetchSegmentIfNeeded = function(segmentIdx) {
|
|||||||
this.fetchSegment(segmentIdx);
|
this.fetchSegment(segmentIdx);
|
||||||
}
|
}
|
||||||
Stream.prototype.handleSeek = function() {
|
Stream.prototype.handleSeek = function() {
|
||||||
var segmentIdx = this.getSegmentIdx(this.video.currentTime);
|
let segmentIdx = this.getSegmentIdx(this.video.currentTime);
|
||||||
this.fetchSegmentIfNeeded(segmentIdx);
|
this.fetchSegmentIfNeeded(segmentIdx);
|
||||||
}
|
}
|
||||||
Stream.prototype.reportDebug = function(...args) {
|
Stream.prototype.reportDebug = function(...args) {
|
||||||
@ -523,7 +524,7 @@ Stream.prototype.reportError = function(...args) {
|
|||||||
|
|
||||||
function fetchRange(url, start, end, cb) {
|
function fetchRange(url, start, end, cb) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.open('get', url);
|
xhr.open('get', url);
|
||||||
xhr.responseType = 'arraybuffer';
|
xhr.responseType = 'arraybuffer';
|
||||||
xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end);
|
xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end);
|
||||||
@ -536,15 +537,15 @@ function fetchRange(url, start, end, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function debounce(func, wait, immediate) {
|
function debounce(func, wait, immediate) {
|
||||||
var timeout;
|
let timeout;
|
||||||
return function() {
|
return function() {
|
||||||
var context = this;
|
let context = this;
|
||||||
var args = arguments;
|
let args = arguments;
|
||||||
var later = function() {
|
let later = function() {
|
||||||
timeout = null;
|
timeout = null;
|
||||||
if (!immediate) func.apply(context, args);
|
if (!immediate) func.apply(context, args);
|
||||||
};
|
};
|
||||||
var callNow = immediate && !timeout;
|
let callNow = immediate && !timeout;
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
timeout = setTimeout(later, wait);
|
timeout = setTimeout(later, wait);
|
||||||
if (callNow) func.apply(context, args);
|
if (callNow) func.apply(context, args);
|
||||||
@ -580,7 +581,7 @@ function reportDebug(...args){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function byteArrayToIntegerLittleEndian(unsignedByteArray){
|
function byteArrayToIntegerLittleEndian(unsignedByteArray){
|
||||||
var result = 0;
|
let result = 0;
|
||||||
for (byte of unsignedByteArray){
|
for (byte of unsignedByteArray){
|
||||||
result = result*256;
|
result = result*256;
|
||||||
result += byte
|
result += byte
|
||||||
@ -588,7 +589,7 @@ function byteArrayToIntegerLittleEndian(unsignedByteArray){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
function byteArrayToFloat(byteArray) {
|
function byteArrayToFloat(byteArray) {
|
||||||
var view = new DataView(byteArray.buffer);
|
let view = new DataView(byteArray.buffer);
|
||||||
if (byteArray.length == 4)
|
if (byteArray.length == 4)
|
||||||
return view.getFloat32(byteArray.byteOffset);
|
return view.getFloat32(byteArray.byteOffset);
|
||||||
else
|
else
|
||||||
@ -599,14 +600,14 @@ function ByteParser(data){
|
|||||||
this.data = new Uint8Array(data);
|
this.data = new Uint8Array(data);
|
||||||
}
|
}
|
||||||
ByteParser.prototype.readInteger = function(nBytes){
|
ByteParser.prototype.readInteger = function(nBytes){
|
||||||
var result = byteArrayToIntegerLittleEndian(
|
let result = byteArrayToIntegerLittleEndian(
|
||||||
this.data.slice(this.curIndex, this.curIndex + nBytes)
|
this.data.slice(this.curIndex, this.curIndex + nBytes)
|
||||||
);
|
);
|
||||||
this.curIndex += nBytes;
|
this.curIndex += nBytes;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
ByteParser.prototype.readBufferBytes = function(nBytes){
|
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;
|
this.curIndex += nBytes;
|
||||||
return result;
|
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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.*/
|
SOFTWARE.*/
|
||||||
function sidx_parse (data, offset) {
|
function sidx_parse (data, offset) {
|
||||||
var bp = new ByteParser(data),
|
let bp = new ByteParser(data),
|
||||||
version = bp.readInteger(1),
|
version = bp.readInteger(1),
|
||||||
flags = bp.readInteger(3),
|
flags = bp.readInteger(3),
|
||||||
referenceId = bp.readInteger(4),
|
referenceId = bp.readInteger(4),
|
||||||
@ -646,9 +647,9 @@ function sidx_parse (data, offset) {
|
|||||||
entryCount = bp.readInteger(2),
|
entryCount = bp.readInteger(2),
|
||||||
entries = [];
|
entries = [];
|
||||||
|
|
||||||
var totalBytesOffset = firstOffset + offset;
|
let totalBytesOffset = firstOffset + offset;
|
||||||
var totalTicks = 0;
|
let totalTicks = 0;
|
||||||
for (var i = entryCount; i > 0; i=i-1 ) {
|
for (let i = entryCount; i > 0; i=i-1 ) {
|
||||||
let referencedSize = bp.readInteger(4),
|
let referencedSize = bp.readInteger(4),
|
||||||
subSegmentDuration = bp.readInteger(4),
|
subSegmentDuration = bp.readInteger(4),
|
||||||
unused = bp.readBufferBytes(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
|
// BEGIN iso-bmff-parser-stream/lib/unbox.js (same license), modified
|
||||||
function unbox(buf) {
|
function unbox(buf) {
|
||||||
var bp = new ByteParser(buf),
|
let bp = new ByteParser(buf),
|
||||||
bufferLength = buf.length,
|
bufferLength = buf.length,
|
||||||
length,
|
length,
|
||||||
typeData,
|
typeData,
|
||||||
@ -712,7 +713,7 @@ function unbox(buf) {
|
|||||||
|
|
||||||
|
|
||||||
function extractWebmInitializationInfo(initializationSegment) {
|
function extractWebmInitializationInfo(initializationSegment) {
|
||||||
var result = {
|
let result = {
|
||||||
timeScale: null,
|
timeScale: null,
|
||||||
cuesOffset: null,
|
cuesOffset: null,
|
||||||
duration: null,
|
duration: null,
|
||||||
@ -740,9 +741,9 @@ function extractWebmInitializationInfo(initializationSegment) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
function parseWebmCues(indexSegment, initInfo) {
|
function parseWebmCues(indexSegment, initInfo) {
|
||||||
var entries = [];
|
let entries = [];
|
||||||
var currentEntry = {};
|
let currentEntry = {};
|
||||||
var cuesOffset = initInfo.cuesOffset;
|
let cuesOffset = initInfo.cuesOffset;
|
||||||
(new EbmlDecoder()).readTags(indexSegment, (tagType, tag) => {
|
(new EbmlDecoder()).readTags(indexSegment, (tagType, tag) => {
|
||||||
if (tag.name == 'CueTime') {
|
if (tag.name == 'CueTime') {
|
||||||
const tickStart = byteArrayToIntegerLittleEndian(tag.data);
|
const tickStart = byteArrayToIntegerLittleEndian(tag.data);
|
||||||
@ -818,7 +819,7 @@ EbmlDecoder.prototype.readTags = function(chunk, onParsedTag) {
|
|||||||
}
|
}
|
||||||
EbmlDecoder.prototype.getSchemaInfo = function(tag) {
|
EbmlDecoder.prototype.getSchemaInfo = function(tag) {
|
||||||
if (Number.isInteger(tag) && schema.has(tag)) {
|
if (Number.isInteger(tag) && schema.has(tag)) {
|
||||||
var name, type;
|
let name, type;
|
||||||
[name, type] = schema.get(tag);
|
[name, type] = schema.get(tag);
|
||||||
return {name, type};
|
return {name, type};
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
function onClickReplies(e) {
|
function onClickReplies(e) {
|
||||||
var details = e.target.parentElement;
|
let details = e.target.parentElement;
|
||||||
// e.preventDefault();
|
// e.preventDefault();
|
||||||
console.log("loading replies ..");
|
console.log("loading replies ..");
|
||||||
doXhr(details.getAttribute("data-src") + "&slim=1", (html) => {
|
doXhr(details.getAttribute("data-src") + "&slim=1", (html) => {
|
||||||
var div = details.querySelector(".comment_page");
|
let div = details.querySelector(".comment_page");
|
||||||
div.innerHTML = html;
|
div.innerHTML = html;
|
||||||
});
|
});
|
||||||
details.removeEventListener('click', onClickReplies);
|
details.removeEventListener('click', onClickReplies);
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
const Q = document.querySelector.bind(document);
|
const Q = document.querySelector.bind(document);
|
||||||
const QA = document.querySelectorAll.bind(document);
|
const QA = document.querySelectorAll.bind(document);
|
||||||
const QId = document.getElementById.bind(document);
|
const QId = document.getElementById.bind(document);
|
||||||
|
let seconds,
|
||||||
|
minutes,
|
||||||
|
hours;
|
||||||
function text(msg) { return document.createTextNode(msg); }
|
function text(msg) { return document.createTextNode(msg); }
|
||||||
function clearNode(node) { while (node.firstChild) node.removeChild(node.firstChild); }
|
function clearNode(node) { while (node.firstChild) node.removeChild(node.firstChild); }
|
||||||
function toTimestamp(seconds) {
|
function toTimestamp(seconds) {
|
||||||
var seconds = Math.floor(seconds);
|
seconds = Math.floor(seconds);
|
||||||
|
|
||||||
var minutes = Math.floor(seconds/60);
|
minutes = Math.floor(seconds/60);
|
||||||
var seconds = seconds % 60;
|
seconds = seconds % 60;
|
||||||
|
|
||||||
var hours = Math.floor(minutes/60);
|
hours = Math.floor(minutes/60);
|
||||||
var minutes = minutes % 60;
|
minutes = minutes % 60;
|
||||||
|
|
||||||
if (hours) {
|
if (hours) {
|
||||||
return `0${hours}:`.slice(-3) + `0${minutes}:`.slice(-3) + `0${seconds}`.slice(-2);
|
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);
|
return `0${minutes}:`.slice(-3) + `0${seconds}`.slice(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cur_track_idx = 0;
|
||||||
var cur_track_idx = 0;
|
|
||||||
function getActiveTranscriptTrackIdx() {
|
function getActiveTranscriptTrackIdx() {
|
||||||
let textTracks = QId("js-video-player").textTracks;
|
let textTracks = QId("js-video-player").textTracks;
|
||||||
if (!textTracks.length) return;
|
if (!textTracks.length) return;
|
||||||
@ -39,7 +41,7 @@ function getDefaultTranscriptTrackIdx() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function doXhr(url, callback=null) {
|
function doXhr(url, callback=null) {
|
||||||
var xhr = new XMLHttpRequest();
|
let xhr = new XMLHttpRequest();
|
||||||
xhr.open("GET", url);
|
xhr.open("GET", url);
|
||||||
xhr.onload = (e) => {
|
xhr.onload = (e) => {
|
||||||
callback(e.currentTarget.response);
|
callback(e.currentTarget.response);
|
||||||
@ -50,7 +52,7 @@ function doXhr(url, callback=null) {
|
|||||||
|
|
||||||
// https://stackoverflow.com/a/30810322
|
// https://stackoverflow.com/a/30810322
|
||||||
function copyTextToClipboard(text) {
|
function copyTextToClipboard(text) {
|
||||||
var textArea = document.createElement("textarea");
|
let textArea = document.createElement("textarea");
|
||||||
|
|
||||||
//
|
//
|
||||||
// *** This styling is an extra step which is likely not required. ***
|
// *** This styling is an extra step which is likely not required. ***
|
||||||
@ -97,8 +99,8 @@ function copyTextToClipboard(text) {
|
|||||||
textArea.select();
|
textArea.select();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var successful = document.execCommand('copy');
|
let successful = document.execCommand('copy');
|
||||||
var msg = successful ? 'successful' : 'unsuccessful';
|
let msg = successful ? 'successful' : 'unsuccessful';
|
||||||
console.log('Copying text command was ' + msg);
|
console.log('Copying text command was ' + msg);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Oops, unable to copy');
|
console.log('Oops, unable to copy');
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
}
|
}
|
||||||
// https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
|
// https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
|
||||||
function sendData(event){
|
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){
|
if(clicked_button === null || clicked_button.getAttribute('type') !== 'submit' || clicked_button.parentElement != event.target){
|
||||||
console.log('ERROR: clicked_button not valid');
|
console.log('ERROR: clicked_button not valid');
|
||||||
return;
|
return;
|
||||||
@ -46,8 +46,8 @@
|
|||||||
return; // video(s) are being removed from playlist, just let it refresh the page
|
return; // video(s) are being removed from playlist, just let it refresh the page
|
||||||
}
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var XHR = new XMLHttpRequest();
|
let XHR = new XMLHttpRequest();
|
||||||
var FD = new FormData(playlistAddForm);
|
let FD = new FormData(playlistAddForm);
|
||||||
|
|
||||||
if(FD.getAll('video_info_list').length === 0){
|
if(FD.getAll('video_info_list').length === 0){
|
||||||
displayMessage('Error: No videos selected', true);
|
displayMessage('Error: No videos selected', true);
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
let qualityOptions = [];
|
let qualityOptions = [];
|
||||||
let qualityDefault;
|
let qualityDefault;
|
||||||
for (var src of data['uni_sources']) {
|
for (let src of data['uni_sources']) {
|
||||||
qualityOptions.push(src.quality_string)
|
qualityOptions.push(src.quality_string)
|
||||||
}
|
}
|
||||||
for (var src of data['pair_sources']) {
|
for (let src of data['pair_sources']) {
|
||||||
qualityOptions.push(src.quality_string)
|
qualityOptions.push(src.quality_string)
|
||||||
}
|
}
|
||||||
if (data['using_pair_sources'])
|
if (data['using_pair_sources'])
|
||||||
@ -100,14 +100,14 @@
|
|||||||
onChange: function(quality) {
|
onChange: function(quality) {
|
||||||
if (quality == 'None') {return;}
|
if (quality == 'None') {return;}
|
||||||
if (quality.includes('(integrated)')) {
|
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) {
|
if (data['uni_sources'][i].quality_string == quality) {
|
||||||
changeQuality({'type': 'uni', 'index': i});
|
changeQuality({'type': 'uni', 'index': i});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
if (data['pair_sources'][i].quality_string == quality) {
|
||||||
changeQuality({'type': 'pair', 'index': i});
|
changeQuality({'type': 'pair', 'index': i});
|
||||||
return;
|
return;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// from: https://git.gir.st/subscriptionfeed.git/blob/59a590d:/app/youtube/templates/watch.html.j2#l28
|
// 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);
|
window.addEventListener("load", load_sponsorblock);
|
||||||
document.addEventListener('DOMContentLoaded', ()=>{
|
document.addEventListener('DOMContentLoaded', ()=>{
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
const video = document.getElementById('js-video-player');
|
const video = document.getElementById('js-video-player');
|
||||||
|
|
||||||
function changeQuality(selection) {
|
function changeQuality(selection) {
|
||||||
var currentVideoTime = video.currentTime;
|
let currentVideoTime = video.currentTime;
|
||||||
var videoPaused = video.paused;
|
let videoPaused = video.paused;
|
||||||
var videoSpeed = video.playbackRate;
|
let videoSpeed = video.playbackRate;
|
||||||
var srcInfo;
|
let srcInfo;
|
||||||
if (avMerge)
|
if (avMerge)
|
||||||
avMerge.close();
|
avMerge.close();
|
||||||
if (selection.type == 'uni'){
|
if (selection.type == 'uni'){
|
||||||
@ -22,9 +22,9 @@ function changeQuality(selection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize av-merge
|
// Initialize av-merge
|
||||||
var avMerge;
|
let avMerge;
|
||||||
if (data.using_pair_sources) {
|
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
|
// Do it dynamically rather than as the default in jinja
|
||||||
// in case javascript is disabled
|
// in case javascript is disabled
|
||||||
avMerge = new AVMerge(video, srcPair, 0);
|
avMerge = new AVMerge(video, srcPair, 0);
|
||||||
@ -42,10 +42,10 @@ if (qs) {
|
|||||||
if (data.time_start != 0 && video) {video.currentTime = data.time_start};
|
if (data.time_start != 0 && video) {video.currentTime = data.time_start};
|
||||||
|
|
||||||
// External video speed control
|
// External video speed control
|
||||||
var speedInput = document.getElementById('speed-control');
|
let speedInput = document.getElementById('speed-control');
|
||||||
speedInput.addEventListener('keyup', (event) => {
|
speedInput.addEventListener('keyup', (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
var speed = parseFloat(speedInput.value);
|
let speed = parseFloat(speedInput.value);
|
||||||
if(!isNaN(speed)){
|
if(!isNaN(speed)){
|
||||||
video.playbackRate = speed;
|
video.playbackRate = speed;
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ if (data.playlist && data.playlist['id'] !== null) {
|
|||||||
// IntersectionObserver isn't supported in pre-quantum
|
// IntersectionObserver isn't supported in pre-quantum
|
||||||
// firefox versions, but the alternative of making it
|
// firefox versions, but the alternative of making it
|
||||||
// manually is a performance drain, so oh well
|
// 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
|
// where in relation to the edge of the viewport, we are observing
|
||||||
rootMargin: "100px",
|
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
|
// 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 => {
|
lazyImages.forEach(img => {
|
||||||
observer.observe(img);
|
observer.observe(img);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user