mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-08-14 23:57:27 +00:00
Merge pull request #116 from TeamPiped/fix/prettier-config
Add Prettier config and format code
This commit is contained in:
commit
4700b198e4
16 changed files with 336 additions and 525 deletions
2
.prettierignore
Normal file
2
.prettierignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dist
|
||||||
|
node_modules
|
11
.prettierrc.json
Normal file
11
.prettierrc.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"singleQuote": false,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"semi": true,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"embeddedLanguageFormatting": "auto",
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"printWidth": 120,
|
||||||
|
"vueIndentScriptAndStyle": false,
|
||||||
|
"quoteProps": "as-needed"
|
||||||
|
}
|
|
@ -8,15 +8,11 @@
|
||||||
|
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
<a href="https://github.com/TeamPiped/Piped">
|
<a href="https://github.com/TeamPiped/Piped">
|
||||||
<font-awesome-icon
|
<font-awesome-icon :icon="['fab', 'github']"></font-awesome-icon>
|
||||||
:icon="['fab', 'github']"
|
|
||||||
></font-awesome-icon>
|
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="bitcoin://13MoHioctZkC7LDSZSb4m32TDT8xNmei1p">
|
<a href="bitcoin://13MoHioctZkC7LDSZSb4m32TDT8xNmei1p">
|
||||||
<font-awesome-icon
|
<font-awesome-icon :icon="['fab', 'bitcoin']"></font-awesome-icon>
|
||||||
:icon="['fab', 'bitcoin']"
|
|
||||||
></font-awesome-icon>
|
|
||||||
13MoHioctZkC7LDSZSb4m32TDT8xNmei1p
|
13MoHioctZkC7LDSZSb4m32TDT8xNmei1p
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default {
|
export default {
|
||||||
BASE_URL: localStorage.getItem("instance") || 'https://pipedapi.kavin.rocks',
|
BASE_URL: localStorage.getItem("instance") || "https://pipedapi.kavin.rocks",
|
||||||
AUTO_PLAY: localStorage.getItem("autoplay") || false
|
AUTO_PLAY: localStorage.getItem("autoplay") || false,
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="channel">
|
<div v-if="channel">
|
||||||
<h1 class="uk-text-center">
|
<h1 class="uk-text-center"><img v-bind:src="channel.avatarUrl" />{{ channel.name }}</h1>
|
||||||
<img v-bind:src="channel.avatarUrl" />{{ channel.name }}
|
<img v-if="channel.bannerUrl" v-bind:src="channel.bannerUrl" style="width: 100%" loading="lazy" />
|
||||||
</h1>
|
|
||||||
<img
|
|
||||||
v-if="channel.bannerUrl"
|
|
||||||
v-bind:src="channel.bannerUrl"
|
|
||||||
style="width: 100%"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<p v-html="this.channel.description.replaceAll('\n', '<br>')"></p>
|
<p v-html="this.channel.description.replaceAll('\n', '<br>')"></p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -19,15 +12,8 @@
|
||||||
v-bind:key="item.url"
|
v-bind:key="item.url"
|
||||||
v-for="item in this.channel.relatedStreams"
|
v-for="item in this.channel.relatedStreams"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link class="uk-link-muted uk-text-justify" v-bind:to="item.url || '/'">
|
||||||
class="uk-link-muted uk-text-justify"
|
<img style="width: 100%" v-bind:src="item.thumbnail" loading="lazy" />
|
||||||
v-bind:to="item.url || '/'"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style="width: 100%"
|
|
||||||
v-bind:src="item.thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<a>{{ item.title }}</a>
|
<a>{{ item.title }}</a>
|
||||||
</router-link>
|
</router-link>
|
||||||
<br />
|
<br />
|
||||||
|
@ -53,7 +39,7 @@ import Constants from "@/Constants.js";
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
channel: null
|
channel: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -65,9 +51,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchChannel() {
|
async fetchChannel() {
|
||||||
return await this.fetchJson(
|
return await this.fetchJson(Constants.BASE_URL + "/channels/" + this.$route.params.channelId);
|
||||||
Constants.BASE_URL + "/channels/" + this.$route.params.channelId
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
async getChannelData() {
|
async getChannelData() {
|
||||||
this.fetchChannel()
|
this.fetchChannel()
|
||||||
|
@ -75,17 +59,8 @@ export default {
|
||||||
.then(() => (document.title = this.channel.name + " - Piped"));
|
.then(() => (document.title = this.channel.name + " - Piped"));
|
||||||
},
|
},
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
if (
|
if (this.loading || !this.channel || !this.channel.nextpage || !this.channel.nextid) return;
|
||||||
this.loading ||
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - window.innerHeight) {
|
||||||
!this.channel ||
|
|
||||||
!this.channel.nextpage ||
|
|
||||||
!this.channel.nextid
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
if (
|
|
||||||
window.innerHeight + window.scrollY >=
|
|
||||||
document.body.offsetHeight - window.innerHeight
|
|
||||||
) {
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.fetchJson(
|
this.fetchJson(
|
||||||
Constants.BASE_URL +
|
Constants.BASE_URL +
|
||||||
|
@ -94,18 +69,16 @@ export default {
|
||||||
"?url=" +
|
"?url=" +
|
||||||
encodeURIComponent(this.channel.nextpage) +
|
encodeURIComponent(this.channel.nextpage) +
|
||||||
"&id=" +
|
"&id=" +
|
||||||
encodeURIComponent(this.channel.nextid)
|
encodeURIComponent(this.channel.nextid),
|
||||||
).then(json => {
|
).then(json => {
|
||||||
this.channel.relatedStreams.concat(json.relatedStreams);
|
this.channel.relatedStreams.concat(json.relatedStreams);
|
||||||
this.channel.nextpage = json.nextpage;
|
this.channel.nextpage = json.nextpage;
|
||||||
this.channel.nextid = json.nextid;
|
this.channel.nextid = json.nextid;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
json.relatedStreams.map(stream =>
|
json.relatedStreams.map(stream => this.channel.relatedStreams.push(stream));
|
||||||
this.channel.relatedStreams.push(stream)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="uk-container-expand">
|
<div class="uk-container-expand">
|
||||||
<div data-shaka-player-container>
|
<div data-shaka-player-container>
|
||||||
<video
|
<video data-shaka-player autoplay style="width: 100%; height: 100%"></video>
|
||||||
data-shaka-player
|
|
||||||
autoplay
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
></video>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -18,7 +14,7 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
video: Object,
|
video: Object,
|
||||||
sponsors: Object,
|
sponsors: Object,
|
||||||
selectedAutoPlay: Boolean
|
selectedAutoPlay: Boolean,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loadVideo() {
|
loadVideo() {
|
||||||
|
@ -37,7 +33,7 @@ export default {
|
||||||
|
|
||||||
const dash = require("@/utils/DashUtils.js").default.generate_dash_file_from_formats(
|
const dash = require("@/utils/DashUtils.js").default.generate_dash_file_from_formats(
|
||||||
streams,
|
streams,
|
||||||
this.video.duration
|
this.video.duration,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (noPrevPlayer)
|
if (noPrevPlayer)
|
||||||
|
@ -74,15 +70,11 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
videoEl.addEventListener("volumechange", () => {
|
videoEl.addEventListener("volumechange", () => {
|
||||||
if (localStorage)
|
if (localStorage) localStorage.setItem("volume", videoEl.volume);
|
||||||
localStorage.setItem("volume", videoEl.volume);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
videoEl.addEventListener("ended", () => {
|
videoEl.addEventListener("ended", () => {
|
||||||
if (
|
if (this.selectedAutoPlay && this.video.relatedStreams.length > 0)
|
||||||
this.selectedAutoPlay &&
|
|
||||||
this.video.relatedStreams.length > 0
|
|
||||||
)
|
|
||||||
this.$router.push(this.video.relatedStreams[0].url);
|
this.$router.push(this.video.relatedStreams[0].url);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -90,52 +82,33 @@ export default {
|
||||||
//TODO: Add sponsors on seekbar: https://github.com/ajayyy/SponsorBlock/blob/e39de9fd852adb9196e0358ed827ad38d9933e29/src/js-components/previewBar.ts#L12
|
//TODO: Add sponsors on seekbar: https://github.com/ajayyy/SponsorBlock/blob/e39de9fd852adb9196e0358ed827ad38d9933e29/src/js-components/previewBar.ts#L12
|
||||||
},
|
},
|
||||||
setPlayerAttrs(player, videoEl, dash, shaka) {
|
setPlayerAttrs(player, videoEl, dash, shaka) {
|
||||||
player
|
player.load("data:application/dash+xml;charset=utf-8;base64," + btoa(dash)).then(() => {
|
||||||
.load(
|
|
||||||
"data:application/dash+xml;charset=utf-8;base64," +
|
|
||||||
btoa(dash)
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
this.video.subtitles.map(subtitle => {
|
this.video.subtitles.map(subtitle => {
|
||||||
player.addTextTrack(
|
player.addTextTrack(subtitle.url, "eng", "SUBTITLE", subtitle.mimeType, null, "English");
|
||||||
subtitle.url,
|
|
||||||
"eng",
|
|
||||||
"SUBTITLE",
|
|
||||||
subtitle.mimeType,
|
|
||||||
null,
|
|
||||||
"English"
|
|
||||||
);
|
|
||||||
player.setTextTrackVisibility(true);
|
player.setTextTrackVisibility(true);
|
||||||
});
|
});
|
||||||
if (localStorage)
|
if (localStorage) videoEl.volume = localStorage.getItem("volume") || 1;
|
||||||
videoEl.volume = localStorage.getItem("volume") || 1;
|
|
||||||
|
|
||||||
const ui =
|
const ui =
|
||||||
this.ui ||
|
this.ui ||
|
||||||
(this.ui = new shaka.ui.Overlay(
|
(this.ui = new shaka.ui.Overlay(
|
||||||
player,
|
player,
|
||||||
document.querySelector(
|
document.querySelector("div[data-shaka-player-container]"),
|
||||||
"div[data-shaka-player-container]"
|
videoEl,
|
||||||
),
|
|
||||||
videoEl
|
|
||||||
));
|
));
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
overflowMenuButtons: [
|
overflowMenuButtons: ["quality", "captions", "playback_rate"],
|
||||||
"quality",
|
|
||||||
"captions",
|
|
||||||
"playback_rate"
|
|
||||||
],
|
|
||||||
seekBarColors: {
|
seekBarColors: {
|
||||||
base: "rgba(255, 255, 255, 0.3)",
|
base: "rgba(255, 255, 255, 0.3)",
|
||||||
buffered: "rgba(255, 255, 255, 0.54)",
|
buffered: "rgba(255, 255, 255, 0.54)",
|
||||||
played: "rgb(255, 0, 0)"
|
played: "rgb(255, 0, 0)",
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
ui.configure(config);
|
ui.configure(config);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
if (this.player) {
|
if (this.player) {
|
||||||
|
@ -143,6 +116,6 @@ export default {
|
||||||
this.player = undefined;
|
this.player = undefined;
|
||||||
this.ui = undefined;
|
this.ui = undefined;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,10 +6,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<b
|
<b
|
||||||
><router-link
|
><router-link class="uk-text-justify" v-bind:to="playlist.uploaderUrl || '/'">
|
||||||
class="uk-text-justify"
|
|
||||||
v-bind:to="playlist.uploaderUrl || '/'"
|
|
||||||
>
|
|
||||||
<img v-bind:src="playlist.uploaderAvatar" loading="lazy" />
|
<img v-bind:src="playlist.uploaderAvatar" loading="lazy" />
|
||||||
{{ playlist.uploader }}</router-link
|
{{ playlist.uploader }}</router-link
|
||||||
></b
|
></b
|
||||||
|
@ -25,25 +22,16 @@
|
||||||
v-bind:key="item.url"
|
v-bind:key="item.url"
|
||||||
v-for="item in this.playlist.relatedStreams"
|
v-for="item in this.playlist.relatedStreams"
|
||||||
>
|
>
|
||||||
<router-link
|
<router-link class="uk-link-muted uk-text-justify" v-bind:to="item.url || '/'">
|
||||||
class="uk-link-muted uk-text-justify"
|
<img style="width: 100%" v-bind:src="item.thumbnail" loading="lazy" />
|
||||||
v-bind:to="item.url || '/'"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style="width: 100%"
|
|
||||||
v-bind:src="item.thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<a>{{ item.title }}</a>
|
<a>{{ item.title }}</a>
|
||||||
</router-link>
|
</router-link>
|
||||||
<br />
|
<br />
|
||||||
<div>
|
<div>
|
||||||
<b class="uk-text-small uk-align-left">
|
<b class="uk-text-small uk-align-left">
|
||||||
<router-link
|
<router-link class="uk-text-justify" v-bind:to="item.uploaderUrl || '/'">{{
|
||||||
class="uk-text-justify"
|
item.uploaderName
|
||||||
v-bind:to="item.uploaderUrl || '/'"
|
}}</router-link>
|
||||||
>{{ item.uploaderName }}</router-link
|
|
||||||
>
|
|
||||||
</b>
|
</b>
|
||||||
<b class="uk-text-small uk-align-right">
|
<b class="uk-text-small uk-align-right">
|
||||||
{{ timeFormat(item.duration) }}
|
{{ timeFormat(item.duration) }}
|
||||||
|
@ -60,7 +48,7 @@ import Constants from "@/Constants.js";
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
playlist: null
|
playlist: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -72,9 +60,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchPlaylist() {
|
async fetchPlaylist() {
|
||||||
return await await this.fetchJson(
|
return await await this.fetchJson(Constants.BASE_URL + "/playlists/" + this.$route.query.list);
|
||||||
Constants.BASE_URL + "/playlists/" + this.$route.query.list
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
async getPlaylistData() {
|
async getPlaylistData() {
|
||||||
this.fetchPlaylist()
|
this.fetchPlaylist()
|
||||||
|
@ -82,17 +68,8 @@ export default {
|
||||||
.then(() => (document.title = this.playlist.name + " - Piped"));
|
.then(() => (document.title = this.playlist.name + " - Piped"));
|
||||||
},
|
},
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
if (
|
if (this.loading || !this.playlist || !this.playlist.nextpage || !this.playlist.nextid) return;
|
||||||
this.loading ||
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - window.innerHeight) {
|
||||||
!this.playlist ||
|
|
||||||
!this.playlist.nextpage ||
|
|
||||||
!this.playlist.nextid
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
if (
|
|
||||||
window.innerHeight + window.scrollY >=
|
|
||||||
document.body.offsetHeight - window.innerHeight
|
|
||||||
) {
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.fetchJson(
|
this.fetchJson(
|
||||||
Constants.BASE_URL +
|
Constants.BASE_URL +
|
||||||
|
@ -101,18 +78,16 @@ export default {
|
||||||
"?url=" +
|
"?url=" +
|
||||||
encodeURIComponent(this.playlist.nextpage) +
|
encodeURIComponent(this.playlist.nextpage) +
|
||||||
"&id=" +
|
"&id=" +
|
||||||
encodeURIComponent(this.playlist.nextid)
|
encodeURIComponent(this.playlist.nextid),
|
||||||
).then(json => {
|
).then(json => {
|
||||||
this.playlist.relatedStreams.concat(json.relatedStreams);
|
this.playlist.relatedStreams.concat(json.relatedStreams);
|
||||||
this.playlist.nextpage = json.nextpage;
|
this.playlist.nextpage = json.nextpage;
|
||||||
this.playlist.nextid = json.nextid;
|
this.playlist.nextid = json.nextid;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
json.relatedStreams.map(stream =>
|
json.relatedStreams.map(stream => this.playlist.relatedStreams.push(stream));
|
||||||
this.playlist.relatedStreams.push(stream)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,71 +2,34 @@
|
||||||
<h1 class="uk-text-bold uk-text-center">Preferences</h1>
|
<h1 class="uk-text-bold uk-text-center">Preferences</h1>
|
||||||
<hr />
|
<hr />
|
||||||
<h2>SponsorBlock</h2>
|
<h2>SponsorBlock</h2>
|
||||||
<p>
|
<p>Uses the API from <a href="https://sponsor.ajay.app/">sponsor.ajay.app</a></p>
|
||||||
Uses the API from <a href="https://sponsor.ajay.app/">sponsor.ajay.app</a>
|
|
||||||
</p>
|
|
||||||
<b>Enable Sponsorblock</b>
|
<b>Enable Sponsorblock</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="sponsorBlock" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="sponsorBlock"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<b>Skip Sponsors</b>
|
<b>Skip Sponsors</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="skipSponsor" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipSponsor"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<b>Skip Intermission/Intro Animation</b>
|
<b>Skip Intermission/Intro Animation</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="skipIntro" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipIntro"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<b>Skip Endcards/Credits</b>
|
<b>Skip Endcards/Credits</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="skipOutro" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipOutro"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<b>Skip Interaction Reminder (Subscribe)</b>
|
<b>Skip Interaction Reminder (Subscribe)</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="skipInteraction" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipInteraction"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<b>Skip Unpaid/Self Promotion</b>
|
<b>Skip Unpaid/Self Promotion</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="skipSelfPromo" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipSelfPromo"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<b>Skip Music: Non-Music Section</b>
|
<b>Skip Music: Non-Music Section</b>
|
||||||
<br />
|
<br />
|
||||||
<input
|
<input class="uk-checkbox" v-model="skipMusicOffTopic" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="skipMusicOffTopic"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
<h2>Instances List</h2>
|
<h2>Instances List</h2>
|
||||||
<table class="uk-table">
|
<table class="uk-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -83,9 +46,7 @@
|
||||||
<td>{{ instance.locations }}</td>
|
<td>{{ instance.locations }}</td>
|
||||||
<td>{{ instance.cdn }}</td>
|
<td>{{ instance.cdn }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a :href="sslScore(instance.apiurl)" target="_blank"
|
<a :href="sslScore(instance.apiurl)" target="_blank">Click Here</a>
|
||||||
>Click Here</a
|
|
||||||
>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -94,16 +55,8 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<b>Instance Selection:</b>
|
<b>Instance Selection:</b>
|
||||||
<select
|
<select class="uk-select" v-model="selectedInstance" @change="onChange($event)">
|
||||||
class="uk-select"
|
<option v-bind:key="instance.name" v-for="instance in instances" v-bind:value="instance.apiurl">
|
||||||
v-model="selectedInstance"
|
|
||||||
@change="onChange($event)"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
v-bind:key="instance.name"
|
|
||||||
v-for="instance in instances"
|
|
||||||
v-bind:value="instance.apiurl"
|
|
||||||
>
|
|
||||||
{{ instance.name }}
|
{{ instance.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -121,13 +74,11 @@ export default {
|
||||||
skipOutro: false,
|
skipOutro: false,
|
||||||
skipInteraction: true,
|
skipInteraction: true,
|
||||||
skipSelfPromo: true,
|
skipSelfPromo: true,
|
||||||
skipMusicOffTopic: true
|
skipMusicOffTopic: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
fetch(
|
fetch("https://raw.githubusercontent.com/wiki/TeamPiped/Piped-Frontend/Instances.md")
|
||||||
"https://raw.githubusercontent.com/wiki/TeamPiped/Piped-Frontend/Instances.md"
|
|
||||||
)
|
|
||||||
.then(resp => resp.text())
|
.then(resp => resp.text())
|
||||||
.then(body => {
|
.then(body => {
|
||||||
var skipped = 0;
|
var skipped = 0;
|
||||||
|
@ -143,16 +94,14 @@ export default {
|
||||||
name: split[0].trim(),
|
name: split[0].trim(),
|
||||||
apiurl: split[1].trim(),
|
apiurl: split[1].trim(),
|
||||||
locations: split[2].trim(),
|
locations: split[2].trim(),
|
||||||
cdn: split[3].trim()
|
cdn: split[3].trim(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
this.selectedInstance =
|
this.selectedInstance = localStorage.getItem("instance") || "https://pipedapi.kavin.rocks";
|
||||||
localStorage.getItem("instance") ||
|
|
||||||
"https://pipedapi.kavin.rocks";
|
|
||||||
|
|
||||||
this.sponsorBlock = localStorage.getItem("sponsorblock") || true;
|
this.sponsorBlock = localStorage.getItem("sponsorblock") || true;
|
||||||
if (localStorage.getItem("selectedSkip")) {
|
if (localStorage.getItem("selectedSkip")) {
|
||||||
|
@ -198,18 +147,13 @@ export default {
|
||||||
if (this.skipOutro) sponsorSelected.push("outro");
|
if (this.skipOutro) sponsorSelected.push("outro");
|
||||||
if (this.skipInteraction) sponsorSelected.push("interaction");
|
if (this.skipInteraction) sponsorSelected.push("interaction");
|
||||||
if (this.skipSelfPromo) sponsorSelected.push("selfpromo");
|
if (this.skipSelfPromo) sponsorSelected.push("selfpromo");
|
||||||
if (this.skipMusicOffTopic)
|
if (this.skipMusicOffTopic) sponsorSelected.push("music_offtopic");
|
||||||
sponsorSelected.push("music_offtopic");
|
|
||||||
localStorage.setItem("selectedSkip", sponsorSelected);
|
localStorage.setItem("selectedSkip", sponsorSelected);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sslScore(url) {
|
sslScore(url) {
|
||||||
return (
|
return "https://www.ssllabs.com/ssltest/analyze.html?d=" + new URL(url).host + "&latest";
|
||||||
"https://www.ssllabs.com/ssltest/analyze.html?d=" +
|
},
|
||||||
new URL(url).host +
|
},
|
||||||
"&latest"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,21 +11,11 @@
|
||||||
v-for="result in results.items"
|
v-for="result in results.items"
|
||||||
>
|
>
|
||||||
<div class="uk-text-secondary" style="background: #0b0e0f">
|
<div class="uk-text-secondary" style="background: #0b0e0f">
|
||||||
<router-link
|
<router-link class="uk-text-emphasis" v-bind:to="result.url || '/'">
|
||||||
class="uk-text-emphasis"
|
<img style="width: 100%" v-bind:src="result.thumbnail" loading="lazy" />
|
||||||
v-bind:to="result.url || '/'"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style="width: 100%"
|
|
||||||
v-bind:src="result.thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<p>{{ result.name }}</p>
|
<p>{{ result.name }}</p>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link class="uk-link-muted" v-bind:to="result.uploaderUrl || '/'">
|
||||||
class="uk-link-muted"
|
|
||||||
v-bind:to="result.uploaderUrl || '/'"
|
|
||||||
>
|
|
||||||
<p>{{ result.uploaderName }}</p>
|
<p>{{ result.uploaderName }}</p>
|
||||||
</router-link>
|
</router-link>
|
||||||
{{ result.duration ? timeFormat(result.duration) : "" }}
|
{{ result.duration ? timeFormat(result.duration) : "" }}
|
||||||
|
@ -48,7 +38,7 @@ import Constants from "@/Constants.js";
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
results: null
|
results: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -61,28 +51,21 @@ export default {
|
||||||
watch: {
|
watch: {
|
||||||
"$route.query.search_query": function(q) {
|
"$route.query.search_query": function(q) {
|
||||||
if (q) this.updateResults();
|
if (q) this.updateResults();
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchResults() {
|
async fetchResults() {
|
||||||
return await await this.fetchJson(
|
return await await this.fetchJson(
|
||||||
Constants.BASE_URL +
|
Constants.BASE_URL + "/search?q=" + encodeURIComponent(this.$route.query.search_query),
|
||||||
"/search?q=" +
|
|
||||||
encodeURIComponent(this.$route.query.search_query)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
async updateResults() {
|
async updateResults() {
|
||||||
document.title = this.$route.query.search_query + " - Piped";
|
document.title = this.$route.query.search_query + " - Piped";
|
||||||
this.results = this.fetchResults().then(
|
this.results = this.fetchResults().then(json => (this.results = json));
|
||||||
json => (this.results = json)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
handleScroll() {
|
handleScroll() {
|
||||||
if (this.loading || !this.results || !this.results.nextpage) return;
|
if (this.loading || !this.results || !this.results.nextpage) return;
|
||||||
if (
|
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - window.innerHeight) {
|
||||||
window.innerHeight + window.scrollY >=
|
|
||||||
document.body.offsetHeight - window.innerHeight
|
|
||||||
) {
|
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.fetchJson(
|
this.fetchJson(
|
||||||
Constants.BASE_URL +
|
Constants.BASE_URL +
|
||||||
|
@ -92,7 +75,7 @@ export default {
|
||||||
"&id=" +
|
"&id=" +
|
||||||
encodeURIComponent(this.results.id) +
|
encodeURIComponent(this.results.id) +
|
||||||
"&q=" +
|
"&q=" +
|
||||||
encodeURIComponent(this.$route.query.search_query)
|
encodeURIComponent(this.$route.query.search_query),
|
||||||
).then(json => {
|
).then(json => {
|
||||||
this.results.nextpage = json.nextpage;
|
this.results.nextpage = json.nextpage;
|
||||||
this.results.id = json.id;
|
this.results.id = json.id;
|
||||||
|
@ -100,7 +83,7 @@ export default {
|
||||||
json.items.map(stream => this.results.items.push(stream));
|
json.items.map(stream => this.results.items.push(stream));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,21 +11,11 @@
|
||||||
v-for="video in videos"
|
v-for="video in videos"
|
||||||
>
|
>
|
||||||
<div class="uk-text-secondary" style="background: #0b0e0f">
|
<div class="uk-text-secondary" style="background: #0b0e0f">
|
||||||
<router-link
|
<router-link class="uk-text-emphasis" v-bind:to="video.url || '/'">
|
||||||
class="uk-text-emphasis"
|
<img style="width: 100%" v-bind:src="video.thumbnail" loading="lazy" />
|
||||||
v-bind:to="video.url || '/'"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style="width: 100%"
|
|
||||||
v-bind:src="video.thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<p>{{ video.title }}</p>
|
<p>{{ video.title }}</p>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link class="uk-link-muted" v-bind:to="video.uploaderUrl || '/'">
|
||||||
class="uk-link-muted"
|
|
||||||
v-bind:to="video.uploaderUrl || '/'"
|
|
||||||
>
|
|
||||||
<p>{{ video.uploaderName }}</p>
|
<p>{{ video.uploaderName }}</p>
|
||||||
</router-link>
|
</router-link>
|
||||||
<b class="uk-text-small uk-align-left">
|
<b class="uk-text-small uk-align-left">
|
||||||
|
@ -48,7 +38,7 @@ import Constants from "@/Constants.js";
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
videos: []
|
videos: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -59,7 +49,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
async fetchTrending() {
|
async fetchTrending() {
|
||||||
return await this.fetchJson(Constants.BASE_URL + "/trending");
|
return await this.fetchJson(Constants.BASE_URL + "/trending");
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="uk-container uk-container-xlarge">
|
<div class="uk-container uk-container-xlarge">
|
||||||
<Player
|
<Player ref="videoPlayer" :video="video" :sponsors="sponsors" :selectedAutoPlay="selectedAutoPlay" />
|
||||||
ref="videoPlayer"
|
|
||||||
:video="video"
|
|
||||||
:sponsors="sponsors"
|
|
||||||
:selectedAutoPlay="selectedAutoPlay"
|
|
||||||
/>
|
|
||||||
<h1 class="uk-text-bold">{{ video.title }}</h1>
|
<h1 class="uk-text-bold">{{ video.title }}</h1>
|
||||||
|
|
||||||
<img :src="video.uploaderAvatar" loading="lazy" />
|
<img :src="video.uploaderAvatar" loading="lazy" />
|
||||||
|
@ -27,27 +22,16 @@
|
||||||
<p>
|
<p>
|
||||||
Uploaded on <b>{{ video.uploadDate }}</b>
|
Uploaded on <b>{{ video.uploadDate }}</b>
|
||||||
</p>
|
</p>
|
||||||
<a
|
<a class="uk-button uk-button-small" style="background: #222" @click="showDesc = !showDesc">
|
||||||
class="uk-button uk-button-small"
|
|
||||||
style="background: #222"
|
|
||||||
@click="showDesc = !showDesc"
|
|
||||||
>
|
|
||||||
{{ showDesc ? "+" : "-" }}
|
{{ showDesc ? "+" : "-" }}
|
||||||
</a>
|
</a>
|
||||||
<p v-show="showDesc" class="uk-light" v-html="video.description"></p>
|
<p v-show="showDesc" class="uk-light" v-html="video.description"></p>
|
||||||
<a v-if="sponsors && sponsors.segments"
|
<a v-if="sponsors && sponsors.segments">Sponsors Segments: {{ sponsors.segments.length }}</a>
|
||||||
>Sponsors Segments: {{ sponsors.segments.length }}</a
|
|
||||||
>
|
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<b>Auto Play next Video:</b>
|
<b>Auto Play next Video:</b>
|
||||||
<input
|
<input class="uk-checkbox" v-model="selectedAutoPlay" @change="onChange($event)" type="checkbox" />
|
||||||
class="uk-checkbox"
|
|
||||||
v-model="selectedAutoPlay"
|
|
||||||
@change="onChange($event)"
|
|
||||||
type="checkbox"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="uk-tile-default uk-text-secondary"
|
class="uk-tile-default uk-text-secondary"
|
||||||
|
@ -57,17 +41,10 @@
|
||||||
>
|
>
|
||||||
<router-link class="uk-link-muted" v-bind:to="related.url">
|
<router-link class="uk-link-muted" v-bind:to="related.url">
|
||||||
<p class="uk-text-emphasis">{{ related.title }}</p>
|
<p class="uk-text-emphasis">{{ related.title }}</p>
|
||||||
<img
|
<img style="width: 100%" v-bind:src="related.thumbnail" loading="lazy" />
|
||||||
style="width: 100%"
|
|
||||||
v-bind:src="related.thumbnail"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</router-link>
|
</router-link>
|
||||||
<p>
|
<p>
|
||||||
<router-link
|
<router-link class="uk-link-muted" v-bind:to="related.uploaderUrl || '/'">
|
||||||
class="uk-link-muted"
|
|
||||||
v-bind:to="related.uploaderUrl || '/'"
|
|
||||||
>
|
|
||||||
<p>{{ related.uploaderName }}</p>
|
<p>{{ related.uploaderName }}</p>
|
||||||
</router-link>
|
</router-link>
|
||||||
<font-awesome-icon icon="eye"></font-awesome-icon>
|
<font-awesome-icon icon="eye"></font-awesome-icon>
|
||||||
|
@ -86,11 +63,11 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
video: {
|
video: {
|
||||||
title: "Loading..."
|
title: "Loading...",
|
||||||
},
|
},
|
||||||
sponsors: null,
|
sponsors: null,
|
||||||
selectedAutoPlay: null,
|
selectedAutoPlay: null,
|
||||||
showDesc: true
|
showDesc: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -104,13 +81,11 @@ export default {
|
||||||
this.getVideoData();
|
this.getVideoData();
|
||||||
this.getSponsors();
|
this.getSponsors();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchVideo() {
|
fetchVideo() {
|
||||||
return this.fetchJson(
|
return this.fetchJson(Constants.BASE_URL + "/streams/" + this.$route.query.v);
|
||||||
Constants.BASE_URL + "/streams/" + this.$route.query.v
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
async fetchSponsors() {
|
async fetchSponsors() {
|
||||||
return await this.fetchJson(
|
return await this.fetchJson(
|
||||||
|
@ -119,21 +94,12 @@ export default {
|
||||||
this.$route.query.v +
|
this.$route.query.v +
|
||||||
"?category=" +
|
"?category=" +
|
||||||
(localStorage && localStorage.getItem("selectedSkip")
|
(localStorage && localStorage.getItem("selectedSkip")
|
||||||
? encodeURIComponent(
|
? encodeURIComponent('["' + localStorage.getItem("selectedSkip").replace(",", '","') + '"]')
|
||||||
'["' +
|
: encodeURIComponent('["sponsor", "interaction", "selfpromo", "music_offtopic"]')),
|
||||||
localStorage
|
|
||||||
.getItem("selectedSkip")
|
|
||||||
.replace(",", '","') +
|
|
||||||
'"]'
|
|
||||||
)
|
|
||||||
: encodeURIComponent(
|
|
||||||
'["sponsor", "interaction", "selfpromo", "music_offtopic"]'
|
|
||||||
))
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onChange() {
|
onChange() {
|
||||||
if (localStorage)
|
if (localStorage) localStorage.setItem("autoplay", this.selectedAutoPlay);
|
||||||
localStorage.setItem("autoplay", this.selectedAutoPlay);
|
|
||||||
},
|
},
|
||||||
async getVideoData() {
|
async getVideoData() {
|
||||||
this.fetchVideo()
|
this.fetchVideo()
|
||||||
|
@ -154,10 +120,10 @@ export default {
|
||||||
async getSponsors() {
|
async getSponsors() {
|
||||||
if (!localStorage || localStorage.getItem("sponsorblock") !== false)
|
if (!localStorage || localStorage.getItem("sponsorblock") !== false)
|
||||||
this.fetchSponsors().then(data => (this.sponsors = data));
|
this.fetchSponsors().then(data => (this.sponsors = data));
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Player
|
Player,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
51
src/main.js
51
src/main.js
|
@ -1,23 +1,22 @@
|
||||||
import { createApp } from 'vue'
|
import { createApp } from "vue";
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||||
import { faThumbsUp, faThumbsDown, faEye } from '@fortawesome/free-solid-svg-icons'
|
import { faThumbsUp, faThumbsDown, faEye } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faGithub, faBitcoin } from '@fortawesome/free-brands-svg-icons'
|
import { faGithub, faBitcoin } from "@fortawesome/free-brands-svg-icons";
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||||
library.add(faThumbsUp, faThumbsDown, faEye, faGithub, faBitcoin)
|
library.add(faThumbsUp, faThumbsDown, faEye, faGithub, faBitcoin);
|
||||||
|
|
||||||
import("uikit/src/less/uikit.less")
|
import("uikit/src/less/uikit.less");
|
||||||
import("uikit/dist/js/uikit.min.js")
|
import("uikit/dist/js/uikit.min.js");
|
||||||
|
|
||||||
import router from '@/router/router'
|
import router from "@/router/router";
|
||||||
import App from './App.vue'
|
import App from "./App.vue";
|
||||||
|
|
||||||
import './registerServiceWorker'
|
import "./registerServiceWorker";
|
||||||
|
|
||||||
const mixin = {
|
const mixin = {
|
||||||
methods: {
|
methods: {
|
||||||
timeFormat: function (duration) {
|
timeFormat: function(duration) {
|
||||||
|
var pad = function(num, size) {
|
||||||
var pad = function (num, size) {
|
|
||||||
return ("000" + num).slice(size * -1);
|
return ("000" + num).slice(size * -1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,19 +32,17 @@ const mixin = {
|
||||||
str += pad(minutes, 2) + ":" + pad(seconds, 2);
|
str += pad(minutes, 2) + ":" + pad(seconds, 2);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
},
|
},
|
||||||
fetchJson: function (url, options) {
|
fetchJson: function(url, options) {
|
||||||
return fetch(url, options)
|
return fetch(url, options).then(response => {
|
||||||
.then(response => {
|
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App);
|
||||||
app.use(router)
|
app.use(router);
|
||||||
app.mixin(mixin)
|
app.mixin(mixin);
|
||||||
app.component('font-awesome-icon', FontAwesomeIcon)
|
app.component("font-awesome-icon", FontAwesomeIcon);
|
||||||
app.mount('#app')
|
app.mount("#app");
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
import { register } from 'register-service-worker'
|
import { register } from "register-service-worker";
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === "production") {
|
||||||
register(`/service-worker.js`, {
|
register(`/service-worker.js`, {
|
||||||
ready() {
|
ready() {
|
||||||
console.log(
|
console.log(
|
||||||
'App is being served from cache by a service worker.\n' +
|
"App is being served from cache by a service worker.\n" +
|
||||||
'For more details, visit https://goo.gl/AFskqB'
|
"For more details, visit https://goo.gl/AFskqB",
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
registered() {
|
registered() {
|
||||||
console.log('Service worker has been registered.')
|
console.log("Service worker has been registered.");
|
||||||
},
|
},
|
||||||
cached() {
|
cached() {
|
||||||
console.log('Content has been cached for offline use.')
|
console.log("Content has been cached for offline use.");
|
||||||
},
|
},
|
||||||
updatefound() {
|
updatefound() {
|
||||||
console.log('New content is downloading.')
|
console.log("New content is downloading.");
|
||||||
},
|
},
|
||||||
updated() {
|
updated() {
|
||||||
console.log('New content is available; please refresh.')
|
console.log("New content is available; please refresh.");
|
||||||
window.location.reload()
|
window.location.reload();
|
||||||
},
|
},
|
||||||
offline() {
|
offline() {
|
||||||
console.log('No internet connection found. App is running in offline mode.')
|
console.log("No internet connection found. App is running in offline mode.");
|
||||||
},
|
},
|
||||||
error(error) {
|
error(error) {
|
||||||
console.error('Error during service worker registration:', error)
|
console.error("Error during service worker registration:", error);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,41 @@
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
|
|
||||||
const routes = [{
|
const routes = [
|
||||||
path: '/watch',
|
{
|
||||||
name: 'Watch',
|
path: "/watch",
|
||||||
component: () => import('../components/WatchVideo.vue')
|
name: "Watch",
|
||||||
}, {
|
component: () => import("../components/WatchVideo.vue"),
|
||||||
path: '/',
|
},
|
||||||
name: 'Trending',
|
{
|
||||||
component: () => import('../components/TrendingPage.vue')
|
path: "/",
|
||||||
}, {
|
name: "Trending",
|
||||||
path: '/channel/:channelId',
|
component: () => import("../components/TrendingPage.vue"),
|
||||||
name: 'Channel',
|
},
|
||||||
component: () => import('../components/Channel.vue')
|
{
|
||||||
}, {
|
path: "/channel/:channelId",
|
||||||
path: '/preferences',
|
name: "Channel",
|
||||||
name: 'Preferences',
|
component: () => import("../components/Channel.vue"),
|
||||||
component: () => import('../components/Preferences.vue')
|
},
|
||||||
}, {
|
{
|
||||||
path: '/results',
|
path: "/preferences",
|
||||||
name: 'SearchResults',
|
name: "Preferences",
|
||||||
component: () => import('../components/SearchResults.vue')
|
component: () => import("../components/Preferences.vue"),
|
||||||
}, {
|
},
|
||||||
path: '/playlist',
|
{
|
||||||
name: 'Playlist',
|
path: "/results",
|
||||||
component: () => import('../components/Playlist.vue')
|
name: "SearchResults",
|
||||||
}]
|
component: () => import("../components/SearchResults.vue"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/playlist",
|
||||||
|
name: "Playlist",
|
||||||
|
component: () => import("../components/Playlist.vue"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(),
|
history: createWebHistory(),
|
||||||
routes
|
routes,
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,189 +1,188 @@
|
||||||
// Based of https://github.com/GilgusMaximus/yt-dash-manifest-generator/blob/master/src/DashGenerator.js
|
// Based of https://github.com/GilgusMaximus/yt-dash-manifest-generator/blob/master/src/DashGenerator.js
|
||||||
|
|
||||||
const xml = require('xml-js')
|
const xml = require("xml-js");
|
||||||
|
|
||||||
const DashUtils = {
|
const DashUtils = {
|
||||||
generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
||||||
const generatedJSON = this.generate_xmljs_json_from_data(VideoFormats, VideoLength)
|
const generatedJSON = this.generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
||||||
return xml.json2xml(generatedJSON)
|
return xml.json2xml(generatedJSON);
|
||||||
},
|
},
|
||||||
generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
||||||
const convertJSON = {
|
const convertJSON = {
|
||||||
"declaration": {
|
declaration: {
|
||||||
"attributes": {
|
attributes: {
|
||||||
"version": "1.0",
|
version: "1.0",
|
||||||
"encoding": "utf-8"
|
encoding: "utf-8",
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"elements": [
|
|
||||||
{
|
|
||||||
"type": "element",
|
|
||||||
"name": "MPD",
|
|
||||||
"attributes": {
|
|
||||||
"xmlns": "urn:mpeg:dash:schema:mpd:2011",
|
|
||||||
"profiles": "urn:mpeg:dash:profile:full:2011",
|
|
||||||
"minBufferTime": "PT1.5S",
|
|
||||||
"type": "static",
|
|
||||||
"mediaPresentationDuration": `PT${VideoLength}S`
|
|
||||||
},
|
},
|
||||||
"elements": [
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "Period",
|
name: "MPD",
|
||||||
"elements": this.generate_adaptation_set(VideoFormatArray)
|
attributes: {
|
||||||
}
|
xmlns: "urn:mpeg:dash:schema:mpd:2011",
|
||||||
]
|
profiles: "urn:mpeg:dash:profile:full:2011",
|
||||||
}
|
minBufferTime: "PT1.5S",
|
||||||
]
|
type: "static",
|
||||||
}
|
mediaPresentationDuration: `PT${VideoLength}S`,
|
||||||
return convertJSON
|
},
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: "element",
|
||||||
|
name: "Period",
|
||||||
|
elements: this.generate_adaptation_set(VideoFormatArray),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
return convertJSON;
|
||||||
},
|
},
|
||||||
generate_adaptation_set(VideoFormatArray) {
|
generate_adaptation_set(VideoFormatArray) {
|
||||||
const adaptationSets = []
|
const adaptationSets = [];
|
||||||
const mimeTypes = []
|
const mimeTypes = [];
|
||||||
const mimeObjects = [[]]
|
const mimeObjects = [[]];
|
||||||
// sort the formats by mime types
|
// sort the formats by mime types
|
||||||
VideoFormatArray.forEach((videoFormat) => {
|
VideoFormatArray.forEach(videoFormat => {
|
||||||
// the dual formats should not be used
|
// the dual formats should not be used
|
||||||
if (videoFormat.mimeType.indexOf("video") != -1 && !videoFormat.videoOnly) {
|
if (videoFormat.mimeType.indexOf("video") != -1 && !videoFormat.videoOnly) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
// if these properties are not available, then we skip it because we cannot set these properties
|
// if these properties are not available, then we skip it because we cannot set these properties
|
||||||
//if (!(videoFormat.hasOwnProperty('initRange') && videoFormat.hasOwnProperty('indexRange'))) {
|
//if (!(videoFormat.hasOwnProperty('initRange') && videoFormat.hasOwnProperty('indexRange'))) {
|
||||||
// return
|
// return
|
||||||
//}
|
//}
|
||||||
const mimeType = videoFormat.mimeType
|
const mimeType = videoFormat.mimeType;
|
||||||
const mimeTypeIndex = mimeTypes.indexOf(mimeType)
|
const mimeTypeIndex = mimeTypes.indexOf(mimeType);
|
||||||
if (mimeTypeIndex > -1) {
|
if (mimeTypeIndex > -1) {
|
||||||
mimeObjects[mimeTypeIndex].push(videoFormat)
|
mimeObjects[mimeTypeIndex].push(videoFormat);
|
||||||
} else {
|
} else {
|
||||||
mimeTypes.push(mimeType)
|
mimeTypes.push(mimeType);
|
||||||
mimeObjects.push([])
|
mimeObjects.push([]);
|
||||||
mimeObjects[mimeTypes.length - 1].push(videoFormat)
|
mimeObjects[mimeTypes.length - 1].push(videoFormat);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
// for each MimeType generate a new Adaptation set with Representations as sub elements
|
// for each MimeType generate a new Adaptation set with Representations as sub elements
|
||||||
for (let i = 0; i < mimeTypes.length; i++) {
|
for (let i = 0; i < mimeTypes.length; i++) {
|
||||||
let isVideoFormat = false
|
let isVideoFormat = false;
|
||||||
const adapSet = {
|
const adapSet = {
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "AdaptationSet",
|
name: "AdaptationSet",
|
||||||
"attributes": {
|
attributes: {
|
||||||
"id": i,
|
id: i,
|
||||||
"mimeType": mimeTypes[i],
|
mimeType: mimeTypes[i],
|
||||||
"startWithSAP": "1",
|
startWithSAP: "1",
|
||||||
"subsegmentAlignment": "true"
|
subsegmentAlignment: "true",
|
||||||
},
|
},
|
||||||
"elements": []
|
elements: [],
|
||||||
}
|
};
|
||||||
if (!mimeTypes[i].includes("audio")) {
|
if (!mimeTypes[i].includes("audio")) {
|
||||||
adapSet.attributes.scanType = "progressive"
|
adapSet.attributes.scanType = "progressive";
|
||||||
isVideoFormat = true
|
isVideoFormat = true;
|
||||||
}
|
}
|
||||||
mimeObjects[i].forEach((format) => {
|
mimeObjects[i].forEach(format => {
|
||||||
if (isVideoFormat) {
|
if (isVideoFormat) {
|
||||||
adapSet.elements.push(this.generate_representation_video(format))
|
adapSet.elements.push(this.generate_representation_video(format));
|
||||||
} else {
|
} else {
|
||||||
adapSet.elements.push(this.generate_representation_audio(format))
|
adapSet.elements.push(this.generate_representation_audio(format));
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
adaptationSets.push(adapSet)
|
adaptationSets.push(adapSet);
|
||||||
}
|
}
|
||||||
return adaptationSets
|
return adaptationSets;
|
||||||
}, generate_representation_audio(Format) {
|
|
||||||
const representation =
|
|
||||||
{
|
|
||||||
"type": "element",
|
|
||||||
"name": "Representation",
|
|
||||||
"attributes": {
|
|
||||||
"id": Format.itag,
|
|
||||||
"codecs": Format.codec,
|
|
||||||
"bandwidth": Format.bitrate
|
|
||||||
},
|
},
|
||||||
"elements": [
|
generate_representation_audio(Format) {
|
||||||
|
const representation = {
|
||||||
|
type: "element",
|
||||||
|
name: "Representation",
|
||||||
|
attributes: {
|
||||||
|
id: Format.itag,
|
||||||
|
codecs: Format.codec,
|
||||||
|
bandwidth: Format.bitrate,
|
||||||
|
},
|
||||||
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "AudioChannelConfiguration",
|
name: "AudioChannelConfiguration",
|
||||||
"attributes": {
|
attributes: {
|
||||||
"schemeIdUri": "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
|
schemeIdUri: "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
|
||||||
"value": "2"
|
value: "2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "BaseURL",
|
name: "BaseURL",
|
||||||
"elements": [
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "text",
|
type: "text",
|
||||||
"text": Format.url
|
text: Format.url,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "SegmentBase",
|
name: "SegmentBase",
|
||||||
"attributes": {
|
attributes: {
|
||||||
"indexRange": `${Format.indexStart}-${Format.indexEnd}`
|
indexRange: `${Format.indexStart}-${Format.indexEnd}`,
|
||||||
},
|
},
|
||||||
"elements": [
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "Initialization",
|
name: "Initialization",
|
||||||
"attributes": {
|
attributes: {
|
||||||
"range": `${Format.initStart}-${Format.initEnd}`
|
range: `${Format.initStart}-${Format.initEnd}`,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
return representation
|
return representation;
|
||||||
},
|
},
|
||||||
generate_representation_video(Format) {
|
generate_representation_video(Format) {
|
||||||
const representation =
|
const representation = {
|
||||||
{
|
type: "element",
|
||||||
"type": "element",
|
name: "Representation",
|
||||||
"name": "Representation",
|
attributes: {
|
||||||
"attributes": {
|
id: Format.itag,
|
||||||
"id": Format.itag,
|
codecs: Format.codec,
|
||||||
"codecs": Format.codec,
|
bandwidth: Format.bitrate,
|
||||||
"bandwidth": Format.bitrate,
|
width: Format.width,
|
||||||
"width": Format.width,
|
height: Format.height,
|
||||||
"height": Format.height,
|
maxPlayoutRate: "1",
|
||||||
"maxPlayoutRate": "1",
|
frameRate: Format.fps,
|
||||||
"frameRate": Format.fps
|
|
||||||
},
|
},
|
||||||
"elements": [
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "BaseURL",
|
name: "BaseURL",
|
||||||
"elements": [
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "text",
|
type: "text",
|
||||||
"text": Format.url
|
text: Format.url,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "SegmentBase",
|
name: "SegmentBase",
|
||||||
"attributes": {
|
attributes: {
|
||||||
"indexRange": `${Format.indexStart}-${Format.indexEnd}`
|
indexRange: `${Format.indexStart}-${Format.indexEnd}`,
|
||||||
},
|
},
|
||||||
"elements": [
|
elements: [
|
||||||
{
|
{
|
||||||
"type": "element",
|
type: "element",
|
||||||
"name": "Initialization",
|
name: "Initialization",
|
||||||
"attributes": {
|
attributes: {
|
||||||
"range": `${Format.initStart}-${Format.initEnd}`
|
range: `${Format.initStart}-${Format.initEnd}`,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
};
|
||||||
return representation
|
return representation;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export default DashUtils;
|
export default DashUtils;
|
||||||
|
|
|
@ -2907,16 +2907,11 @@ core-js@^2.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-js@^3.10.0:
|
core-js@^3.10.0, core-js@^3.6.5:
|
||||||
version "3.10.0"
|
version "3.10.0"
|
||||||
resolved "https://registry.npm.taobao.org/core-js/download/core-js-3.10.0.tgz?cache=0&sync_timestamp=1617182041689&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.10.0.tgz#9a020547c8b6879f929306949e31496bbe2ae9b3"
|
resolved "https://registry.npm.taobao.org/core-js/download/core-js-3.10.0.tgz?cache=0&sync_timestamp=1617182041689&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcore-js%2Fdownload%2Fcore-js-3.10.0.tgz#9a020547c8b6879f929306949e31496bbe2ae9b3"
|
||||||
integrity sha1-mgIFR8i2h5+SkwaUnjFJa74q6bM=
|
integrity sha1-mgIFR8i2h5+SkwaUnjFJa74q6bM=
|
||||||
|
|
||||||
core-js@^3.6.5:
|
|
||||||
version "3.10.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.0.tgz#9a020547c8b6879f929306949e31496bbe2ae9b3"
|
|
||||||
integrity sha512-MQx/7TLgmmDVamSyfE+O+5BHvG1aUGj/gHhLn1wVtm2B5u1eVIPvh7vkfjwWKNCjrTJB8+He99IntSQ1qP+vYQ==
|
|
||||||
|
|
||||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
|
|
Loading…
Reference in a new issue