mirror of
https://github.com/TeamPiped/Piped.git
synced 2025-01-09 14:26:59 +00:00
Merge remote-tracking branch 'origin/master' into toast
This commit is contained in:
commit
defefed9ed
@ -143,6 +143,7 @@ Contributions in any other form are also welcomed.
|
|||||||
- [Hyperpipe](https://codeberg.org/Hyperpipe/Hyperpipe) - an alternative privacy respecting frontend for YouTube Music.
|
- [Hyperpipe](https://codeberg.org/Hyperpipe/Hyperpipe) - an alternative privacy respecting frontend for YouTube Music.
|
||||||
- [Musicale](https://github.com/Bellisario/musicale) - an alternative to YouTube Music, with style.
|
- [Musicale](https://github.com/Bellisario/musicale) - an alternative to YouTube Music, with style.
|
||||||
- [ytify](https://github.com/n-ce/ytify) - a complementary minimal audio streaming frontend for YouTube.
|
- [ytify](https://github.com/n-ce/ytify) - a complementary minimal audio streaming frontend for YouTube.
|
||||||
|
- [PsTube](https://github.com/prateekmedia/pstube) - Watch and download videos without ads
|
||||||
|
|
||||||
## YourKit
|
## YourKit
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ server {
|
|||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
|
error_log off;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<link title="Piped" type="application/opensearchdescription+xml" rel="search" href="/opensearch.xml" />
|
<link title="Piped" type="application/opensearchdescription+xml" rel="search" href="/opensearch.xml" />
|
||||||
<title>Piped</title>
|
<title>Piped</title>
|
||||||
|
<meta name="theme-color" content="#0f0f0f">
|
||||||
<meta property="og:title" content="Piped" />
|
<meta property="og:title" content="Piped" />
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta property="og:image" content="/img/icons/favicon-32x32.png" />
|
<meta property="og:image" content="/img/icons/favicon-32x32.png" />
|
||||||
|
26
package.json
26
package.json
@ -14,11 +14,11 @@
|
|||||||
"@fortawesome/free-solid-svg-icons": "6.3.0",
|
"@fortawesome/free-solid-svg-icons": "6.3.0",
|
||||||
"@fortawesome/vue-fontawesome": "3.0.3",
|
"@fortawesome/vue-fontawesome": "3.0.3",
|
||||||
"buffer": "6.0.3",
|
"buffer": "6.0.3",
|
||||||
"dompurify": "3.0.0",
|
"dompurify": "3.0.1",
|
||||||
"hotkeys-js": "3.10.1",
|
"hotkeys-js": "3.10.1",
|
||||||
"javascript-time-ago": "2.5.9",
|
"javascript-time-ago": "2.5.9",
|
||||||
"mux.js": "6.3.0",
|
"mux.js": "6.3.0",
|
||||||
"shaka-player": "4.3.4",
|
"shaka-player": "4.3.5",
|
||||||
"stream-browserify": "3.0.0",
|
"stream-browserify": "3.0.0",
|
||||||
"vue": "3.2.47",
|
"vue": "3.2.47",
|
||||||
"vue-i18n": "9.2.2",
|
"vue-i18n": "9.2.2",
|
||||||
@ -26,22 +26,22 @@
|
|||||||
"xml-js": "1.6.11"
|
"xml-js": "1.6.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify/json": "2.2.27",
|
"@iconify/json": "2.2.35",
|
||||||
"@intlify/vite-plugin-vue-i18n": "6.0.3",
|
"@intlify/vite-plugin-vue-i18n": "6.0.3",
|
||||||
"@unocss/preset-icons": "0.50.0",
|
"@unocss/preset-icons": "0.50.6",
|
||||||
"@unocss/preset-web-fonts": "0.50.0",
|
"@unocss/preset-web-fonts": "0.50.6",
|
||||||
"@unocss/transformer-directives": "0.50.0",
|
"@unocss/transformer-directives": "0.50.6",
|
||||||
"@unocss/transformer-variant-group": "0.50.0",
|
"@unocss/transformer-variant-group": "0.50.6",
|
||||||
"@vitejs/plugin-legacy": "4.0.1",
|
"@vitejs/plugin-legacy": "4.0.2",
|
||||||
"@vitejs/plugin-vue": "4.0.0",
|
"@vitejs/plugin-vue": "4.1.0",
|
||||||
"@vue/compiler-sfc": "3.2.47",
|
"@vue/compiler-sfc": "3.2.47",
|
||||||
"eslint": "8.34.0",
|
"eslint": "8.36.0",
|
||||||
"eslint-config-prettier": "8.6.0",
|
"eslint-config-prettier": "8.7.0",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
"eslint-plugin-vue": "9.9.0",
|
"eslint-plugin-vue": "9.9.0",
|
||||||
"prettier": "2.8.4",
|
"prettier": "2.8.4",
|
||||||
"unocss": "0.50.0",
|
"unocss": "0.50.6",
|
||||||
"vite": "4.1.4",
|
"vite": "4.2.0",
|
||||||
"vite-plugin-eslint": "1.8.1",
|
"vite-plugin-eslint": "1.8.1",
|
||||||
"vite-plugin-pwa": "0.14.4"
|
"vite-plugin-pwa": "0.14.4"
|
||||||
},
|
},
|
||||||
|
13
src/App.vue
13
src/App.vue
@ -1,12 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="w-full min-h-screen px-1vw py-5 reset" :class="[theme]">
|
<div class="flex flex-col w-full min-h-screen px-1vw py-5 reset" :class="[theme]">
|
||||||
|
<div class="flex-1">
|
||||||
<NavBar />
|
<NavBar />
|
||||||
|
|
||||||
<router-view v-slot="{ Component }">
|
<router-view v-slot="{ Component }">
|
||||||
<keep-alive :max="5">
|
<keep-alive :max="5">
|
||||||
<component :is="Component" :key="$route.fullPath" />
|
<component :is="Component" :key="$route.fullPath" />
|
||||||
</keep-alive>
|
</keep-alive>
|
||||||
</router-view>
|
</router-view>
|
||||||
|
</div>
|
||||||
|
|
||||||
<FooterComponent />
|
<FooterComponent />
|
||||||
</div>
|
</div>
|
||||||
@ -34,6 +35,14 @@ export default {
|
|||||||
if (themePref == "auto") this.theme = darkModePreference.matches ? "dark" : "light";
|
if (themePref == "auto") this.theme = darkModePreference.matches ? "dark" : "light";
|
||||||
else this.theme = themePref;
|
else this.theme = themePref;
|
||||||
|
|
||||||
|
// Change title bar color based on user's theme
|
||||||
|
const themeColor = document.querySelector("meta[name='theme-color']");
|
||||||
|
if (this.theme === "light") {
|
||||||
|
themeColor.setAttribute("content", "#FFF");
|
||||||
|
} else {
|
||||||
|
themeColor.setAttribute("content", "#0F0F0F");
|
||||||
|
}
|
||||||
|
|
||||||
// Used for the scrollbar
|
// Used for the scrollbar
|
||||||
const root = document.querySelector(":root");
|
const root = document.querySelector(":root");
|
||||||
this.theme == "dark" ? root.classList.add("dark") : root.classList.remove("dark");
|
this.theme == "dark" ? root.classList.add("dark") : root.classList.remove("dark");
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<ErrorHandler v-if="channel && channel.error" :message="channel.message" :error="channel.error" />
|
<ErrorHandler v-if="channel && channel.error" :message="channel.message" :error="channel.error" />
|
||||||
|
|
||||||
<div v-if="channel" v-show="!channel.error">
|
<LoadingIndicatorPage :show-content="channel != null && !channel.error">
|
||||||
<div class="flex justify-center place-items-center">
|
<img
|
||||||
|
v-if="channel.bannerUrl"
|
||||||
|
:src="channel.bannerUrl"
|
||||||
|
class="w-full py-1.5 h-30 md:h-50 object-cover"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<div class="flex flex-col md:flex-row justify-between items-center">
|
||||||
|
<div class="flex place-items-center">
|
||||||
<img height="48" width="48" class="rounded-full m-1" :src="channel.avatarUrl" />
|
<img height="48" width="48" class="rounded-full m-1" :src="channel.avatarUrl" />
|
||||||
<h1 v-text="channel.name" />
|
<div class="flex gap-1 items-center">
|
||||||
<font-awesome-icon class="ml-1.5 !text-3xl" v-if="channel.verified" icon="check" />
|
<h1 v-text="channel.name" class="!text-xl" />
|
||||||
|
<font-awesome-icon class="!text-xl" v-if="channel.verified" icon="check" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img v-if="channel.bannerUrl" :src="channel.bannerUrl" class="w-full pb-1.5" loading="lazy" />
|
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
|
||||||
<p class="whitespace-pre-wrap">
|
|
||||||
<span v-html="purifyHTML(rewriteDescription(channel.description))" />
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
<button
|
<button
|
||||||
class="btn"
|
class="btn"
|
||||||
@click="subscribeHandler"
|
@click="subscribeHandler"
|
||||||
@ -30,14 +35,30 @@
|
|||||||
v-if="channel.id"
|
v-if="channel.id"
|
||||||
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${channel.id}`"
|
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${channel.id}`"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="btn flex-col mx-3"
|
class="btn flex-col"
|
||||||
>
|
>
|
||||||
<font-awesome-icon icon="rss" />
|
<font-awesome-icon icon="rss" />
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
|
<div v-if="channel.description" class="whitespace-pre-wrap py-2 mx-1">
|
||||||
|
<span v-if="fullDescription" v-html="purifyHTML(rewriteDescription(channel.description))" />
|
||||||
|
<span v-html="purifyHTML(rewriteDescription(channel.description.slice(0, 100)))" v-else />
|
||||||
|
<span v-if="channel.description.length > 100 && !fullDescription">...</span>
|
||||||
|
<button
|
||||||
|
v-if="channel.description.length > 100"
|
||||||
|
class="hover:underline font-semibold text-neutral-500 block whitespace-normal"
|
||||||
|
@click="fullDescription = !fullDescription"
|
||||||
|
>
|
||||||
|
[{{ fullDescription ? $t("actions.show_less") : $t("actions.show_more") }}]
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<WatchOnYouTubeButton :link="`https://youtube.com/channel/${this.channel.id}`" />
|
<WatchOnYouTubeButton :link="`https://youtube.com/channel/${this.channel.id}`" />
|
||||||
|
|
||||||
<div class="flex mt-4 mb-2">
|
<div class="flex my-2 mx-1">
|
||||||
<button
|
<button
|
||||||
v-for="(tab, index) in tabs"
|
v-for="(tab, index) in tabs"
|
||||||
:key="tab.name"
|
:key="tab.name"
|
||||||
@ -61,19 +82,21 @@
|
|||||||
hide-channel
|
hide-channel
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</LoadingIndicatorPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ErrorHandler from "./ErrorHandler.vue";
|
import ErrorHandler from "./ErrorHandler.vue";
|
||||||
import ContentItem from "./ContentItem.vue";
|
import ContentItem from "./ContentItem.vue";
|
||||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||||
|
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
ContentItem,
|
ContentItem,
|
||||||
WatchOnYouTubeButton,
|
WatchOnYouTubeButton,
|
||||||
|
LoadingIndicatorPage,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -82,6 +105,7 @@ export default {
|
|||||||
tabs: [],
|
tabs: [],
|
||||||
selectedTab: 0,
|
selectedTab: 0,
|
||||||
contentItems: [],
|
contentItems: [],
|
||||||
|
fullDescription: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -121,7 +145,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
async fetchChannel() {
|
async fetchChannel() {
|
||||||
const url = this.apiUrl() + "/" + this.$route.params.path + "/" + this.$route.params.channelId;
|
const url = this.$route.path.includes("@")
|
||||||
|
? this.apiUrl() + "/c/" + this.$route.params.channelId
|
||||||
|
: this.apiUrl() + "/" + this.$route.params.path + "/" + this.$route.params.channelId;
|
||||||
return await this.fetchJson(url);
|
return await this.fetchJson(url);
|
||||||
},
|
},
|
||||||
async getChannelData() {
|
async getChannelData() {
|
||||||
|
@ -24,27 +24,29 @@
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="video-grid">
|
<LoadingIndicatorPage :show-content="videosStore != null" class="video-grid">
|
||||||
<template v-for="video in videos" :key="video.url">
|
<template v-for="video in videos" :key="video.url">
|
||||||
<VideoItem v-if="shouldShowVideo(video)" :is-feed="true" :item="video" />
|
<VideoItem v-if="shouldShowVideo(video)" :is-feed="true" :item="video" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</LoadingIndicatorPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import VideoItem from "./VideoItem.vue";
|
import VideoItem from "./VideoItem.vue";
|
||||||
import SortingSelector from "./SortingSelector.vue";
|
import SortingSelector from "./SortingSelector.vue";
|
||||||
|
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
VideoItem,
|
VideoItem,
|
||||||
SortingSelector,
|
SortingSelector,
|
||||||
|
LoadingIndicatorPage,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentVideoCount: 0,
|
currentVideoCount: 0,
|
||||||
videoStep: 100,
|
videoStep: 100,
|
||||||
videosStore: [],
|
videosStore: null,
|
||||||
videos: [],
|
videos: [],
|
||||||
availableFilters: ["all", "shorts", "videos"],
|
availableFilters: ["all", "shorts", "videos"],
|
||||||
selectedFilter: "all",
|
selectedFilter: "all",
|
||||||
|
55
src/components/LoadingIndicatorPage.vue
Normal file
55
src/components/LoadingIndicatorPage.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="!showContent" class="flex min-h-[75vh] w-full justify-center items-center">
|
||||||
|
<span id="spinner" />
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#spinner:after {
|
||||||
|
--spinner-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark #spinner:after {
|
||||||
|
--spinner-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#spinner {
|
||||||
|
display: inline-block;
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
#spinner:after {
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
width: 54px;
|
||||||
|
height: 54px;
|
||||||
|
margin: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4px solid var(--spinner-color);
|
||||||
|
border-color: var(--spinner-color) transparent var(--spinner-color) transparent;
|
||||||
|
animation: spinner 1.2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spinner {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
showContent: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<ErrorHandler v-if="playlist && playlist.error" :message="playlist.message" :error="playlist.error" />
|
<ErrorHandler v-if="playlist && playlist.error" :message="playlist.message" :error="playlist.error" />
|
||||||
|
|
||||||
<div v-if="playlist" v-show="!playlist.error">
|
<LoadingIndicatorPage :show-content="playlist" v-show="!playlist.error">
|
||||||
<h1 class="text-center my-4" v-text="playlist.name" />
|
<h1 class="text-center my-4" v-text="playlist.name" />
|
||||||
|
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
@ -46,11 +46,12 @@
|
|||||||
width="168"
|
width="168"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</LoadingIndicatorPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ErrorHandler from "./ErrorHandler.vue";
|
import ErrorHandler from "./ErrorHandler.vue";
|
||||||
|
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||||
import VideoItem from "./VideoItem.vue";
|
import VideoItem from "./VideoItem.vue";
|
||||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||||
|
|
||||||
@ -59,6 +60,7 @@ export default {
|
|||||||
ErrorHandler,
|
ErrorHandler,
|
||||||
VideoItem,
|
VideoItem,
|
||||||
WatchOnYouTubeButton,
|
WatchOnYouTubeButton,
|
||||||
|
LoadingIndicatorPage,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -88,7 +90,7 @@ export default {
|
|||||||
},
|
},
|
||||||
}).then(json => {
|
}).then(json => {
|
||||||
if (json.error) alert(json.error);
|
if (json.error) alert(json.error);
|
||||||
else if (json.filter(playlist => playlist.id === playlistId).length > 0) this.admin = true;
|
else if (json.some(playlist => playlist.id === playlistId)) this.admin = true;
|
||||||
});
|
});
|
||||||
this.isPlaylistBookmarked();
|
this.isPlaylistBookmarked();
|
||||||
},
|
},
|
||||||
|
@ -376,6 +376,7 @@ export default {
|
|||||||
languages: [
|
languages: [
|
||||||
{ code: "ar", name: "Arabic" },
|
{ code: "ar", name: "Arabic" },
|
||||||
{ code: "az", name: "Azərbaycan" },
|
{ code: "az", name: "Azərbaycan" },
|
||||||
|
{ code: "bg", name: "Български" },
|
||||||
{ code: "bn", name: "বাংলা" },
|
{ code: "bn", name: "বাংলা" },
|
||||||
{ code: "bs", name: "Bosanski" },
|
{ code: "bs", name: "Bosanski" },
|
||||||
{ code: "ca", name: "Català" },
|
{ code: "ca", name: "Català" },
|
||||||
@ -436,7 +437,7 @@ export default {
|
|||||||
|
|
||||||
this.fetchJson("https://piped-instances.kavin.rocks/").then(resp => {
|
this.fetchJson("https://piped-instances.kavin.rocks/").then(resp => {
|
||||||
this.instances = resp;
|
this.instances = resp;
|
||||||
if (this.instances.filter(instance => instance.api_url == this.apiUrl()).length == 0)
|
if (!this.instances.some(instance => instance.api_url == this.apiUrl()))
|
||||||
this.instances.push({
|
this.instances.push({
|
||||||
name: "Custom Instance",
|
name: "Custom Instance",
|
||||||
api_url: this.apiUrl(),
|
api_url: this.apiUrl(),
|
||||||
@ -615,4 +616,10 @@ export default {
|
|||||||
.pref {
|
.pref {
|
||||||
@apply flex justify-between items-center my-2 mx-[15vw] lt-md:mx-[2vw];
|
@apply flex justify-between items-center my-2 mx-[15vw] lt-md:mx-[2vw];
|
||||||
}
|
}
|
||||||
|
.pref:nth-child(odd) {
|
||||||
|
@apply bg-gray-200;
|
||||||
|
}
|
||||||
|
.dark .pref:nth-child(odd) {
|
||||||
|
@apply bg-dark-800;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -18,19 +18,21 @@
|
|||||||
</i18n-t>
|
</i18n-t>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="results" class="video-grid">
|
<LoadingIndicatorPage :show-content="results != null && results.items?.length" class="video-grid">
|
||||||
<template v-for="result in results.items" :key="result.url">
|
<template v-for="result in results.items" :key="result.url">
|
||||||
<ContentItem :item="result" height="94" width="168" />
|
<ContentItem :item="result" height="94" width="168" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</LoadingIndicatorPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ContentItem from "./ContentItem.vue";
|
import ContentItem from "./ContentItem.vue";
|
||||||
|
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ContentItem,
|
ContentItem,
|
||||||
|
LoadingIndicatorPage,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -3,17 +3,19 @@
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="video-grid">
|
<LoadingIndicatorPage :show-content="videos.length != 0" class="video-grid">
|
||||||
<VideoItem v-for="video in videos" :key="video.url" :item="video" height="118" width="210" />
|
<VideoItem v-for="video in videos" :key="video.url" :item="video" height="118" width="210" />
|
||||||
</div>
|
</LoadingIndicatorPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||||
import VideoItem from "./VideoItem.vue";
|
import VideoItem from "./VideoItem.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
VideoItem,
|
VideoItem,
|
||||||
|
LoadingIndicatorPage,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
>
|
>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<img
|
<img
|
||||||
class="w-full aspect-video"
|
class="w-full aspect-video object-contain"
|
||||||
:src="item.thumbnail"
|
:src="item.thumbnail"
|
||||||
:alt="item.title"
|
:alt="item.title"
|
||||||
:class="{ 'shorts-img': item.isShort }"
|
:class="{ 'shorts-img': item.isShort, 'opacity-75': item.watched }"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<!-- progress bar -->
|
<!-- progress bar -->
|
||||||
|
@ -92,7 +92,7 @@ export default {
|
|||||||
this.hotkeysPromise.then(() => {
|
this.hotkeysPromise.then(() => {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.$hotkeys(
|
this.$hotkeys(
|
||||||
"f,m,j,k,l,c,space,up,down,left,right,0,1,2,3,4,5,6,7,8,9,shift+n,shift+,,shift+.,return",
|
"f,m,j,k,l,c,space,up,down,left,right,0,1,2,3,4,5,6,7,8,9,shift+n,shift+,,shift+.,return,.,,",
|
||||||
function (e, handler) {
|
function (e, handler) {
|
||||||
const videoEl = self.$refs.videoEl;
|
const videoEl = self.$refs.videoEl;
|
||||||
switch (handler.key) {
|
switch (handler.key) {
|
||||||
@ -191,6 +191,14 @@ export default {
|
|||||||
case "return":
|
case "return":
|
||||||
self.skipSegment(videoEl);
|
self.skipSegment(videoEl);
|
||||||
break;
|
break;
|
||||||
|
case ".":
|
||||||
|
videoEl.currentTime += 0.04;
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
|
case ",":
|
||||||
|
videoEl.currentTime -= 0.04;
|
||||||
|
e.preventDefault();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -206,6 +214,8 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadVideo() {
|
async loadVideo() {
|
||||||
|
this.updateSponsors();
|
||||||
|
|
||||||
const component = this;
|
const component = this;
|
||||||
const videoEl = this.$refs.videoEl;
|
const videoEl = this.$refs.videoEl;
|
||||||
|
|
||||||
@ -263,9 +273,7 @@ export default {
|
|||||||
|
|
||||||
const MseSupport = window.MediaSource !== undefined;
|
const MseSupport = window.MediaSource !== undefined;
|
||||||
|
|
||||||
const lbry = this.getPreferenceBoolean("disableLBRY", false)
|
const lbry = null;
|
||||||
? null
|
|
||||||
: this.video.videoStreams.filter(stream => stream.quality === "LBRY")[0];
|
|
||||||
|
|
||||||
var uri;
|
var uri;
|
||||||
var mime;
|
var mime;
|
||||||
@ -275,9 +283,10 @@ export default {
|
|||||||
mime = "application/x-mpegURL";
|
mime = "application/x-mpegURL";
|
||||||
} else if (this.video.audioStreams.length > 0 && !lbry && MseSupport) {
|
} else if (this.video.audioStreams.length > 0 && !lbry && MseSupport) {
|
||||||
if (!this.video.dash) {
|
if (!this.video.dash) {
|
||||||
const dash = (
|
const dash = (await import("../utils/DashUtils.js")).generate_dash_file_from_formats(
|
||||||
await import("@/utils/DashUtils.js").then(mod => mod.default)
|
streams,
|
||||||
).generate_dash_file_from_formats(streams, this.video.duration);
|
this.video.duration,
|
||||||
|
);
|
||||||
|
|
||||||
uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(dash);
|
uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(dash);
|
||||||
} else {
|
} else {
|
||||||
@ -313,7 +322,7 @@ export default {
|
|||||||
uri = this.video.hls;
|
uri = this.video.hls;
|
||||||
mime = "application/x-mpegURL";
|
mime = "application/x-mpegURL";
|
||||||
} else {
|
} else {
|
||||||
uri = this.video.videoStreams.filter(stream => stream.codec == null).slice(-1)[0].url;
|
uri = this.video.videoStreams.findLast(stream => stream.codec == null).url;
|
||||||
mime = "video/mp4";
|
mime = "video/mp4";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,6 +372,9 @@ export default {
|
|||||||
else this.setPlayerAttrs(this.$player, videoEl, uri, mime, this.$shaka);
|
else this.setPlayerAttrs(this.$player, videoEl, uri, mime, this.$shaka);
|
||||||
|
|
||||||
if (noPrevPlayer) {
|
if (noPrevPlayer) {
|
||||||
|
videoEl.addEventListener("loadeddata", () => {
|
||||||
|
if (document.pictureInPictureElement) videoEl.requestPictureInPicture();
|
||||||
|
});
|
||||||
videoEl.addEventListener("timeupdate", () => {
|
videoEl.addEventListener("timeupdate", () => {
|
||||||
const time = videoEl.currentTime;
|
const time = videoEl.currentTime;
|
||||||
this.$emit("timeupdate", time);
|
this.$emit("timeupdate", time);
|
||||||
@ -647,22 +659,7 @@ export default {
|
|||||||
|
|
||||||
if (markers) markers.style.background = `linear-gradient(${array.join(",")})`;
|
if (markers) markers.style.background = `linear-gradient(${array.join(",")})`;
|
||||||
},
|
},
|
||||||
destroy(hotkeys) {
|
updateSponsors() {
|
||||||
if (this.$ui) {
|
|
||||||
this.$ui.destroy();
|
|
||||||
this.$ui = undefined;
|
|
||||||
this.$player = undefined;
|
|
||||||
}
|
|
||||||
if (this.$player) {
|
|
||||||
this.$player.destroy();
|
|
||||||
this.$player = undefined;
|
|
||||||
}
|
|
||||||
if (hotkeys) this.$hotkeys?.unbind();
|
|
||||||
this.$refs.container?.querySelectorAll("div").forEach(node => node.remove());
|
|
||||||
},
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
sponsors() {
|
|
||||||
const skipOptions = this.getPreferenceJSON("skipOptions", {});
|
const skipOptions = this.getPreferenceJSON("skipOptions", {});
|
||||||
this.sponsors?.segments?.forEach(segment => {
|
this.sponsors?.segments?.forEach(segment => {
|
||||||
const option = skipOptions[segment.category];
|
const option = skipOptions[segment.category];
|
||||||
@ -674,6 +671,19 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
destroy(hotkeys) {
|
||||||
|
if (this.$ui && !document.pictureInPictureElement) {
|
||||||
|
this.$ui.destroy();
|
||||||
|
this.$ui = undefined;
|
||||||
|
this.$player = undefined;
|
||||||
|
}
|
||||||
|
if (this.$player) {
|
||||||
|
this.$player.destroy();
|
||||||
|
if (!document.pictureInPictureElement) this.$player = undefined;
|
||||||
|
}
|
||||||
|
if (hotkeys) this.$hotkeys?.unbind();
|
||||||
|
this.$refs.container?.querySelectorAll("div").forEach(node => node.remove());
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="video && !isEmbed" class="w-full">
|
<LoadingIndicatorPage :show-content="video && !isEmbed" class="w-full">
|
||||||
<ErrorHandler v-if="video && video.error" :message="video.message" :error="video.error" />
|
<ErrorHandler v-if="video && video.error" :message="video.message" :error="video.error" />
|
||||||
<Transition>
|
<Transition>
|
||||||
<ToastComponent v-if="shouldShowToast" @dismissed="dismiss">
|
<ToastComponent v-if="shouldShowToast" @dismissed="dismiss">
|
||||||
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
<div v-show="!video.error">
|
<div v-show="!video.error">
|
||||||
<div :class="isMobile ? 'flex-col' : 'flex'">
|
<div :class="isMobile ? 'flex-col' : 'flex'">
|
||||||
|
<keep-alive>
|
||||||
<VideoPlayer
|
<VideoPlayer
|
||||||
ref="videoPlayer"
|
ref="videoPlayer"
|
||||||
:video="video"
|
:video="video"
|
||||||
@ -29,6 +30,7 @@
|
|||||||
@timeupdate="onTimeUpdate"
|
@timeupdate="onTimeUpdate"
|
||||||
@ended="onVideoEnded"
|
@ended="onVideoEnded"
|
||||||
/>
|
/>
|
||||||
|
</keep-alive>
|
||||||
<ChaptersBar
|
<ChaptersBar
|
||||||
:mobileLayout="isMobile"
|
:mobileLayout="isMobile"
|
||||||
v-if="video?.chapters?.length > 0 && showChapters"
|
v-if="video?.chapters?.length > 0 && showChapters"
|
||||||
@ -219,7 +221,7 @@
|
|||||||
<hr class="sm:hidden" />
|
<hr class="sm:hidden" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</LoadingIndicatorPage>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -232,6 +234,7 @@ import PlaylistAddModal from "./PlaylistAddModal.vue";
|
|||||||
import ShareModal from "./ShareModal.vue";
|
import ShareModal from "./ShareModal.vue";
|
||||||
import PlaylistVideos from "./PlaylistVideos.vue";
|
import PlaylistVideos from "./PlaylistVideos.vue";
|
||||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||||
|
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||||
import ToastComponent from "./ToastComponent.vue";
|
import ToastComponent from "./ToastComponent.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -246,14 +249,13 @@ export default {
|
|||||||
ShareModal,
|
ShareModal,
|
||||||
PlaylistVideos,
|
PlaylistVideos,
|
||||||
WatchOnYouTubeButton,
|
WatchOnYouTubeButton,
|
||||||
|
LoadingIndicatorPage,
|
||||||
ToastComponent,
|
ToastComponent,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
||||||
return {
|
return {
|
||||||
video: {
|
video: null,
|
||||||
title: "Loading...",
|
|
||||||
},
|
|
||||||
playlistId: null,
|
playlistId: null,
|
||||||
playlist: null,
|
playlist: null,
|
||||||
index: null,
|
index: null,
|
||||||
@ -361,7 +363,7 @@ export default {
|
|||||||
this.showDesc = !this.getPreferenceBoolean("minimizeDescription", false);
|
this.showDesc = !this.getPreferenceBoolean("minimizeDescription", false);
|
||||||
this.showRecs = !this.getPreferenceBoolean("minimizeRecommendations", false);
|
this.showRecs = !this.getPreferenceBoolean("minimizeRecommendations", false);
|
||||||
this.showChapters = !this.getPreferenceBoolean("minimizeChapters", false);
|
this.showChapters = !this.getPreferenceBoolean("minimizeChapters", false);
|
||||||
if (this.video.duration) {
|
if (this.video?.duration) {
|
||||||
document.title = this.video.title + " - Piped";
|
document.title = this.video.title + " - Piped";
|
||||||
this.$refs.videoPlayer.loadVideo();
|
this.$refs.videoPlayer.loadVideo();
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
"login": "تسجيل الدخول",
|
"login": "تسجيل الدخول",
|
||||||
"register": "إنشاء حساب",
|
"register": "إنشاء حساب",
|
||||||
"preferences": "الإعدادات",
|
"preferences": "الإعدادات",
|
||||||
"history": "تاريخ التصفح",
|
"history": "سجل المشاهدة",
|
||||||
"subscriptions": "الاشتراكات",
|
"subscriptions": "الاشتراكات",
|
||||||
"playlists": "قوائم التشغيل",
|
"playlists": "قوائم التشغيل",
|
||||||
"feed": "التغذية",
|
"feed": "محتوى الاشتراكات",
|
||||||
"account": "الحساب",
|
"account": "الحساب",
|
||||||
"instance": "الخادم",
|
"instance": "الخادم",
|
||||||
"player": "المشغل",
|
"player": "المشغل",
|
||||||
@ -127,7 +127,8 @@
|
|||||||
"skip_button_only": "إظهار زر التخطي",
|
"skip_button_only": "إظهار زر التخطي",
|
||||||
"skip_automatically": "تلقائيا",
|
"skip_automatically": "تلقائيا",
|
||||||
"min_segment_length": "الحد الأدنى لطول الفصل (بالثواني)",
|
"min_segment_length": "الحد الأدنى لطول الفصل (بالثواني)",
|
||||||
"skip_segment": "تخطي الجزء"
|
"skip_segment": "تخطي الجزء",
|
||||||
|
"show_less": "عرض أقل"
|
||||||
},
|
},
|
||||||
"video": {
|
"video": {
|
||||||
"sponsor_segments": "المقاطع الإعلانية",
|
"sponsor_segments": "المقاطع الإعلانية",
|
||||||
|
168
src/locales/bg.json
Normal file
168
src/locales/bg.json
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
{
|
||||||
|
"titles": {
|
||||||
|
"channels": "Канали",
|
||||||
|
"login": "Вход",
|
||||||
|
"register": "Регистрация",
|
||||||
|
"feed": "Абонаменти",
|
||||||
|
"history": "История",
|
||||||
|
"playlists": "Плейлисти",
|
||||||
|
"instance": "Инстанция",
|
||||||
|
"player": "Плейър",
|
||||||
|
"livestreams": "Излъчвания на живо",
|
||||||
|
"bookmarks": "Отметки",
|
||||||
|
"trending": "Набиращи популярност",
|
||||||
|
"account": "Профил",
|
||||||
|
"preferences": "Настройки",
|
||||||
|
"subscriptions": "Абонаменти"
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"most_recent": "Най-скорошен",
|
||||||
|
"unsubscribe": "Отписване - {count}",
|
||||||
|
"uses_api_from": "Използва API от ",
|
||||||
|
"skip_sponsors": "Пропускане на спонсори",
|
||||||
|
"skip_preview": "Пропускане на преглед/обобщение",
|
||||||
|
"skip_self_promo": "Пропускане на самореклама/неплатена реклама",
|
||||||
|
"min_segment_length": "Минимална дължина на сегмента (в секунди)",
|
||||||
|
"default_quality": "Качество по подразбиране",
|
||||||
|
"minimize_comments_default": "Минимизиране на коментарите по подразбиране",
|
||||||
|
"subscribe": "Абониране - {count}",
|
||||||
|
"view_subscriptions": "Преглед на абонаменти",
|
||||||
|
"sort_by": "Сортиране по:",
|
||||||
|
"least_recent": "Най-малко скорошен",
|
||||||
|
"channel_name_asc": "Име на канал (А-Я)",
|
||||||
|
"channel_name_desc": "Име на канал (Я-А)",
|
||||||
|
"back": "Назад",
|
||||||
|
"enable_sponsorblock": "Активиране на SponsorBlock",
|
||||||
|
"skip_button_only": "Показване на бутона за пропускане",
|
||||||
|
"skip_automatically": "Автоматично",
|
||||||
|
"skip_intro": "Пропускане на прекъсване/въвеждаща анимация",
|
||||||
|
"skip_outro": "Пропускане на крайни карти/надписи",
|
||||||
|
"skip_interaction": "Пропускане на напомняне за абониране",
|
||||||
|
"skip_non_music": "Попускане Немузикален раздел в музика",
|
||||||
|
"skip_highlight": "Пропускане на видео акцент",
|
||||||
|
"show_markers": "Показване на маркери в плейъра",
|
||||||
|
"skip_segment": "Пропускане на сегмент",
|
||||||
|
"theme": "Тема",
|
||||||
|
"auto": "Автоматично",
|
||||||
|
"dark": "Тъмна",
|
||||||
|
"light": "Светла",
|
||||||
|
"autoplay_video": "Автоматично пускане на видео",
|
||||||
|
"audio_only": "Само аудио",
|
||||||
|
"buffering_goal": "Буфериране (в секунди)",
|
||||||
|
"country_selection": "Избор на държава",
|
||||||
|
"default_homepage": "Начална страница по подразбиране",
|
||||||
|
"minimize_description_default": "Минимизиране на описанието по подразбиране",
|
||||||
|
"store_watch_history": "Запазване на историята на гледане",
|
||||||
|
"language_selection": "Избор на език",
|
||||||
|
"instances_list": "Списък на инстанциите",
|
||||||
|
"enabled_codecs": "Разрешени кодеци (множество)",
|
||||||
|
"instance_selection": "Избор на инстанция",
|
||||||
|
"show_more": "Покажи повече",
|
||||||
|
"yes": "Да",
|
||||||
|
"no": "Не",
|
||||||
|
"export_to_json": "Експорт в JSON",
|
||||||
|
"import_from_json": "Импорт от JSON/CSV",
|
||||||
|
"loop_this_video": "Повтаряне на това видео",
|
||||||
|
"auto_play_next_video": "Автоматично пускане на следващото видео",
|
||||||
|
"donations": "Дарения за разработка",
|
||||||
|
"minimize_comments": "Минимизиране на коментарите",
|
||||||
|
"show_comments": "Показване на коментарите",
|
||||||
|
"show_description": "Показване на описание",
|
||||||
|
"search": "Търси",
|
||||||
|
"minimize_description": "Минимизиране на описание",
|
||||||
|
"filter": "Филтър",
|
||||||
|
"clear_history": "Изчистване на историята",
|
||||||
|
"minimize_recommendations": "Минимизиране на препоръчани",
|
||||||
|
"show_recommendations": "Показване на препоръчани",
|
||||||
|
"view_ssl_score": "Преглед на SSL резултат",
|
||||||
|
"loading": "Зареждане...",
|
||||||
|
"hide_replies": "Скрий отговорите",
|
||||||
|
"load_more_replies": "Зареди още отговори",
|
||||||
|
"remove_from_playlist": "Премахване от плейлист",
|
||||||
|
"create_playlist": "Създаване на плейлист",
|
||||||
|
"reset_preferences": "Нулиране на настройките",
|
||||||
|
"with_timecode": "Сподели с текущото време",
|
||||||
|
"piped_link": "Piped връзка",
|
||||||
|
"documentation": "Документация",
|
||||||
|
"delete_account": "Изтрий акаунта",
|
||||||
|
"download_as_txt": "Изтегляне като .txt",
|
||||||
|
"share": "Сподели",
|
||||||
|
"follow_link": "Последвай връзката",
|
||||||
|
"add_to_playlist": "Добави към плейлист",
|
||||||
|
"delete_playlist_video_confirm": "Да се премахне ли видеото от плейлиста?",
|
||||||
|
"show_watch_on_youtube": "Показване на бутона \"Гледай в YouTube\"",
|
||||||
|
"source_code": "Изходен код",
|
||||||
|
"minimize_chapters_default": "Минимизиране на разделите по подразбиране",
|
||||||
|
"minimize_recommendations_default": "Минимизиране на препоръчани по подразбиране",
|
||||||
|
"show_chapters": "Раздели",
|
||||||
|
"logout": "Отписване от това устройство",
|
||||||
|
"clone_playlist": "Клониране на плейлист",
|
||||||
|
"clone_playlist_success": "Успешно клониране!",
|
||||||
|
"backup_preferences": "Архивиране на настройките",
|
||||||
|
"rename_playlist": "Преименуване на плейлиста",
|
||||||
|
"new_playlist_name": "Ново име на плейлиста",
|
||||||
|
"back_to_home": "Обратно към начална страница",
|
||||||
|
"status_page": "Статус",
|
||||||
|
"copy_link": "Копирай връзката",
|
||||||
|
"time_code": "Текущо време (в секунди)",
|
||||||
|
"reply_count": "{count} отговора",
|
||||||
|
"restore_preferences": "Възстановяване на настройките",
|
||||||
|
"invalidate_session": "Отписване от всички устройства",
|
||||||
|
"different_auth_instance": "Използване на различна инстанция за удостоверяване",
|
||||||
|
"store_search_history": "Запазване на историята на търсене",
|
||||||
|
"instance_auth_selection": "Избор на инстанция за удостоверяване",
|
||||||
|
"confirm_reset_preferences": "Сигурни ли сте, че искате да нулирате настройките?",
|
||||||
|
"hide_watched": "Скриване на гледани видеоклипове в Абонаменти"
|
||||||
|
},
|
||||||
|
"player": {
|
||||||
|
"watch_on": "Гледай в {0}"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"username": "Потребителско име",
|
||||||
|
"password": "Парола"
|
||||||
|
},
|
||||||
|
"video": {
|
||||||
|
"videos": "Видеоклипове",
|
||||||
|
"views": "{views} показвания",
|
||||||
|
"chapters": "Раздели",
|
||||||
|
"all": "Всички",
|
||||||
|
"watched": "Гледани",
|
||||||
|
"category": "Категория"
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"version": "Версия",
|
||||||
|
"registered_users": "Регистрирани потребители",
|
||||||
|
"instance_locations": "Местоположения на инстанция",
|
||||||
|
"instance_name": "Име на инстанция",
|
||||||
|
"has_cdn": "Има ли CDN?",
|
||||||
|
"up_to_date": "Актуален?",
|
||||||
|
"ssl_score": "SSL резултат"
|
||||||
|
},
|
||||||
|
"comment": {
|
||||||
|
"disabled": "Коментарите са деактивирани.",
|
||||||
|
"pinned_by": "Фиксиран от {author}",
|
||||||
|
"loading": "Коментарите се зареждат...",
|
||||||
|
"user_disabled": "Коментарите са деактивирани в настройките."
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"did_you_mean": "Имахте предвид: {0}?",
|
||||||
|
"all": "YouTube: Всички",
|
||||||
|
"videos": "YouTube: Видеоклипове",
|
||||||
|
"channels": "YouTube: Канали",
|
||||||
|
"playlists": "YouTube: Плейлисти",
|
||||||
|
"music_songs": "YT Music: Песни",
|
||||||
|
"music_videos": "YT Music: Видеоклипове",
|
||||||
|
"music_albums": "YT Music: Албуми",
|
||||||
|
"music_playlists": "YT Music: Плейлисти"
|
||||||
|
},
|
||||||
|
"subscriptions": {
|
||||||
|
"subscribed_channels_count": "Абониран за: {0}"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"page_not_found": "Страницата не е намерена",
|
||||||
|
"copied": "Копирано!",
|
||||||
|
"cannot_copy": "Не може да се копира!",
|
||||||
|
"local_storage": "Това действие изисква localStorage, разрешени ли са бисквитките?",
|
||||||
|
"register_no_email_note": "Използването на имейл като потребителско име не се препоръчва. Продължете все пак?"
|
||||||
|
}
|
||||||
|
}
|
@ -104,7 +104,11 @@
|
|||||||
"show_watch_on_youtube": "Schaltfläche „Auf YouTube ansehen“ anzeigen",
|
"show_watch_on_youtube": "Schaltfläche „Auf YouTube ansehen“ anzeigen",
|
||||||
"with_playlist": "Mit Wiedergabeliste teilen",
|
"with_playlist": "Mit Wiedergabeliste teilen",
|
||||||
"playlist_bookmarked": "Markiert",
|
"playlist_bookmarked": "Markiert",
|
||||||
"bookmark_playlist": "Lesezeichen"
|
"bookmark_playlist": "Lesezeichen",
|
||||||
|
"skip_segment": "Segment überspringen",
|
||||||
|
"skip_automatically": "Automatisch",
|
||||||
|
"min_segment_length": "Minimale Segmentlänge (in Sekunden)",
|
||||||
|
"skip_button_only": "Überspringen-Schaltfläche anzeigen"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"watch_on": "Auf {0} ansehen"
|
"watch_on": "Auf {0} ansehen"
|
||||||
@ -134,7 +138,8 @@
|
|||||||
"live": "{0} Live",
|
"live": "{0} Live",
|
||||||
"chapters": "Kapitel",
|
"chapters": "Kapitel",
|
||||||
"shorts": "Shorts",
|
"shorts": "Shorts",
|
||||||
"all": "Alle"
|
"all": "Alle",
|
||||||
|
"category": "Kategorie"
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"ssl_score": "SSL-Bewertung",
|
"ssl_score": "SSL-Bewertung",
|
||||||
|
@ -129,7 +129,9 @@
|
|||||||
"with_playlist": "Share with playlist",
|
"with_playlist": "Share with playlist",
|
||||||
"bookmark_playlist": "Bookmark",
|
"bookmark_playlist": "Bookmark",
|
||||||
"playlist_bookmarked": "Bookmarked",
|
"playlist_bookmarked": "Bookmarked",
|
||||||
"dismiss": "Dismiss"
|
"dismiss": "Dismiss",
|
||||||
|
"show_more": "Show more",
|
||||||
|
"show_less": "Show less"
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"pinned_by": "Pinned by {author}",
|
"pinned_by": "Pinned by {author}",
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
"instance_selection": "Selección de instancias",
|
"instance_selection": "Selección de instancias",
|
||||||
"enabled_codecs": "Códecs habilitados (múltiples)",
|
"enabled_codecs": "Códecs habilitados (múltiples)",
|
||||||
"instances_list": "Lista de instancias",
|
"instances_list": "Lista de instancias",
|
||||||
"language_selection": "Selección de lenguajes",
|
"language_selection": "Selección de idioma",
|
||||||
"store_watch_history": "Recordar historial de visualización",
|
"store_watch_history": "Recordar historial de visualización",
|
||||||
"minimize_description_default": "Minimizar la descripción por defecto",
|
"minimize_description_default": "Minimizar la descripción por defecto",
|
||||||
"show_comments": "Mostrar comentarios",
|
"show_comments": "Mostrar comentarios",
|
||||||
|
@ -120,7 +120,11 @@
|
|||||||
"no_valid_playlists": "Le fichier ne contient pas de listes de lecture valides !",
|
"no_valid_playlists": "Le fichier ne contient pas de listes de lecture valides !",
|
||||||
"bookmark_playlist": "Marque-page",
|
"bookmark_playlist": "Marque-page",
|
||||||
"playlist_bookmarked": "Dans les marque-pages",
|
"playlist_bookmarked": "Dans les marque-pages",
|
||||||
"with_playlist": "Partager avec la liste de lecture"
|
"with_playlist": "Partager avec la liste de lecture",
|
||||||
|
"skip_button_only": "Afficher le bouton de saut",
|
||||||
|
"skip_automatically": "Automatiquement",
|
||||||
|
"min_segment_length": "Longueur minimale du segment (en secondes)",
|
||||||
|
"skip_segment": "Sauter le segment"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"watch_on": "Regarder sur {0}"
|
"watch_on": "Regarder sur {0}"
|
||||||
@ -134,7 +138,8 @@
|
|||||||
"chapters": "Chapitres",
|
"chapters": "Chapitres",
|
||||||
"live": "{0} en direct",
|
"live": "{0} en direct",
|
||||||
"shorts": "Courtes",
|
"shorts": "Courtes",
|
||||||
"all": "Tout"
|
"all": "Tout",
|
||||||
|
"category": "Catégorie"
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"ssl_score": "Score SSL",
|
"ssl_score": "Score SSL",
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
"instances_list": "רשימת עותקים",
|
"instances_list": "רשימת עותקים",
|
||||||
"enabled_codecs": "מפענחים פעילים (מגוון)",
|
"enabled_codecs": "מפענחים פעילים (מגוון)",
|
||||||
"instance_selection": "בחירת עותק",
|
"instance_selection": "בחירת עותק",
|
||||||
"show_more": "להציג עוד",
|
"show_more": "להציג יותר",
|
||||||
"yes": "כן",
|
"yes": "כן",
|
||||||
"no": "לא",
|
"no": "לא",
|
||||||
"export_to_json": "ייצוא ל־JSON",
|
"export_to_json": "ייצוא ל־JSON",
|
||||||
@ -127,7 +127,8 @@
|
|||||||
"skip_button_only": "הצגת כפתור דילוג",
|
"skip_button_only": "הצגת כפתור דילוג",
|
||||||
"min_segment_length": "אורך מקטע מזערי (בשניות)",
|
"min_segment_length": "אורך מקטע מזערי (בשניות)",
|
||||||
"skip_segment": "דילוג על מקטע",
|
"skip_segment": "דילוג על מקטע",
|
||||||
"skip_automatically": "אוטומטית"
|
"skip_automatically": "אוטומטית",
|
||||||
|
"show_less": "להציג פחות"
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"pinned_by": "ננעץ על ידי {author}",
|
"pinned_by": "ננעץ על ידי {author}",
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
"chapters": "Poglavlja",
|
"chapters": "Poglavlja",
|
||||||
"live": "{0} uživo",
|
"live": "{0} uživo",
|
||||||
"shorts": "Kratka videa",
|
"shorts": "Kratka videa",
|
||||||
"all": "Sva"
|
"all": "Sva",
|
||||||
|
"category": "Kategorija"
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"ssl_score": "SSL ocjena",
|
"ssl_score": "SSL ocjena",
|
||||||
@ -92,7 +93,7 @@
|
|||||||
"select_playlist": "Odaberi popis snimaka",
|
"select_playlist": "Odaberi popis snimaka",
|
||||||
"please_select_playlist": "Odaberi popis snimaka",
|
"please_select_playlist": "Odaberi popis snimaka",
|
||||||
"delete_playlist_video_confirm": "Ukloniti video iz popisa snimaka?",
|
"delete_playlist_video_confirm": "Ukloniti video iz popisa snimaka?",
|
||||||
"show_markers": "Prikaži oznake na Pokretaču",
|
"show_markers": "Prikaži oznake na playeru",
|
||||||
"delete_account": "Izbriši račun",
|
"delete_account": "Izbriši račun",
|
||||||
"logout": "Odjavi se s ovog uređaja",
|
"logout": "Odjavi se s ovog uređaja",
|
||||||
"minimize_recommendations_default": "Standardno sakrij preporuke",
|
"minimize_recommendations_default": "Standardno sakrij preporuke",
|
||||||
@ -130,7 +131,11 @@
|
|||||||
"no_valid_playlists": "Datoteka ne sadrži ispravne popise snimaka!",
|
"no_valid_playlists": "Datoteka ne sadrži ispravne popise snimaka!",
|
||||||
"with_playlist": "Dijeli s popisom snimaka",
|
"with_playlist": "Dijeli s popisom snimaka",
|
||||||
"playlist_bookmarked": "Zabilježeno",
|
"playlist_bookmarked": "Zabilježeno",
|
||||||
"bookmark_playlist": "Zabilježi"
|
"bookmark_playlist": "Zabilježi",
|
||||||
|
"skip_button_only": "Prikaži gumb za preskakanje",
|
||||||
|
"skip_automatically": "Automatski",
|
||||||
|
"skip_segment": "Preskoči segment",
|
||||||
|
"min_segment_length": "Najmanja duljina segmenta (u sekundama)"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"watch_on": "Gledaj na {0}"
|
"watch_on": "Gledaj na {0}"
|
||||||
@ -146,7 +151,7 @@
|
|||||||
"playlists": "Popisi snimaka",
|
"playlists": "Popisi snimaka",
|
||||||
"account": "Račun",
|
"account": "Račun",
|
||||||
"instance": "Instanca",
|
"instance": "Instanca",
|
||||||
"player": "Pokretač",
|
"player": "Player",
|
||||||
"channels": "Kanali",
|
"channels": "Kanali",
|
||||||
"livestreams": "Prijenosi uživo",
|
"livestreams": "Prijenosi uživo",
|
||||||
"bookmarks": "Zabilješke"
|
"bookmarks": "Zabilješke"
|
||||||
|
@ -138,7 +138,8 @@
|
|||||||
"live": "{0} Diretta",
|
"live": "{0} Diretta",
|
||||||
"chapters": "Capitoli",
|
"chapters": "Capitoli",
|
||||||
"shorts": "Short",
|
"shorts": "Short",
|
||||||
"all": "Tutti"
|
"all": "Tutti",
|
||||||
|
"category": "Categoria"
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"ssl_score": "Valutazione SSL",
|
"ssl_score": "Valutazione SSL",
|
||||||
|
@ -31,11 +31,11 @@
|
|||||||
"uses_api_from": "API使用元 ",
|
"uses_api_from": "API使用元 ",
|
||||||
"enable_sponsorblock": "SponsorBlock を有効化",
|
"enable_sponsorblock": "SponsorBlock を有効化",
|
||||||
"skip_sponsors": "広告をスキップ",
|
"skip_sponsors": "広告をスキップ",
|
||||||
"skip_intro": "休止時間/イントロ画面をスキップ",
|
"skip_intro": "休止時間/導入アニメをスキップ",
|
||||||
"skip_outro": "終了画面/クレジットをスキップ",
|
"skip_outro": "終了シーン/クレジットをスキップ",
|
||||||
"skip_preview": "プレビュー/要約をスキップ",
|
"skip_preview": "プレビュー/要約をスキップ",
|
||||||
"skip_interaction": "チャンネル登録など操作を求める自己宣伝をスキップ",
|
"skip_interaction": "チャンネル登録など操作を求める自己宣伝をスキップ",
|
||||||
"skip_self_promo": "無償/自己プロモーションをスキップ",
|
"skip_self_promo": "無報酬/自己の宣伝をスキップ",
|
||||||
"skip_non_music": "音楽: 非音楽部分をスキップ",
|
"skip_non_music": "音楽: 非音楽部分をスキップ",
|
||||||
"theme": "テーマ",
|
"theme": "テーマ",
|
||||||
"auto": "自動",
|
"auto": "自動",
|
||||||
@ -43,12 +43,12 @@
|
|||||||
"light": "ライト",
|
"light": "ライト",
|
||||||
"autoplay_video": "動画を自動再生",
|
"autoplay_video": "動画を自動再生",
|
||||||
"audio_only": "音声のみ",
|
"audio_only": "音声のみ",
|
||||||
"default_quality": "デフォルトの画質",
|
"default_quality": "標準の画質",
|
||||||
"buffering_goal": "バッファリング目標値 (秒)",
|
"buffering_goal": "バッファリング目標値 (秒)",
|
||||||
"country_selection": "国の選択",
|
"country_selection": "国の選択",
|
||||||
"default_homepage": "ホームに表示するページ",
|
"default_homepage": "ホームに表示するページ",
|
||||||
"show_comments": "コメントを表示",
|
"show_comments": "コメントを表示",
|
||||||
"minimize_description_default": "デフォルトで詳細を最小化する",
|
"minimize_description_default": "最初から説明を最小化",
|
||||||
"store_watch_history": "再生履歴を保存する",
|
"store_watch_history": "再生履歴を保存する",
|
||||||
"language_selection": "言語の選択",
|
"language_selection": "言語の選択",
|
||||||
"instances_list": "インスタンス一覧",
|
"instances_list": "インスタンス一覧",
|
||||||
@ -68,16 +68,16 @@
|
|||||||
"show_recommendations": "おすすめを見る",
|
"show_recommendations": "おすすめを見る",
|
||||||
"disable_lbry": "ストリーミングのLBRYを無効化",
|
"disable_lbry": "ストリーミングのLBRYを無効化",
|
||||||
"enable_lbry_proxy": "LBRYプロキシをオン",
|
"enable_lbry_proxy": "LBRYプロキシをオン",
|
||||||
"view_ssl_score": "SSLスコアを見る",
|
"view_ssl_score": "SSLの評価を表示",
|
||||||
"search": "検索",
|
"search": "検索",
|
||||||
"filter": "フィルター",
|
"filter": "フィルター",
|
||||||
"loading": "読み込み中…",
|
"loading": "読み込み中…",
|
||||||
"clear_history": "再生履歴を削除",
|
"clear_history": "再生履歴を削除",
|
||||||
"hide_replies": "返信を非表示",
|
"hide_replies": "返信を非表示",
|
||||||
"load_more_replies": "返信をもっと見る",
|
"load_more_replies": "返信をもっと見る",
|
||||||
"skip_filler_tangent": "無関係なコンテンツをスキップ",
|
"skip_filler_tangent": "無関係な談話をスキップ",
|
||||||
"skip_highlight": "ハイライトをスキップ",
|
"skip_highlight": "ハイライトをスキップ",
|
||||||
"add_to_playlist": "再生リストに追加する",
|
"add_to_playlist": "再生リストに追加",
|
||||||
"create_playlist": "再生リストを作成",
|
"create_playlist": "再生リストを作成",
|
||||||
"remove_from_playlist": "再生リストから削除",
|
"remove_from_playlist": "再生リストから削除",
|
||||||
"delete_playlist_video_confirm": "再生リストからこの動画を削除しますか?",
|
"delete_playlist_video_confirm": "再生リストからこの動画を削除しますか?",
|
||||||
@ -98,9 +98,9 @@
|
|||||||
"different_auth_instance": "認証に別のインスタンスを使う",
|
"different_auth_instance": "認証に別のインスタンスを使う",
|
||||||
"download_as_txt": ".txtでダウンロード",
|
"download_as_txt": ".txtでダウンロード",
|
||||||
"logout": "このデバイスでログアウト",
|
"logout": "このデバイスでログアウト",
|
||||||
"minimize_recommendations_default": "デフォルトでおすすめを最小化する",
|
"minimize_recommendations_default": "最初からおすすめを最小化",
|
||||||
"hide_watched": "再生済みの動画をフィードに表示しない",
|
"hide_watched": "再生済みの動画をフィードに表示しない",
|
||||||
"minimize_chapters_default": "デフォルトでチャプターを最小化する",
|
"minimize_chapters_default": "最初からチャプターを最小化",
|
||||||
"show_watch_on_youtube": "「YouTubeで見る」ボタンを表示する",
|
"show_watch_on_youtube": "「YouTubeで見る」ボタンを表示する",
|
||||||
"invalidate_session": "すべてのデバイスでログアウトする",
|
"invalidate_session": "すべてのデバイスでログアウトする",
|
||||||
"instance_auth_selection": "認証インスタンスの選択",
|
"instance_auth_selection": "認証インスタンスの選択",
|
||||||
@ -119,11 +119,15 @@
|
|||||||
"follow_link": "リンクに従う",
|
"follow_link": "リンクに従う",
|
||||||
"reply_count": "{count} 件の返信",
|
"reply_count": "{count} 件の返信",
|
||||||
"clone_playlist": "再生リストを複製",
|
"clone_playlist": "再生リストを複製",
|
||||||
"minimize_comments_default": "デフォルトでコメントを最小化する",
|
"minimize_comments_default": "最初からコメントを最小化",
|
||||||
"no_valid_playlists": "ファイルに有効な再生リストが含まれていません。",
|
"no_valid_playlists": "このファイルは有効な再生リストではありません!",
|
||||||
"playlist_bookmarked": "ブックマーク完了",
|
"playlist_bookmarked": "ブックマーク完了",
|
||||||
"bookmark_playlist": "ブックマーク",
|
"bookmark_playlist": "ブックマーク",
|
||||||
"with_playlist": "再生リストで共有"
|
"with_playlist": "再生リストで共有",
|
||||||
|
"skip_automatically": "自動",
|
||||||
|
"skip_button_only": "スキップボタン表示",
|
||||||
|
"skip_segment": "ここをスキップ",
|
||||||
|
"min_segment_length": "最小の区切りの長さ (秒)"
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"pinned_by": "{author} によって固定",
|
"pinned_by": "{author} によって固定",
|
||||||
@ -135,8 +139,8 @@
|
|||||||
"instance_name": "インスタンス名",
|
"instance_name": "インスタンス名",
|
||||||
"instance_locations": "インスタンスの場所",
|
"instance_locations": "インスタンスの場所",
|
||||||
"has_cdn": "CDNの有無",
|
"has_cdn": "CDNの有無",
|
||||||
"ssl_score": "SSLスコア",
|
"ssl_score": "SSLの評価",
|
||||||
"registered_users": "登録済みユーザー",
|
"registered_users": "登録ユーザー数",
|
||||||
"version": "バージョン",
|
"version": "バージョン",
|
||||||
"up_to_date": "最新?"
|
"up_to_date": "最新?"
|
||||||
},
|
},
|
||||||
@ -153,7 +157,8 @@
|
|||||||
"chapters": "チャプター",
|
"chapters": "チャプター",
|
||||||
"live": "{0} ライブ配信",
|
"live": "{0} ライブ配信",
|
||||||
"shorts": "ショート",
|
"shorts": "ショート",
|
||||||
"all": "すべて"
|
"all": "すべて",
|
||||||
|
"category": "分類"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "もしかして: {0}?",
|
"did_you_mean": "もしかして: {0}?",
|
||||||
|
@ -58,15 +58,15 @@
|
|||||||
"remove_from_playlist": "Uit Afspeellijst Verwijderen",
|
"remove_from_playlist": "Uit Afspeellijst Verwijderen",
|
||||||
"select_playlist": "Selecteer een Afspeellijst",
|
"select_playlist": "Selecteer een Afspeellijst",
|
||||||
"delete_playlist_confirm": "Deze afspeellijst verwijderen?",
|
"delete_playlist_confirm": "Deze afspeellijst verwijderen?",
|
||||||
"please_select_playlist": "Kies een afspeellijst a.u.b.",
|
"please_select_playlist": "Selecteer een afspeellijst alsjeblief",
|
||||||
"instance_selection": "Instantie Selectie",
|
"instance_selection": "Instantie Selectie",
|
||||||
"import_from_json": "Importeren uit JSON/CSV",
|
"import_from_json": "Importeren uit JSON/CSV",
|
||||||
"clear_history": "Geschiedenis Wissen",
|
"clear_history": "Geschiedenis Wissen",
|
||||||
"load_more_replies": "Laad meer Antwoorden",
|
"load_more_replies": "Laad meer Antwoorden",
|
||||||
"delete_playlist_video_confirm": "Video van playlist verwijderen?",
|
"delete_playlist_video_confirm": "Video uit deze afspeellijst verwijderen?",
|
||||||
"create_playlist": "Afspeellijst Maken",
|
"create_playlist": "Afspeellijst Maken",
|
||||||
"delete_playlist": "Afspeellijst Verwijderen",
|
"delete_playlist": "Afspeellijst Verwijderen",
|
||||||
"show_markers": "Toon markeringen op Speler",
|
"show_markers": "Laat markeringen op speler zien",
|
||||||
"store_search_history": "Zoekgeschiedenis Opslaan",
|
"store_search_history": "Zoekgeschiedenis Opslaan",
|
||||||
"minimize_chapters_default": "Hoofdstukken Standaard Minimaliseren",
|
"minimize_chapters_default": "Hoofdstukken Standaard Minimaliseren",
|
||||||
"show_watch_on_youtube": "Toon Bekijk op YouTube knop",
|
"show_watch_on_youtube": "Toon Bekijk op YouTube knop",
|
||||||
@ -77,8 +77,8 @@
|
|||||||
"copy_link": "Link kopiëren",
|
"copy_link": "Link kopiëren",
|
||||||
"hide_watched": "Verberg bekeken video's in de feed",
|
"hide_watched": "Verberg bekeken video's in de feed",
|
||||||
"minimize_comments": "Opmerkingen minimaliseren",
|
"minimize_comments": "Opmerkingen minimaliseren",
|
||||||
"instance_auth_selection": "Autenticatie Instantie Selectie",
|
"instance_auth_selection": "Selectie authenticatie-instantie",
|
||||||
"clone_playlist": "Afspeellijst klonen",
|
"clone_playlist": "Afspeellijst dupliceren",
|
||||||
"download_as_txt": "Downloaden als .txt",
|
"download_as_txt": "Downloaden als .txt",
|
||||||
"rename_playlist": "Afspeellijst hernoemen",
|
"rename_playlist": "Afspeellijst hernoemen",
|
||||||
"new_playlist_name": "Nieuwe afspeellijstnaam",
|
"new_playlist_name": "Nieuwe afspeellijstnaam",
|
||||||
@ -91,20 +91,24 @@
|
|||||||
"instance_donations": "Instantie donaties",
|
"instance_donations": "Instantie donaties",
|
||||||
"reply_count": "{count} antwoorden",
|
"reply_count": "{count} antwoorden",
|
||||||
"no_valid_playlists": "Het bestand bevat geen geldige afspeellijsten!",
|
"no_valid_playlists": "Het bestand bevat geen geldige afspeellijsten!",
|
||||||
"clone_playlist_success": "Succesvol gekloond!",
|
"clone_playlist_success": "Dupliceren gelukt!",
|
||||||
"reset_preferences": "Voorkeuren opnieuw instellen",
|
"reset_preferences": "Voorkeuren herstellen",
|
||||||
"back_to_home": "Terug naar de start",
|
"back_to_home": "Terug naar de start",
|
||||||
"minimize_comments_default": "Opmerkingen Standaard Minimaliseren",
|
"minimize_comments_default": "Opmerkingen Standaard Minimaliseren",
|
||||||
"delete_account": "Account Verwijderen",
|
"delete_account": "Account Verwijderen",
|
||||||
"logout": "Uitloggen van dit apparaat",
|
"logout": "Uitloggen op dit apparaat",
|
||||||
"minimize_recommendations_default": "Aanbevelingen Standaard Minimaliseren",
|
"minimize_recommendations_default": "Aanbevelingen Standaard Minimaliseren",
|
||||||
"confirm_reset_preferences": "Weet u zeker dat u uw voorkeuren opnieuw wilt instellen?",
|
"confirm_reset_preferences": "Weet u zeker dat u uw voorkeuren opnieuw wilt instellen?",
|
||||||
"backup_preferences": "Back-up voorkeuren",
|
"backup_preferences": "Back-up voorkeuren",
|
||||||
"invalidate_session": "Alle apparaten afmelden",
|
"invalidate_session": "Uitloggen op alle apparaten",
|
||||||
"different_auth_instance": "Gebruik een andere instantie voor authenticatie",
|
"different_auth_instance": "Gebruik een andere instantie voor authenticatie",
|
||||||
"with_playlist": "Delen met afspeellijst",
|
"with_playlist": "Delen met afspeellijst",
|
||||||
"playlist_bookmarked": "Bladwijzer gemaakt",
|
"playlist_bookmarked": "Bladwijzer gemaakt",
|
||||||
"bookmark_playlist": "Bladwijzer"
|
"bookmark_playlist": "Bladwijzer",
|
||||||
|
"skip_automatically": "Automatisch",
|
||||||
|
"skip_button_only": "toon de overslaan knop",
|
||||||
|
"min_segment_length": "Minimale segmentlengte (in seconden)",
|
||||||
|
"skip_segment": "segment overslaan"
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"register": "Registreren",
|
"register": "Registreren",
|
||||||
@ -113,9 +117,9 @@
|
|||||||
"preferences": "Voorkeuren",
|
"preferences": "Voorkeuren",
|
||||||
"history": "Geschiedenis",
|
"history": "Geschiedenis",
|
||||||
"subscriptions": "Abonnementen",
|
"subscriptions": "Abonnementen",
|
||||||
"trending": "Trending",
|
"trending": "populair",
|
||||||
"playlists": "Afspeellijsten",
|
"playlists": "Afspeellijsten",
|
||||||
"account": "Account",
|
"account": "profiel",
|
||||||
"instance": "Instantie",
|
"instance": "Instantie",
|
||||||
"player": "Speler",
|
"player": "Speler",
|
||||||
"livestreams": "Livestreams",
|
"livestreams": "Livestreams",
|
||||||
@ -148,7 +152,9 @@
|
|||||||
"sponsor_segments": "Sponsorsegmenten",
|
"sponsor_segments": "Sponsorsegmenten",
|
||||||
"ratings_disabled": "Beoordelingen Uitgeschakeld",
|
"ratings_disabled": "Beoordelingen Uitgeschakeld",
|
||||||
"live": "{0} Live",
|
"live": "{0} Live",
|
||||||
"shorts": "Shorts"
|
"shorts": "Shorts",
|
||||||
|
"category": "Categorie",
|
||||||
|
"all": "Alle"
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"has_cdn": "Heeft CDN?",
|
"has_cdn": "Heeft CDN?",
|
||||||
@ -161,8 +167,8 @@
|
|||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"pinned_by": "Vastgemaakt door {author}",
|
"pinned_by": "Vastgemaakt door {author}",
|
||||||
"user_disabled": "Reacties zijn uitgeschakeld in de instellingen.",
|
"user_disabled": "Opmerkingen zijn uitgeschakeld in de instellingen.",
|
||||||
"loading": "Reacties laden...",
|
"loading": "Opmerkingen laden...",
|
||||||
"disabled": "Reacties zijn uitgeschakeld door de uploader."
|
"disabled": "Reacties zijn uitgeschakeld door de uploader."
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
@ -170,7 +176,8 @@
|
|||||||
"copied": "Gekopieerd!",
|
"copied": "Gekopieerd!",
|
||||||
"cannot_copy": "Kan niet kopiëren!",
|
"cannot_copy": "Kan niet kopiëren!",
|
||||||
"page_not_found": "Pagina niet gevonden",
|
"page_not_found": "Pagina niet gevonden",
|
||||||
"local_storage": "Deze actie vereist lokale opslag, zijn cookies ingeschakeld?"
|
"local_storage": "Deze actie vereist lokale opslag, zijn cookies ingeschakeld?",
|
||||||
|
"register_no_email_note": "Een e-mailadres als gebruikersnaam gebruiken wordt afgeraden. Toch doorgaan?"
|
||||||
},
|
},
|
||||||
"subscriptions": {
|
"subscriptions": {
|
||||||
"subscribed_channels_count": "Geabonneerd op: {0}"
|
"subscribed_channels_count": "Geabonneerd op: {0}"
|
||||||
|
@ -144,7 +144,8 @@
|
|||||||
"ratings_disabled": "ମୂଲ୍ୟାୟନ ଅକ୍ଷମ ହୋଇଛି",
|
"ratings_disabled": "ମୂଲ୍ୟାୟନ ଅକ୍ଷମ ହୋଇଛି",
|
||||||
"chapters": "ଅଧ୍ୟାୟ ଗୁଡ଼ିକ",
|
"chapters": "ଅଧ୍ୟାୟ ଗୁଡ଼ିକ",
|
||||||
"live": "{0} ସିଧାପ୍ରସାରଣ",
|
"live": "{0} ସିଧାପ୍ରସାରଣ",
|
||||||
"all": "ସମସ୍ତ"
|
"all": "ସମସ୍ତ",
|
||||||
|
"category": "ବର୍ଗ"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "ଆପଣ କହିବାକୁ ଚାହୁଁଛନ୍ତି କି: {0}?",
|
"did_you_mean": "ଆପଣ କହିବାକୁ ଚାହୁଁଛନ୍ତି କି: {0}?",
|
||||||
|
@ -157,7 +157,8 @@
|
|||||||
"chapters": "Rozdziały",
|
"chapters": "Rozdziały",
|
||||||
"live": "{0} Na żywo",
|
"live": "{0} Na żywo",
|
||||||
"shorts": "Krótkie wideo",
|
"shorts": "Krótkie wideo",
|
||||||
"all": "Wszystkie"
|
"all": "Wszystkie",
|
||||||
|
"category": "Kategoria"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "Czy chodziło ci o: {0}?",
|
"did_you_mean": "Czy chodziło ci o: {0}?",
|
||||||
|
@ -100,7 +100,15 @@
|
|||||||
"minimize_recommendations": "Ascunde Recomandări",
|
"minimize_recommendations": "Ascunde Recomandări",
|
||||||
"yes": "Da",
|
"yes": "Da",
|
||||||
"show_comments": "Arată Comentarii",
|
"show_comments": "Arată Comentarii",
|
||||||
"show_description": "Arată Descriere"
|
"show_description": "Arată Descriere",
|
||||||
|
"bookmark_playlist": "Marcaj",
|
||||||
|
"no_valid_playlists": "Fișierul nu conține playlist-uri valide!",
|
||||||
|
"skip_automatically": "Automat",
|
||||||
|
"min_segment_length": "Lungimea minimă a segmentului (în secunde)",
|
||||||
|
"skip_segment": "Sări segmentul",
|
||||||
|
"skip_button_only": "Afișează butonul de săritură",
|
||||||
|
"with_playlist": "Distribuie cu playlist",
|
||||||
|
"playlist_bookmarked": "Marcat"
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"ssl_score": "Scor SSL",
|
"ssl_score": "Scor SSL",
|
||||||
@ -125,7 +133,9 @@
|
|||||||
"sponsor_segments": "Segmente Sponsori",
|
"sponsor_segments": "Segmente Sponsori",
|
||||||
"ratings_disabled": "Like-uri dezactivate",
|
"ratings_disabled": "Like-uri dezactivate",
|
||||||
"live": "{0} Live",
|
"live": "{0} Live",
|
||||||
"videos": "Video-uri"
|
"videos": "Video-uri",
|
||||||
|
"category": "Categorie",
|
||||||
|
"all": "Tot"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"username": "Nume User",
|
"username": "Nume User",
|
||||||
@ -146,7 +156,9 @@
|
|||||||
"cannot_copy": "Nu se poate copia!",
|
"cannot_copy": "Nu se poate copia!",
|
||||||
"preferences_note": "Sfat: preferințele sunt salvate in memoria locala a browserului tău. Ștergând datele browserului le ștergi si pe ele.",
|
"preferences_note": "Sfat: preferințele sunt salvate in memoria locala a browserului tău. Ștergând datele browserului le ștergi si pe ele.",
|
||||||
"page_not_found": "Pagină negăsită",
|
"page_not_found": "Pagină negăsită",
|
||||||
"copied": "S-a copiat!"
|
"copied": "S-a copiat!",
|
||||||
|
"register_no_email_note": "Utilizarea unui e-mail ca nume de utilizator nu este recomandată. Continui oricum?",
|
||||||
|
"local_storage": "Această acțiune necesită localStorage, sunt activate cookie-urile?"
|
||||||
},
|
},
|
||||||
"subscriptions": {
|
"subscriptions": {
|
||||||
"subscribed_channels_count": "Abonat la: {0}"
|
"subscribed_channels_count": "Abonat la: {0}"
|
||||||
@ -164,7 +176,8 @@
|
|||||||
"livestreams": "Live-uri",
|
"livestreams": "Live-uri",
|
||||||
"channels": "Canale",
|
"channels": "Canale",
|
||||||
"preferences": "Preferințe",
|
"preferences": "Preferințe",
|
||||||
"player": "Player"
|
"player": "Player",
|
||||||
|
"bookmarks": "Marcaje"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"watch_on": "Vezi pe {0}"
|
"watch_on": "Vezi pe {0}"
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
"register": "Регистрация",
|
"register": "Регистрация",
|
||||||
"feed": "Подписки",
|
"feed": "Подписки",
|
||||||
"preferences": "Настройки",
|
"preferences": "Настройки",
|
||||||
"history": "История просмотров",
|
"history": "История",
|
||||||
"subscriptions": "Ваши подписки",
|
"subscriptions": "Подписки",
|
||||||
"playlists": "Плейлисты",
|
"playlists": "Плейлисты",
|
||||||
"account": "Аккаунт",
|
"account": "Аккаунт",
|
||||||
"player": "Плеер",
|
"player": "Плеер",
|
||||||
@ -28,7 +28,7 @@
|
|||||||
"channel_name_asc": "Имя канала (А-Я)",
|
"channel_name_asc": "Имя канала (А-Я)",
|
||||||
"channel_name_desc": "Имя канала (Я-А)",
|
"channel_name_desc": "Имя канала (Я-А)",
|
||||||
"back": "Назад",
|
"back": "Назад",
|
||||||
"uses_api_from": "Использовать API, предоставляемое ",
|
"uses_api_from": "Использовать API ",
|
||||||
"enable_sponsorblock": "Включить Sponsorblock",
|
"enable_sponsorblock": "Включить Sponsorblock",
|
||||||
"skip_sponsors": "Пропускать спонсорскую рекламу",
|
"skip_sponsors": "Пропускать спонсорскую рекламу",
|
||||||
"skip_intro": "Пропускать заставку/интро",
|
"skip_intro": "Пропускать заставку/интро",
|
||||||
@ -67,7 +67,7 @@
|
|||||||
"minimize_recommendations": "Свернуть рекомендации",
|
"minimize_recommendations": "Свернуть рекомендации",
|
||||||
"show_recommendations": "Показать рекомендации",
|
"show_recommendations": "Показать рекомендации",
|
||||||
"disable_lbry": "Отключить LBRY для стриминга",
|
"disable_lbry": "Отключить LBRY для стриминга",
|
||||||
"enable_lbry_proxy": "Проксировать видео с LBRY",
|
"enable_lbry_proxy": "Проксировать видео для LBRY",
|
||||||
"view_ssl_score": "Посмотреть настройки SSL",
|
"view_ssl_score": "Посмотреть настройки SSL",
|
||||||
"search": "Поиск",
|
"search": "Поиск",
|
||||||
"filter": "Фильтр",
|
"filter": "Фильтр",
|
||||||
@ -85,42 +85,42 @@
|
|||||||
"select_playlist": "Выбрать плейлист",
|
"select_playlist": "Выбрать плейлист",
|
||||||
"delete_playlist_confirm": "Удалить этот плейлист?",
|
"delete_playlist_confirm": "Удалить этот плейлист?",
|
||||||
"delete_playlist_video_confirm": "Удалить видео из плейлиста?",
|
"delete_playlist_video_confirm": "Удалить видео из плейлиста?",
|
||||||
"show_markers": "Показать Mаркеры Hа Проигрывателе",
|
"show_markers": "Показать маркеры на проигрывателе",
|
||||||
"delete_account": "Удалить аккаунт",
|
"delete_account": "Удалить аккаунт",
|
||||||
"logout": "Выйти из этого устройства",
|
"logout": "Выйти из этого устройства",
|
||||||
"download_as_txt": "Скачать как .txt",
|
"download_as_txt": "Скачать как .txt",
|
||||||
"minimize_recommendations_default": "Скрыть Рекомендации по умолчанию",
|
"minimize_recommendations_default": "Скрыть Рекомендации по умолчанию",
|
||||||
"invalidate_session": "Выйти из всех устройств",
|
"invalidate_session": "Выйти из всех устройств",
|
||||||
"different_auth_instance": "Использовать другие средства аутентификации",
|
"different_auth_instance": "Использовать другое зеркало для аутентификации",
|
||||||
"instance_auth_selection": "Выбор средств аутентификации",
|
"instance_auth_selection": "Выбор зеркала аутентификации",
|
||||||
"clone_playlist": "Клонировать плейлист",
|
"clone_playlist": "Клонировать плейлист",
|
||||||
"clone_playlist_success": "Клонирование прошло успешно!",
|
"clone_playlist_success": "Успешно клонировано!",
|
||||||
"show_chapters": "Части",
|
"show_chapters": "Главы",
|
||||||
"rename_playlist": "Переименовать плейлист",
|
"rename_playlist": "Переименовать плейлист",
|
||||||
"new_playlist_name": "Новое название плейлиста",
|
"new_playlist_name": "Новое название плейлиста",
|
||||||
"share": "Поделиться",
|
"share": "Поделиться",
|
||||||
"with_timecode": "Поделиться с отметкой времени",
|
"with_timecode": "Поделиться с таймкодом",
|
||||||
"piped_link": "Ссылка Piped",
|
"piped_link": "Ссылка Piped",
|
||||||
"follow_link": "Ссылка подписки",
|
"follow_link": "Перейти по ссылке",
|
||||||
"copy_link": "Скопировать ссылку",
|
"copy_link": "Скопировать ссылку",
|
||||||
"time_code": "Тайм-код (в секундах)",
|
"time_code": "Таймкод (в секундах)",
|
||||||
"reset_preferences": "Сбросить настройки",
|
"reset_preferences": "Сбросить настройки",
|
||||||
"confirm_reset_preferences": "Вы уверены, что хотите сбросить настройки?",
|
"confirm_reset_preferences": "Вы уверены, что хотите сбросить настройки?",
|
||||||
"backup_preferences": "Бэкап настроек",
|
"backup_preferences": "Бэкап настроек",
|
||||||
"restore_preferences": "Восстановить настройки",
|
"restore_preferences": "Восстановить настройки",
|
||||||
"back_to_home": "Вернутся на главную",
|
"back_to_home": "Назад на главную",
|
||||||
"store_search_history": "Хранить историю поиска",
|
"store_search_history": "Хранить историю поиска",
|
||||||
"hide_watched": "Скрыть просмотренные видео в ленте",
|
"hide_watched": "Скрыть просмотренные видео в ленте",
|
||||||
"status_page": "Статус",
|
"status_page": "Статус",
|
||||||
"source_code": "Исходный код",
|
"source_code": "Исходный код",
|
||||||
"documentation": "Пожертвования сервера",
|
"documentation": "Документация",
|
||||||
"instance_donations": "Пожертвования сервера",
|
"instance_donations": "Пожертвования зеркала",
|
||||||
"reply_count": "{count} ответов",
|
"reply_count": "{count} ответов",
|
||||||
"minimize_comments_default": "Сворачивать комментарии по умолчанию",
|
"minimize_comments_default": "Сворачивать комментарии по умолчанию",
|
||||||
"minimize_comments": "Свернуть комментарии",
|
"minimize_comments": "Свернуть комментарии",
|
||||||
"show_watch_on_youtube": "Показать кнопку Смотреть на YouTube",
|
"show_watch_on_youtube": "Показать кнопку Смотреть на YouTube",
|
||||||
"minimize_chapters_default": "Скрывать главы по умолчанию",
|
"minimize_chapters_default": "Скрывать главы по умолчанию",
|
||||||
"no_valid_playlists": "Файл не содержит действительных списков воспроизведения!",
|
"no_valid_playlists": "Файл не содержит действующих плейлистов!",
|
||||||
"with_playlist": "Поделиться с плейлистом",
|
"with_playlist": "Поделиться с плейлистом",
|
||||||
"bookmark_playlist": "Закладка",
|
"bookmark_playlist": "Закладка",
|
||||||
"playlist_bookmarked": "В закладках",
|
"playlist_bookmarked": "В закладках",
|
||||||
@ -130,14 +130,14 @@
|
|||||||
"skip_segment": "Пропустить сегмент"
|
"skip_segment": "Пропустить сегмент"
|
||||||
},
|
},
|
||||||
"comment": {
|
"comment": {
|
||||||
"pinned_by": "Прикреплено пользователем {author}",
|
"pinned_by": "Закреплено пользователем {author}",
|
||||||
"loading": "Загрузка комментариев...",
|
"loading": "Загрузка комментариев...",
|
||||||
"user_disabled": "Комментарии отключены в настройках.",
|
"user_disabled": "Комментарии отключены в настройках.",
|
||||||
"disabled": "Коментарии отключены автором."
|
"disabled": "Комментарии отключены автором."
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"instance_name": "Название",
|
"instance_name": "Имя зеркала",
|
||||||
"instance_locations": "Местоположение",
|
"instance_locations": "Местоположения зеркала",
|
||||||
"has_cdn": "Имеется CDN?",
|
"has_cdn": "Имеется CDN?",
|
||||||
"ssl_score": "Оценка настроек SSL",
|
"ssl_score": "Оценка настроек SSL",
|
||||||
"registered_users": "Зарегистрировано пользователей",
|
"registered_users": "Зарегистрировано пользователей",
|
||||||
@ -145,7 +145,7 @@
|
|||||||
"up_to_date": "Версия актуальна?"
|
"up_to_date": "Версия актуальна?"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"username": "Аккаунт на Piped",
|
"username": "Имя пользователя",
|
||||||
"password": "Пароль"
|
"password": "Пароль"
|
||||||
},
|
},
|
||||||
"video": {
|
"video": {
|
||||||
@ -157,7 +157,8 @@
|
|||||||
"live": "{0} В эфире",
|
"live": "{0} В эфире",
|
||||||
"chapters": "Содержание",
|
"chapters": "Содержание",
|
||||||
"shorts": "Shorts",
|
"shorts": "Shorts",
|
||||||
"all": "Все"
|
"all": "Все",
|
||||||
|
"category": "Категория"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "Может быть вы имели в виду: {0}?",
|
"did_you_mean": "Может быть вы имели в виду: {0}?",
|
||||||
@ -174,11 +175,11 @@
|
|||||||
"subscribed_channels_count": "Подписан на: {0}"
|
"subscribed_channels_count": "Подписан на: {0}"
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"preferences_note": "Примечание: настройки сохранены в локальном хранилище браузера. При удалении данных браузера они будут удалены.",
|
"preferences_note": "Примечание: настройки сохранены в локальном хранилище браузера. Удаление данных вашего браузера сбросит их.",
|
||||||
"copied": "Скопировано!",
|
"copied": "Скопировано!",
|
||||||
"cannot_copy": "Не получилось скопировать!",
|
"cannot_copy": "Не удалось скопировать!",
|
||||||
"page_not_found": "Страница не найдена",
|
"page_not_found": "Страница не найдена",
|
||||||
"local_storage": "Это действие требует локального хранилища (localStorage), разрешены ли файлы cookie?",
|
"local_storage": "Это действие требует разрешения localStorage, включены ли cookie-файлы?",
|
||||||
"register_no_email_note": "Использование электронной почты в качестве имени пользователя не рекомендуется. Продолжить?"
|
"register_no_email_note": "Использование электронной почты в качестве имени пользователя не рекомендуется. Продолжить?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,8 @@
|
|||||||
"shorts": "කෙටි වීඩියෝ",
|
"shorts": "කෙටි වීඩියෝ",
|
||||||
"ratings_disabled": "ශ්රේණිගත කිරීම් අබල කර ඇත",
|
"ratings_disabled": "ශ්රේණිගත කිරීම් අබල කර ඇත",
|
||||||
"live": "{0} සජීවී",
|
"live": "{0} සජීවී",
|
||||||
"all": "සියල්ල"
|
"all": "සියල්ල",
|
||||||
|
"category": "කාණ්ඩය"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "ඔබ අදහස් කළේ: {0}?",
|
"did_you_mean": "ඔබ අදහස් කළේ: {0}?",
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
"export_to_json": "JSON Olarak Dışa Aktar",
|
"export_to_json": "JSON Olarak Dışa Aktar",
|
||||||
"no": "Hayır",
|
"no": "Hayır",
|
||||||
"yes": "Evet",
|
"yes": "Evet",
|
||||||
"show_more": "Daha Fazla Göster",
|
"show_more": "Daha fazla göster",
|
||||||
"instance_selection": "Örnek Seçimi",
|
"instance_selection": "Örnek Seçimi",
|
||||||
"loading": "Yükleniyor...",
|
"loading": "Yükleniyor...",
|
||||||
"filter": "Filtrele",
|
"filter": "Filtrele",
|
||||||
@ -108,7 +108,8 @@
|
|||||||
"min_segment_length": "En Küçük Bölüm Uzunluğu (saniye cinsinden)",
|
"min_segment_length": "En Küçük Bölüm Uzunluğu (saniye cinsinden)",
|
||||||
"skip_segment": "Bölümü Atla",
|
"skip_segment": "Bölümü Atla",
|
||||||
"skip_button_only": "Atla düğmesini göster",
|
"skip_button_only": "Atla düğmesini göster",
|
||||||
"skip_automatically": "Otomatik olarak"
|
"skip_automatically": "Otomatik olarak",
|
||||||
|
"show_less": "Daha az göster"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"watch_on": "{0} Üzerinde İzle"
|
"watch_on": "{0} Üzerinde İzle"
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
"show_comments": "Hiển thị bình luận",
|
"show_comments": "Hiển thị bình luận",
|
||||||
"store_watch_history": "Lịch sử xem trên cửa hàng",
|
"store_watch_history": "Lịch sử xem trên cửa hàng",
|
||||||
"language_selection": "Lựa chọn ngôn ngữ",
|
"language_selection": "Lựa chọn ngôn ngữ",
|
||||||
"instances_list": "Danh sách phiên bản",
|
"instances_list": "Danh sách instance",
|
||||||
"show_more": "Hiện thị nhiều hơn",
|
"show_more": "Hiện thị nhiều hơn",
|
||||||
"import_from_json": "Nhập từ JSON/CSV",
|
"import_from_json": "Nhập từ JSON/CSV",
|
||||||
"loop_this_video": "Lặp lại video này",
|
"loop_this_video": "Lặp lại video này",
|
||||||
@ -53,7 +53,7 @@
|
|||||||
"light": "Sáng",
|
"light": "Sáng",
|
||||||
"audio_only": "Chỉ có âm thanh",
|
"audio_only": "Chỉ có âm thanh",
|
||||||
"minimize_description_default": "Thu nhỏ mô tả theo mặc định",
|
"minimize_description_default": "Thu nhỏ mô tả theo mặc định",
|
||||||
"instance_selection": "Lựa chọn phiên bản",
|
"instance_selection": "Lựa chọn instance",
|
||||||
"yes": "Có",
|
"yes": "Có",
|
||||||
"enabled_codecs": "Các codec được bật (Nhiều)",
|
"enabled_codecs": "Các codec được bật (Nhiều)",
|
||||||
"export_to_json": "Xuất định dạng JSON",
|
"export_to_json": "Xuất định dạng JSON",
|
||||||
@ -78,7 +78,8 @@
|
|||||||
"minimize_comments": "Thu nhỏ bình luận",
|
"minimize_comments": "Thu nhỏ bình luận",
|
||||||
"reply_count": "{count} phản hồi",
|
"reply_count": "{count} phản hồi",
|
||||||
"status_page": "Trạng thái",
|
"status_page": "Trạng thái",
|
||||||
"new_playlist_name": "Tên danh sách phát mới"
|
"new_playlist_name": "Tên danh sách phát mới",
|
||||||
|
"skip_automatically": "Tự động"
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"register": "Đăng ký",
|
"register": "Đăng ký",
|
||||||
@ -92,7 +93,8 @@
|
|||||||
"account": "Tài khoản",
|
"account": "Tài khoản",
|
||||||
"channels": "Kênh",
|
"channels": "Kênh",
|
||||||
"instance": "Instance",
|
"instance": "Instance",
|
||||||
"player": "Trình phát video"
|
"player": "Trình phát video",
|
||||||
|
"livestreams": "Phát sóng trực tiếp"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"watch_on": "Xem trên {0}"
|
"watch_on": "Xem trên {0}"
|
||||||
@ -104,8 +106,8 @@
|
|||||||
"disabled": "Bình luận đã bị tắt bởi người đăng video."
|
"disabled": "Bình luận đã bị tắt bởi người đăng video."
|
||||||
},
|
},
|
||||||
"preferences": {
|
"preferences": {
|
||||||
"instance_name": "Tên phiên bản",
|
"instance_name": "Tên instance",
|
||||||
"instance_locations": "Vị trí phiên bản",
|
"instance_locations": "Vị trí instance",
|
||||||
"has_cdn": "Có CDN?",
|
"has_cdn": "Có CDN?",
|
||||||
"registered_users": "Người dùng đã đăng ký",
|
"registered_users": "Người dùng đã đăng ký",
|
||||||
"version": "Phiên bản",
|
"version": "Phiên bản",
|
||||||
@ -124,7 +126,8 @@
|
|||||||
"live": "{0} Trực tiếp",
|
"live": "{0} Trực tiếp",
|
||||||
"chapters": "Chương",
|
"chapters": "Chương",
|
||||||
"videos": "Video",
|
"videos": "Video",
|
||||||
"shorts": "Shorts"
|
"shorts": "Shorts",
|
||||||
|
"all": "Tất cả"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"did_you_mean": "Ý của bạn là: {0}?",
|
"did_you_mean": "Ý của bạn là: {0}?",
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
"least_recent": "最早的",
|
"least_recent": "最早的",
|
||||||
"most_recent": "最新的",
|
"most_recent": "最新的",
|
||||||
"sort_by": "排序:",
|
"sort_by": "排序:",
|
||||||
"view_subscriptions": "查看订阅",
|
"view_subscriptions": "查看订阅列表",
|
||||||
"unsubscribe": "取消订阅 - {count}",
|
"unsubscribe": "取消订阅 - {count}",
|
||||||
"subscribe": "订阅 - {count}",
|
"subscribe": "订阅 - {count}",
|
||||||
"loading": "正在加载...",
|
"loading": "正在加载...",
|
||||||
@ -108,7 +108,8 @@
|
|||||||
"skip_automatically": "自动",
|
"skip_automatically": "自动",
|
||||||
"min_segment_length": "最小分段长度(以秒为单位)",
|
"min_segment_length": "最小分段长度(以秒为单位)",
|
||||||
"skip_segment": "跳过分段",
|
"skip_segment": "跳过分段",
|
||||||
"skip_button_only": "显示跳过按钮"
|
"skip_button_only": "显示跳过按钮",
|
||||||
|
"show_less": "显示更少"
|
||||||
},
|
},
|
||||||
"video": {
|
"video": {
|
||||||
"sponsor_segments": "赞助商部分",
|
"sponsor_segments": "赞助商部分",
|
||||||
@ -141,8 +142,8 @@
|
|||||||
"watch_on": "在 {0} 观看"
|
"watch_on": "在 {0} 观看"
|
||||||
},
|
},
|
||||||
"titles": {
|
"titles": {
|
||||||
"feed": "RSS 订阅源",
|
"feed": "订阅流",
|
||||||
"subscriptions": "订阅",
|
"subscriptions": "订阅列表",
|
||||||
"history": "历史",
|
"history": "历史",
|
||||||
"preferences": "设置",
|
"preferences": "设置",
|
||||||
"register": "注册",
|
"register": "注册",
|
||||||
|
@ -27,7 +27,7 @@ const routes = [
|
|||||||
component: () => import("../components/PlaylistPage.vue"),
|
component: () => import("../components/PlaylistPage.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/:path(v|w|embed|shorts|watch)/:v?",
|
path: "/:path(v|w|embed|live|shorts|watch)/:v?",
|
||||||
name: "WatchVideo",
|
name: "WatchVideo",
|
||||||
component: () => import("../components/WatchVideo.vue"),
|
component: () => import("../components/WatchVideo.vue"),
|
||||||
},
|
},
|
||||||
@ -41,6 +41,11 @@ const routes = [
|
|||||||
name: "Channel",
|
name: "Channel",
|
||||||
component: () => import("../components/ChannelPage.vue"),
|
component: () => import("../components/ChannelPage.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/@:channelId",
|
||||||
|
name: "Channel handle",
|
||||||
|
component: () => import("../components/ChannelPage.vue"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "Login",
|
name: "Login",
|
||||||
|
@ -4,12 +4,12 @@ import { Buffer } from "buffer";
|
|||||||
window.Buffer = Buffer;
|
window.Buffer = Buffer;
|
||||||
import { json2xml } from "xml-js";
|
import { json2xml } from "xml-js";
|
||||||
|
|
||||||
const DashUtils = {
|
export function generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
||||||
generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
const generatedJSON = generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
||||||
const generatedJSON = this.generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
|
||||||
return json2xml(generatedJSON);
|
return json2xml(generatedJSON);
|
||||||
},
|
}
|
||||||
generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
|
||||||
|
function generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
||||||
const convertJSON = {
|
const convertJSON = {
|
||||||
declaration: {
|
declaration: {
|
||||||
attributes: {
|
attributes: {
|
||||||
@ -32,22 +32,26 @@ const DashUtils = {
|
|||||||
{
|
{
|
||||||
type: "element",
|
type: "element",
|
||||||
name: "Period",
|
name: "Period",
|
||||||
elements: this.generate_adaptation_set(VideoFormatArray),
|
elements: generate_adaptation_set(VideoFormatArray),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
return convertJSON;
|
return convertJSON;
|
||||||
},
|
}
|
||||||
generate_adaptation_set(VideoFormatArray) {
|
|
||||||
|
function generate_adaptation_set(VideoFormatArray) {
|
||||||
const adaptationSets = [];
|
const adaptationSets = [];
|
||||||
|
|
||||||
let mimeAudioObjs = [];
|
let mimeAudioObjs = [];
|
||||||
|
|
||||||
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.includes("video") && !videoFormat.videoOnly) ||
|
||||||
|
videoFormat.mimeType.includes("application")
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,17 +101,18 @@ const DashUtils = {
|
|||||||
for (var i = 0; i < mimeAudioObj.videoFormats.length; i++) {
|
for (var i = 0; i < mimeAudioObj.videoFormats.length; i++) {
|
||||||
const videoFormat = mimeAudioObj.videoFormats[i];
|
const videoFormat = mimeAudioObj.videoFormats[i];
|
||||||
if (isVideoFormat) {
|
if (isVideoFormat) {
|
||||||
adapSet.elements.push(this.generate_representation_video(videoFormat));
|
adapSet.elements.push(generate_representation_video(videoFormat));
|
||||||
} else {
|
} else {
|
||||||
adapSet.elements.push(this.generate_representation_audio(videoFormat));
|
adapSet.elements.push(generate_representation_audio(videoFormat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adaptationSets.push(adapSet);
|
adaptationSets.push(adapSet);
|
||||||
});
|
});
|
||||||
return adaptationSets;
|
return adaptationSets;
|
||||||
},
|
}
|
||||||
generate_representation_audio(Format) {
|
|
||||||
|
function generate_representation_audio(Format) {
|
||||||
const representation = {
|
const representation = {
|
||||||
type: "element",
|
type: "element",
|
||||||
name: "Representation",
|
name: "Representation",
|
||||||
@ -154,8 +159,9 @@ const DashUtils = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
return representation;
|
return representation;
|
||||||
},
|
}
|
||||||
generate_representation_video(Format) {
|
|
||||||
|
function generate_representation_video(Format) {
|
||||||
const representation = {
|
const representation = {
|
||||||
type: "element",
|
type: "element",
|
||||||
name: "Representation",
|
name: "Representation",
|
||||||
@ -198,7 +204,4 @@ const DashUtils = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
return representation;
|
return representation;
|
||||||
},
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export default DashUtils;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user