DOM update performance improvements, bit of a CSS restructure, fixes

This commit is contained in:
ThaUnknown 2021-03-28 14:29:22 +02:00
parent 58b0ff1cfb
commit 72d46f14fe
4 changed files with 191 additions and 137 deletions

View file

@ -7408,7 +7408,8 @@ select.form-control[multiple] > option:disabled {
/* Switch */
.custom-switch {
display: block;
display: flex;
flex-direction: column;
position: relative;
line-height: var(--switch-line-height);
}
@ -7421,6 +7422,7 @@ select.form-control[multiple] > option:disabled {
}
.custom-switch label {
display: inline-block;
position: relative;
margin-bottom: 0;
padding-left: var(--switch-label-padding-left);
cursor: pointer;
@ -7432,7 +7434,7 @@ select.form-control[multiple] > option:disabled {
.custom-switch label.blank {
padding-left: var(--switch-label-blank-padding-left);
}
.custom-switch label:before {
.custom-switch label::before {
content: "";
display: inline-block;
position: absolute;
@ -7441,54 +7443,53 @@ select.form-control[multiple] > option:disabled {
top: 0;
left: 0;
background-color: var(--lm-switch-bg-color);
border: var(--switch-border-width) solid var(--lm-switch-border-color);
border: var(--switch-border-width) solid;
border-color: var(--lm-switch-border-color);
border-radius: var(--switch-border-radius);
box-shadow: var(--lm-switch-box-shadow);
}
.custom-switch input[type="checkbox"]:hover~label:before {
.custom-switch input[type="checkbox"]:hover+label::before {
background-color: var(--lm-switch-bg-color-hover);
border-color: var(--lm-switch-border-color-hover);
box-shadow: var(--lm-switch-box-shadow-hover);
}
.custom-switch input[type="checkbox"]:focus~label:before {
.custom-switch input[type="checkbox"]:focus+label::before {
border-color: var(--lm-switch-border-color-focus);
-moz-box-shadow: var(--lm-switch-box-shadow-focus);
-webkit-box-shadow: var(--lm-switch-box-shadow-focus);
box-shadow: var(--lm-switch-box-shadow-focus);
}
.custom-switch input[type="checkbox"]:checked~label:before {
.custom-switch input[type="checkbox"]:checked+label::before {
background-color: var(--lm-switch-bg-color-checked);
border-color: var(--lm-switch-border-color-checked);
box-shadow: var(--lm-switch-box-shadow-checked);
}
.custom-switch input[type="checkbox"]:checked:focus~label:before {
.custom-switch input[type="checkbox"]:checked:focus+label::before {
border-color: var(--lm-switch-border-color-checked-focus);
-moz-box-shadow: var(--lm-switch-box-shadow-checked-focus);
-webkit-box-shadow: var(--lm-switch-box-shadow-checked-focus);
box-shadow: var(--lm-switch-box-shadow-checked-focus);
}
.dark-mode .custom-switch label:before {
.dark-mode .custom-switch label::before {
background-color: var(--dm-switch-bg-color);
border-color: var(--dm-switch-border-color);
box-shadow: var(--dm-switch-box-shadow);
}
.dark-mode .custom-switch input[type="checkbox"]:hover~label:before {
.dark-mode .custom-switch input[type="checkbox"]:hover+label::before {
background-color: var(--dm-switch-bg-color-hover);
border-color: var(--dm-switch-border-color-hover);
box-shadow: var(--dm-switch-box-shadow-hover);
}
.dark-mode .custom-switch input[type="checkbox"]:focus~label:before {
.dark-mode .custom-switch input[type="checkbox"]:focus+label::before {
border-color: var(--dm-switch-border-color-focus);
-moz-box-shadow: var(--dm-switch-box-shadow-focus);
-webkit-box-shadow: var(--dm-switch-box-shadow-focus);
box-shadow: var(--dm-switch-box-shadow-focus);
}
.dark-mode .custom-switch input[type="checkbox"]:checked~label:before {
.dark-mode .custom-switch input[type="checkbox"]:checked+label::before {
background-color: var(--dm-switch-bg-color-checked);
border-color: var(--dm-switch-border-color-checked);
box-shadow: var(--dm-switch-box-shadow-checked);
}
.dark-mode .custom-switch input[type="checkbox"]:checked:focus~label:before {
.dark-mode .custom-switch input[type="checkbox"]:checked:focus+label::before {
border-color: var(--dm-switch-border-color-checked-focus);
-moz-box-shadow: var(--dm-switch-box-shadow-checked-focus);
-webkit-box-shadow: var(--dm-switch-box-shadow-checked-focus);
box-shadow: var(--dm-switch-box-shadow-checked-focus);
}
.custom-switch label:after{
.custom-switch label::after{
content: "";
position: absolute;
height: var(--switch-slider-width-height);
@ -7496,50 +7497,57 @@ select.form-control[multiple] > option:disabled {
top: var(--switch-slider-top);
left: var(--switch-slider-left);
background-color: var(--lm-switch-slider-bg-color);
border: var(--switch-slider-border-width) solid var(--lm-switch-slider-border-color);
border: var(--switch-slider-border-width) solid;
border-color: var(--lm-switch-slider-border-color);
border-radius: var(--switch-slider-border-radius);
-webkit-transition: left .1s;
box-shadow: var(--lm-switch-slider-box-shadow);
transition: left .1s;
}
.dark-mode .custom-switch label:after {
.dark-mode .custom-switch label::after {
background-color: var(--dm-switch-slider-bg-color);
border-color: var(--dm-switch-slider-border-color);
box-shadow: var(--dm-switch-slider-box-shadow);
}
.custom-switch input[type="checkbox"]:checked~label:after {
.custom-switch input[type="checkbox"]:checked+label::after {
top: var(--switch-slider-top-checked);
left: var(--switch-slider-left-checked);
background-color: var(--lm-switch-slider-bg-color-checked);
border-color: var(--lm-switch-slider-border-color-checked);
box-shadow: var(--lm-switch-slider-box-shadow-checked);
}
.dark-mode .custom-switch input[type="checkbox"]:checked~label:after {
.dark-mode .custom-switch input[type="checkbox"]:checked+label::after {
background-color: var(--dm-switch-slider-bg-color-checked);
border-color: var(--dm-switch-slider-border-color-checked);
box-shadow: var(--dm-switch-slider-box-shadow-checked);
}
.custom-switch input[type="checkbox"]:disabled~label {
.custom-switch input[type="checkbox"]:disabled+label {
opacity: 0.6;
cursor: not-allowed;
}
.custom-switch input[type="checkbox"]:disabled~label:before,
.custom-switch input[type="checkbox"]:hover:disabled~label:before {
.custom-switch input[type="checkbox"]:disabled+label::before,
.custom-switch input[type="checkbox"]:hover:disabled+label::before {
background-color: var(--lm-switch-bg-color);
border-color: var(--lm-switch-border-color);
box-shadow: var(--lm-switch-box-shadow);
}
.custom-switch input[type="checkbox"]:disabled:checked~label:before,
.custom-switch input[type="checkbox"]:hover:disabled:checked~label:before {
.custom-switch input[type="checkbox"]:disabled:checked+label::before,
.custom-switch input[type="checkbox"]:hover:disabled:checked+label::before {
background-color: var(--lm-switch-bg-color-checked);
border-color: var(--lm-switch-border-color-checked);
box-shadow: var(--lm-switch-box-shadow-checked);
}
.dark-mode .custom-switch input[type="checkbox"]:disabled~label:before,
.dark-mode .custom-switch input[type="checkbox"]:hover:disabled~label:before {
.dark-mode .custom-switch input[type="checkbox"]:disabled+label::before,
.dark-mode .custom-switch input[type="checkbox"]:hover:disabled+label::before {
background-color: var(--dm-switch-bg-color);
border-color: var(--dm-switch-border-color);
box-shadow: var(--dm-switch-box-shadow);
}
.dark-mode .custom-switch input[type="checkbox"]:disabled:checked~label:before,
.dark-mode .custom-switch input[type="checkbox"]:hover:disabled:checked~label:before {
.dark-mode .custom-switch input[type="checkbox"]:disabled:checked+label::before,
.dark-mode .custom-switch input[type="checkbox"]:hover:disabled:checked+label::before {
background-color: var(--dm-switch-bg-color-checked);
border-color: var(--dm-switch-border-color-checked);
box-shadow: var(--dm-switch-box-shadow-checked);
}
/* Input file */
.custom-file {

View file

@ -4,7 +4,6 @@
--volume-level: 100%;
--progress: 0%;
--buffer: 0%;
--height: 0;
--download: 0%;
color: #b6b6b6;
--ts: "";
@ -75,6 +74,20 @@
border-image-source: linear-gradient(90deg, #e5204c var(--download), rgba(0, 0, 0, .8) var(--download))
}
.stats span {
display: flex;
}
#peers::after, #downSpeed::after, #upSpeed::after{
content: attr(data-value);
font-size: 1.8rem !important;
white-space: nowrap;
align-self: center;
font-weight: 600;
font-family: Roboto, Arial, Helvetica, sans-serif;
padding-left: 1.2rem;
}
.player {
position: absolute;
user-select: none;
@ -90,10 +103,6 @@
cursor: pointer
}
.stats .ts {
padding: 0 1.2rem 0 0 !important
}
.player span {
font-size: 2.2rem !important;
color: #ececec;
@ -110,13 +119,6 @@
font-weight: 600
}
#progress,
.prog {
width: 100%;
height: 100%;
position: relative;
}
#video {
width: 100%;
height: 100%
@ -155,11 +157,6 @@
background: linear-gradient(90deg, #e5204c var(--volume-level), rgba(255, 255, 255, .2) var(--volume-level))
}
#progress::-webkit-slider-runnable-track {
height: 3px;
background: linear-gradient(90deg, #e5204c var(--progress), rgba(255, 255, 255, .4) var(--progress), rgba(255, 255, 255, .4) var(--buffer), rgba(255, 255, 255, .2) var(--buffer))
}
.controls input[type=range]:hover::-webkit-slider-thumb {
height: 12px;
width: 12px;
@ -176,6 +173,20 @@
transition: all .1s ease
}
#progress::-webkit-slider-runnable-track {
height: 3px;
background: linear-gradient(90deg, #e5204c var(--progress), rgba(255, 255, 255, .4) var(--progress), rgba(255, 255, 255, .4) var(--buffer), rgba(255, 255, 255, .2) var(--buffer))
}
#progress,
.prog,
.prog div{
display: flex;
width: 100%;
height: 100%;
position: relative;
}
#progress+img,
#progress::before {
pointer-events: none;
@ -193,17 +204,39 @@
#progress+img {
content: "";
height: var(--height);
height: 0;
top: -2rem;
width: 150px;
}
#progress::before {
top: .5rem;
content: attr(data-ts)
content: attr(data-elapsed);
}
#progress:active~img,
.prog::before,
.prog::after {
color: #ececec;
font-size: 1.8rem !important;
white-space: nowrap;
align-self: center;
cursor: default;
line-height: var(--base-line-height);
padding: 0 1.2rem;
font-weight: 600;
}
.prog::before {
content: attr(data-elapsed)
}
.prog::after {
content: attr(data-remaining)
}
#progress {
display: flex;
}
#progress:active+img,
#progress:active::before {
opacity: 1
}

View file

@ -175,28 +175,26 @@
<div id="nowPlayingDisplay" class="col-4 ts text-truncate">
</div>
<div class="d-flex col-4 justify-content-center">
<span class="material-icons">
<span class="ctrl material-icons" id="peers" data-value="0" data-name="peers">
people
</span>
<span class="ts" id="peers">0</span>
<span class="material-icons">
<span class="ctrl material-icons" id="downSpeed" data-value="0 B/s" data-name="downSpeed">
arrow_downward
</span>
<span class="ts" id="downSpeed">0 B/s</span>
<span class="material-icons">
<span class="ctrl material-icons" id="upSpeed" data-value="0 B/s" data-name="upSpeed">
arrow_upward
</span>
<span class="ts" id="upSpeed">0 B/s</span>
</div>
<div class="col-4 d-flex justify-content-end">
<span id="dl" class="material-icons pointer ctrl"
title="Wait For File To Fully Download Before Saving To Drive" disabled data-name="downloadFile">
title="Wait For File To Fully Download Before Saving To Drive" disabled
data-name="downloadFile">
get_app
</span>
</div>
</div>
<div id="ptoggle" class="h-full d-flex justify-content-center align-items-center">
<div id="buffering" class="hidden">
<div id="buffering" class="hidden ctrl" data-name="buffering">
</div>
</div>
<div class="controls d-flex">
@ -216,34 +214,39 @@
<input class="ctrl" type="range" value="100" id="volume" step="any" data-name="setVolume">
</div>
<div class="audio-tracks dropdown dropup with-arrow">
<span class="material-icons" title="Audio Tracks [T]" id="baudio" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>
<span class="material-icons ctrl" title="Audio Tracks [T]" id="baudio" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled data-name="audioButton">
queue_music
</span>
<div class="dropdown-menu dropdown-menu-left ctrl custom-radio p-10 pb-5 text-capitalize" aria-labelledby="baudio" data-name="selectAudio">
<div class="dropdown-menu dropdown-menu-left ctrl custom-radio p-10 pb-5 text-capitalize"
aria-labelledby="baudio" data-name="selectAudio">
</div>
</div>
<span class="ts" id="elapsed">00:00</span>
<div class="prog">
<input class="ctrl" type="range" min="0" max="100" value="0" id="progress" step="any" data-name="setProgress">
<img id="thumb">
<div class="prog ctrl" data-name="progressWrapper" data-elapsed="00:00" data-remaining="00:00">
<div>
<input class="ctrl" type="range" min="0" max="100" value="0" id="progress" step="any"
data-name="setProgress">
<img class="ctrl" data-elapsed="00:00" data-name="thumbnail">
</div>
</div>
<span class="ts" id="remaining">00:00</span>
<div class="subtitles dropdown dropup with-arrow">
<span class="material-icons" title="Subtitles [C]" id="bcap" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled>
<span class="material-icons ctrl" title="Subtitles [C]" id="bcap" data-toggle="dropdown"
aria-haspopup="true" aria-expanded="false" disabled data-name="captionsButton">
subtitles
</span>
<div class="dropdown-menu dropdown-menu-right ctrl custom-radio p-10 pb-5 text-capitalize" aria-labelledby="bcap" data-name="selectCaptions">
<div class="dropdown-menu dropdown-menu-right ctrl custom-radio p-10 pb-5 text-capitalize"
aria-labelledby="bcap" data-name="selectCaptions">
</div>
</div>
<span class="material-icons ctrl" title="Popout Window [P]" id="bpip" data-name="togglePopout">
picture_in_picture
</span>
<span class="material-icons ctrl" title="Theatre Mode [T]" id="btheatre" data-name="toggleTheatre">
<span class="material-icons ctrl" title="Theatre Mode [T]" id="btheatre"
data-name="toggleTheatre">
crop_16_9
</span>
<span class="material-icons ctrl" title="Fullscreen [F]" id="bfull" data-name="toggleFullscreen">
<span class="material-icons ctrl" title="Fullscreen [F]" id="bfull"
data-name="toggleFullscreen">
fullscreen
</span>
</div>
@ -631,21 +634,26 @@
</div>
</div>
<div class="input-group mb-10 w-200" data-toggle="tooltip" data-placement="top"
data-title="The Default Styles For Subtitles That Don't Have Styles Specified">
<div class="input-group-prepend">
<span class="input-group-text">Default Style</span>
data-title="The Default Styles For Subtitles That Don't Have Styles Specified">
<div class="input-group-prepend">
<span class="input-group-text">Default Style</span>
</div>
<input id="subtitle1" type="text" list="subtitle1list" class="form-control"
autocomplete="off" value="SubsPlease">
<datalist id="subtitle1list">
<option value="SubsPlease">Roboto
Medium,26,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,0,0,0,0,100,100,0,0,1,1.3,0,2,20,20,23,1
</option>
<option value="Erai-raws">Open Sans
Semibold,45,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,10,10,25,1
</option>
</datalist>
</div>
<div class="custom-switch mb-10" data-toggle="tooltip" data-placement="top"
data-title="Displays Subtitles In PiP And ChromeCast, CPU Intensive">
<input type="checkbox" id="subtitle3" checked>
<label for="subtitle3">Burn In Subtitles</label>
</div>
<input id="subtitle1" type="text" list="subtitle1list" class="form-control"
autocomplete="off" value="SubsPlease">
<datalist id="subtitle1list">
<option value="SubsPlease">Roboto Medium,26,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,0,0,0,0,100,100,0,0,1,1.3,0,2,20,20,23,1</option>
<option value="Erai-raws">Open Sans Semibold,45,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,10,10,25,1</option>
</datalist>
</div>
<div class="custom-switch mb-10" data-toggle="tooltip" data-placement="top" data-title="Displays Subtitles In PiP And ChromeCast, CPU Intensive">
<input type="checkbox" id="subtitle3" checked>
<label for="subtitle3">Burn In Subtitles</label>
</div>
<div class="custom-switch mb-10" data-toggle="tooltip" data-placement="top"
data-title="Generates Small Thumbnail Images When Using The Seek Bar After A Video Finished Downloading, VERY CPU Intensive">
<input type="checkbox" id="player5" checked>
@ -686,7 +694,8 @@
autocomplete="off" value="SubsPlease">
<datalist id="torrent4list">
<option value="SubsPlease">https://subsplease.org/rss/?r=</option>
<option value="Erai-raws">https://miru.kirdow.com/request/?url=https://www.erai-raws.info/rss-</option>
<option value="Erai-raws">
https://miru.kirdow.com/request/?url=https://www.erai-raws.info/rss-</option>
</datalist>
</div>
<div class="input-group w-200 mb-10" data-toggle="tooltip" data-placement="top"
@ -698,16 +707,16 @@
class="form-control text-right">
</div>
<div class="input-group w-200 mb-10" data-toggle="tooltip" data-placement="top"
data-title="Download/Upload Speed Limit For Torrents, Higher Values Increase CPU Usage">
<div class="input-group-prepend">
<span class="input-group-text">Speed Cap</span>
data-title="Download/Upload Speed Limit For Torrents, Higher Values Increase CPU Usage">
<div class="input-group-prepend">
<span class="input-group-text">Speed Cap</span>
</div>
<input id="torrent7" type="number" value="10" min="1" max="30"
class="form-control text-right">
<div class="input-group-append">
<span class="input-group-text">MB/s</span>
</div>
</div>
<input id="torrent7" type="number" value="10" min="1" max="30"
class="form-control text-right">
<div class="input-group-append">
<span class="input-group-text">MB/s</span>
</div>
</div>
<div class="custom-switch mb-10" data-toggle="tooltip" data-placement="top" data-title="Skips The Torrent Selection Popup, Might Lead To Unwanted Videos Being
Played">
<input type="checkbox" id="torrent2">
@ -728,7 +737,8 @@
<input type="checkbox" id="torrent5">
<label for="torrent5">Drive Caching</label>
</div>
<div class="custom-switch mb-20" data-toggle="tooltip" data-placement="top" data-title="Only Downloads Pieces Directly Required For Playback Instead Of The Entire File. Recommended Only For Low-End Devices">
<div class="custom-switch mb-20" data-toggle="tooltip" data-placement="top"
data-title="Only Downloads Pieces Directly Required For Playback Instead Of The Entire File. Recommended Only For Low-End Devices">
<input type="checkbox" id="torrent8">
<label for="torrent8">Streamed Download</label>
</div>

View file

@ -94,12 +94,12 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
this.video.addEventListener('loadedmetadata', () => {
if (this.video.audioTracks?.length > 1) {
baudio.removeAttribute('disabled') // TODO: fix
this.controls.audioButton.removeAttribute('disabled')
for (const track of this.video.audioTracks) {
this.createRadioElement(track, 'audio')
}
} else {
baudio.setAttribute('disabled', '') // TODO: fix
this.controls.audioButton.setAttribute('disabled', '')
}
})
@ -320,7 +320,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
this.video.src = `/app/webtorrent/${torrent.infoHash}/${encodeURI(this.currentFile.path)}`
this.video.load()
if (this.videoFiles.length > 1) bpl.removeAttribute('disabled') // TODO: fix
if (this.videoFiles.length > 1) this.controls.playNext.removeAttribute('disabled')
if (this.currentFile.done) {
this.postDownload()
@ -354,7 +354,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
type: 'image/jpg'
}]
})
if (parseInt(this.nowPlaying[1]) >= this.nowPlaying[0].episodes) bnext.setAttribute('disabled', '') // TODO: fix
if (parseInt(this.nowPlaying[1]) >= this.nowPlaying[0].episodes) this.controls.playNext.setAttribute('disabled', '')
let streamingEpisode
if (this.nowPlaying[0].streamingEpisodes.length >= Number(this.nowPlaying[1])) {
streamingEpisode = this.nowPlaying[0].streamingEpisodes.filter(episode => episodeRx.exec(episode.title) && Number(episodeRx.exec(episode.title)[1]) === Number(this.nowPlaying[1]))[0]
@ -369,10 +369,10 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
sizes: '256x256',
type: 'image/jpg'
}]
nowPlayingDisplay.innerHTML = `EP ${Number(this.nowPlaying[1])} - ${episodeRx.exec(streamingEpisode.title)[2]}`
nowPlayingDisplay.textContent = `EP ${Number(this.nowPlaying[1])} - ${episodeRx.exec(streamingEpisode.title)[2]}`
} else {
document.title = `${this.nowPlaying[0].title.userPreferred} - EP ${Number(this.nowPlaying[1])} - Miru`
nowPlayingDisplay.innerHTML = `EP ${Number(this.nowPlaying[1])}`
nowPlayingDisplay.textContent = `EP ${Number(this.nowPlaying[1])}`
}
}
if ('mediaSession' in navigator && mediaMetadata) navigator.mediaSession.metadata = mediaMetadata
@ -382,6 +382,8 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
if (this.subtitleData.renderer) this.subtitleData.renderer.dispose()
if (this.subtitleData.fonts) this.subtitleData.fonts.forEach(file => URL.revokeObjectURL(file)) // ideally this should clean up after its been downloaded by the sw renderer, but oh well
this.controls.downloadFile.setAttribute('disabled', '')
this.currentFile = undefined
this.currentTorrent = undefined
this.video.poster = ''
// some attemt at cache clearing
this.video.pause()
@ -416,8 +418,10 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
interval: undefined,
video: undefined
}
nowPlayingDisplay.innerHTML = '' // TODO: fix
bcap.setAttribute('disabled', '') // TODO: fix
nowPlayingDisplay.textContent = '' // TODO: fix
this.controls.captionsButton.setAttribute('disabled', '')
this.controls.selectCaptions.textContent = ''
this.controls.selectAudio.textContent = ''
this.controls.openPlaylist.setAttribute('disabled', '')
this.controls.playNext.removeAttribute('disabled')
navNowPlaying.classList.add('d-none') // TODO: fix
@ -428,9 +432,9 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
async playVideo () {
try {
await this.video.play()
this.controls.playPause.innerHTML = 'pause'
this.controls.playPause.textContent = 'pause'
} catch (err) {
this.controls.playPause.innerHTML = 'play_arrow'
this.controls.playPause.textContent = 'play_arrow'
}
}
@ -438,7 +442,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
if (this.video.paused) {
this.playVideo()
} else {
this.controls.playPause.innerHTML = 'play_arrow'
this.controls.playPause.textContent = 'play_arrow'
this.video.pause()
}
}
@ -447,7 +451,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
const level = volume === undefined ? Number(this.controls.setVolume.value) : volume
this.controls.setVolume.value = level
this.controls.setVolume.style.setProperty('--volume-level', level + '%')
this.controls.toggleMute.innerHTML = level === 0 ? 'volume_off' : 'volume_up'
this.controls.toggleMute.textContent = level === 0 ? 'volume_off' : 'volume_up'
this.video.volume = level / 100
}
@ -469,7 +473,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
}
updateFullscreen () {
document.fullscreenElement ? this.controls.toggleFullscreen.innerHTML = 'fullscreen_exit' : this.controls.toggleFullscreen.innerHTML = 'fullscreen'
document.fullscreenElement ? this.controls.toggleFullscreen.textContent = 'fullscreen_exit' : this.controls.toggleFullscreen.textContent = 'fullscreen'
}
openPlaylist () {
@ -482,8 +486,8 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
if (this.videoFiles?.length > 1 && this.videoFiles.indexOf(this.currentFile) < this.videoFiles.length) {
const fileIndex = this.videoFiles.indexOf(this.currentFile) + 1
const nowPlaying = [this.nowPlaying[0], parseInt(this.nowPlaying[1]) + 1] // TODO: fix
cleanupVideo()
buildVideo(this.videoFiles[fileIndex], nowPlaying) // TODO: fix
this.cleanupVideo()
this.buildVideo(this.videoFiles[fileIndex], nowPlaying) // TODO: fix
} else {
if (this.onNext) this.onNext()
}
@ -509,7 +513,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
const renderFrame = () => {
if (running === true) {
context.drawImage(this.video, 0, 0)
context.drawImage(subtitleCanvas, 0, 0, canvas.width, canvas.height) // TODO: reference SO canvas
context.drawImage(subtitleCanvas, 0, 0, canvas.width, canvas.height)
window.requestAnimationFrame(renderFrame)
}
}
@ -588,13 +592,13 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
if (this.bufferTimeout) {
clearTimeout(this.bufferTimeout)
this.bufferTimeout = undefined
buffering.classList.add('hidden') // non-tplayer specific // TODO: fix this
this.controls.buffering.classList.add('hidden')
}
}
showBuffering () {
this.bufferTimeout = setTimeout(() => {
buffering.classList.remove('hidden') // non-tplayer specific // TODO: fix this
this.controls.buffering.classList.remove('hidden')
this.resetImmerse()
}, 150)
}
@ -621,7 +625,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
const height = this.thumbnailData.canvas.width / (this.video.videoWidth / this.video.videoHeight)
this.thumbnailData.interval = this.video.duration / 300 < 5 ? 5 : this.video.duration / 300
this.thumbnailData.canvas.height = height
thumb.style.setProperty('--height', height + 'px') // TODO: fix
this.controls.thumbnail.style.setProperty('height', height + 'px')
}
createThumbnail (video) {
@ -681,21 +685,20 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
setProgress (progressPercent) {
progressPercent = progressPercent || 0
const currentTime = this.video.duration * progressPercent / 100 || 0
this.controls.setProgress.style.setProperty('--progress', progressPercent + '%')
thumb.src = this.thumbnailData.thumbnails[Math.floor(currentTime / this.thumbnailData.interval)] || ' ' // TODO: fix
thumb.style.setProperty('--progress', progressPercent + '%') // TODO: fix
elapsed.innerHTML = this.toTS(currentTime) // TODO: fix
remaining.innerHTML = this.toTS(this.video.duration - currentTime) // TODO: fix
this.controls.progressWrapper.style.setProperty('--progress', progressPercent + '%')
this.controls.thumbnail.src = this.thumbnailData.thumbnails[Math.floor(currentTime / this.thumbnailData.interval)] || ' '
this.controls.setProgress.dataset.elapsed = this.toTS(currentTime)
this.controls.progressWrapper.dataset.elapsed = this.toTS(currentTime)
this.controls.progressWrapper.dataset.remaining = this.toTS(this.video.duration - currentTime)
this.controls.setProgress.value = progressPercent
this.controls.setProgress.setAttribute('data-ts', this.toTS(currentTime))
}
updateDisplay () {
if (this.currentTorrent && this.currentFile) {
this.player.style.setProperty('--download', this.currentFile.progress * 100 + '%')
peers.innerHTML = this.currentTorrent.numPeers
downSpeed.innerHTML = this.prettyBytes(this.currentTorrent.downloadSpeed) + '/s'
upSpeed.innerHTML = this.prettyBytes(this.currentTorrent.uploadSpeed) + '/s'
this.controls.peers.dataset.value = this.currentTorrent.numPeers
this.controls.downSpeed.dataset.value = this.prettyBytes(this.currentTorrent.downloadSpeed) + '/s'
this.controls.upSpeed.dataset.value = this.prettyBytes(this.currentTorrent.uploadSpeed) + '/s'
}
window.requestAnimationFrame(() => setTimeout(() => this.updateDisplay(), 200))
}
@ -715,7 +718,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
? type === 'captions'
? (track.language || (!Object.values(this.subtitleData.headers).some(header => header.language === 'eng' || header.language === 'en') ? 'eng' : header.type)) + (track.name ? ' - ' + track.name : '')
: (track.language || (!Object.values(this.video.audioTracks).some(track => track.language === 'eng' || track.language === 'en') ? 'eng' : track.label)) + (track.label ? ' - ' + track.label : '')
: 'OFF'
: 'OFF' // TODO: clean this up, TLDR assume english track if track lang is undefined || 'und' and there isnt an existing eng track already
frag.appendChild(input)
frag.appendChild(label)
if (type === 'captions') {
@ -749,7 +752,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
}
constructSub (subtitle, isNotAss) {
if (isNotAss) { // converts VTT or other to SSA
if (isNotAss === true) { // converts VTT or other to SSA
const matches = subtitle.text.match(/<[^>]+>/g) // create array of all tags
if (matches) {
matches.forEach(match => {
@ -773,7 +776,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
(subtitle.marginR || '0') + ',' +
(subtitle.marginV || '0') + ',' +
(subtitle.effect || '') + ',' +
subtitle.text
subtitle.text || ''
}
async parseSubtitles (file) { // parse subtitles fully after a download is finished
@ -787,7 +790,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
this.subtitleData.stream = undefined
this.selectCaptions(this.subtitleData.current)
parser = undefined
bcap.removeAttribute('disabled') // TODO: fix
this.controls.captionsButton.removeAttribute('disabled')
if (!this.video.paused) {
this.video.pause()
this.playVideo()
@ -805,7 +808,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
handleSubtitleParser (parser, skipFile) {
parser.once('tracks', tracks => {
bcap.removeAttribute('disabled') // TODO: fix
this.controls.captionsButton.removeAttribute('disabled')
tracks.forEach(track => {
if (!this.subtitleData.tracks[track.number]) {
// overwrite webvtt or other header with custom one
@ -958,7 +961,7 @@ Style: Default,${options.defaultSSAStyles || 'Roboto Medium,26,&H00FFFFFF,&H0000
cleanupTorrents () {
// creates an array of all non-offline store torrents and removes them
this.torrents.filter(torrent => !this.offlineTorrents[torrent.infoHash]).forEach(torrent => torrent.destroy({ destroyStore: true }))
document.querySelector('.playlist').innerHTML = ''
document.querySelector('.playlist').textContent = ''
}
// add torrent for offline download
@ -1015,7 +1018,7 @@ const client = new TorrentPlayer({
autoNext: settings.player6,
streamedDownload: settings.torrent6,
generateThumbnails: settings.player5,
defaultSSAStyles: Object.values(subtitle1list.options).filter(item => item.value === settings.subtitle1)[0].innerText,
defaultSSAStyles: Object.values(subtitle1list.options).filter(item => item.value === settings.subtitle1)[0].textContent,
onDownloadDone: (name) => {
halfmoon.initStickyAlert({
content: `<span class="text-break">${name}</span> has finished downloading. Now seeding.`,