mirror of
https://github.com/TeamPiped/Piped.git
synced 2025-08-06 10:44:11 +00:00
Commit everything.
This commit is contained in:
16
src/App.vue
16
src/App.vue
@@ -64,15 +64,11 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(
|
||||
this.fetchJson(
|
||||
Constants.BASE_URL +
|
||||
"/suggestions?query=" +
|
||||
encodeURI(this.searchText + e.key)
|
||||
)
|
||||
.then(resp => resp.json())
|
||||
.then(json => {
|
||||
this.searchSuggestions = json;
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -104,7 +100,7 @@ export default {
|
||||
background-color: #0b0e0f;
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-color: #15191a #444a4e;
|
||||
}
|
||||
</style>
|
||||
* {
|
||||
scrollbar-color: #15191a #444a4e;
|
||||
}
|
||||
</style>
|
||||
|
@@ -7,6 +7,7 @@
|
||||
v-if="channel.bannerUrl"
|
||||
v-bind:src="channel.bannerUrl"
|
||||
style="width: 100%"
|
||||
loading="lazy"
|
||||
/>
|
||||
<p v-html="this.channel.description.replaceAll('\n', '<br>')"></p>
|
||||
|
||||
@@ -22,17 +23,23 @@
|
||||
class="uk-link-muted uk-text-justify"
|
||||
v-bind:to="item.url || '/'"
|
||||
>
|
||||
<img style="width: 100%" v-bind:src="item.thumbnail" />
|
||||
<img
|
||||
style="width: 100%"
|
||||
v-bind:src="item.thumbnail"
|
||||
loading="lazy"
|
||||
/>
|
||||
<a>{{ item.title }}</a>
|
||||
</router-link>
|
||||
<br />
|
||||
<div>
|
||||
<b class="uk-text-small uk-align-left">
|
||||
{{ timeFormat(item.duration) }}
|
||||
</b>
|
||||
<b class="uk-text-small uk-align-right">
|
||||
<font-awesome-icon icon="eye"></font-awesome-icon>
|
||||
{{ item.views }} views
|
||||
<br />
|
||||
{{ item.uploadedDate }}
|
||||
</b>
|
||||
<b class="uk-text-small uk-align-right">
|
||||
{{ timeFormat(item.duration) }}
|
||||
</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,13 +65,9 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchChannel() {
|
||||
return await (
|
||||
await fetch(
|
||||
Constants.BASE_URL +
|
||||
"/channels/" +
|
||||
this.$route.params.channelId
|
||||
)
|
||||
).json();
|
||||
return await this.fetchJson(
|
||||
Constants.BASE_URL + "/channels/" + this.$route.params.channelId
|
||||
);
|
||||
},
|
||||
async getChannelData() {
|
||||
this.fetchChannel()
|
||||
@@ -78,22 +81,20 @@ export default {
|
||||
document.body.offsetHeight - window.innerHeight
|
||||
) {
|
||||
this.loading = true;
|
||||
fetch(
|
||||
this.fetchJson(
|
||||
Constants.BASE_URL +
|
||||
"/nextpage/channels/" +
|
||||
this.$route.params.channelId +
|
||||
"?url=" +
|
||||
encodeURIComponent(this.channel.nextpage)
|
||||
)
|
||||
.then(body => body.json())
|
||||
.then(json => {
|
||||
this.channel.relatedStreams.concat(json.relatedStreams);
|
||||
this.channel.nextpage = json.nextpage;
|
||||
this.loading = false;
|
||||
json.relatedStreams.map(stream =>
|
||||
this.channel.relatedStreams.push(stream)
|
||||
);
|
||||
});
|
||||
).then(json => {
|
||||
this.channel.relatedStreams.concat(json.relatedStreams);
|
||||
this.channel.nextpage = json.nextpage;
|
||||
this.loading = false;
|
||||
json.relatedStreams.map(stream =>
|
||||
this.channel.relatedStreams.push(stream)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div v-if="playlist">
|
||||
<h1 class="uk-text-center">
|
||||
<img v-bind:src="playlist.avatarUrl" />{{ playlist.name }}
|
||||
<img v-bind:src="playlist.avatarUrl" loading="lazy" />
|
||||
{{ playlist.name }}
|
||||
</h1>
|
||||
|
||||
<b
|
||||
@@ -9,7 +10,7 @@
|
||||
class="uk-text-justify"
|
||||
v-bind:to="playlist.uploaderUrl || '/'"
|
||||
>
|
||||
<img v-bind:src="playlist.uploaderAvatar" />
|
||||
<img v-bind:src="playlist.uploaderAvatar" loading="lazy" />
|
||||
{{ playlist.uploader }}</router-link
|
||||
></b
|
||||
>
|
||||
@@ -28,7 +29,11 @@
|
||||
class="uk-link-muted uk-text-justify"
|
||||
v-bind:to="item.url || '/'"
|
||||
>
|
||||
<img style="width: 100%" v-bind:src="item.thumbnail" />
|
||||
<img
|
||||
style="width: 100%"
|
||||
v-bind:src="item.thumbnail"
|
||||
loading="lazy"
|
||||
/>
|
||||
<a>{{ item.title }}</a>
|
||||
</router-link>
|
||||
<br />
|
||||
@@ -67,11 +72,9 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchPlaylist() {
|
||||
return await (
|
||||
await fetch(
|
||||
Constants.BASE_URL + "/playlists/" + this.$route.query.list
|
||||
)
|
||||
).json();
|
||||
return await await this.fetchJson(
|
||||
Constants.BASE_URL + "/playlists/" + this.$route.query.list
|
||||
);
|
||||
},
|
||||
async getPlaylistData() {
|
||||
this.fetchPlaylist()
|
||||
@@ -86,24 +89,20 @@ export default {
|
||||
document.body.offsetHeight - window.innerHeight
|
||||
) {
|
||||
this.loading = true;
|
||||
fetch(
|
||||
this.fetchJson(
|
||||
Constants.BASE_URL +
|
||||
"/nextpage/playlists/" +
|
||||
this.$route.query.list +
|
||||
"?url=" +
|
||||
encodeURIComponent(this.playlist.nextpage)
|
||||
)
|
||||
.then(body => body.json())
|
||||
.then(json => {
|
||||
this.playlist.relatedStreams.concat(
|
||||
json.relatedStreams
|
||||
);
|
||||
this.playlist.nextpage = json.nextpage;
|
||||
this.loading = false;
|
||||
json.relatedStreams.map(stream =>
|
||||
this.playlist.relatedStreams.push(stream)
|
||||
);
|
||||
});
|
||||
).then(json => {
|
||||
this.playlist.relatedStreams.concat(json.relatedStreams);
|
||||
this.playlist.nextpage = json.nextpage;
|
||||
this.loading = false;
|
||||
json.relatedStreams.map(stream =>
|
||||
this.playlist.relatedStreams.push(stream)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,11 @@
|
||||
class="uk-text-emphasis"
|
||||
v-bind:to="result.url || '/'"
|
||||
>
|
||||
<img style="width: 100%" v-bind:src="result.thumbnail" />
|
||||
<img
|
||||
style="width: 100%"
|
||||
v-bind:src="result.thumbnail"
|
||||
loading="lazy"
|
||||
/>
|
||||
<p>{{ result.name }}</p>
|
||||
</router-link>
|
||||
<router-link
|
||||
@@ -25,6 +29,8 @@
|
||||
<p>{{ result.uploaderName }}</p>
|
||||
</router-link>
|
||||
{{ result.duration ? timeFormat(result.duration) : "" }}
|
||||
<br />
|
||||
{{ "1/1/2020" }}
|
||||
<b v-if="result.views" class="uk-text-small uk-align-right">
|
||||
<font-awesome-icon icon="eye"></font-awesome-icon>
|
||||
{{ result.views }} views
|
||||
@@ -57,13 +63,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchResults() {
|
||||
return await (
|
||||
await fetch(
|
||||
Constants.BASE_URL +
|
||||
"/search?q=" +
|
||||
encodeURIComponent(this.$route.query.search_query)
|
||||
)
|
||||
).json();
|
||||
return await await this.fetchJson(
|
||||
Constants.BASE_URL +
|
||||
"/search?q=" +
|
||||
encodeURIComponent(this.$route.query.search_query)
|
||||
);
|
||||
},
|
||||
async updateResults() {
|
||||
document.title = this.$route.query.search_query + " - Piped";
|
||||
@@ -78,7 +82,7 @@ export default {
|
||||
document.body.offsetHeight - window.innerHeight
|
||||
) {
|
||||
this.loading = true;
|
||||
fetch(
|
||||
this.fetchJson(
|
||||
Constants.BASE_URL +
|
||||
"/nextpage/search" +
|
||||
"?url=" +
|
||||
@@ -87,16 +91,12 @@ export default {
|
||||
encodeURIComponent(this.results.id) +
|
||||
"&q=" +
|
||||
encodeURIComponent(this.$route.query.search_query)
|
||||
)
|
||||
.then(body => body.json())
|
||||
.then(json => {
|
||||
this.results.nextpage = json.nextpage;
|
||||
this.results.id = json.id;
|
||||
this.loading = false;
|
||||
json.items.map(stream =>
|
||||
this.results.items.push(stream)
|
||||
);
|
||||
});
|
||||
).then(json => {
|
||||
this.results.nextpage = json.nextpage;
|
||||
this.results.id = json.id;
|
||||
this.loading = false;
|
||||
json.items.map(stream => this.results.items.push(stream));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,11 @@
|
||||
class="uk-text-emphasis"
|
||||
v-bind:to="video.url || '/'"
|
||||
>
|
||||
<img style="width: 100%" v-bind:src="video.thumbnail" />
|
||||
<img
|
||||
style="width: 100%"
|
||||
v-bind:src="video.thumbnail"
|
||||
loading="lazy"
|
||||
/>
|
||||
<p>{{ video.title }}</p>
|
||||
</router-link>
|
||||
<router-link
|
||||
@@ -24,10 +28,14 @@
|
||||
>
|
||||
<p>{{ video.uploaderName }}</p>
|
||||
</router-link>
|
||||
{{ timeFormat(video.duration) }}
|
||||
<b class="uk-text-small uk-align-right">
|
||||
<b class="uk-text-small uk-align-left">
|
||||
<font-awesome-icon icon="eye"></font-awesome-icon>
|
||||
{{ video.views }} views
|
||||
<br />
|
||||
{{ video.uploadedDate }}
|
||||
</b>
|
||||
<b class="uk-text-small uk-align-right">
|
||||
{{ timeFormat(video.duration) }}
|
||||
</b>
|
||||
</div>
|
||||
</div>
|
||||
@@ -50,7 +58,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async fetchTrending() {
|
||||
return await (await fetch(Constants.BASE_URL + "/trending")).json();
|
||||
return await this.fetchJson(Constants.BASE_URL + "/trending");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -1,13 +1,9 @@
|
||||
<template>
|
||||
<div class="uk-container uk-container-xlarge">
|
||||
<video
|
||||
controls
|
||||
ref="player"
|
||||
class="video-js preview-player-dimensions"
|
||||
></video>
|
||||
<video controls ref="player"></video>
|
||||
<h1 class="uk-text-bold">{{ video.title }}</h1>
|
||||
|
||||
<img :src="video.uploaderAvatar" />
|
||||
<img :src="video.uploaderAvatar" loading="lazy" />
|
||||
<router-link class="uk-text-bold" v-bind:to="video.uploaderUrl || '/'">
|
||||
<a>{{ video.uploader }}</a>
|
||||
</router-link>
|
||||
@@ -56,7 +52,11 @@
|
||||
>
|
||||
<router-link class="uk-link-muted" v-bind:to="related.url">
|
||||
<p class="uk-text-emphasis">{{ related.title }}</p>
|
||||
<img style="width: 100%" v-bind:src="related.thumbnail" />
|
||||
<img
|
||||
style="width: 100%"
|
||||
v-bind:src="related.thumbnail"
|
||||
loading="lazy"
|
||||
/>
|
||||
</router-link>
|
||||
<p>
|
||||
<router-link
|
||||
@@ -73,14 +73,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import("video.js/dist/video-js.css");
|
||||
import("@silvermine/videojs-quality-selector/dist/css/quality-selector.css");
|
||||
import videojs from "video.js";
|
||||
import("videojs-hotkeys");
|
||||
const shaka = import("shaka-player/dist/shaka-player.compiled.js");
|
||||
import Constants from "@/Constants.js";
|
||||
import("@silvermine/videojs-quality-selector").then(module => {
|
||||
module.default(videojs);
|
||||
});
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
@@ -119,22 +113,18 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchVideo() {
|
||||
return await (
|
||||
await fetch(
|
||||
Constants.BASE_URL + "/streams/" + this.$route.query.v
|
||||
)
|
||||
).json();
|
||||
fetchVideo() {
|
||||
return this.fetchJson(
|
||||
Constants.BASE_URL + "/streams/" + this.$route.query.v
|
||||
);
|
||||
},
|
||||
async fetchSponsors() {
|
||||
return await (
|
||||
await fetch(
|
||||
Constants.BASE_URL +
|
||||
"/sponsors/" +
|
||||
this.$route.query.v +
|
||||
'?category=["sponsor","interaction","selfpromo","music_offtopic"]'
|
||||
)
|
||||
).json();
|
||||
await this.fetchJson(
|
||||
Constants.BASE_URL +
|
||||
"/sponsors/" +
|
||||
this.$route.query.v +
|
||||
'?category=["sponsor","interaction","selfpromo","music_offtopic"]'
|
||||
);
|
||||
},
|
||||
onChange() {
|
||||
if (localStorage)
|
||||
@@ -142,7 +132,9 @@ export default {
|
||||
},
|
||||
async getVideoData() {
|
||||
this.fetchVideo()
|
||||
.then(data => (this.video = data))
|
||||
.then(data => {
|
||||
this.video = data;
|
||||
})
|
||||
.then(() => {
|
||||
document.title = this.video.title + " - Piped";
|
||||
|
||||
@@ -151,96 +143,63 @@ export default {
|
||||
.replaceAll("https://www.youtube.com", "")
|
||||
.replaceAll("\n", "<br>");
|
||||
|
||||
const options = {
|
||||
autoplay: false,
|
||||
controlBar: {
|
||||
children: [
|
||||
"playToggle",
|
||||
"currentTimeDisplay",
|
||||
"progressControl",
|
||||
"volumePanel",
|
||||
"qualitySelector",
|
||||
"captionsButton",
|
||||
"fullscreenToggle"
|
||||
]
|
||||
},
|
||||
responsive: false,
|
||||
aspectRatio: "16:9"
|
||||
};
|
||||
|
||||
const noPrevPlayer = !this.player;
|
||||
|
||||
var streams = [];
|
||||
|
||||
streams.push(...this.video.audioStreams);
|
||||
streams.push(...this.video.videoStreams);
|
||||
|
||||
const dash = require("../utils/DashUtils.js").default.generate_dash_file_from_formats(
|
||||
streams,
|
||||
this.video.duration
|
||||
);
|
||||
|
||||
if (noPrevPlayer) {
|
||||
this.player = videojs(this.$refs.player, options);
|
||||
if (localStorage)
|
||||
this.player.volume(
|
||||
localStorage.getItem("volume") || 1
|
||||
);
|
||||
setTimeout(function() {
|
||||
shaka
|
||||
.then(shaka => shaka.default)
|
||||
.then(shaka => {
|
||||
console.log(shaka);
|
||||
|
||||
shaka.polyfill.installAll();
|
||||
|
||||
this.player = new shaka.Player(
|
||||
document.querySelector("video")
|
||||
);
|
||||
|
||||
this.player.load(
|
||||
"data:application/dash+xml;charset=utf-8;base64," +
|
||||
btoa(dash)
|
||||
);
|
||||
});
|
||||
}, 0);
|
||||
// if (localStorage)
|
||||
// this.player.volume(
|
||||
// localStorage.getItem("volume") || 1
|
||||
// );
|
||||
}
|
||||
|
||||
shaka;
|
||||
|
||||
console.log(this.player);
|
||||
|
||||
if (this.$route.query.t)
|
||||
this.player.currentTime(this.$route.query.t);
|
||||
|
||||
this.player.hotkeys({
|
||||
volumeStep: 0.1,
|
||||
seekStep: 5,
|
||||
enableModifiersForNumbers: false,
|
||||
enableHoverScroll: true
|
||||
});
|
||||
// this.player.poster(this.video.thumbnailUrl);
|
||||
|
||||
this.player.poster(this.video.thumbnailUrl);
|
||||
|
||||
var src = [];
|
||||
|
||||
// src.push({
|
||||
// src:
|
||||
// "data:application/dash+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPE1QRCB0eXBlPSJzdGF0aWMiIHhtbG5zPSJ1cm46bXBlZzpkYXNoOnNjaGVtYTptcGQ6MjAxMSIgbWluQnVmZmVyVGltZT0iUFQxLjVTIiBtZWRpYVByZXNlbnRhdGlvbkR1cmF0aW9uPSJQVDIyMC43NjIyMDgzMzMzMzMzMlMiIHByb2ZpbGVzPSJ1cm46bXBlZzpkYXNoOnByb2ZpbGU6aXNvZmYtbWFpbjoyMDExIj4KICA8UGVyaW9kIHN0YXJ0PSJQVDBTIj4KICAgIDxBZGFwdGF0aW9uU2V0PgogICAgICA8UmVwcmVzZW50YXRpb24gaWQ9InZpZGVvMDEiIG1pbWVUeXBlPSJ2aWRlby9tcDQiIGNvZGVjcz0iYXZjMS42NDAwMjgiIGJhbmR3aWR0aD0iMjgxNjM0Ij4KICAgICAgICAgIDxCYXNlVVJMPmh0dHBzOi8vcGlwZWRwcm94eS5rYXZpbi5yb2Nrcy92aWRlb3BsYXliYWNrP2V4cGlyZT0xNjA1NjkxNTMzJmVpPUxaUzBYLVA5RG9TLWh3YU95Sl9vRHcmaXA9MjA5LjE0MS40Ni4zOCZpZD0wN2FmZTI0MmY2ODg4ZDdjJml0YWc9MjQ4JmFpdGFncz0xMzMlMkMxMzQlMkMxMzUlMkMxMzYlMkMxMzclMkMxNjAlMkMyNDIlMkMyNDMlMkMyNDQlMkMyNDclMkMyNDglMkMyNzgmc291cmNlPXlvdXR1YmUmcmVxdWlyZXNzbD15ZXMmbWg9U0EmbW09MzElMkMyOSZtbj1zbi1uNHY3c243cyUyQ3NuLW40djdrbmxrJm1zPWF1JTJDcmR1Jm12PW0mbXZpPTUmcGw9MjMmZ2NyPXVzJmluaXRjd25kYnBzPTExMTI1MCZ2cHJ2PTEmbWltZT12aWRlbyUyRndlYm0mbnM9dllDakpkUFdQTWVjeHhrS3NlXzF4QUFGJmdpcj15ZXMmY2xlbj01MDE0MDM4NyZkdXI9MjIwLjc2MiZsbXQ9MTYwNTY0ODY5MjQyNjI0NSZtdD0xNjA1NjY5ODg1JmZ2aXA9NSZrZWVwYWxpdmU9eWVzJmM9V0VCJnR4cD01NDMyNDM0Jm49blYweDdYZXlodTV4R2ZIJnNwYXJhbXM9ZXhwaXJlJTJDZWklMkNpcCUyQ2lkJTJDYWl0YWdzJTJDc291cmNlJTJDcmVxdWlyZXNzbCUyQ2djciUyQ3ZwcnYlMkNtaW1lJTJDbnMlMkNnaXIlMkNjbGVuJTJDZHVyJTJDbG10JmxzcGFyYW1zPW1oJTJDbW0lMkNtbiUyQ21zJTJDbXYlMkNtdmklMkNwbCUyQ2luaXRjd25kYnBzJmxzaWc9QUczQ194QXdSQUlnUGh1ZklrTzBfZFBSdnFNRFhvRVZsYV9Dbzk1ZkpOYXdwbEM4QWE4eDJCd0NJRVhlOHdnTFJKeUFvZ2xNZmVPak1YTTF0d2hkcnRVWEV3eWowRVZOajFXTSZzaWc9QU9xMFFKOHdSUUloQVA5VDNQNXBCemJpZ3FoaXd2OXVlZjJDMlVoWFlmOHNfbDU2RzFla1VjV25BaUFCU0pSNFdLRlMxS05nUkhjRkUtVGJFRWFiWUtSYlA4YnItcVlzRTczVFFnPT0maG9zdD1yNS0tLXNuLW40djdzbjdzLmdvb2dsZXZpZGVvLmNvbTwvQmFzZVVSTD4KICAgICAgICA8U2VnbWVudEJhc2UgaW5kZXhSYW5nZT0iNzQwLTYyMTc0ODMxIj4KICAgICAgICAgIDxJbml0aWFsaXphdGlvbiByYW5nZT0iMC03NDAiLz4KICAgICAgICA8L1NlZ21lbnRCYXNlPgogICAgICAgIDwvUmVwcmVzZW50YXRpb24+CiAgICA8L0FkYXB0YXRpb25TZXQ+CiAgPC9QZXJpb2Q+CjwvTVBEPgo=",
|
||||
// type: "application/dash+xml",
|
||||
// label: "DASH"
|
||||
// this.video.subtitles.map(subtitle => {
|
||||
// this.player.addRemoteTextTrack({
|
||||
// kind: "captions",
|
||||
// src: subtitle.url.replace("fmt=ttml", "fmt=vtt"),
|
||||
// label: "Track",
|
||||
// language: "en",
|
||||
// type: "captions/captions.vtt"
|
||||
// });
|
||||
// });
|
||||
|
||||
this.video.videoStreams.map(stream =>
|
||||
src.push({
|
||||
src: stream.url,
|
||||
type: stream.mimeType,
|
||||
label: stream.quality,
|
||||
videoOnly: stream.videoOnly
|
||||
})
|
||||
);
|
||||
|
||||
this.video.audioStreams.map(stream =>
|
||||
src.push({
|
||||
src: stream.url,
|
||||
type: stream.mimeType,
|
||||
label: stream.quality
|
||||
})
|
||||
);
|
||||
|
||||
this.video.subtitles.map(subtitle => {
|
||||
this.player.addRemoteTextTrack({
|
||||
kind: "captions",
|
||||
src: subtitle.url.replace("fmt=ttml", "fmt=vtt"),
|
||||
label: "Track",
|
||||
language: "en",
|
||||
type: "captions/captions.vtt"
|
||||
});
|
||||
});
|
||||
|
||||
this.player.src(src);
|
||||
|
||||
const currentSrc = src.filter(
|
||||
src => src.src == this.player.currentSrc()
|
||||
)[0];
|
||||
|
||||
if (currentSrc.videoOnly)
|
||||
if (!this.audioplayer)
|
||||
this.audioplayer = new Audio(
|
||||
this.video.audioStreams.slice(-1)[0].url
|
||||
);
|
||||
else
|
||||
this.audioplayer.src = this.video.audioStreams.slice(
|
||||
-1
|
||||
)[0].url;
|
||||
// this.player.src(src);
|
||||
|
||||
if (noPrevPlayer) {
|
||||
this.player.on("timeupdate", () => {
|
||||
@@ -262,78 +221,29 @@ export default {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.audioplayer) {
|
||||
const delay =
|
||||
this.audioplayer.currentTime -
|
||||
this.player.currentTime(),
|
||||
absdelay = Math.abs(delay);
|
||||
|
||||
console.log(delay);
|
||||
|
||||
if (absdelay > 0.05) {
|
||||
this.audioplayer.currentTime =
|
||||
absdelay > 0.2
|
||||
? this.player.currentTime()
|
||||
: this.player.currentTime() - delay;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.player.on("play", () => {
|
||||
if (this.audioplayer) this.audioplayer.play();
|
||||
});
|
||||
// this.player.on("volumechange", () => {
|
||||
// if (this.audioplayer)
|
||||
// this.audioplayer.volume = this.player.volume();
|
||||
// if (localStorage)
|
||||
// localStorage.setItem(
|
||||
// "volume",
|
||||
// this.player.volume()
|
||||
// );
|
||||
// });
|
||||
|
||||
this.player.on("pause", () => {
|
||||
if (this.audioplayer) {
|
||||
this.audioplayer.currentTime = this.player.currentTime();
|
||||
this.audioplayer.pause();
|
||||
}
|
||||
});
|
||||
|
||||
this.player.on("volumechange", () => {
|
||||
if (this.audioplayer)
|
||||
this.audioplayer.volume = this.player.volume();
|
||||
if (localStorage)
|
||||
localStorage.setItem(
|
||||
"volume",
|
||||
this.player.volume()
|
||||
);
|
||||
});
|
||||
|
||||
this.player.on("ended", () => {
|
||||
if (
|
||||
this.selectedAutoPlay &&
|
||||
this.video.relatedStreams.length > 0
|
||||
)
|
||||
this.$router.push(
|
||||
this.video.relatedStreams[0].url
|
||||
);
|
||||
});
|
||||
// this.player.on("ended", () => {
|
||||
// if (
|
||||
// this.selectedAutoPlay &&
|
||||
// this.video.relatedStreams.length > 0
|
||||
// )
|
||||
// this.$router.push(
|
||||
// this.video.relatedStreams[0].url
|
||||
// );
|
||||
// });
|
||||
}
|
||||
|
||||
if (!noPrevPlayer)
|
||||
this.player
|
||||
.remoteTextTracks()
|
||||
.map(track =>
|
||||
this.player.removeRemoteTextTrack(track)
|
||||
);
|
||||
|
||||
this.video.subtitles.map(subtitle => {
|
||||
this.player.addRemoteTextTrack(
|
||||
{
|
||||
kind: "captions",
|
||||
src: subtitle.url.replace(
|
||||
"fmt=ttml",
|
||||
"fmt=vtt"
|
||||
),
|
||||
label: "Track",
|
||||
type: "captions/captions.vtt"
|
||||
},
|
||||
false
|
||||
).mode = "showing";
|
||||
});
|
||||
|
||||
//const parent = this.player.el().querySelector(".vjs-progress-holder")
|
||||
//TODO: Add sponsors on seekbar: https://github.com/ajayyy/SponsorBlock/blob/e39de9fd852adb9196e0358ed827ad38d9933e29/src/js-components/previewBar.ts#L12
|
||||
});
|
||||
|
@@ -33,6 +33,12 @@ const mixin = {
|
||||
|
||||
return str;
|
||||
|
||||
},
|
||||
fetchJson: function (url, options) {
|
||||
return fetch(url, options)
|
||||
.then(response => {
|
||||
return response.json();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
189
src/utils/DashUtils.js
Normal file
189
src/utils/DashUtils.js
Normal file
@@ -0,0 +1,189 @@
|
||||
// Based of https://github.com/GilgusMaximus/yt-dash-manifest-generator/blob/master/src/DashGenerator.js
|
||||
|
||||
const xml = require('xml-js')
|
||||
|
||||
const DashUtils = {
|
||||
generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
||||
const generatedJSON = this.generate_xmljs_json_from_data(VideoFormats, VideoLength)
|
||||
return xml.json2xml(generatedJSON)
|
||||
},
|
||||
generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
||||
const convertJSON = {
|
||||
"declaration": {
|
||||
"attributes": {
|
||||
"version": "1.0",
|
||||
"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": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "Period",
|
||||
"elements": this.generate_adaptation_set(VideoFormatArray)
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
return convertJSON
|
||||
},
|
||||
generate_adaptation_set(VideoFormatArray) {
|
||||
const adaptationSets = []
|
||||
const mimeTypes = []
|
||||
const mimeObjects = [[]]
|
||||
// sort the formats by mime types
|
||||
VideoFormatArray.forEach((videoFormat) => {
|
||||
// the dual formats should not be used
|
||||
if (videoFormat.mimeType.indexOf("video") != -1 && !videoFormat.videoOnly) {
|
||||
return
|
||||
}
|
||||
// if these properties are not available, then we skip it because we cannot set these properties
|
||||
//if (!(videoFormat.hasOwnProperty('initRange') && videoFormat.hasOwnProperty('indexRange'))) {
|
||||
// return
|
||||
//}
|
||||
const mimeType = videoFormat.mimeType
|
||||
const mimeTypeIndex = mimeTypes.indexOf(mimeType)
|
||||
if (mimeTypeIndex > -1) {
|
||||
mimeObjects[mimeTypeIndex].push(videoFormat)
|
||||
} else {
|
||||
mimeTypes.push(mimeType)
|
||||
mimeObjects.push([])
|
||||
mimeObjects[mimeTypes.length - 1].push(videoFormat)
|
||||
}
|
||||
})
|
||||
// for each MimeType generate a new Adaptation set with Representations as sub elements
|
||||
for (let i = 0; i < mimeTypes.length; i++) {
|
||||
let isVideoFormat = false
|
||||
const adapSet = {
|
||||
"type": "element",
|
||||
"name": "AdaptationSet",
|
||||
"attributes": {
|
||||
"id": i,
|
||||
"mimeType": mimeTypes[i],
|
||||
"startWithSAP": "1",
|
||||
"subsegmentAlignment": "true"
|
||||
},
|
||||
"elements": []
|
||||
}
|
||||
if (!mimeTypes[i].includes("audio")) {
|
||||
adapSet.attributes.scanType = "progressive"
|
||||
isVideoFormat = true
|
||||
}
|
||||
mimeObjects[i].forEach((format) => {
|
||||
if (isVideoFormat) {
|
||||
adapSet.elements.push(this.generate_representation_video(format))
|
||||
} else {
|
||||
adapSet.elements.push(this.generate_representation_audio(format))
|
||||
}
|
||||
})
|
||||
adaptationSets.push(adapSet)
|
||||
}
|
||||
return adaptationSets
|
||||
}, generate_representation_audio(Format) {
|
||||
const representation =
|
||||
{
|
||||
"type": "element",
|
||||
"name": "Representation",
|
||||
"attributes": {
|
||||
"id": Format.itag,
|
||||
"codecs": Format.codec,
|
||||
"bandwidth": Format.bitrate
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "AudioChannelConfiguration",
|
||||
"attributes": {
|
||||
"schemeIdUri": "urn:mpeg:dash:23003:3:audio_channel_configuration:2011",
|
||||
"value": "2"
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "BaseURL",
|
||||
"elements": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": Format.url
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "SegmentBase",
|
||||
"attributes": {
|
||||
"indexRange": `${Format.indexStart}-${Format.indexEnd}`
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "Initialization",
|
||||
"attributes": {
|
||||
"range": `${Format.initStart}-${Format.initEnd}`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
return representation
|
||||
},
|
||||
generate_representation_video(Format) {
|
||||
const representation =
|
||||
{
|
||||
"type": "element",
|
||||
"name": "Representation",
|
||||
"attributes": {
|
||||
"id": Format.itag,
|
||||
"codecs": Format.codec,
|
||||
"bandwidth": Format.bitrate,
|
||||
"width": Format.width,
|
||||
"height": Format.height,
|
||||
"maxPlayoutRate": "1",
|
||||
"frameRate": Format.fps
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "BaseURL",
|
||||
"elements": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": Format.url
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "SegmentBase",
|
||||
"attributes": {
|
||||
"indexRange": `${Format.indexStart}-${Format.indexEnd}`
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "Initialization",
|
||||
"attributes": {
|
||||
"range": `${Format.initStart}-${Format.initEnd}`
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
return representation
|
||||
}
|
||||
}
|
||||
|
||||
export default DashUtils;
|
Reference in New Issue
Block a user