0
0
Fork 0
mirror of https://github.com/VueTubeApp/VueTube synced 2024-11-25 12:45:17 +00:00

player settings: preload

This commit is contained in:
Nikita Krupin 2022-07-29 00:44:26 -04:00
parent 51b0be2acd
commit c598603450
6 changed files with 180 additions and 73 deletions

View file

@ -33,8 +33,12 @@
:height="isFullscreen ? '100%' : 'auto'"
style="transition: filter 0.15s ease-in-out, transform 0.15s linear"
:class="
controls || seeking || skipping
? verticalFullscreen
controls ||
seeking ||
skipping ||
($store.state.player.preload && buffered < 100)
? verticalFullscreen &&
!($store.state.player.preload && buffered < 100)
? 'dim-ish'
: 'dim'
: ''
@ -137,6 +141,7 @@
<!-- controls container -->
<div
v-if="$refs.player && $refs.player.currentSrc"
style="transition: opacity 0.15s ease-in-out"
:style="
controls && !seeking
@ -248,7 +253,7 @@
<v-spacer />
<!-- // TODO: merge the bottom 2 into 1 reusable component -->
<quality
v-if="$refs.player"
v-if="$refs.player && $refs.player.currentSrc"
:sources="sources"
:current-source="$refs.player"
@quality="qualityHandler($event)"
@ -309,6 +314,22 @@
($refs.player.currentTime = $event), ($refs.audio.currentTime = $event)
"
/>
<v-progress-circular
v-if="$store.state.player.preload && buffered < 100"
style="
transform: translate(-50%, -50%);
position: absolute;
left: 50%;
top: 50%;
"
:value="buffered"
color="primary"
:rotate="-90"
:size="64"
>
<b>{{ buffered }}%</b>
</v-progress-circular>
</div>
</template>
@ -381,7 +402,7 @@ export default {
let vid = this.$refs.player;
// TODO: this.$store.state.player.quality, check if exists and select the closest one
if (this.$store.state.player.prebuffer) this.prebuffer(this.sources[0].url);
if (this.$store.state.player.preload) this.prebuffer(this.sources[0].url);
else {
this.audSrc = this.sources[this.sources.length - 1].url;
this.vidSrc = this.sources[0].url;
@ -439,26 +460,29 @@ export default {
);
},
beforeDestroy() {
this.xhr.abort();
if (this.isFullscreen) this.exitFullscreen();
screen.orientation.removeEventListener("change");
},
methods: {
prebuffer(url) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
this.xhr = new XMLHttpRequest();
this.xhr.open("GET", url, true);
this.xhr.responseType = "blob";
xhr.addEventListener(
this.xhr.addEventListener(
"load",
() => {
if (xhr.status === 200) {
var blob = xhr.response;
if (this.xhr.status === 200) {
var blob = this.xhr.response;
console.error(this.xhr);
this.blobToDataURL(blob, (dataurl) => {
console.log(dataurl);
this.vidSrc = dataurl;
this.buffered = 100;
});
} else {
console.error("errorred pre-fetch", xhr.status);
console.error("errorred pre-fetch", this.xhr.status);
}
},
false
@ -466,17 +490,18 @@ export default {
var prev_pc = 0;
// TODO: big progress overlay (##%) to replace controls while loading if pre-buffering is enabled
xhr.addEventListener("progress", (event) => {
this.xhr.addEventListener("progress", (event) => {
if (event.lengthComputable) {
var pc = Math.round((event.loaded / event.total) * 100);
if (pc != prev_pc) {
prev_pc = pc; // ##%
console.log("buffering progress", pc);
if (pc < 100) this.buffered = pc;
console.warn(this.xhr);
}
}
});
xhr.send();
this.xhr.send();
},
blobToDataURL(blob, callback) {
var a = new FileReader();

View file

@ -6,63 +6,92 @@
<!-- // TODO: quality auto-adjustment settings -->
<!-- // TODO: Data saver -->
<!-- // TODO: Player UI -->
<!-- <v-divider v-if="!$store.state.tweaks.roundTweak" />
<v-divider v-if="!$store.state.tweaks.roundTweak" />
<h3 class="ml-8 mt-8">
<v-icon class="mb-1 mr-1">mdi-play-speed</v-icon>
Preload
Preload (UNSTABLE)
</h3>
<v-card
flat
class="mx-4 my-2 pa-4 d-flex flex-row justify-between background"
:class="
$store.state.tweaks.roundTweak > 0
? $vuetify.theme.dark
? 'lighten-1'
: 'darken-1'
: ''
"
class="mx-4 mt-2 mb-8 background"
:style="{
borderRadius: `${$store.state.tweaks.roundTweak / 2}rem`,
border: preload
? `2.1px solid var(--v-primary-base) !important`
: '2.1px solid var(--v-background-base)',
borderRadius: `${$store.state.tweaks.roundTweak / 1.9}rem`,
}"
@click="(preload = !preload), $vuetube.haptics.hapticsImpactLight(1)"
>
<div>
Pre-buffer video data before playback to avoid buffering pauses.
<b class="red--text">(can be data intensive it high quality presets)</b>
<br />
<br />
<hr class="primary mr-6" style="opacity: 0.25" />
<span class="overline">Buffering threshold: 15%</span>
</div>
<v-spacer />
<v-switch
v-model="preload"
style="pointer-events: none"
class="mt-0"
inset
/>
<br />
<v-card
flat
class="pa-4 d-flex flex-row background"
:class="
$store.state.tweaks.roundTweak > 0
? $vuetify.theme.dark
? 'lighten-1'
: 'darken-1'
: ''
"
:style="{
borderRadius: `${$store.state.tweaks.roundTweak / 2}rem`,
}"
@click="(preload = !preload), $vuetube.haptics.hapticsImpactLight(1)"
>
<div class="pr-4">
<div style="font-size: 0.75rem">
Pre-buffer video data before playback to avoid buffering pauses.
<b class="primary--text">
(can be data intensive at high quality presets)
</b>
</div>
<div
:class="preload ? 'primary' : 'background'"
class="my-3 mr-6 rounded-right"
style="width: 100%; height: 2px; margin-left: -1.1rem"
/>
<div>Buffering Threshold &middot; {{ preloadUpTo }}%</div>
<div
class="background--text"
:class="$vuetify.theme.dark ? 'text--lighten-4' : 'text--darken-4'"
style="font-size: 0.75rem"
>
The video will start playing after this much of the video is loaded.
<b class="red--text">(doesn't work yet)</b>
</div>
</div>
<v-switch
v-model="preload"
style="pointer-events: none"
class="mt-0"
inset
/>
</v-card>
<v-slider
v-model="speed"
step=".25"
thumb-size="64"
style="transition-duration: 0.3s; transition-property: all"
:rules="[(s) => s <= 4 || 'Might cause issues with buffering.']"
:min="0.25"
:max="16"
v-show="preload"
v-model="preloadUpTo"
:min="1"
:max="100"
thumb-label
persistent-hint
height="20"
:hint="preloadUpTo <= 10 || 'This can take a very long time.'"
class="pt-4 px-0 pb-1"
track-color="background"
thumb-color="primary background--text"
style="z-index: 69420; position: absolute; bottom: -1.83rem"
:style="{
borderRadius: `${$store.state.tweaks.roundTweak / 4}rem`,
width: `calc(100% - 2rem - ${$store.state.tweaks.roundTweak}rem)`,
left: `${$store.state.tweaks.roundTweak / 2 + 1}rem`,
}"
@input="$vuetube.haptics.hapticsImpactLight(0)"
>
<template #thumb-label="{ value }">
<b class="background--text" style="font-size: 1.15rem">
{{ value.toFixed(2) }}x
</b>
</template>
</v-slider>
</v-card> -->
</v-card>
<v-divider v-if="!$store.state.tweaks.roundTweak" />
<v-divider v-if="!$store.state.tweaks.roundTweak && !preload" />
<h3 class="ml-8 mt-8">
<v-icon class="mb-1 mr-1">mdi-speedometer</v-icon>
@ -79,7 +108,7 @@
>
<v-card
flat
class="mb-1 pa-4 d-flex flex-row justify-between background"
class="mb-1 pa-4 d-flex flex-row background"
:class="
$store.state.tweaks.roundTweak > 0
? $vuetify.theme.dark
@ -114,16 +143,9 @@
inset
/>
</v-card>
<v-card flat class="d-flex flex-row justify-between background">
<v-card flat class="d-flex flex-row background">
<speed
class="background mr-1 px-4 d-flex justify-center align-center"
style="
font-size: 1.5rem !important;
font-weight: bold !important;
color: black !important;
background: red;
text-shadow: 0 0 2rem green;
"
:current-speed="speed"
:class="
$store.state.tweaks.roundTweak > 0
@ -142,7 +164,6 @@
step=".25"
thumb-size="64"
class="pa-0 pt-5 pl-6 pb-2 ma-0 background"
style="transition-duration: 0.3s; transition-property: all"
:rules="[(s) => s <= 4 || 'Might cause issues with buffering.']"
:min="0.25"
:max="16"
@ -176,7 +197,18 @@ export default {
components: {
speed,
},
data: function () {
return this.initializeState();
},
computed: {
loop: {
get() {
return this.$store.state.player.loop;
},
set(value) {
this.$store.commit("player/setLoop", value);
},
},
speed: {
get() {
return this.$store.state.player.speed;
@ -201,6 +233,49 @@ export default {
this.$store.commit("player/setPreload", value);
},
},
preloadUpTo: {
get() {
return this.$store.state.player.preloadUpTo;
},
set(value) {
this.$store.commit("player/setPreloadUpTo", value);
},
},
},
methods: {
initializeState() {
return {
toggles: [
{
value: false,
name: "Captions",
icon: "mdi-closed-caption",
disabled: true,
},
{
value: false,
name: "Autoskip",
icon: "mdi-skip-next",
disabled: true,
},
{
action: () => {},
value: false,
name: "Mute",
icon: "mdi-volume-off",
disabled: true,
},
{
action: () => {
this.loop = !this.loop;
},
value: this.loop,
name: "Loop",
icon: "mdi-sync-circle",
},
],
};
},
},
};
</script>

View file

@ -126,7 +126,7 @@
<v-divider v-if="!$store.state.tweaks.roundTweak" />
<v-card
flat
class="d-flex flex-row justify-between mx-4 mb-4 pa-4 background"
class="d-flex flex-row mx-4 mb-4 pa-4 background"
:class="
$store.state.tweaks.roundTweak > 0
? $vuetify.theme.dark

View file

@ -6,7 +6,7 @@
<!-- // TODO: Top and Bottom bar color selection -->
<v-card
flat
class="mx-4 my-2 px-4 py-2 d-flex flex-row justify-between background"
class="mx-4 my-2 px-4 py-2 d-flex flex-row background"
style="transition-duration: 0.3s; transition-property: border-radius"
:class="
roundTweak > 0 ? ($vuetify.theme.dark ? 'lighten-1' : 'darken-1') : ''
@ -35,7 +35,7 @@
<v-card
flat
class="mx-4 my-2 px-4 py-2 d-flex flex-row justify-between background"
class="mx-4 my-2 px-4 py-2 d-flex flex-row background"
style="transition-duration: 0.3s; transition-property: border-radius"
:class="
roundTweak > 0 ? ($vuetify.theme.dark ? 'lighten-1' : 'darken-1') : ''
@ -79,7 +79,7 @@
<!-- margin: $store.state.tweaks.roundTweak > 0 ? '0 1rem' : '0', -->
<v-card
flat
class="mb-1 px-4 py-2 d-flex flex-row justify-between background"
class="mb-1 px-4 py-2 d-flex flex-row background"
:class="
roundTweak > 0 ? ($vuetify.theme.dark ? 'lighten-1' : 'darken-1') : ''
"
@ -107,7 +107,7 @@
</v-card>
<v-card
flat
class="mb-1 px-4 py-2 d-flex flex-row justify-between background"
class="mb-1 px-4 py-2 d-flex flex-row background"
:class="
roundTweak > 0 ? ($vuetify.theme.dark ? 'lighten-1' : 'darken-1') : ''
"
@ -151,7 +151,7 @@
<template #thumb-label="{ value }">
<div
class="pa-4 background"
:style="{ borderRadius: value * 3 + 'px !important' }"
:style="{ borderRadius: value * 3.5 + 'px !important' }"
></div>
</template>
</v-slider>

View file

@ -53,7 +53,7 @@
<v-icon v-else class="ml-4">mdi-chevron-down</v-icon>
</div>
<div
class="d-flex justify-space-around"
class="d-flex justify-space-between"
:class="
$store.state.tweaks.roundWatch && $store.state.tweaks.roundTweak > 0
? $vuetify.theme.dark

View file

@ -3,6 +3,7 @@ export const state = () => ({
speed: 1,
speedAutosave: null,
preload: null,
preloadUpTo: 100,
// quality: null,
// qualityAutoSwitch: null,
// shortFullscreen: null,
@ -20,6 +21,8 @@ export const mutations = {
(JSON.parse(localStorage.getItem("speedAutosave")) === false)
);
state.preload = JSON.parse(localStorage.getItem("preload")) === true; // defaults to false
state.preloadUpTo =
JSON.parse(localStorage.getItem("preloadUpTo")) || 100; // defaults to 100(percent)
}
},
setLoop(state, payload) {
@ -38,4 +41,8 @@ export const mutations = {
state.preload = payload;
localStorage.setItem("preload", payload);
},
setPreloadUpTo(state, payload) {
state.preloadUpTo = payload;
localStorage.setItem("preloadUpTo", payload);
},
};