308 lines
9.9 KiB
JavaScript
308 lines
9.9 KiB
JavaScript
window.addEventListener('DOMContentLoaded', (event) => {
|
|
const video = document.getElementById('player_video');
|
|
const audio = document.getElementById('player_audio');
|
|
|
|
formats = JSON.parse(document.getElementById('yt_formats').innerText)
|
|
.filter((fmt) => isFormatSupported(fmt) === true)
|
|
.sort((a, b) => {
|
|
if (a.vcodec === 'none' && b.vcodec !== 'none') {
|
|
return -1;
|
|
}
|
|
if (a.vcodec !== 'none' && b.vcodec === 'none') {
|
|
return 1;
|
|
}
|
|
if (a.vcodec !== 'none' && b.vcodec !== 'none') {
|
|
return b.height - a.height;
|
|
}
|
|
if (a.acodec !== 'none' && b.acodec !== 'none') {
|
|
return b.abr - a.abr;
|
|
}
|
|
});
|
|
console.log(formats);
|
|
|
|
if (localStorage.getItem("videoStream") == null || localStorage.getItem("videoStream") == "") {
|
|
const videoFormat = formats.find((fmt) => fmt.vcodec !== 'none');
|
|
const audioFormat = videoFormat.acodec === 'none' ? formats.find((fmt) => fmt.acodec !== 'none') : null;
|
|
console.log('selected video format', videoFormat);
|
|
console.log('selected audio format', audioFormat);
|
|
|
|
selectStreams(videoFormat, audioFormat)
|
|
} else {
|
|
let videoFormat = formats.find((fmt) => fmt.format_id == localStorage.getItem("videoStream"));
|
|
if (videoFormat == null) {
|
|
videoFormat = formats.find((fmt) => fmt.vcodec !== 'none');
|
|
}
|
|
let audioFormat = videoFormat.acodec === 'none' ? formats.find((fmt) => fmt.format_id == localStorage.getItem("audioStream")) : null;
|
|
if (audioFormat == null) {
|
|
audioFormat = videoFormat.acodec === 'none' ? formats.find((fmt) => fmt.acodec !== 'none') : null;
|
|
}
|
|
console.log('selected video format', videoFormat);
|
|
console.log('selected audio format', audioFormat);
|
|
|
|
selectStreams(videoFormat, audioFormat)
|
|
}
|
|
|
|
|
|
if (localStorage.getItem("volume") != null) {
|
|
setVolume(localStorage.getItem("volume"));
|
|
}
|
|
const playButton = document.querySelector('.ytp-button[aria-label="Play"]');
|
|
function toggleVideo(play) {
|
|
const { classList } = playButton;
|
|
const shouldPlay = typeof play === 'boolean' ? play : video.paused;
|
|
try {
|
|
if (shouldPlay) {
|
|
classList.remove('ytp-button-play');
|
|
classList.add('ytp-button-pause');
|
|
if (video.ended) {
|
|
video.currentTime = 0;
|
|
audio.currentTime = 0;
|
|
}
|
|
video.play();
|
|
if (audio.src) {
|
|
audio.play();
|
|
}
|
|
} else {
|
|
classList.remove('ytp-button-pause');
|
|
classList.add('ytp-button-play');
|
|
video.pause();
|
|
if (audio.src) {
|
|
audio.pause();
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
|
|
function updateTime() {
|
|
document.querySelector('.ytp-time-current').innerHTML =
|
|
Math.floor(video.currentTime / 60) +
|
|
':' +
|
|
Math.floor(video.currentTime % 60)
|
|
.toString()
|
|
.padStart(2, '0');
|
|
document.querySelector('.ytp-time-duration').innerHTML =
|
|
Math.floor(video.duration / 60) +
|
|
':' +
|
|
Math.floor(video.duration % 60)
|
|
.toString()
|
|
.padStart(2, '0');
|
|
document.querySelector('.ytp-play-progress').style.transform = 'scaleX(' + video.currentTime / video.duration + ')';
|
|
document.querySelector('.html5-scrubber-button').style.left = (video.currentTime / video.duration) * 100 + '%';
|
|
}
|
|
|
|
function scrub(e) {
|
|
const w = document.querySelector('.ytp-progress-list').getBoundingClientRect();
|
|
const amount = (e.clientX - w.x) / w.width;
|
|
video.currentTime = video.duration * amount;
|
|
audio.currentTime = audio.duration * amount;
|
|
console.log(e);
|
|
}
|
|
|
|
function volume(e) {
|
|
const v = document.querySelector('.ytp-volume-slider').getBoundingClientRect();
|
|
const amount = (e.clientX - v.x) / v.width;
|
|
setVolume(amount);
|
|
}
|
|
|
|
function setVolume(amount) {
|
|
if (audio.src) {
|
|
audio.volume = amount;
|
|
localStorage.setItem("volume", audio.volume);
|
|
} else {
|
|
video.volume = amount;
|
|
localStorage.setItem("volume", video.volume);
|
|
}
|
|
document.querySelector('.ytp-volume-slider-foreground').style.left = amount * 51 + 'px';
|
|
const icon = document.querySelector('.ytp-button-volume');
|
|
if (amount == 0) {
|
|
icon.dataset.value = 'off';
|
|
} else if (amount < 0.2) {
|
|
icon.dataset.value = 'min';
|
|
} else if (amount < 0.4) {
|
|
icon.dataset.value = 'quiet';
|
|
} else if (amount < 0.6) {
|
|
icon.dataset.value = 'normal';
|
|
} else if (amount < 0.8) {
|
|
icon.dataset.value = 'loud';
|
|
} else {
|
|
icon.dataset.value = 'max';
|
|
}
|
|
}
|
|
|
|
function toggleFullscreen() {
|
|
if (document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement) {
|
|
if (document.mozCancelFullScreen) {
|
|
document.mozCancelFullScreen();
|
|
} else if (document.cancelFullScreen) {
|
|
document.cancelFullScreen();
|
|
} else if (document.webkitCancelFullScreen) {
|
|
document.webkitCancelFullScreen();
|
|
}
|
|
} else {
|
|
movie = document.getElementById('movie_player');
|
|
|
|
if (movie.requestFullscreen) {
|
|
movie.requestFullscreen();
|
|
} else if (movie.mozRequestFullScreen) {
|
|
movie.mozRequestFullScreen();
|
|
} else if (movie.webkitRequestFullscreen) {
|
|
movie.webkitRequestFullscreen();
|
|
}
|
|
}
|
|
}
|
|
|
|
function toggleSettings() {
|
|
let menu = document.querySelector('.settings_menu');
|
|
if(menu.style.display == "block") {
|
|
menu.style.display = "none";
|
|
} else {
|
|
menu.style.display = "block";
|
|
}
|
|
}
|
|
|
|
function applyStreams() {
|
|
let autoplayInput = document.querySelector('#autoplayInput');
|
|
let videoStreamInput = document.querySelector('#videoStreamInput');
|
|
let audioStreamInput = document.querySelector('#audioStreamInput');
|
|
localStorage.setItem("videoStream", videoStreamInput.value);
|
|
localStorage.setItem("audioStream", audioStreamInput.value);
|
|
localStorage.setItem("autoplay", autoplayInput.checked);
|
|
|
|
const videoFormat = formats.find((fmt) => fmt.format_id == videoStreamInput.value);
|
|
const audioFormat = videoFormat.acodec === 'none' ? formats.find((fmt) => fmt.format_id == audioStreamInput.value) : null;
|
|
selectStreams(videoFormat, audioFormat)
|
|
}
|
|
|
|
function resetStreams() {
|
|
localStorage.removeItem("videoStream");
|
|
localStorage.removeItem("audioStream");
|
|
}
|
|
|
|
function seekRelative(v) {
|
|
video.pause();
|
|
video.currentTime=video.currentTime+v;
|
|
if(audio) {
|
|
audio.pause();
|
|
audio.currentTime=video.currentTime;
|
|
}
|
|
playbackWait();
|
|
}
|
|
|
|
function handleKeyboard(e) {
|
|
if (e.key == "ArrowLeft") {
|
|
seekRelative(-5);
|
|
e.preventDefault();
|
|
} else if (e.key == "ArrowRight") {
|
|
seekRelative(5);
|
|
e.preventDefault();
|
|
} else if (e.key == " " || e.key == "k") {
|
|
toggleVideo();
|
|
e.preventDefault();
|
|
} else if (e.key == "j") {
|
|
seekRelative(-10);
|
|
} else if (e.key == "l") {
|
|
seekRelative(10);
|
|
} else if (e.key == "f") {
|
|
toggleFullscreen();
|
|
}
|
|
}
|
|
|
|
function handleProtected(e) {
|
|
console.log(e)
|
|
if(e.originalTarget.error.code == 4 && ! e.originalTarget.currentSrc.startsWith("https://"+window.location.hostname)) {
|
|
e.target.src="https://"+window.location.hostname+"/proxy?url="+encodeURIComponent(encodeURIComponent(e.originalTarget.currentSrc))
|
|
}
|
|
}
|
|
function getMimeType(fmt) {
|
|
const mainType = fmt.vcodec !== 'none' ? 'video' : 'audio';
|
|
let secondary = {
|
|
m4a: 'mp4',
|
|
}[fmt.ext] || fmt.ext;
|
|
const codecs = [fmt.vcodec, fmt.acodec].filter(c => c && c !== 'none').join(', ');
|
|
return `${mainType}/${secondary}; codecs="${codecs}"`;
|
|
}
|
|
|
|
function isFormatSupported(fmt) {
|
|
if (!['http', 'https'].includes(fmt.protocol))
|
|
return false;
|
|
|
|
// must be very old: https://developer.mozilla.org/en-US/docs/Web/API/MediaSource/isTypeSupported#browser_compatibility
|
|
if (!('MediaSource' in window)) {
|
|
if (['avc1', 'none'].includes(fmt.vcodec.substring(0, 4))
|
|
&& ['mp4a', 'none'].includes(fmt.acodec.substring(0, 4))) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return MediaSource.isTypeSupported(getMimeType(fmt));
|
|
}
|
|
|
|
function selectStreams(videoFormat, audioFormat) {
|
|
video.src = videoFormat.url;
|
|
if (audioFormat) {
|
|
audio.src = audioFormat.url;
|
|
}
|
|
}
|
|
|
|
function playbackWait() {
|
|
waiting = setInterval(()=> {
|
|
if (document.querySelector("video").readyState == 4) {
|
|
toggleVideo(true);
|
|
clearInterval(waiting)
|
|
} else {
|
|
console.log("waiting...")
|
|
}
|
|
},100);
|
|
}
|
|
|
|
// document.querySelector('.ytp-button-play').addEventListener('click', () => toggleVideo());
|
|
document.querySelector('.ytp-settings-button').addEventListener('click', () => toggleSettings());
|
|
document.querySelector('#applyStreams').addEventListener('click', () => applyStreams());
|
|
document.querySelector('#resetStreams').addEventListener('click', () => resetStreams());
|
|
playButton.addEventListener('click', () => toggleVideo());
|
|
video.addEventListener('click', () => toggleVideo());
|
|
video.addEventListener('dblclick', () => toggleFullscreen());
|
|
let videoWaiting = false;
|
|
let audioWaiting = false;
|
|
video.addEventListener('waiting', () => {
|
|
toggleVideo(false);
|
|
videoWaiting = true;
|
|
});
|
|
video.addEventListener('playing', () => {
|
|
videoWaiting = false;
|
|
console.log(`videoWaiting ${videoWaiting}, audioWaiting ${audioWaiting}`);
|
|
if (!audioWaiting) {
|
|
toggleVideo(true);
|
|
}
|
|
});
|
|
audio.addEventListener('waiting', () => {
|
|
toggleVideo(false);
|
|
audioWaiting = true;
|
|
});
|
|
audio.addEventListener('playing', () => {
|
|
audioWaiting = false;
|
|
console.log(`videoWaiting ${videoWaiting}, audioWaiting ${audioWaiting}`);
|
|
if (!videoWaiting) {
|
|
toggleVideo(true);
|
|
}
|
|
});
|
|
video.addEventListener('timeupdate', () => updateTime());
|
|
video.addEventListener('ended', () => toggleVideo(false)); // just to change the classes
|
|
document.querySelector('.ytp-progress-list').addEventListener('click', (e) => scrub(e));
|
|
// document.querySelector('.ytp-play-progress').addEventListener('click', (e) => scrub(e));
|
|
document.querySelector('.ytp-volume-slider').addEventListener('click', (e) => volume(e));
|
|
document.querySelector('.ytp-button-fullscreen-enter').addEventListener('click', () => toggleFullscreen());
|
|
document.querySelector('video').addEventListener('error', (e) => handleProtected(e));
|
|
document.querySelector('audio').addEventListener('error', (e) => handleProtected(e));
|
|
document.querySelector('body').addEventListener('keydown', (e) => handleKeyboard(e));
|
|
|
|
if(localStorage.getItem("autoplay") == "true") {
|
|
toggleVideo(true);
|
|
document.querySelector('#autoplayInput').checked = true;
|
|
playbackWait();
|
|
}
|
|
});
|