mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-08-14 23:57:27 +00:00
Merge remote-tracking branch 'upstream/master' into feature-add-seen
This commit is contained in:
commit
65bf960c96
97 changed files with 5952 additions and 2954 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -22,7 +22,7 @@ body:
|
|||
label: Official Instance
|
||||
description: Can the bug be reproduced on the official instance?
|
||||
options:
|
||||
- label: The bug is reproducable on the [official hosted instance](http://piped.kavin.rocks/) or is API related.
|
||||
- label: The bug is reproducable on the [official hosted instance](http://piped.video/) or is API related.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
|
|
30
.github/workflows/deploy-azure.yml
vendored
Normal file
30
.github/workflows/deploy-azure.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
name: Azure Static Web Apps CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build_and_deploy_job:
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
name: Build and Deploy Job
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: true
|
||||
- name: Build And Deploy
|
||||
id: builddeploy
|
||||
uses: Azure/static-web-apps-deploy@v1
|
||||
with:
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_LEMON_WATER_0063A7F03 }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
|
||||
action: "upload"
|
||||
###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
|
||||
# For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
|
||||
app_location: "/" # App source code path
|
||||
app_build_command: "yarn build && ./localizefonts.sh"
|
||||
api_location: "" # Api source code path - optional
|
||||
output_location: "dist" # Built app content directory - optional
|
||||
###### End of Repository/Build Configurations ######
|
4
.github/workflows/docker-build.yml
vendored
4
.github/workflows/docker-build.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
with:
|
||||
cache: "yarn"
|
||||
- run: yarn install --prefer-offline
|
||||
- run: yarn build --out-dir dist-ci && sed -i 's/fonts.gstatic.com/fonts.kavin.rocks/g' dist-ci/assets/*.css
|
||||
- run: yarn build && ./localizefonts.sh && mv dist/ dist-ci/
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
with:
|
||||
|
@ -33,7 +33,7 @@ jobs:
|
|||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.ci
|
||||
|
|
2
.github/workflows/ipfs-build.yml
vendored
2
.github/workflows/ipfs-build.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
with:
|
||||
cache: "yarn"
|
||||
- run: yarn install --prefer-offline
|
||||
- run: yarn build && sed -i 's/fonts.gstatic.com/fonts.kavin.rocks/g' dist/assets/*.css && cp dist/index.html dist/ipfs-404.html
|
||||
- run: yarn build && ./localizefonts.sh && cp dist/index.html dist/ipfs-404.html
|
||||
- uses: aquiladev/ipfs-action@v0.3.1-alpha.2
|
||||
id: ipfs-add
|
||||
with:
|
||||
|
|
22
.github/workflows/weblate-merge.yml
vendored
Normal file
22
.github/workflows/weblate-merge.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
name: Merge Weblate translations
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened]
|
||||
|
||||
jobs:
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Check if en.json has been updated
|
||||
run: |
|
||||
if -n git diff ${{ github.event.pull_request.base.sha }}..${{ github.sha }} src/locales/en.json; then
|
||||
exit 1
|
||||
fi
|
||||
- name: AutoMerge Weblate translations
|
||||
if: github.event.pull_request.user.login == 'weblate'
|
||||
run: gh pr merge --auto --delete-branch --merge "$PR_URL"
|
||||
env:
|
||||
PR_URL: ${{github.event.pull_request.html_url}}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -2,12 +2,16 @@ FROM node:lts-alpine AS build
|
|||
|
||||
WORKDIR /app/
|
||||
|
||||
RUN --mount=type=cache,target=/var/cache/apk \
|
||||
apk add --no-cache \
|
||||
curl
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN --mount=type=cache,target=/root/.cache/yarn \
|
||||
--mount=type=cache,target=/app/node_modules \
|
||||
yarn install --prefer-offline && \
|
||||
yarn build && sed -i 's/fonts.gstatic.com/fonts.kavin.rocks/g' dist/assets/*.css
|
||||
yarn build && ./localizefonts.sh
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
|
|
25
README.md
25
README.md
|
@ -2,7 +2,7 @@
|
|||
|
||||
[](https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
[](https://matrix.to/#/#piped:matrix.org)
|
||||
[](https://piped.kavin.rocks/register)
|
||||
[](https://piped.video/register)
|
||||
[](https://piped-ipfs.kavin.rocks/)
|
||||
[](https://github.com/TeamPiped/Piped/stargazers)
|
||||
[](https://github.com/TeamPiped/Piped/commits)
|
||||
|
@ -39,6 +39,7 @@ By using Piped, you can freely watch and listen to content without the fear of p
|
|||
- [x] [Available in many languages](src/locales), thanks to [our translators](https://hosted.weblate.org/projects/piped/frontend/)
|
||||
- [x] Embedded video support
|
||||
- [x] No age restriction
|
||||
- [x] Bypasses Geo restrictions if possible through a federated network
|
||||
|
||||
**Technical Features**
|
||||
|
||||
|
@ -46,7 +47,8 @@ By using Piped, you can freely watch and listen to content without the fear of p
|
|||
- [x] Performant by design, designed to handle 1000s of users concurrently
|
||||
- [x] Does not use official YouTube APIs
|
||||
- [x] Uses [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor) to extract information
|
||||
- [x] Public [JSON API](https://piped-docs.kavin.rocks/docs/api-documentation/)
|
||||
- [x] Public [JSON API](https://docs.piped.video/docs/api-documentation/)
|
||||
- [x] Federated protocol on Matrix to let instances collaborate with each other
|
||||
|
||||
## Screenshots
|
||||
|
||||
|
@ -61,13 +63,13 @@ By using Piped, you can freely watch and listen to content without the fear of p
|
|||
|
||||
## Self-Hosting
|
||||
|
||||
See https://piped-docs.kavin.rocks/docs/self-hosting/ for more details.
|
||||
See https://docs.piped.video/docs/self-hosting/ for more details.
|
||||
|
||||
The source code of the documentation website is available at https://github.com/TeamPiped/Documentation.
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation can be found at https://piped-docs.kavin.rocks (accessible via IPNS as well).
|
||||
The documentation can be found at https://docs.piped.video (accessible via IPNS as well).
|
||||
|
||||
## Extensions
|
||||
|
||||
|
@ -79,6 +81,16 @@ To redirect all YouTube links to Piped, you are highly recommended to use either
|
|||
|
||||
You can help by translating the project to a language you speak at https://hosted.weblate.org/projects/piped/frontend/
|
||||
|
||||
### Mirrors
|
||||
|
||||
- Cloudflare Pages - [cf.piped.video](https://cf.piped.video/)
|
||||
- Vercel - [vc.piped.video](https://vc.piped.video/)
|
||||
- Render - [re.piped.video](https://re.piped.video/)
|
||||
- Fleek - [fl.piped.video](https://fl.piped.video/)
|
||||
- DigitalOcean - [do.piped.video](https://do.piped.video/)
|
||||
- Netlify - [nf.piped.video](https://nf.piped.video/)
|
||||
- Azure - [az.piped.video](https://az.piped.video/)
|
||||
|
||||
### Forking, and contributing
|
||||
|
||||
- Fork the repository on GitHub: https://github.com/TeamPiped/Piped/fork
|
||||
|
@ -129,6 +141,11 @@ Contributions in any other form are also welcomed.
|
|||
- [Yattee](https://github.com/yattee/yattee) - an alternative frontend for YouTube, for IOS.
|
||||
- [LibreTube](https://github.com/Libre-tube/LibreTube) - an alternative frontend for YouTube, for Android.
|
||||
- [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.
|
||||
- [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 on Android, Linux, Windows, iOS, and Mac OSX.
|
||||
- [Piped-Material](https://github.com/mmjee/Piped-Material) - A fork of Piped, focusing on better performance and a more usable design.
|
||||
- [ReacTube](https://github.com/NeeRaj-2401/ReacTube) - Privacy friendly & distraction free Youtube front-end using Piped API.
|
||||
|
||||
## YourKit
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ server {
|
|||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
error_log off;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="background: #0f0f0f" lang="en">
|
||||
<html style="background: #0f0f0f" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
@ -7,6 +7,7 @@
|
|||
<link rel="icon" href="/favicon.ico" />
|
||||
<link title="Piped" type="application/opensearchdescription+xml" rel="search" href="/opensearch.xml" />
|
||||
<title>Piped</title>
|
||||
<meta name="theme-color" content="#0f0f0f">
|
||||
<meta property="og:title" content="Piped" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="/img/icons/favicon-32x32.png" />
|
||||
|
|
10
localizefonts.sh
Executable file
10
localizefonts.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
base='https://fonts\.(gstatic\.com|kavin\.rocks)'
|
||||
fonts=$(cat dist/assets/* | grep -Po "$base[^)]*" | sort | uniq)
|
||||
for font in $fonts; do
|
||||
file="dist/fonts$(echo "$font" | sed -E "s#$base##")"
|
||||
mkdir -p "$(dirname "$file")"
|
||||
curl -L "$font" -o "$file"
|
||||
done
|
||||
sed -Ei "s#$base#/fonts#g" dist/assets/*
|
49
package.json
49
package.json
|
@ -6,44 +6,45 @@
|
|||
"serve": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"format": "prettier -w --ignore-path .gitignore **/**.{js,vue}",
|
||||
"lint": "eslint --fix --color --ignore-path .gitignore --ext .js,.vue ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "6.2.0",
|
||||
"@fortawesome/free-brands-svg-icons": "6.2.0",
|
||||
"@fortawesome/free-solid-svg-icons": "6.2.0",
|
||||
"@fortawesome/vue-fontawesome": "3.0.2",
|
||||
"@fortawesome/fontawesome-svg-core": "6.4.0",
|
||||
"@fortawesome/free-brands-svg-icons": "6.4.0",
|
||||
"@fortawesome/free-solid-svg-icons": "6.4.0",
|
||||
"@fortawesome/vue-fontawesome": "3.0.3",
|
||||
"buffer": "6.0.3",
|
||||
"dompurify": "2.4.0",
|
||||
"hotkeys-js": "3.10.0",
|
||||
"dompurify": "3.0.2",
|
||||
"hotkeys-js": "3.10.2",
|
||||
"javascript-time-ago": "2.5.9",
|
||||
"mux.js": "6.2.0",
|
||||
"shaka-player": "4.2.3",
|
||||
"mux.js": "6.3.0",
|
||||
"shaka-player": "4.3.6",
|
||||
"stream-browserify": "3.0.0",
|
||||
"vue": "3.2.43",
|
||||
"vue": "3.2.47",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-router": "4.1.6",
|
||||
"xml-js": "1.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "2.1.135",
|
||||
"@iconify/json": "2.2.58",
|
||||
"@intlify/vite-plugin-vue-i18n": "6.0.3",
|
||||
"@unocss/preset-icons": "0.46.4",
|
||||
"@unocss/preset-web-fonts": "0.46.4",
|
||||
"@unocss/transformer-directives": "0.46.4",
|
||||
"@unocss/transformer-variant-group": "0.46.4",
|
||||
"@vitejs/plugin-legacy": "2.3.1",
|
||||
"@vitejs/plugin-vue": "3.2.0",
|
||||
"@vue/compiler-sfc": "3.2.43",
|
||||
"eslint": "8.27.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"@unocss/preset-icons": "0.51.8",
|
||||
"@unocss/preset-web-fonts": "0.51.8",
|
||||
"@unocss/transformer-directives": "0.51.8",
|
||||
"@unocss/transformer-variant-group": "0.51.8",
|
||||
"@vitejs/plugin-legacy": "4.0.3",
|
||||
"@vitejs/plugin-vue": "4.2.1",
|
||||
"@vue/compiler-sfc": "3.2.47",
|
||||
"eslint": "8.39.0",
|
||||
"eslint-config-prettier": "8.8.0",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-vue": "9.7.0",
|
||||
"prettier": "2.7.1",
|
||||
"unocss": "0.46.4",
|
||||
"vite": "3.2.3",
|
||||
"eslint-plugin-vue": "9.11.0",
|
||||
"prettier": "2.8.8",
|
||||
"unocss": "0.51.8",
|
||||
"vite": "4.3.4",
|
||||
"vite-plugin-eslint": "1.8.1",
|
||||
"vite-plugin-pwa": "0.13.3"
|
||||
"vite-plugin-pwa": "0.14.7"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
|
1
public/_redirects
Normal file
1
public/_redirects
Normal file
|
@ -0,0 +1 @@
|
|||
/* /index.html 200
|
|
@ -4,7 +4,7 @@
|
|||
<LongName>Piped Search</LongName>
|
||||
<Description>Search for videos, channels, and playlists on Piped</Description>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Image width="48" height="48" type="image/x-icon">https://piped.kavin.rocks/favicon.ico</Image>
|
||||
<Url method="get" rel="results" type="text/html" template="https://piped.kavin.rocks/results?search_query={searchTerms}" />
|
||||
<Image width="48" height="48" type="image/x-icon">https://piped.video/favicon.ico</Image>
|
||||
<Url method="get" rel="results" type="text/html" template="https://piped.video/results?search_query={searchTerms}" />
|
||||
<Url method="get" rel="suggestions" type="application/x-suggestions+json" template="https://pipedapi.kavin.rocks/opensearch/suggestions?query={searchTerms}" />
|
||||
</OpenSearchDescription>
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow:
|
||||
Disallow: /
|
||||
|
|
|
@ -17,5 +17,10 @@
|
|||
],
|
||||
"groupName": "unocss"
|
||||
}
|
||||
]
|
||||
],
|
||||
"lockFileMaintenance": {
|
||||
"enabled": true,
|
||||
"automerge": true
|
||||
},
|
||||
"platformAutomerge": true
|
||||
}
|
||||
|
|
113
src/App.vue
113
src/App.vue
|
@ -1,12 +1,13 @@
|
|||
<template>
|
||||
<div class="w-full min-h-screen px-1vw reset" :class="[theme]">
|
||||
<NavBar />
|
||||
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :max="5">
|
||||
<component :is="Component" :key="$route.fullPath" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
<div class="flex flex-col w-full min-h-screen px-1vw py-5 antialiased reset" :class="[theme]">
|
||||
<div class="flex-1">
|
||||
<NavBar />
|
||||
<router-view v-slot="{ Component }">
|
||||
<keep-alive :max="5">
|
||||
<component :is="Component" :key="$route.fullPath" />
|
||||
</keep-alive>
|
||||
</router-view>
|
||||
</div>
|
||||
|
||||
<FooterComponent />
|
||||
</div>
|
||||
|
@ -33,6 +34,18 @@ export default {
|
|||
let themePref = this.getPreferenceString("theme", "dark");
|
||||
if (themePref == "auto") this.theme = darkModePreference.matches ? "dark" : "light";
|
||||
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
|
||||
const root = document.querySelector(":root");
|
||||
this.theme == "dark" ? root.classList.add("dark") : root.classList.remove("dark");
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
@ -40,29 +53,30 @@ export default {
|
|||
darkModePreference.addEventListener("change", () => {
|
||||
this.setTheme();
|
||||
});
|
||||
if (this.getPreferenceBoolean("watchHistory", false) || this.getPreferenceBoolean("hideWatched", false)) {
|
||||
if ("indexedDB" in window) {
|
||||
const request = indexedDB.open("piped-db", 2);
|
||||
request.onupgradeneeded = ev => {
|
||||
const db = request.result;
|
||||
console.log("Upgrading object store.");
|
||||
if (!db.objectStoreNames.contains("watch_history")) {
|
||||
const store = db.createObjectStore("watch_history", { keyPath: "videoId" });
|
||||
store.createIndex("video_id_idx", "videoId", { unique: true });
|
||||
store.createIndex("id_idx", "id", { unique: true, autoIncrement: true });
|
||||
}
|
||||
if (ev.oldVersion < 2) {
|
||||
const store = request.transaction.objectStore("watch_history");
|
||||
store.createIndex("watchedAt", "watchedAt", { unique: false });
|
||||
}
|
||||
};
|
||||
request.onsuccess = e => {
|
||||
window.db = e.target.result;
|
||||
};
|
||||
} else {
|
||||
console.log("This browser doesn't support IndexedDB");
|
||||
}
|
||||
}
|
||||
if ("indexedDB" in window) {
|
||||
const request = indexedDB.open("piped-db", 3);
|
||||
request.onupgradeneeded = ev => {
|
||||
const db = request.result;
|
||||
console.log("Upgrading object store.");
|
||||
if (!db.objectStoreNames.contains("watch_history")) {
|
||||
const store = db.createObjectStore("watch_history", { keyPath: "videoId" });
|
||||
store.createIndex("video_id_idx", "videoId", { unique: true });
|
||||
store.createIndex("id_idx", "id", { unique: true, autoIncrement: true });
|
||||
}
|
||||
if (ev.oldVersion < 2) {
|
||||
const store = request.transaction.objectStore("watch_history");
|
||||
store.createIndex("watchedAt", "watchedAt", { unique: false });
|
||||
}
|
||||
if (!db.objectStoreNames.contains("playlist_bookmarks")) {
|
||||
const store = db.createObjectStore("playlist_bookmarks", { keyPath: "playlistId" });
|
||||
store.createIndex("playlist_id_idx", "playlistId", { unique: true });
|
||||
store.createIndex("id_idx", "id", { unique: true, autoIncrement: true });
|
||||
}
|
||||
};
|
||||
request.onsuccess = e => {
|
||||
window.db = e.target.result;
|
||||
};
|
||||
} else console.log("This browser doesn't support IndexedDB");
|
||||
|
||||
const App = this;
|
||||
|
||||
|
@ -99,8 +113,12 @@ b {
|
|||
text-align: start;
|
||||
}
|
||||
|
||||
:root {
|
||||
color-scheme: only light;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
background-color: #15191a;
|
||||
background-color: #d1d5db;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
|
@ -119,13 +137,40 @@ b {
|
|||
background-color: #0b0e0f;
|
||||
}
|
||||
|
||||
:root {
|
||||
scrollbar-color: #4b4f52 #d1d5db;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar {
|
||||
background-color: #15191a;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb {
|
||||
background-color: #4b4f52;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #5b6469;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-thumb:active {
|
||||
background-color: #485053;
|
||||
}
|
||||
|
||||
.dark ::-webkit-scrollbar-corner {
|
||||
background-color: #0b0e0f;
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
scrollbar-color: #4b4f52 #15191a;
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-color: #15191a #444a4e;
|
||||
@apply font-sans;
|
||||
}
|
||||
|
||||
.video-grid {
|
||||
@apply grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 col-auto lt-md:gap-x-2.5 md:gap-x-1vw gap-y-1.5;
|
||||
@apply grid grid-cols-1 mx-2 sm:mx-0 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 col-auto lt-md:gap-x-3 md:gap-x-6 gap-y-5;
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
|
|
@ -1,43 +1,64 @@
|
|||
<template>
|
||||
<ErrorHandler v-if="channel && channel.error" :message="channel.message" :error="channel.error" />
|
||||
|
||||
<div v-if="channel" v-show="!channel.error">
|
||||
<div class="flex justify-center place-items-center">
|
||||
<img height="48" width="48" class="rounded-full m-1" :src="channel.avatarUrl" />
|
||||
<h1 v-text="channel.name" />
|
||||
<font-awesome-icon class="ml-1.5 !text-3xl" v-if="channel.verified" icon="check" />
|
||||
<LoadingIndicatorPage :show-content="channel != null && !channel.error">
|
||||
<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" />
|
||||
<div class="flex gap-1 items-center">
|
||||
<h1 v-text="channel.name" class="!text-xl" />
|
||||
<font-awesome-icon class="!text-xl" v-if="channel.verified" icon="check" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
class="btn"
|
||||
@click="subscribeHandler"
|
||||
v-t="{
|
||||
path: `actions.${subscribed ? 'unsubscribe' : 'subscribe'}`,
|
||||
args: { count: numberFormat(channel.subscriberCount) },
|
||||
}"
|
||||
></button>
|
||||
|
||||
<!-- RSS Feed button -->
|
||||
<a
|
||||
aria-label="RSS feed"
|
||||
title="RSS feed"
|
||||
role="button"
|
||||
v-if="channel.id"
|
||||
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${channel.id}`"
|
||||
target="_blank"
|
||||
class="btn flex-col"
|
||||
>
|
||||
<font-awesome-icon icon="rss" />
|
||||
</a>
|
||||
</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(urlify(channel.description))" />
|
||||
</p>
|
||||
|
||||
<button
|
||||
class="btn"
|
||||
@click="subscribeHandler"
|
||||
v-t="{
|
||||
path: `actions.${subscribed ? 'unsubscribe' : 'subscribe'}`,
|
||||
args: { count: numberFormat(channel.subscriberCount) },
|
||||
}"
|
||||
></button>
|
||||
|
||||
<!-- RSS Feed button -->
|
||||
<a
|
||||
aria-label="RSS feed"
|
||||
title="RSS feed"
|
||||
role="button"
|
||||
v-if="channel.id"
|
||||
:href="`${apiUrl()}/feed/unauthenticated/rss?channels=${channel.id}`"
|
||||
target="_blank"
|
||||
class="btn flex-col mx-3"
|
||||
>
|
||||
<font-awesome-icon icon="rss" />
|
||||
</a>
|
||||
<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}`" />
|
||||
|
||||
<div class="flex mt-4 mb-2">
|
||||
<div class="flex my-2 mx-1">
|
||||
<button
|
||||
v-for="(tab, index) in tabs"
|
||||
:key="tab.name"
|
||||
|
@ -61,19 +82,21 @@
|
|||
hide-channel
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</LoadingIndicatorPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ErrorHandler from "./ErrorHandler.vue";
|
||||
import ContentItem from "./ContentItem.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ErrorHandler,
|
||||
ContentItem,
|
||||
WatchOnYouTubeButton,
|
||||
LoadingIndicatorPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -82,6 +105,7 @@ export default {
|
|||
tabs: [],
|
||||
selectedTab: 0,
|
||||
contentItems: [],
|
||||
fullDescription: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
@ -121,7 +145,9 @@ export default {
|
|||
});
|
||||
},
|
||||
async fetchChannel() {
|
||||
const url = this.apiUrl() + "/" + this.$route.params.path + "/" + this.$route.params.channelId;
|
||||
const url = this.$route.path.includes("@")
|
||||
? this.apiUrl() + "/@/" + this.$route.params.channelId
|
||||
: this.apiUrl() + "/" + this.$route.params.path + "/" + this.$route.params.channelId;
|
||||
return await this.fetchJson(url);
|
||||
},
|
||||
async getChannelData() {
|
||||
|
@ -136,10 +162,12 @@ export default {
|
|||
this.tabs.push({
|
||||
translatedName: this.$t("video.videos"),
|
||||
});
|
||||
const tabQuery = this.$route.query.tab;
|
||||
for (let i = 0; i < this.channel.tabs.length; i++) {
|
||||
let tab = this.channel.tabs[i];
|
||||
tab.translatedName = this.getTranslatedTabName(tab.name);
|
||||
this.tabs.push(tab);
|
||||
if (tab.name === tabQuery) this.loadTab(i + 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -195,23 +223,23 @@ export default {
|
|||
},
|
||||
});
|
||||
} else {
|
||||
this.handleLocalSubscriptions(this.channel.id);
|
||||
if (!this.handleLocalSubscriptions(this.channel.id)) return;
|
||||
}
|
||||
this.subscribed = !this.subscribed;
|
||||
},
|
||||
getTranslatedTabName(tabName) {
|
||||
let translatedTabName = tabName;
|
||||
switch (tabName) {
|
||||
case "Livestreams":
|
||||
case "livestreams":
|
||||
translatedTabName = this.$t("titles.livestreams");
|
||||
break;
|
||||
case "Playlists":
|
||||
case "playlists":
|
||||
translatedTabName = this.$t("titles.playlists");
|
||||
break;
|
||||
case "Channels":
|
||||
case "channels":
|
||||
translatedTabName = this.$t("titles.channels");
|
||||
break;
|
||||
case "Shorts":
|
||||
case "shorts":
|
||||
translatedTabName = this.$t("video.shorts");
|
||||
break;
|
||||
default:
|
||||
|
@ -222,10 +250,17 @@ export default {
|
|||
},
|
||||
loadTab(index) {
|
||||
this.selectedTab = index;
|
||||
|
||||
// update the tab query in the url path
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.set("tab", this.tabs[index].name ?? "videos");
|
||||
window.history.replaceState(window.history.state, "", url);
|
||||
|
||||
if (index == 0) {
|
||||
this.contentItems = this.channel.relatedStreams;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.tabs[index].content) {
|
||||
this.contentItems = this.tabs[index].content;
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!-- desktop view -->
|
||||
<div v-if="!mobileLayout" class="flex-col overflow-y-scroll max-h-75vh min-h-64 lt-lg:hidden">
|
||||
<div v-if="!mobileLayout" class="flex-col overflow-y-scroll max-w-35vw max-h-75vh min-h-64 lt-lg:hidden">
|
||||
<h2 class="mb-2 bg-gray-500/50 p-2" aria-label="chapters" title="chapters">
|
||||
{{ $t("video.chapters") }} ({{ chapters.length }})
|
||||
</h2>
|
||||
|
@ -13,7 +13,7 @@
|
|||
>
|
||||
<div class="flex">
|
||||
<span class="mt-5 mr-2 text-current" v-text="index + 1" />
|
||||
<img :src="chapter.image" :alt="chapter.title" />
|
||||
<img class="shrink-0" :src="chapter.image" :alt="chapter.title" />
|
||||
<div class="flex flex-col m-2">
|
||||
<span class="text-sm" :title="chapter.title" v-text="chapter.title" />
|
||||
<span class="text-sm font-bold text-blue-500" v-text="timeFormat(chapter.start)" />
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
<div class="comment-meta text-sm mb-1.5" v-text="comment.commentedTime" />
|
||||
</div>
|
||||
<div class="whitespace-pre-wrap" v-html="urlify(comment.commentText)" />
|
||||
<div class="whitespace-pre-wrap" v-html="purifyHTML(comment.commentText)" />
|
||||
<div class="comment-footer mt-1 flex items-center">
|
||||
<div class="i-fa-solid:thumbs-up" />
|
||||
<span class="ml-1" v-text="numberFormat(comment.likeCount)" />
|
||||
|
|
|
@ -11,38 +11,45 @@
|
|||
</a>
|
||||
</span>
|
||||
|
||||
<label for="filters" class="ml-10 mr-2">
|
||||
<strong v-text="`${$t('actions.filter')}:`" />
|
||||
</label>
|
||||
<select id="filters" v-model="selectedFilter" default="all" class="select w-auto" @change="onFilterChange()">
|
||||
<option v-for="filter in availableFilters" :key="filter" :value="filter" v-t="`video.${filter}`" />
|
||||
</select>
|
||||
|
||||
<span class="md:float-right">
|
||||
<SortingSelector by-key="uploaded" @apply="order => videos.sort(order)" />
|
||||
</span>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="video-grid">
|
||||
<VideoItem
|
||||
:is-feed="true"
|
||||
v-for="video in videos"
|
||||
:key="video.url"
|
||||
:item="video"
|
||||
@update:watched="onUpdateWatched"
|
||||
/>
|
||||
</div>
|
||||
<LoadingIndicatorPage :show-content="videosStore != null" class="video-grid">
|
||||
<template v-for="video in videos" :key="video.url">
|
||||
<VideoItem v-if="shouldShowVideo(video)" :is-feed="true" :item="video" @update:watched="onUpdateWatched" />
|
||||
</template>
|
||||
</LoadingIndicatorPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VideoItem from "./VideoItem.vue";
|
||||
import SortingSelector from "./SortingSelector.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VideoItem,
|
||||
SortingSelector,
|
||||
LoadingIndicatorPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentVideoCount: 0,
|
||||
videoStep: 100,
|
||||
videosStore: [],
|
||||
videosStore: null,
|
||||
videos: [],
|
||||
availableFilters: ["all", "shorts", "videos"],
|
||||
selectedFilter: "all",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -57,6 +64,8 @@ export default {
|
|||
this.loadMoreVideos();
|
||||
this.updateWatched(this.videos);
|
||||
});
|
||||
|
||||
this.selectedFilter = this.getPreferenceString("feedFilter") ?? "all";
|
||||
},
|
||||
activated() {
|
||||
document.title = this.$t("titles.feed") + " - Piped";
|
||||
|
@ -100,6 +109,19 @@ export default {
|
|||
const subset = this.videos.filter(({ url }) => urls.includes(url));
|
||||
if (subset.length > 0) this.updateWatched(subset);
|
||||
},
|
||||
shouldShowVideo(video) {
|
||||
switch (this.selectedFilter.toLowerCase()) {
|
||||
case "shorts":
|
||||
return video.isShort;
|
||||
case "videos":
|
||||
return !video.isShort;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
},
|
||||
onFilterChange() {
|
||||
this.setPreference("feedFilter", this.selectedFilter);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<template>
|
||||
<footer class="text-center py-4 rounded-xl children:(mx-3) w-full mt-10 mb-5">
|
||||
<footer class="text-center py-4 rounded-xl children:(mx-3) w-full mt-10">
|
||||
<a aria-label="GitHub" href="https://github.com/TeamPiped/Piped" target="_blank">
|
||||
<font-awesome-icon :icon="['fab', 'github']" />
|
||||
<span class="ml-2" v-t="'actions.source_code'" />
|
||||
</a>
|
||||
<a href="https://piped-docs.kavin.rocks/" target="_blank">
|
||||
<a href="https://docs.piped.video/" target="_blank">
|
||||
<font-awesome-icon :icon="['fa', 'book']" />
|
||||
<span class="ml-2" v-t="'actions.documentation'" />
|
||||
</a>
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<div class="flex">
|
||||
<div>
|
||||
<button class="btn" v-t="'actions.clear_history'" @click="clearHistory" />
|
||||
|
||||
<button class="btn mx-3" v-t="'actions.export_to_json'" @click="exportHistory" />
|
||||
</div>
|
||||
|
||||
<div class="right-1">
|
||||
|
@ -36,7 +38,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
(async () => {
|
||||
if (window.db) {
|
||||
if (window.db && this.getPreferenceBoolean("watchHistory", false)) {
|
||||
var tx = window.db.transaction("watch_history", "readonly");
|
||||
var store = tx.objectStore("watch_history");
|
||||
const cursorRequest = store.index("watchedAt").openCursor(null, "prev");
|
||||
|
@ -52,6 +54,8 @@ export default {
|
|||
duration: video.duration,
|
||||
thumbnail: video.thumbnail,
|
||||
watchedAt: video.watchedAt,
|
||||
watched: true,
|
||||
currentTime: video.currentTime,
|
||||
});
|
||||
if (this.videos.length < 1000) cursor.continue();
|
||||
}
|
||||
|
@ -71,6 +75,22 @@ export default {
|
|||
}
|
||||
this.videos = [];
|
||||
},
|
||||
exportHistory() {
|
||||
const dateStr = new Date().toISOString().split(".")[0];
|
||||
let json = {
|
||||
format: "Piped",
|
||||
version: 1,
|
||||
playlists: [
|
||||
{
|
||||
name: `Piped History ${dateStr}`,
|
||||
type: "history",
|
||||
visibility: "private",
|
||||
videos: this.videos.map(video => "https://youtube.com" + video.url),
|
||||
},
|
||||
],
|
||||
};
|
||||
this.download(JSON.stringify(json), `piped_history_${dateStr}.json`, "application/json");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -158,7 +158,11 @@ export default {
|
|||
: [...new Set((this.getLocalSubscriptions() ?? []).concat(newChannels))];
|
||||
// Sort for better cache hits
|
||||
subscriptions.sort();
|
||||
localStorage.setItem("localSubscriptions", JSON.stringify(subscriptions));
|
||||
try {
|
||||
localStorage.setItem("localSubscriptions", JSON.stringify(subscriptions));
|
||||
} catch (e) {
|
||||
alert(this.$t("info.local_storage"));
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
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>
|
|
@ -34,7 +34,10 @@ export default {
|
|||
|
||||
<style scoped>
|
||||
.modal {
|
||||
@apply fixed z-50 top-0 left-0 w-full h-full bg-dark-900 bg-opacity-80 transition-opacity table;
|
||||
@apply fixed z-50 top-0 left-0 w-full h-full bg-gray bg-opacity-80 transition-opacity table;
|
||||
}
|
||||
.dark .modal {
|
||||
@apply bg-dark-900 bg-opacity-80;
|
||||
}
|
||||
|
||||
.modal > div {
|
||||
|
@ -42,7 +45,10 @@ export default {
|
|||
}
|
||||
|
||||
.modal-container {
|
||||
@apply w-min m-auto px-8 bg-dark-700 p-6 rounded-xl min-w-[20vw] relative;
|
||||
@apply w-min m-auto px-8 bg-white p-6 rounded-xl min-w-[20vw] relative;
|
||||
}
|
||||
.dark .modal-container {
|
||||
@apply bg-dark-700;
|
||||
}
|
||||
|
||||
.modal-container > button {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<nav class="flex flex-wrap items-center justify-center px-2 sm:px-4 py-2.5 w-full relative">
|
||||
<nav class="flex flex-wrap items-center justify-center px-2 sm:px-4 pb-2.5 w-full relative">
|
||||
<div class="flex-1 flex justify-start">
|
||||
<router-link class="flex font-bold text-3xl items-center font-sans" to="/"
|
||||
><img
|
||||
|
@ -11,10 +11,10 @@
|
|||
/>iped</router-link
|
||||
>
|
||||
</div>
|
||||
<div class="lt-md:hidden">
|
||||
<div class="lt-md:hidden search-container">
|
||||
<input
|
||||
v-model="searchText"
|
||||
class="input w-72 h-10"
|
||||
class="input w-72 h-10 pr-20"
|
||||
type="text"
|
||||
role="search"
|
||||
ref="videoSearch"
|
||||
|
@ -25,6 +25,7 @@
|
|||
@focus="onInputFocus"
|
||||
@blur="onInputBlur"
|
||||
/>
|
||||
<span v-if="searchText" class="delete-search" @click="searchText = ''">⨉</span>
|
||||
</div>
|
||||
<!-- three vertical lines for toggling the hamburger menu on mobile -->
|
||||
<button class="md:hidden flex flex-col justify-end mr-3" @click="showTopNav = !showTopNav">
|
||||
|
@ -49,7 +50,7 @@
|
|||
<li v-if="shouldShowHistory">
|
||||
<router-link v-t="'titles.history'" to="/history" />
|
||||
</li>
|
||||
<li v-if="authenticated">
|
||||
<li>
|
||||
<router-link v-t="'titles.playlists'" to="/playlists" />
|
||||
</li>
|
||||
<li v-if="!shouldShowTrending">
|
||||
|
@ -78,7 +79,7 @@
|
|||
<li v-if="shouldShowHistory">
|
||||
<router-link v-t="'titles.history'" to="/history" />
|
||||
</li>
|
||||
<li v-if="authenticated">
|
||||
<li>
|
||||
<router-link v-t="'titles.playlists'" to="/playlists" />
|
||||
</li>
|
||||
<li v-if="!shouldShowTrending">
|
||||
|
@ -86,7 +87,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
<!-- search suggestions for mobile devices -->
|
||||
<div class="w-{full - 4} md:hidden mx-2">
|
||||
<div class="mobile-search md:hidden mx-2 search-container">
|
||||
<input
|
||||
v-model="searchText"
|
||||
class="input h-10 w-full"
|
||||
|
@ -99,6 +100,7 @@
|
|||
@focus="onInputFocus"
|
||||
@blur="onInputBlur"
|
||||
/>
|
||||
<span v-if="searchText" class="delete-search" @click="searchText = ''">⨉</span>
|
||||
</div>
|
||||
<SearchSuggestions
|
||||
v-show="(searchText || showSearchHistory) && suggestionsVisible"
|
||||
|
@ -137,8 +139,8 @@ export default {
|
|||
shouldShowTrending(_this) {
|
||||
return _this.getPreferenceString("homepage", "trending") != "trending";
|
||||
},
|
||||
showSearchHistory() {
|
||||
return localStorage.getItem("searchHistory") && localStorage.getItem("search_history");
|
||||
showSearchHistory(_this) {
|
||||
return _this.getPreferenceBoolean("searchHistory", false) && localStorage.getItem("search_history");
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
@ -178,3 +180,17 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.search-container {
|
||||
@apply relative inline-flex items-center;
|
||||
}
|
||||
.delete-search {
|
||||
@apply absolute right-3 cursor-pointer rounded-full bg-[#ccc] w-4 h-4 text-center text-black opacity-50 hover:(opacity-70) text-size-[13px];
|
||||
line-height: 1.05;
|
||||
}
|
||||
.mobile-search {
|
||||
width: calc(100% - 1rem);
|
||||
@apply mx-2;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,14 +10,15 @@
|
|||
</p>
|
||||
</router-link>
|
||||
<p v-if="props.item.description" v-text="props.item.description" />
|
||||
|
||||
<router-link v-if="props.item.uploaderUrl" class="link" :to="props.item.uploaderUrl">
|
||||
<p>
|
||||
<span v-text="props.item.uploader" />
|
||||
<span v-text="props.item.uploaderName" />
|
||||
<font-awesome-icon class="ml-1.5" v-if="props.item.uploaderVerified" icon="check" />
|
||||
</p>
|
||||
</router-link>
|
||||
<a v-else-if="props.item.uploaderName" class="link" v-text="props.item.uploaderName" />
|
||||
|
||||
<a v-if="props.item.uploaderName" class="link" v-text="props.item.uploaderName" />
|
||||
<template v-if="props.item.videos >= 0">
|
||||
<br v-if="props.item.uploaderName" />
|
||||
<strong v-text="`${props.item.videos} ${$t('video.videos')}`" />
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<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" />
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
|
@ -14,6 +14,10 @@
|
|||
<div>
|
||||
<strong v-text="`${playlist.videos} ${$t('video.videos')}`" />
|
||||
<br />
|
||||
<button class="btn mr-1" v-if="!isPipedPlaylist" @click="bookmarkPlaylist">
|
||||
{{ $t(`actions.${isBookmarked ? "playlist_bookmarked" : "bookmark_playlist"}`)
|
||||
}}<font-awesome-icon class="ml-3" icon="bookmark" />
|
||||
</button>
|
||||
<button class="btn mr-1" v-if="authenticated && !isPipedPlaylist" @click="clonePlaylist">
|
||||
{{ $t("actions.clone_playlist") }}<font-awesome-icon class="ml-3" icon="clone" />
|
||||
</button>
|
||||
|
@ -42,11 +46,12 @@
|
|||
width="168"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</LoadingIndicatorPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ErrorHandler from "./ErrorHandler.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
import VideoItem from "./VideoItem.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
|
||||
|
@ -55,11 +60,13 @@ export default {
|
|||
ErrorHandler,
|
||||
VideoItem,
|
||||
WatchOnYouTubeButton,
|
||||
LoadingIndicatorPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
playlist: null,
|
||||
admin: false,
|
||||
isBookmarked: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -83,8 +90,9 @@ export default {
|
|||
},
|
||||
}).then(json => {
|
||||
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();
|
||||
},
|
||||
activated() {
|
||||
window.addEventListener("scroll", this.handleScroll);
|
||||
|
@ -100,7 +108,10 @@ export default {
|
|||
async getPlaylistData() {
|
||||
this.fetchPlaylist()
|
||||
.then(data => (this.playlist = data))
|
||||
.then(() => this.updateTitle());
|
||||
.then(() => {
|
||||
this.updateTitle();
|
||||
this.updateWatched(this.playlist.relatedStreams);
|
||||
});
|
||||
},
|
||||
async updateTitle() {
|
||||
document.title = this.playlist.name + " - Piped";
|
||||
|
@ -140,10 +151,52 @@ export default {
|
|||
downloadPlaylistAsTxt() {
|
||||
var data = "";
|
||||
this.playlist.relatedStreams.forEach(element => {
|
||||
data += "https://piped.kavin.rocks" + element.url + "\n";
|
||||
data += "https://piped.video" + element.url + "\n";
|
||||
});
|
||||
this.download(data, this.playlist.name + ".txt", "text/plain");
|
||||
},
|
||||
async bookmarkPlaylist() {
|
||||
if (!this.playlist) return;
|
||||
|
||||
if (this.isBookmarked) {
|
||||
this.removePlaylistBookmark();
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.db) {
|
||||
const playlistId = this.$route.query.list;
|
||||
var tx = window.db.transaction("playlist_bookmarks", "readwrite");
|
||||
var store = tx.objectStore("playlist_bookmarks");
|
||||
store.put({
|
||||
playlistId: playlistId,
|
||||
name: this.playlist.name,
|
||||
uploader: this.playlist.uploader,
|
||||
uploaderUrl: this.playlist.uploaderUrl,
|
||||
thumbnail: this.playlist.thumbnailUrl,
|
||||
uploaderAvatar: this.playlist.uploaderAvatar,
|
||||
videos: this.playlist.videos,
|
||||
});
|
||||
this.isBookmarked = true;
|
||||
}
|
||||
},
|
||||
async removePlaylistBookmark() {
|
||||
var tx = window.db.transaction("playlist_bookmarks", "readwrite");
|
||||
var store = tx.objectStore("playlist_bookmarks");
|
||||
store.delete(this.$route.query.list);
|
||||
this.isBookmarked = false;
|
||||
},
|
||||
async isPlaylistBookmarked() {
|
||||
// needed in order to change the is bookmarked var later
|
||||
const App = this;
|
||||
const playlistId = this.$route.query.list;
|
||||
var tx = window.db.transaction("playlist_bookmarks", "readwrite");
|
||||
var store = tx.objectStore("playlist_bookmarks");
|
||||
var req = store.openCursor(playlistId);
|
||||
req.onsuccess = function (e) {
|
||||
var cursor = e.target.result;
|
||||
App.isBookmarked = cursor ? true : false;
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -32,6 +32,7 @@ export default {
|
|||
},
|
||||
mounted() {
|
||||
this.updateScroll();
|
||||
this.updateWatched(this.playlist.relatedStreams);
|
||||
},
|
||||
methods: {
|
||||
updateScroll() {
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
<template>
|
||||
<h1 class="font-bold text-center my-4" v-t="'titles.playlists'" />
|
||||
<h2 v-if="authenticated" class="font-bold my-4" v-t="'titles.playlists'" />
|
||||
|
||||
<hr />
|
||||
|
||||
<button v-t="'actions.create_playlist'" class="btn" @click="createPlaylist" />
|
||||
<div v-if="authenticated" class="flex justify-between mb-3">
|
||||
<button v-t="'actions.create_playlist'" class="btn" @click="onCreatePlaylist" />
|
||||
<div class="flex">
|
||||
<button
|
||||
v-if="this.playlists.length > 0"
|
||||
v-t="'actions.export_to_json'"
|
||||
class="btn"
|
||||
@click="exportPlaylists"
|
||||
/>
|
||||
<input id="fileSelector" ref="fileSelector" type="file" class="display-none" @change="importPlaylists" />
|
||||
<label for="fileSelector" v-t="'actions.import_from_json'" class="btn ml-2" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="video-grid">
|
||||
<div v-for="playlist in playlists" :key="playlist.id">
|
||||
|
@ -26,6 +36,35 @@
|
|||
<button class="btn h-auto ml-2" @click="deletePlaylist(playlist.id)" v-t="'actions.delete_playlist'" />
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<h2 class="font-bold my-4" v-t="'titles.bookmarks'" />
|
||||
|
||||
<div v-if="bookmarks" class="video-grid">
|
||||
<router-link
|
||||
v-for="(playlist, index) in bookmarks"
|
||||
:key="playlist.playlistId"
|
||||
:to="`/playlist?list=${playlist.playlistId}`"
|
||||
>
|
||||
<img class="w-full" :src="playlist.thumbnail" alt="thumbnail" />
|
||||
<div class="relative text-sm">
|
||||
<span class="thumbnail-overlay thumbnail-right" v-text="`${playlist.videos} ${$t('video.videos')}`" />
|
||||
<div class="absolute bottom-100px right-5px px-5px z-100" @click.prevent="removeBookmark(index)">
|
||||
<font-awesome-icon class="ml-3" icon="bookmark" />
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical"
|
||||
class="my-2 overflow-hidden flex link"
|
||||
:title="playlist.name"
|
||||
v-text="playlist.name"
|
||||
/>
|
||||
<a :href="playlist.uploaderUrl" class="flex items-center">
|
||||
<img class="rounded-full w-32px h-32px" :src="playlist.uploaderAvatar" />
|
||||
<span class="ml-3 hover:underline" v-text="playlist.uploader" />
|
||||
</a>
|
||||
</router-link>
|
||||
</div>
|
||||
<br />
|
||||
</template>
|
||||
|
||||
|
@ -34,11 +73,12 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
playlists: [],
|
||||
bookmarks: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.authenticated) this.fetchPlaylists();
|
||||
else this.$router.push("/login");
|
||||
this.loadPlaylistBookmarks();
|
||||
},
|
||||
activated() {
|
||||
document.title = this.$t("titles.playlists") + " - Piped";
|
||||
|
@ -94,22 +134,120 @@ export default {
|
|||
else this.playlists = this.playlists.filter(playlist => playlist.id !== id);
|
||||
});
|
||||
},
|
||||
createPlaylist() {
|
||||
onCreatePlaylist() {
|
||||
const name = prompt(this.$t("actions.create_playlist"));
|
||||
if (name)
|
||||
this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).then(json => {
|
||||
if (json.error) alert(json.error);
|
||||
else this.fetchPlaylists();
|
||||
});
|
||||
if (!name) return;
|
||||
this.createPlaylist(name).then(json => {
|
||||
if (json.error) alert(json.error);
|
||||
else this.fetchPlaylists();
|
||||
});
|
||||
},
|
||||
async createPlaylist(name) {
|
||||
let json = await this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
return json;
|
||||
},
|
||||
async exportPlaylists() {
|
||||
if (!this.playlists) return;
|
||||
let json = {
|
||||
format: "Piped",
|
||||
version: 1,
|
||||
playlists: [],
|
||||
};
|
||||
let tasks = this.playlists.map(playlist => this.fetchPlaylistJson(playlist.id));
|
||||
json.playlists = await Promise.all(tasks);
|
||||
this.download(JSON.stringify(json), "playlists.json", "application/json");
|
||||
},
|
||||
async fetchPlaylistJson(playlistId) {
|
||||
let playlist = await this.fetchJson(this.authApiUrl() + "/playlists/" + playlistId);
|
||||
let playlistJson = {
|
||||
name: playlist.name,
|
||||
// possible other types: history, watch later, ...
|
||||
type: "playlist",
|
||||
// as Invidious supports public and private playlists
|
||||
visibility: "private",
|
||||
// list of the videos, starting with "https://youtube.com" to clarify that those are YT videos
|
||||
videos: playlist.relatedStreams.map(stream => "https://youtube.com" + stream.url),
|
||||
};
|
||||
return playlistJson;
|
||||
},
|
||||
async importPlaylists() {
|
||||
const file = this.$refs.fileSelector.files[0];
|
||||
let text = await file.text();
|
||||
let tasks = [];
|
||||
// list of playlists exported from Piped
|
||||
if (text.includes("playlists")) {
|
||||
let playlists = JSON.parse(text).playlists;
|
||||
if (!playlists.length) {
|
||||
alert(this.$t("actions.no_valid_playlists"));
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < playlists.length; i++) {
|
||||
tasks.push(this.createPlaylistWithVideos(playlists[i]));
|
||||
}
|
||||
// CSV from Google Takeout
|
||||
} else if (file.name.slice(-4).toLowerCase() == ".csv") {
|
||||
const lines = text.split("\n");
|
||||
const playlist = {
|
||||
name: lines[1].split(",")[4],
|
||||
videos: lines
|
||||
.slice(4, lines.length)
|
||||
.filter(line => line != "")
|
||||
.map(line => `https://youtube.com/watch?v=${line.split(",")[0]}`),
|
||||
};
|
||||
tasks.push(this.createPlaylistWithVideos(playlist));
|
||||
} else {
|
||||
alert(this.$t("actions.no_valid_playlists"));
|
||||
return;
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
window.location.reload();
|
||||
},
|
||||
async createPlaylistWithVideos(playlist) {
|
||||
let newPlaylist = await this.createPlaylist(playlist.name);
|
||||
let videoIds = playlist.videos.map(url => url.substr(-11));
|
||||
await this.addVideosToPlaylist(newPlaylist.playlistId, videoIds);
|
||||
},
|
||||
async addVideosToPlaylist(playlistId, videoIds) {
|
||||
await this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
playlistId: playlistId,
|
||||
videoIds: videoIds,
|
||||
}),
|
||||
headers: {
|
||||
Authorization: this.getAuthToken(),
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
},
|
||||
async loadPlaylistBookmarks() {
|
||||
if (!window.db) return;
|
||||
var tx = window.db.transaction("playlist_bookmarks", "readonly");
|
||||
var store = tx.objectStore("playlist_bookmarks");
|
||||
const cursorRequest = store.openCursor();
|
||||
cursorRequest.onsuccess = e => {
|
||||
const cursor = e.target.result;
|
||||
if (cursor) {
|
||||
const bookmark = cursor.value;
|
||||
this.bookmarks.push(bookmark);
|
||||
cursor.continue();
|
||||
}
|
||||
};
|
||||
},
|
||||
async removeBookmark(index) {
|
||||
var tx = window.db.transaction("playlist_bookmarks", "readwrite");
|
||||
var store = tx.objectStore("playlist_bookmarks");
|
||||
store.delete(this.bookmarks[index].playlistId);
|
||||
this.bookmarks.splice(index, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -45,6 +45,16 @@
|
|||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkAutoPlayNextCountdown">
|
||||
<strong v-t="'actions.autoplay_next_countdown'" />
|
||||
<input
|
||||
id="chkAutoPlayNextCountdown"
|
||||
v-model="autoPlayNextCountdown"
|
||||
class="input w-24"
|
||||
type="number"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkAudioOnly">
|
||||
<strong v-t="'actions.audio_only'" />
|
||||
<input id="chkAudioOnly" v-model="listen" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
|
@ -183,71 +193,36 @@
|
|||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkSkipSponsors">
|
||||
<strong v-t="'actions.skip_sponsors'" />
|
||||
<input id="chkSkipSponsors" v-model="skipSponsor" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
</label>
|
||||
<label class="pref" for="chkSkipIntro">
|
||||
<strong v-t="'actions.skip_intro'" />
|
||||
<input id="chkSkipIntro" v-model="skipIntro" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
</label>
|
||||
<label class="pref" for="chkSkipOutro">
|
||||
<strong v-t="'actions.skip_outro'" />
|
||||
<input id="chkSkipOutro" v-model="skipOutro" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
</label>
|
||||
<label class="pref" for="chkSkipPreview">
|
||||
<strong v-t="'actions.skip_preview'" />
|
||||
<input id="chkSkipPreview" v-model="skipPreview" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
</label>
|
||||
<label class="pref" for="chkSkipInteraction">
|
||||
<strong v-t="'actions.skip_interaction'" />
|
||||
<input
|
||||
id="chkSkipInteraction"
|
||||
v-model="skipInteraction"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkSkipSelfPromo">
|
||||
<strong v-t="'actions.skip_self_promo'" />
|
||||
<input
|
||||
id="chkSkipSelfPromo"
|
||||
v-model="skipSelfPromo"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkSkipNonMusic">
|
||||
<strong v-t="'actions.skip_non_music'" />
|
||||
<input
|
||||
id="chkSkipNonMusic"
|
||||
v-model="skipMusicOffTopic"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkSkipHighlight">
|
||||
<strong v-t="'actions.skip_highlight'" />
|
||||
<input
|
||||
id="chkSkipHighlight"
|
||||
v-model="skipHighlight"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="chkSkipFiller">
|
||||
<strong v-t="'actions.skip_filler_tangent'" />
|
||||
<input id="chkSkipFiller" v-model="skipFiller" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
</label>
|
||||
<label class="pref" for="chkShowMarkers">
|
||||
<strong v-t="'actions.show_markers'" />
|
||||
<input id="chkShowMarkers" v-model="showMarkers" class="checkbox" type="checkbox" @change="onChange($event)" />
|
||||
</label>
|
||||
|
||||
<div v-if="sponsorBlock">
|
||||
<label v-for="[name, item] in skipOptions" class="pref" :for="'ddlSkip_' + name" :key="name">
|
||||
<strong v-t="item.label" />
|
||||
<select :id="'ddlSkip_' + name" v-model="item.value" class="select w-auto" @change="onChange($event)">
|
||||
<option v-t="'actions.no'" value="no" />
|
||||
<option v-t="'actions.skip_button_only'" value="button" />
|
||||
<option v-t="'actions.skip_automatically'" value="auto" />
|
||||
</select>
|
||||
</label>
|
||||
<label class="pref" for="chkShowMarkers">
|
||||
<strong v-t="'actions.show_markers'" />
|
||||
<input
|
||||
id="chkShowMarkers"
|
||||
v-model="showMarkers"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
<label class="pref" for="txtMinSegmentLength">
|
||||
<strong v-t="'actions.min_segment_length'" />
|
||||
<input
|
||||
id="txtMinSegmentLength"
|
||||
v-model="minSegmentLength"
|
||||
class="input w-24"
|
||||
type="text"
|
||||
@change="onChange($event)"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<h2 class="text-center" v-t="'titles.instance'" />
|
||||
<label class="pref" for="ddlInstanceSelection">
|
||||
<strong v-text="`${$t('actions.instance_selection')}:`" />
|
||||
|
@ -366,18 +341,22 @@ export default {
|
|||
selectedAuthInstance: null,
|
||||
instances: [],
|
||||
sponsorBlock: true,
|
||||
skipSponsor: true,
|
||||
skipIntro: false,
|
||||
skipOutro: false,
|
||||
skipPreview: false,
|
||||
skipInteraction: true,
|
||||
skipSelfPromo: true,
|
||||
skipMusicOffTopic: true,
|
||||
skipHighlight: false,
|
||||
skipFiller: false,
|
||||
skipOptions: new Map([
|
||||
["sponsor", { value: "auto", label: "actions.skip_sponsors" }],
|
||||
["intro", { value: "no", label: "actions.skip_intro" }],
|
||||
["outro", { value: "no", label: "actions.skip_outro" }],
|
||||
["preview", { value: "no", label: "actions.skip_preview" }],
|
||||
["interaction", { value: "auto", label: "actions.skip_interaction" }],
|
||||
["selfpromo", { value: "auto", label: "actions.skip_self_promo" }],
|
||||
["music_offtopic", { value: "auto", label: "actions.skip_non_music" }],
|
||||
["poi_highlight", { value: "no", label: "actions.skip_highlight" }],
|
||||
["filler", { value: "no", label: "actions.skip_filler_tangent" }],
|
||||
]),
|
||||
showMarkers: true,
|
||||
minSegmentLength: 0,
|
||||
selectedTheme: "dark",
|
||||
autoPlayVideo: true,
|
||||
autoPlayNextCountdown: 5,
|
||||
listen: false,
|
||||
resolutions: [144, 240, 360, 480, 720, 1080, 1440, 2160, 4320],
|
||||
defaultQuality: 0,
|
||||
|
@ -397,6 +376,7 @@ export default {
|
|||
languages: [
|
||||
{ code: "ar", name: "Arabic" },
|
||||
{ code: "az", name: "Azərbaycan" },
|
||||
{ code: "bg", name: "Български" },
|
||||
{ code: "bn", name: "বাংলা" },
|
||||
{ code: "bs", name: "Bosanski" },
|
||||
{ code: "ca", name: "Català" },
|
||||
|
@ -415,6 +395,7 @@ export default {
|
|||
{ code: "hi", name: "हिंदी" },
|
||||
{ code: "id", name: "Indonesia" },
|
||||
{ code: "is", name: "Íslenska" },
|
||||
{ code: "kab", name: "Taqbaylit" },
|
||||
{ code: "hr", name: "Hrvatski" },
|
||||
{ code: "it", name: "Italiano" },
|
||||
{ code: "ja", name: "日本語" },
|
||||
|
@ -423,12 +404,15 @@ export default {
|
|||
{ code: "ml", name: "മലയാളം" },
|
||||
{ code: "nb_NO", name: "Norwegian Bokmål" },
|
||||
{ code: "nl", name: "Nederlands" },
|
||||
{ code: "oc", name: "Occitan" },
|
||||
{ code: "or", name: "ଓଡ଼ିଆ" },
|
||||
{ code: "pl", name: "Polski" },
|
||||
{ code: "pt", name: "Português" },
|
||||
{ code: "pt_PT", name: "Português (Portugal)" },
|
||||
{ code: "pt_BR", name: "Português (Brasil)" },
|
||||
{ code: "ro", name: "Română" },
|
||||
{ code: "ru", name: "Русский" },
|
||||
{ code: "si", name: "සිංහල" },
|
||||
{ code: "sr", name: "Српски" },
|
||||
{ code: "sv", name: "Svenska" },
|
||||
{ code: "ta", name: "தமிழ்" },
|
||||
|
@ -453,7 +437,7 @@ export default {
|
|||
|
||||
this.fetchJson("https://piped-instances.kavin.rocks/").then(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({
|
||||
name: "Custom Instance",
|
||||
api_url: this.apiUrl(),
|
||||
|
@ -468,57 +452,28 @@ export default {
|
|||
this.selectedAuthInstance = this.getPreferenceString("auth_instance_url", this.selectedInstance);
|
||||
|
||||
this.sponsorBlock = this.getPreferenceBoolean("sponsorblock", true);
|
||||
if (localStorage.getItem("selectedSkip") !== null) {
|
||||
var skipList = localStorage.getItem("selectedSkip").split(",");
|
||||
this.skipSponsor =
|
||||
this.skipIntro =
|
||||
this.skipOutro =
|
||||
this.skipPreview =
|
||||
this.skipInteraction =
|
||||
this.skipSelfPromo =
|
||||
this.skipMusicOffTopic =
|
||||
this.skipHighlight =
|
||||
this.skipFiller =
|
||||
false;
|
||||
var skipOptions, skipList;
|
||||
if ((skipOptions = this.getPreferenceJSON("skipOptions")) !== undefined) {
|
||||
Object.entries(skipOptions).forEach(([key, value]) => {
|
||||
var opt = this.skipOptions.get(key);
|
||||
if (opt !== undefined) opt.value = value;
|
||||
else console.log("Unknown sponsor type: " + key);
|
||||
});
|
||||
} else if ((skipList = this.getPreferenceString("selectedSkip")) !== undefined) {
|
||||
skipList = skipList.split(",");
|
||||
this.skipOptions.forEach(opt => (opt.value = "no"));
|
||||
skipList.forEach(skip => {
|
||||
switch (skip) {
|
||||
case "sponsor":
|
||||
this.skipSponsor = true;
|
||||
break;
|
||||
case "intro":
|
||||
this.skipIntro = true;
|
||||
break;
|
||||
case "outro":
|
||||
this.skipOutro = true;
|
||||
break;
|
||||
case "preview":
|
||||
this.skipPreview = true;
|
||||
break;
|
||||
case "interaction":
|
||||
this.skipInteraction = true;
|
||||
break;
|
||||
case "selfpromo":
|
||||
this.skipSelfPromo = true;
|
||||
break;
|
||||
case "music_offtopic":
|
||||
this.skipMusicOffTopic = true;
|
||||
break;
|
||||
case "poi_highlight":
|
||||
this.skipHighlight = true;
|
||||
break;
|
||||
case "filler":
|
||||
this.skipFiller = true;
|
||||
break;
|
||||
default:
|
||||
console.log("Unknown sponsor type: " + skip);
|
||||
break;
|
||||
}
|
||||
var opt = this.skipOptions.get(skip);
|
||||
if (opt !== undefined) opt.value = "auto";
|
||||
else console.log("Unknown sponsor type: " + skip);
|
||||
});
|
||||
}
|
||||
|
||||
this.showMarkers = this.getPreferenceBoolean("showMarkers", true);
|
||||
this.minSegmentLength = Math.max(this.getPreferenceNumber("minSegmentLength", 0), 0);
|
||||
this.selectedTheme = this.getPreferenceString("theme", "dark");
|
||||
this.autoPlayVideo = this.getPreferenceBoolean("playerAutoPlay", true);
|
||||
this.autoPlayNextCountdown = this.getPreferenceNumber("autoPlayNextCountdown", 5);
|
||||
this.listen = this.getPreferenceBoolean("listen", false);
|
||||
this.defaultQuality = Number(localStorage.getItem("quality"));
|
||||
this.bufferingGoal = Math.max(Number(localStorage.getItem("bufferGoal")), 10);
|
||||
|
@ -565,21 +520,15 @@ export default {
|
|||
localStorage.setItem("auth_instance_url", this.selectedAuthInstance);
|
||||
localStorage.setItem("sponsorblock", this.sponsorBlock);
|
||||
|
||||
var sponsorSelected = [];
|
||||
if (this.skipSponsor) sponsorSelected.push("sponsor");
|
||||
if (this.skipIntro) sponsorSelected.push("intro");
|
||||
if (this.skipOutro) sponsorSelected.push("outro");
|
||||
if (this.skipPreview) sponsorSelected.push("preview");
|
||||
if (this.skipInteraction) sponsorSelected.push("interaction");
|
||||
if (this.skipSelfPromo) sponsorSelected.push("selfpromo");
|
||||
if (this.skipMusicOffTopic) sponsorSelected.push("music_offtopic");
|
||||
if (this.skipHighlight) sponsorSelected.push("poi_highlight");
|
||||
if (this.skipFiller) sponsorSelected.push("filler");
|
||||
localStorage.setItem("selectedSkip", sponsorSelected);
|
||||
var skipOptions = {};
|
||||
this.skipOptions.forEach((v, k) => (skipOptions[k] = v.value));
|
||||
localStorage.setItem("skipOptions", JSON.stringify(skipOptions));
|
||||
|
||||
localStorage.setItem("showMarkers", this.showMarkers);
|
||||
localStorage.setItem("minSegmentLength", this.minSegmentLength);
|
||||
localStorage.setItem("theme", this.selectedTheme);
|
||||
localStorage.setItem("playerAutoPlay", this.autoPlayVideo);
|
||||
localStorage.setItem("autoPlayNextCountdown", this.autoPlayNextCountdown);
|
||||
localStorage.setItem("listen", this.listen);
|
||||
localStorage.setItem("quality", this.defaultQuality);
|
||||
localStorage.setItem("bufferGoal", this.bufferingGoal);
|
||||
|
@ -667,4 +616,10 @@ export default {
|
|||
.pref {
|
||||
@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>
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { isEmail } from "../utils/Misc.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
@ -52,6 +54,8 @@ export default {
|
|||
methods: {
|
||||
register() {
|
||||
if (!this.username || !this.password) return;
|
||||
if (isEmail(this.username) && !confirm(this.$t("info.register_no_email_note"))) return;
|
||||
|
||||
this.fetchJson(this.authApiUrl() + "/register", null, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
|
|
|
@ -18,19 +18,21 @@
|
|||
</i18n-t>
|
||||
</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">
|
||||
<ContentItem :item="result" height="94" width="168" />
|
||||
</template>
|
||||
</div>
|
||||
</LoadingIndicatorPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentItem from "./ContentItem.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ContentItem,
|
||||
LoadingIndicatorPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -72,7 +74,10 @@ export default {
|
|||
},
|
||||
async updateResults() {
|
||||
document.title = this.$route.query.search_query + " - Piped";
|
||||
this.results = this.fetchResults().then(json => (this.results = json));
|
||||
this.results = this.fetchResults().then(json => {
|
||||
this.results = json;
|
||||
this.updateWatched(this.results.items);
|
||||
});
|
||||
},
|
||||
updateFilter() {
|
||||
this.$router.replace({
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
<template>
|
||||
<ModalComponent>
|
||||
<h2 v-t="'actions.share'" />
|
||||
<div class="flex justify-between mt-4">
|
||||
<label v-t="'actions.with_timecode'" for="withTimeCode" />
|
||||
<input id="withTimeCode" type="checkbox" v-model="withTimeCode" @change="onChange" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<label v-t="'actions.piped_link'" />
|
||||
<input type="checkbox" v-model="pipedLink" @change="onChange" />
|
||||
</div>
|
||||
<div class="flex justify-between mt-2">
|
||||
<div v-if="this.hasPlaylist" class="flex justify-between">
|
||||
<label v-t="'actions.with_playlist'" />
|
||||
<input type="checkbox" v-model="withPlaylist" @change="onChange" />
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<label v-t="'actions.with_timecode'" for="withTimeCode" />
|
||||
<input id="withTimeCode" type="checkbox" v-model="withTimeCode" @change="onChange" />
|
||||
</div>
|
||||
<div v-if="this.withTimeCode" class="flex justify-between mt-2">
|
||||
<label v-t="'actions.time_code'" />
|
||||
<input class="input w-12" type="text" v-model="timeStamp" />
|
||||
</div>
|
||||
<a :href="generatedLink" target="_blank"><h3 class="mt-4" v-text="generatedLink" /></a>
|
||||
<a :href="generatedLink" target="_blank">
|
||||
<h3 class="mt-4" v-text="generatedLink" />
|
||||
</a>
|
||||
<div class="flex justify-end mt-4">
|
||||
<button class="btn" v-t="'actions.follow_link'" @click="followLink()" />
|
||||
<button class="btn ml-3" v-t="'actions.copy_link'" @click="copyLink()" />
|
||||
|
@ -34,6 +40,12 @@ export default {
|
|||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
playlistId: {
|
||||
type: String,
|
||||
},
|
||||
playlistIndex: {
|
||||
type: Number,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ModalComponent,
|
||||
|
@ -42,13 +54,17 @@ export default {
|
|||
return {
|
||||
withTimeCode: true,
|
||||
pipedLink: true,
|
||||
withPlaylist: true,
|
||||
timeStamp: null,
|
||||
hasPlaylist: false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.timeStamp = parseInt(this.currentTime);
|
||||
this.withTimeCode = this.getPreferenceBoolean("shareWithTimeCode", true);
|
||||
this.pipedLink = this.getPreferenceBoolean("shareAsPipedLink", true);
|
||||
this.withPlaylist = this.getPreferenceBoolean("shareWithPlaylist", true);
|
||||
this.hasPlaylist = this.playlistId != undefined && !isNaN(this.playlistIndex);
|
||||
},
|
||||
methods: {
|
||||
followLink() {
|
||||
|
@ -66,8 +82,9 @@ export default {
|
|||
}
|
||||
},
|
||||
onChange() {
|
||||
this.setPreference("shareWithTimeCode", this.withTimeCode);
|
||||
this.setPreference("shareAsPipedLink", this.pipedLink);
|
||||
this.setPreference("shareWithTimeCode", this.withTimeCode, true);
|
||||
this.setPreference("shareAsPipedLink", this.pipedLink, true);
|
||||
this.setPreference("shareWithPlaylist", this.withPlaylist, true);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
|
@ -77,6 +94,10 @@ export default {
|
|||
: "https://youtu.be/" + this.videoId;
|
||||
var url = new URL(baseUrl);
|
||||
if (this.withTimeCode && this.timeStamp > 0) url.searchParams.append("t", this.timeStamp);
|
||||
if (this.hasPlaylist && this.withPlaylist) {
|
||||
url.searchParams.append("list", this.playlistId);
|
||||
url.searchParams.append("index", this.playlistIndex);
|
||||
}
|
||||
return url.href;
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<h1 class="font-bold text-center my-4" v-t="'titles.subscriptions'" />
|
||||
|
||||
<!-- import / export section -->
|
||||
<div class="flex justify-between w-full">
|
||||
<div class="flex">
|
||||
<button class="btn mx-1">
|
||||
|
@ -8,25 +8,31 @@
|
|||
</button>
|
||||
<button class="btn" @click="exportHandler" v-t="'actions.export_to_json'" />
|
||||
</div>
|
||||
<i18n-t keypath="subscriptions.subscribed_channels_count">{{ subscriptions.length }}</i18n-t>
|
||||
<!-- subscriptions count, only shown if there are any -->
|
||||
<i18n-t v-if="subscriptions.length > 0" keypath="subscriptions.subscribed_channels_count">{{
|
||||
subscriptions.length
|
||||
}}</i18n-t>
|
||||
</div>
|
||||
<br />
|
||||
<hr />
|
||||
|
||||
<div class="grid">
|
||||
<div class="mb-3" v-for="subscription in subscriptions" :key="subscription.url">
|
||||
<div class="flex justify-center place-items-center">
|
||||
<div class="w-full flex justify-between items-center">
|
||||
<router-link :to="subscription.url" class="flex text-center font-bold text-4xl">
|
||||
<img :src="subscription.avatar" class="rounded-full h-[fit-content]" width="48" height="48" />
|
||||
<span class="mx-2" v-text="subscription.name" />
|
||||
</router-link>
|
||||
<button
|
||||
class="btn w-min"
|
||||
@click="handleButton(subscription)"
|
||||
v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Subscriptions card list -->
|
||||
<div class="xl:grid xl:grid-cols-5 <md:flex-wrap">
|
||||
<!-- channel info card -->
|
||||
<div
|
||||
class="col m-2 p-1 border rounded-lg border-gray-500"
|
||||
v-for="subscription in subscriptions"
|
||||
:key="subscription.url"
|
||||
>
|
||||
<router-link :to="subscription.url" class="flex p-2 font-bold text-4x4">
|
||||
<img :src="subscription.avatar" class="rounded-full h-[fit-content]" width="48" height="48" />
|
||||
<span class="self-center mx-2" v-text="subscription.name" />
|
||||
</router-link>
|
||||
<!-- subscribe / unsubscribe btn -->
|
||||
<button
|
||||
class="btn w-full mt-2"
|
||||
@click="handleButton(subscription)"
|
||||
v-t="`actions.${subscription.subscribed ? 'unsubscribe' : 'subscribe'}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
|
28
src/components/ToastComponent.vue
Normal file
28
src/components/ToastComponent.vue
Normal file
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div class="toast">
|
||||
<slot />
|
||||
<button @click="dismiss" v-t="'actions.dismiss'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
dismiss() {
|
||||
this.$emit("dismissed");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.toast {
|
||||
@apply bg-white/80 text-black flex flex-col justify-center fixed top-12 right-12 p-4 min-w-max shadow rounded duration-200 z-9999;
|
||||
}
|
||||
.dark .toast {
|
||||
@apply bg-dark-900/80 text-white;
|
||||
}
|
||||
.toast button {
|
||||
@apply underline;
|
||||
}
|
||||
</style>
|
|
@ -3,17 +3,19 @@
|
|||
|
||||
<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" />
|
||||
</div>
|
||||
</LoadingIndicatorPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
import VideoItem from "./VideoItem.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VideoItem,
|
||||
LoadingIndicatorPage,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -21,6 +23,7 @@ export default {
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.$route.path == "/" && this.getPreferenceString("homepage", "trending") == "feed") return;
|
||||
let region = this.getPreferenceString("region", "US");
|
||||
|
||||
this.fetchTrending(region).then(videos => {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div v-if="showVideo">
|
||||
<router-link
|
||||
class="focus:underline hover:underline inline-block w-full"
|
||||
:to="{
|
||||
path: '/watch',
|
||||
query: {
|
||||
|
@ -10,13 +11,24 @@
|
|||
},
|
||||
}"
|
||||
>
|
||||
<img
|
||||
class="w-full"
|
||||
:src="item.thumbnail"
|
||||
:alt="item.title"
|
||||
:class="{ 'shorts-img': item.isShort }"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="w-full">
|
||||
<img
|
||||
class="w-full aspect-video object-contain"
|
||||
:src="item.thumbnail"
|
||||
:alt="item.title"
|
||||
:class="{ 'shorts-img': item.isShort, 'opacity-75': item.watched }"
|
||||
loading="lazy"
|
||||
/>
|
||||
<!-- progress bar -->
|
||||
<div class="relative w-full h-1">
|
||||
<div
|
||||
class="absolute bottom-0 left-0 h-1 bg-red-600"
|
||||
v-if="item.watched && item.duration > 0"
|
||||
:style="{ width: `clamp(0%, ${(item.currentTime / item.duration) * 100}%, 100%` }"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative text-sm">
|
||||
<span
|
||||
class="thumbnail-overlay thumbnail-right"
|
||||
|
@ -39,72 +51,29 @@
|
|||
<div>
|
||||
<p
|
||||
style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical"
|
||||
class="my-2 overflow-hidden flex link"
|
||||
class="pt-2 overflow-hidden flex link font-bold"
|
||||
:title="item.title"
|
||||
v-text="item.title"
|
||||
/>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<div class="float-right m-0 inline-block children:px-1">
|
||||
<router-link
|
||||
:to="{
|
||||
path: '/watch',
|
||||
query: {
|
||||
v: item.url.substr(-11),
|
||||
...(playlistId && { list: playlistId }),
|
||||
...(index >= 0 && { index: index + 1 }),
|
||||
listen: '1',
|
||||
},
|
||||
}"
|
||||
:aria-label="'Listen to ' + item.title"
|
||||
:title="'Listen to ' + item.title"
|
||||
>
|
||||
<font-awesome-icon icon="headphones" />
|
||||
</router-link>
|
||||
<button v-if="authenticated" :title="$t('actions.add_to_playlist')" @click="showModal = !showModal">
|
||||
<font-awesome-icon icon="circle-plus" />
|
||||
</button>
|
||||
<button
|
||||
v-if="admin"
|
||||
:title="$t('actions.remove_from_playlist')"
|
||||
ref="removeButton"
|
||||
@click="removeVideo(item.url.substr(-11))"
|
||||
>
|
||||
<font-awesome-icon icon="circle-minus" />
|
||||
</button>
|
||||
<button
|
||||
v-if="
|
||||
isFeed &&
|
||||
(this.getPreferenceBoolean('watchHistory', false) ||
|
||||
this.getPreferenceBoolean('hideWatched', false))
|
||||
"
|
||||
@click="toggleWatched(item.url.substr(-11))"
|
||||
ref="watchButton"
|
||||
>
|
||||
<font-awesome-icon icon="eye-slash" :title="$t('actions.mark_as_unwatched')" v-if="item.watched" />
|
||||
<font-awesome-icon icon="eye" :title="$t('actions.mark_as_watched')" v-else />
|
||||
</button>
|
||||
<PlaylistAddModal v-if="showModal" :video-id="item.url.substr(-11)" @close="showModal = !showModal" />
|
||||
</div>
|
||||
|
||||
<div class="flex">
|
||||
<router-link :to="item.uploaderUrl">
|
||||
<img
|
||||
v-if="item.uploaderAvatar"
|
||||
:src="item.uploaderAvatar"
|
||||
loading="lazy"
|
||||
:alt="item.uploaderName"
|
||||
class="rounded-full mr-0.5 mt-0.5 w-32px h-32px"
|
||||
width="68"
|
||||
height="68"
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<div class="w-[calc(100%-32px-1rem)]">
|
||||
<div class="px-2 flex-1">
|
||||
<router-link
|
||||
v-if="item.uploaderUrl && item.uploaderName && !hideChannel"
|
||||
class="link-secondary overflow-hidden block"
|
||||
class="link-secondary overflow-hidden block text-sm"
|
||||
:to="item.uploaderUrl"
|
||||
:title="item.uploaderName"
|
||||
>
|
||||
|
@ -112,14 +81,56 @@
|
|||
<font-awesome-icon class="ml-1.5" v-if="item.uploaderVerified" icon="check" />
|
||||
</router-link>
|
||||
|
||||
<strong v-if="item.views >= 0 || item.uploadedDate" class="text-sm">
|
||||
<div v-if="item.views >= 0 || item.uploadedDate" class="text-xs font-normal text-gray-300 mt-1">
|
||||
<span v-if="item.views >= 0">
|
||||
<font-awesome-icon icon="eye" />
|
||||
<span class="pl-0.5" v-text="`${numberFormat(item.views)} •`" />
|
||||
<span class="pl-1" v-text="`${numberFormat(item.views)} •`" />
|
||||
</span>
|
||||
<span v-if="item.uploaded > 0" class="pl-0.5" v-text="timeAgo(item.uploaded)" />
|
||||
<span v-else-if="item.uploadedDate" class="pl-0.5" v-text="item.uploadedDate" />
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2.5">
|
||||
<router-link
|
||||
:to="{
|
||||
path: '/watch',
|
||||
query: {
|
||||
v: item.url.substr(-11),
|
||||
...(playlistId && { list: playlistId }),
|
||||
...(index >= 0 && { index: index + 1 }),
|
||||
listen: '1',
|
||||
},
|
||||
}"
|
||||
:aria-label="'Listen to ' + item.title"
|
||||
:title="'Listen to ' + item.title"
|
||||
>
|
||||
<font-awesome-icon icon="headphones" />
|
||||
</router-link>
|
||||
<button v-if="authenticated" :title="$t('actions.add_to_playlist')" @click="showModal = !showModal">
|
||||
<font-awesome-icon icon="circle-plus" />
|
||||
</button>
|
||||
<button
|
||||
v-if="admin"
|
||||
:title="$t('actions.remove_from_playlist')"
|
||||
ref="removeButton"
|
||||
@click="removeVideo(item.url.substr(-11))"
|
||||
>
|
||||
<font-awesome-icon icon="circle-minus" />
|
||||
</button>
|
||||
<button
|
||||
v-if="
|
||||
isFeed &&
|
||||
(this.getPreferenceBoolean('watchHistory', false) ||
|
||||
this.getPreferenceBoolean('hideWatched', false))
|
||||
"
|
||||
@click="toggleWatched(item.url.substr(-11))"
|
||||
ref="watchButton"
|
||||
>
|
||||
<font-awesome-icon icon="eye-slash" v-if="item.watched" :title="$t('actions.mark_as_unwatched')" />
|
||||
<font-awesome-icon icon="eye" v-else :title="$t('actions.mark_as_watched')" />
|
||||
</button>
|
||||
<PlaylistAddModal v-if="showModal" :video-id="item.url.substr(-11)" @close="showModal = !showModal" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -127,7 +138,7 @@
|
|||
|
||||
<style>
|
||||
.shorts-img {
|
||||
@apply max-h-[17.5vh] w-full object-contain;
|
||||
@apply w-full object-contain;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -6,11 +6,23 @@
|
|||
:class="{ 'player-container': !isEmbed }"
|
||||
>
|
||||
<video ref="videoEl" class="w-full" data-shaka-player :autoplay="shouldAutoPlay" :loop="selectedAutoLoop" />
|
||||
<canvas id="preview" />
|
||||
<button
|
||||
v-if="inSegment"
|
||||
class="skip-segment-button"
|
||||
type="button"
|
||||
:aria-label="$t('actions.skip_segment')"
|
||||
aria-pressed="false"
|
||||
@click="onClickSkipSegment"
|
||||
>
|
||||
<span v-t="'actions.skip_segment'" />
|
||||
<i class="material-icons-round">skip_next</i>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import("shaka-player/dist/controls.css");
|
||||
import "shaka-player/dist/controls.css";
|
||||
const shaka = import("shaka-player/dist/shaka-player.ui.js");
|
||||
if (!window.muxjs) {
|
||||
import("mux.js").then(muxjs => {
|
||||
|
@ -27,14 +39,6 @@ export default {
|
|||
return {};
|
||||
},
|
||||
},
|
||||
playlist: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
index: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
},
|
||||
sponsors: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
|
@ -51,6 +55,8 @@ export default {
|
|||
lastUpdate: new Date().getTime(),
|
||||
initialSeekComplete: false,
|
||||
destroying: false,
|
||||
inSegment: false,
|
||||
isHoveringTimebar: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -88,7 +94,7 @@ export default {
|
|||
this.hotkeysPromise.then(() => {
|
||||
var self = this;
|
||||
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+.",
|
||||
"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+.,alt+p,return,.,,",
|
||||
function (e, handler) {
|
||||
const videoEl = self.$refs.videoEl;
|
||||
switch (handler.key) {
|
||||
|
@ -184,6 +190,22 @@ export default {
|
|||
case "shift+.":
|
||||
self.$player.trickPlay(Math.min(videoEl.playbackRate + 0.25, 2));
|
||||
break;
|
||||
case "alt+p":
|
||||
document.pictureInPictureElement
|
||||
? document.exitPictureInPicture()
|
||||
: videoEl.requestPictureInPicture();
|
||||
break;
|
||||
case "return":
|
||||
self.skipSegment(videoEl);
|
||||
break;
|
||||
case ".":
|
||||
videoEl.currentTime += 0.04;
|
||||
e.preventDefault();
|
||||
break;
|
||||
case ",":
|
||||
videoEl.currentTime -= 0.04;
|
||||
e.preventDefault();
|
||||
break;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -199,6 +221,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
async loadVideo() {
|
||||
this.updateSponsors();
|
||||
|
||||
const component = this;
|
||||
const videoEl = this.$refs.videoEl;
|
||||
|
||||
|
@ -226,7 +250,7 @@ export default {
|
|||
}
|
||||
videoEl.currentTime = start;
|
||||
this.initialSeekComplete = true;
|
||||
} else if (window.db) {
|
||||
} else if (window.db && this.getPreferenceBoolean("watchHistory", false)) {
|
||||
var tx = window.db.transaction("watch_history", "readonly");
|
||||
var store = tx.objectStore("watch_history");
|
||||
var request = store.get(this.video.id);
|
||||
|
@ -256,9 +280,7 @@ export default {
|
|||
|
||||
const MseSupport = window.MediaSource !== undefined;
|
||||
|
||||
const lbry = this.getPreferenceBoolean("disableLBRY", false)
|
||||
? null
|
||||
: this.video.videoStreams.filter(stream => stream.quality === "LBRY")[0];
|
||||
const lbry = null;
|
||||
|
||||
var uri;
|
||||
var mime;
|
||||
|
@ -268,12 +290,17 @@ export default {
|
|||
mime = "application/x-mpegURL";
|
||||
} else if (this.video.audioStreams.length > 0 && !lbry && MseSupport) {
|
||||
if (!this.video.dash) {
|
||||
const dash = (
|
||||
await import("@/utils/DashUtils.js").then(mod => mod.default)
|
||||
).generate_dash_file_from_formats(streams, this.video.duration);
|
||||
const dash = (await import("../utils/DashUtils.js")).generate_dash_file_from_formats(
|
||||
streams,
|
||||
this.video.duration,
|
||||
);
|
||||
|
||||
uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(dash);
|
||||
} else uri = this.video.dash;
|
||||
} else {
|
||||
const url = new URL(this.video.dash);
|
||||
url.searchParams.set("rewrite", false);
|
||||
uri = url.toString();
|
||||
}
|
||||
mime = "application/dash+xml";
|
||||
} else if (lbry) {
|
||||
uri = lbry.url;
|
||||
|
@ -302,7 +329,7 @@ export default {
|
|||
uri = this.video.hls;
|
||||
mime = "application/x-mpegURL";
|
||||
} 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";
|
||||
}
|
||||
|
||||
|
@ -352,48 +379,54 @@ export default {
|
|||
else this.setPlayerAttrs(this.$player, videoEl, uri, mime, this.$shaka);
|
||||
|
||||
if (noPrevPlayer) {
|
||||
videoEl.addEventListener("loadeddata", () => {
|
||||
if (document.pictureInPictureElement) videoEl.requestPictureInPicture();
|
||||
});
|
||||
videoEl.addEventListener("timeupdate", () => {
|
||||
const time = videoEl.currentTime;
|
||||
this.$emit("timeupdate", time);
|
||||
this.updateProgressDatabase(time);
|
||||
if (this.sponsors && this.sponsors.segments) {
|
||||
this.sponsors.segments.map(segment => {
|
||||
if (!segment.skipped || this.selectedAutoLoop) {
|
||||
const end = segment.segment[1];
|
||||
if (time >= segment.segment[0] && time < end) {
|
||||
console.log("Skipped segment at " + time);
|
||||
videoEl.currentTime = end;
|
||||
segment.skipped = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
const segment = this.findCurrentSegment(time);
|
||||
this.inSegment = !!segment;
|
||||
if (segment?.autoskip && (!segment.skipped || this.selectedAutoLoop)) {
|
||||
this.skipSegment(videoEl, segment);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
videoEl.addEventListener("volumechange", () => {
|
||||
this.setPreference("volume", videoEl.volume);
|
||||
this.setPreference("volume", videoEl.volume, true);
|
||||
});
|
||||
|
||||
videoEl.addEventListener("ratechange", e => {
|
||||
const rate = videoEl.playbackRate;
|
||||
if (rate > 0 && !isNaN(videoEl.duration) && !isNaN(videoEl.duration - e.timeStamp / 1000))
|
||||
this.setPreference("rate", rate);
|
||||
this.setPreference("rate", rate, true);
|
||||
});
|
||||
|
||||
videoEl.addEventListener("ended", () => {
|
||||
if (
|
||||
!this.selectedAutoLoop &&
|
||||
this.selectedAutoPlay &&
|
||||
(this.playlist?.relatedStreams?.length > 0 || this.video.relatedStreams.length > 0)
|
||||
) {
|
||||
this.navigateNext();
|
||||
}
|
||||
this.$emit("ended");
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: Add sponsors on seekbar: https://github.com/ajayyy/SponsorBlock/blob/e39de9fd852adb9196e0358ed827ad38d9933e29/src/js-components/previewBar.ts#L12
|
||||
},
|
||||
findCurrentSegment(time) {
|
||||
return this.sponsors?.segments?.find(s => time >= s.segment[0] && time < s.segment[1]);
|
||||
},
|
||||
onClickSkipSegment() {
|
||||
const videoEl = this.$refs.videoEl;
|
||||
this.skipSegment(videoEl);
|
||||
},
|
||||
skipSegment(videoEl, segment) {
|
||||
const time = videoEl.currentTime;
|
||||
if (!segment) segment = this.findCurrentSegment(time);
|
||||
if (!segment) return;
|
||||
console.log("Skipped segment at " + time);
|
||||
videoEl.currentTime = segment.segment[1];
|
||||
segment.skipped = true;
|
||||
},
|
||||
setPlayerAttrs(localPlayer, videoEl, uri, mime, shaka) {
|
||||
const url = "/watch?v=" + this.video.id;
|
||||
|
||||
|
@ -440,7 +473,14 @@ export default {
|
|||
|
||||
this.$ui = new shaka.ui.Overlay(localPlayer, this.$refs.container, videoEl);
|
||||
|
||||
const overflowMenuButtons = ["quality", "captions", "picture_in_picture", "playback_rate", "airplay"];
|
||||
const overflowMenuButtons = [
|
||||
"quality",
|
||||
"language",
|
||||
"captions",
|
||||
"picture_in_picture",
|
||||
"playback_rate",
|
||||
"airplay",
|
||||
];
|
||||
|
||||
if (this.isEmbed) {
|
||||
overflowMenuButtons.push("open_new_tab");
|
||||
|
@ -460,8 +500,13 @@ export default {
|
|||
|
||||
this.updateMarkers();
|
||||
|
||||
const event = new Event("playerInit");
|
||||
window.dispatchEvent(event);
|
||||
|
||||
const player = this.$ui.getControls().getPlayer();
|
||||
|
||||
this.setupSeekbarPreview();
|
||||
|
||||
this.$player = player;
|
||||
|
||||
const disableVideo = this.getPreferenceBoolean("listen", false) && !this.video.livestream;
|
||||
|
@ -480,22 +525,40 @@ export default {
|
|||
if (qualityConds) this.$player.configure("abr.enabled", false);
|
||||
|
||||
player.load(uri, 0, mime).then(() => {
|
||||
const isSafari = window.navigator?.vendor?.includes("Apple");
|
||||
|
||||
if (!isSafari) {
|
||||
// Set the audio language
|
||||
const prefLang = this.getPreferenceString("hl", "en").substr(0, 2);
|
||||
var lang = "en";
|
||||
for (var l in player.getAudioLanguages()) {
|
||||
if (l == prefLang) {
|
||||
lang = l;
|
||||
return;
|
||||
}
|
||||
}
|
||||
player.selectAudioLanguage(lang);
|
||||
}
|
||||
|
||||
if (qualityConds) {
|
||||
var leastDiff = Number.MAX_VALUE;
|
||||
var bestStream = null;
|
||||
|
||||
var bestAudio = 0;
|
||||
|
||||
const tracks = player
|
||||
.getVariantTracks()
|
||||
.filter(track => track.language == lang || track.language == "und");
|
||||
|
||||
// Choose the best audio stream
|
||||
if (quality >= 480)
|
||||
player.getVariantTracks().forEach(track => {
|
||||
tracks.forEach(track => {
|
||||
const audioBandwidth = track.audioBandwidth;
|
||||
if (audioBandwidth > bestAudio) bestAudio = audioBandwidth;
|
||||
});
|
||||
|
||||
// Find best matching stream based on resolution and bitrate
|
||||
player
|
||||
.getVariantTracks()
|
||||
tracks
|
||||
.sort((a, b) => a.bandwidth - b.bandwidth)
|
||||
.forEach(stream => {
|
||||
if (stream.audioBandwidth < bestAudio) return;
|
||||
|
@ -514,7 +577,7 @@ export default {
|
|||
player.addTextTrackAsync(
|
||||
subtitle.url,
|
||||
subtitle.code,
|
||||
"SUBTITLE",
|
||||
"subtitles",
|
||||
subtitle.mimeType,
|
||||
null,
|
||||
subtitle.name,
|
||||
|
@ -525,6 +588,10 @@ export default {
|
|||
videoEl.playbackRate = rate;
|
||||
videoEl.defaultPlaybackRate = rate;
|
||||
});
|
||||
|
||||
// expand the player to fullscreen when the fullscreen query equals true
|
||||
if (this.$route.query.fullscreen === "true" && !this.$ui.getControls().isFullScreenEnabled())
|
||||
this.$ui.getControls().toggleFullScreen();
|
||||
},
|
||||
async updateProgressDatabase(time) {
|
||||
// debounce
|
||||
|
@ -549,29 +616,6 @@ export default {
|
|||
this.$refs.videoEl.currentTime = time;
|
||||
}
|
||||
},
|
||||
navigateNext() {
|
||||
const params = this.$route.query;
|
||||
let url = this.playlist?.relatedStreams?.[this.index]?.url ?? this.video.relatedStreams[0].url;
|
||||
const searchParams = new URLSearchParams();
|
||||
for (var param in params)
|
||||
switch (param) {
|
||||
case "v":
|
||||
case "t":
|
||||
break;
|
||||
case "index":
|
||||
if (this.index < this.playlist.relatedStreams.length) searchParams.set("index", this.index + 1);
|
||||
break;
|
||||
case "list":
|
||||
if (this.index < this.playlist.relatedStreams.length) searchParams.set("list", params.list);
|
||||
break;
|
||||
default:
|
||||
searchParams.set(param, params[param]);
|
||||
break;
|
||||
}
|
||||
const paramStr = searchParams.toString();
|
||||
if (paramStr.length > 0) url += "&" + paramStr;
|
||||
this.$router.push(url);
|
||||
},
|
||||
updateMarkers() {
|
||||
const markers = this.$refs.container.querySelector(".shaka-ad-markers");
|
||||
const array = ["to right"];
|
||||
|
@ -624,29 +668,120 @@ export default {
|
|||
|
||||
if (markers) markers.style.background = `linear-gradient(${array.join(",")})`;
|
||||
},
|
||||
updateSponsors() {
|
||||
const skipOptions = this.getPreferenceJSON("skipOptions", {});
|
||||
this.sponsors?.segments?.forEach(segment => {
|
||||
const option = skipOptions[segment.category];
|
||||
segment.autoskip = option === undefined || option === "auto";
|
||||
});
|
||||
if (this.getPreferenceBoolean("showMarkers", true)) {
|
||||
this.shakaPromise.then(() => {
|
||||
this.updateMarkers();
|
||||
});
|
||||
}
|
||||
},
|
||||
setupSeekbarPreview() {
|
||||
if (!this.video.previewFrames) return;
|
||||
let seekBar = document.querySelector(".shaka-seek-bar");
|
||||
// load the thumbnail preview when the user moves over the seekbar
|
||||
seekBar.addEventListener("mousemove", e => {
|
||||
this.isHoveringTimebar = true;
|
||||
const position = (e.offsetX / e.target.offsetWidth) * this.video.duration;
|
||||
this.showSeekbarPreview(position * 1000);
|
||||
});
|
||||
// hide the preview when the user stops hovering the seekbar
|
||||
seekBar.addEventListener("mouseout", () => {
|
||||
this.isHoveringTimebar = false;
|
||||
let canvas = document.querySelector("#preview");
|
||||
canvas.style.display = "none";
|
||||
});
|
||||
},
|
||||
async showSeekbarPreview(position) {
|
||||
const frame = this.getFrame(position);
|
||||
const originalImage = await this.loadImage(frame.url);
|
||||
if (!this.isHoveringTimebar) return;
|
||||
|
||||
const seekBar = document.querySelector(".shaka-seek-bar");
|
||||
const canvas = document.querySelector("#preview");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// get the new sizes for the image to be drawn into the canvas
|
||||
const originalWidth = originalImage.naturalWidth;
|
||||
const originalHeight = originalImage.naturalHeight;
|
||||
// image can have less frames than server told us so calculate them ourselves
|
||||
const imageFramesPerPageX = originalImage.naturalWidth / frame.frameWidth;
|
||||
const imageFramesPerPageY = originalImage.naturalHeight / frame.frameHeight;
|
||||
const offsetX = originalWidth * (frame.positionX / imageFramesPerPageX);
|
||||
const offsetY = originalHeight * (frame.positionY / imageFramesPerPageY);
|
||||
|
||||
canvas.width = frame.frameWidth > 100 ? frame.frameWidth : frame.frameWidth * 2;
|
||||
canvas.height = frame.frameWidth > 100 ? frame.frameHeight : frame.frameHeight * 2;
|
||||
// draw the thumbnail preview into the canvas by cropping only the relevant part
|
||||
ctx.drawImage(
|
||||
originalImage,
|
||||
offsetX,
|
||||
offsetY,
|
||||
frame.frameWidth,
|
||||
frame.frameHeight,
|
||||
0,
|
||||
0,
|
||||
canvas.width,
|
||||
canvas.height,
|
||||
);
|
||||
|
||||
// calculate the thumbnail preview offset and display it
|
||||
const seekbarPadding = 2; // percentage of seekbar padding
|
||||
const centerOffset = position / this.video.duration / 10;
|
||||
const left = centerOffset - ((0.5 * canvas.width) / seekBar.clientWidth) * 100;
|
||||
const maxLeft = ((seekBar.clientWidth - canvas.clientWidth) / seekBar.clientWidth) * 100 - seekbarPadding;
|
||||
canvas.style.left = `max(${seekbarPadding}%, min(${left}%, ${maxLeft}%))`;
|
||||
canvas.style.display = "block";
|
||||
},
|
||||
// ineffective algorithm to find the thumbnail corresponding to the currently hovered position in the video
|
||||
getFrame(position) {
|
||||
let startPosition = 0;
|
||||
const framePage = this.video.previewFrames.at(-1);
|
||||
for (let i = 0; i < framePage.urls.length; i++) {
|
||||
for (let positionY = 0; positionY < framePage.framesPerPageY; positionY++) {
|
||||
for (let positionX = 0; positionX < framePage.framesPerPageX; positionX++) {
|
||||
const endPosition = startPosition + framePage.durationPerFrame;
|
||||
if (position >= startPosition && position <= endPosition) {
|
||||
return {
|
||||
url: framePage.urls[i],
|
||||
positionX: positionX,
|
||||
positionY: positionY,
|
||||
frameWidth: framePage.frameWidth,
|
||||
frameHeight: framePage.frameHeight,
|
||||
};
|
||||
}
|
||||
startPosition = endPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
// creates a new image from an URL
|
||||
loadImage(url) {
|
||||
return new Promise(r => {
|
||||
const i = new Image();
|
||||
i.onload = () => r(i);
|
||||
i.src = url;
|
||||
});
|
||||
},
|
||||
destroy(hotkeys) {
|
||||
if (this.$ui) {
|
||||
if (this.$ui && !document.pictureInPictureElement) {
|
||||
this.$ui.destroy();
|
||||
this.$ui = undefined;
|
||||
this.$player = undefined;
|
||||
}
|
||||
if (this.$player) {
|
||||
this.$player.destroy();
|
||||
this.$player = undefined;
|
||||
if (!document.pictureInPictureElement) this.$player = undefined;
|
||||
}
|
||||
if (hotkeys) this.$hotkeys?.unbind();
|
||||
this.$refs.container?.querySelectorAll("div").forEach(node => node.remove());
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
sponsors() {
|
||||
if (this.getPreferenceBoolean("showMarkers", true)) {
|
||||
this.shakaPromise.then(() => {
|
||||
this.updateMarkers();
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -681,4 +816,43 @@ export default {
|
|||
background-color: rgba(0, 0, 0, 0.6) !important;
|
||||
padding: 0.09em 0;
|
||||
}
|
||||
|
||||
.skip-segment-button {
|
||||
/* position button above player overlay */
|
||||
z-index: 1000;
|
||||
|
||||
position: absolute;
|
||||
transform: translate(0, -50%);
|
||||
top: 50%;
|
||||
right: 0;
|
||||
|
||||
background-color: rgb(0 0 0 / 0.5);
|
||||
border: 2px rgba(255, 255, 255, 0.75) solid;
|
||||
border-right: 0;
|
||||
border-radius: 0.75em;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
padding: 0.5em;
|
||||
|
||||
/* center text vertically */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
color: #fff;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.skip-segment-button .material-icons-round {
|
||||
font-size: 1.6em !important;
|
||||
line-height: inherit !important;
|
||||
}
|
||||
|
||||
#preview {
|
||||
position: absolute;
|
||||
z-index: 2000;
|
||||
bottom: 0;
|
||||
margin-bottom: 4.5%;
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -4,29 +4,33 @@
|
|||
ref="videoPlayer"
|
||||
:video="video"
|
||||
:sponsors="sponsors"
|
||||
:playlist="playlist"
|
||||
:index="index"
|
||||
:selected-auto-play="false"
|
||||
:selected-auto-loop="selectedAutoLoop"
|
||||
:is-embed="isEmbed"
|
||||
/>
|
||||
</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" />
|
||||
<Transition>
|
||||
<ToastComponent v-if="shouldShowToast" @dismissed="dismiss">
|
||||
<i18n-t keypath="info.next_video_countdown">{{ counter }}</i18n-t>
|
||||
</ToastComponent>
|
||||
</Transition>
|
||||
|
||||
<div v-show="!video.error">
|
||||
<div :class="isMobile ? 'flex-col' : 'flex'">
|
||||
<VideoPlayer
|
||||
ref="videoPlayer"
|
||||
:video="video"
|
||||
:sponsors="sponsors"
|
||||
:playlist="playlist"
|
||||
:index="index"
|
||||
:selected-auto-play="selectedAutoPlay"
|
||||
:selected-auto-loop="selectedAutoLoop"
|
||||
@timeupdate="onTimeUpdate"
|
||||
/>
|
||||
<keep-alive>
|
||||
<VideoPlayer
|
||||
ref="videoPlayer"
|
||||
:video="video"
|
||||
:sponsors="sponsors"
|
||||
:selected-auto-play="selectedAutoPlay"
|
||||
:selected-auto-loop="selectedAutoLoop"
|
||||
@timeupdate="onTimeUpdate"
|
||||
@ended="onVideoEnded"
|
||||
/>
|
||||
</keep-alive>
|
||||
<ChaptersBar
|
||||
:mobileLayout="isMobile"
|
||||
v-if="video?.chapters?.length > 0 && showChapters"
|
||||
|
@ -92,6 +96,8 @@
|
|||
v-if="showShareModal"
|
||||
:video-id="getVideoId()"
|
||||
:current-time="currentTime"
|
||||
:playlist-id="playlistId"
|
||||
:playlist-index="index"
|
||||
@close="showShareModal = !showShareModal"
|
||||
/>
|
||||
<div class="flex">
|
||||
|
@ -146,10 +152,13 @@
|
|||
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-show="showDesc" class="break-words" v-html="purifyHTML(video.description)" />
|
||||
<div
|
||||
v-if="showDesc && sponsors && sponsors.segments"
|
||||
v-text="`${$t('video.sponsor_segments')}: ${sponsors.segments.length}`"
|
||||
/>
|
||||
<template v-if="showDesc">
|
||||
<div
|
||||
v-if="sponsors && sponsors.segments"
|
||||
v-text="`${$t('video.sponsor_segments')}: ${sponsors.segments.length}`"
|
||||
/>
|
||||
<div v-if="video.category" v-text="`${$t('video.category')}: ${video.category}`" />
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
@ -212,7 +221,7 @@
|
|||
<hr class="sm:hidden" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LoadingIndicatorPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -225,6 +234,8 @@ import PlaylistAddModal from "./PlaylistAddModal.vue";
|
|||
import ShareModal from "./ShareModal.vue";
|
||||
import PlaylistVideos from "./PlaylistVideos.vue";
|
||||
import WatchOnYouTubeButton from "./WatchOnYouTubeButton.vue";
|
||||
import LoadingIndicatorPage from "./LoadingIndicatorPage.vue";
|
||||
import ToastComponent from "./ToastComponent.vue";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
|
@ -238,13 +249,13 @@ export default {
|
|||
ShareModal,
|
||||
PlaylistVideos,
|
||||
WatchOnYouTubeButton,
|
||||
LoadingIndicatorPage,
|
||||
ToastComponent,
|
||||
},
|
||||
data() {
|
||||
const smallViewQuery = window.matchMedia("(max-width: 640px)");
|
||||
return {
|
||||
video: {
|
||||
title: "Loading...",
|
||||
},
|
||||
video: null,
|
||||
playlistId: null,
|
||||
playlist: null,
|
||||
index: null,
|
||||
|
@ -265,6 +276,9 @@ export default {
|
|||
showShareModal: false,
|
||||
isMobile: true,
|
||||
currentTime: 0,
|
||||
shouldShowToast: false,
|
||||
timeoutCounter: null,
|
||||
counter: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -286,6 +300,9 @@ export default {
|
|||
year: "numeric",
|
||||
});
|
||||
},
|
||||
defaultCounter(_this) {
|
||||
return _this.getPreferenceNumber("autoPlayNextCountdown", 5);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// check screen size
|
||||
|
@ -304,7 +321,7 @@ export default {
|
|||
(async () => {
|
||||
const videoId = this.getVideoId();
|
||||
const instance = this;
|
||||
if (window.db && !this.video.error) {
|
||||
if (window.db && this.getPreferenceBoolean("watchHistory", false) && !this.video.error) {
|
||||
var tx = window.db.transaction("watch_history", "readwrite");
|
||||
var store = tx.objectStore("watch_history");
|
||||
var request = store.get(videoId);
|
||||
|
@ -334,6 +351,7 @@ export default {
|
|||
this.getPlaylistData();
|
||||
this.getSponsors();
|
||||
if (!this.isEmbed && this.showComments) this.getComments();
|
||||
window.addEventListener("click", this.handleClick);
|
||||
window.addEventListener("resize", () => {
|
||||
this.smallView = this.smallViewQuery.matches;
|
||||
});
|
||||
|
@ -345,7 +363,7 @@ export default {
|
|||
this.showDesc = !this.getPreferenceBoolean("minimizeDescription", false);
|
||||
this.showRecs = !this.getPreferenceBoolean("minimizeRecommendations", false);
|
||||
this.showChapters = !this.getPreferenceBoolean("minimizeChapters", false);
|
||||
if (this.video.duration) {
|
||||
if (this.video?.duration) {
|
||||
document.title = this.video.title + " - Piped";
|
||||
this.$refs.videoPlayer.loadVideo();
|
||||
}
|
||||
|
@ -354,24 +372,40 @@ export default {
|
|||
deactivated() {
|
||||
this.active = false;
|
||||
window.removeEventListener("scroll", this.handleScroll);
|
||||
this.dismiss();
|
||||
},
|
||||
unmounted() {
|
||||
window.removeEventListener("scroll", this.handleScroll);
|
||||
window.removeEventListener("click", this.handleClick);
|
||||
this.dismiss();
|
||||
},
|
||||
methods: {
|
||||
fetchVideo() {
|
||||
return this.fetchJson(this.apiUrl() + "/streams/" + this.getVideoId());
|
||||
},
|
||||
async fetchSponsors() {
|
||||
return await this.fetchJson(this.apiUrl() + "/sponsors/" + this.getVideoId(), {
|
||||
category:
|
||||
'["' +
|
||||
this.getPreferenceString("selectedSkip", "sponsor,interaction,selfpromo,music_offtopic").replaceAll(
|
||||
",",
|
||||
'","',
|
||||
) +
|
||||
'"]',
|
||||
var selectedSkip = this.getPreferenceString(
|
||||
"selectedSkip",
|
||||
"sponsor,interaction,selfpromo,music_offtopic",
|
||||
).split(",");
|
||||
const skipOptions = this.getPreferenceJSON("skipOptions");
|
||||
if (skipOptions !== undefined) {
|
||||
selectedSkip = Object.keys(skipOptions).filter(
|
||||
k => skipOptions[k] !== undefined && skipOptions[k] !== "no",
|
||||
);
|
||||
}
|
||||
|
||||
const sponsors = await this.fetchJson(this.apiUrl() + "/sponsors/" + this.getVideoId(), {
|
||||
category: JSON.stringify(selectedSkip),
|
||||
});
|
||||
|
||||
const minSegmentLength = Math.max(this.getPreferenceNumber("minSegmentLength", 0), 0);
|
||||
sponsors.segments = sponsors.segments?.filter(segment => {
|
||||
const length = segment.segment[1] - segment.segment[0];
|
||||
return length >= minSegmentLength;
|
||||
});
|
||||
|
||||
return sponsors;
|
||||
},
|
||||
toggleComments() {
|
||||
this.showComments = !this.showComments;
|
||||
|
@ -383,7 +417,7 @@ export default {
|
|||
return this.fetchJson(this.apiUrl() + "/comments/" + this.getVideoId());
|
||||
},
|
||||
onChange() {
|
||||
this.setPreference("autoplay", this.selectedAutoPlay);
|
||||
this.setPreference("autoplay", this.selectedAutoPlay, true);
|
||||
},
|
||||
async getVideoData() {
|
||||
await this.fetchVideo()
|
||||
|
@ -404,13 +438,8 @@ export default {
|
|||
elem.outerHTML = elem.getAttribute("href");
|
||||
});
|
||||
xmlDoc.querySelectorAll("br").forEach(elem => (elem.outerHTML = "\n"));
|
||||
this.video.description = this.urlify(xmlDoc.querySelector("body").innerHTML)
|
||||
.replaceAll(/(?:http(?:s)?:\/\/)?(?:www\.)?youtube\.com(\/[/a-zA-Z0-9_?=&-]*)/gm, "$1")
|
||||
.replaceAll(
|
||||
/(?:http(?:s)?:\/\/)?(?:www\.)?youtu\.be\/(?:watch\?v=)?([/a-zA-Z0-9_?=&-]*)/gm,
|
||||
"/watch?v=$1",
|
||||
)
|
||||
.replaceAll("\n", "<br>");
|
||||
this.video.description = this.rewriteDescription(xmlDoc.querySelector("body").innerHTML);
|
||||
this.updateWatched(this.video.relatedStreams);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -449,7 +478,10 @@ export default {
|
|||
this.fetchSponsors().then(data => (this.sponsors = data));
|
||||
},
|
||||
async getComments() {
|
||||
this.fetchComments().then(data => (this.comments = data));
|
||||
this.fetchComments().then(data => {
|
||||
this.rewriteComments(data.comments);
|
||||
this.comments = data;
|
||||
});
|
||||
},
|
||||
async fetchSubscribedStatus() {
|
||||
if (!this.channelId) return;
|
||||
|
@ -472,6 +504,23 @@ export default {
|
|||
this.subscribed = json.subscribed;
|
||||
});
|
||||
},
|
||||
rewriteComments(data) {
|
||||
data.forEach(comment => {
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(comment.commentText, "text/html");
|
||||
xmlDoc.querySelectorAll("a").forEach(elem => {
|
||||
if (!elem.innerText.match(/(?:[\d]{1,2}:)?(?:[\d]{1,2}):(?:[\d]{1,2})/))
|
||||
elem.outerHTML = elem.getAttribute("href");
|
||||
});
|
||||
comment.commentText = xmlDoc
|
||||
.querySelector("body")
|
||||
.innerHTML.replaceAll(/(?:http(?:s)?:\/\/)?(?:www\.)?youtube\.com(\/[/a-zA-Z0-9_?=&-]*)/gm, "$1")
|
||||
.replaceAll(
|
||||
/(?:http(?:s)?:\/\/)?(?:www\.)?youtu\.be\/(?:watch\?v=)?([/a-zA-Z0-9_?=&-]*)/gm,
|
||||
"/watch?v=$1",
|
||||
);
|
||||
});
|
||||
},
|
||||
subscribeHandler() {
|
||||
if (this.authenticated) {
|
||||
this.fetchJson(this.authApiUrl() + (this.subscribed ? "/unsubscribe" : "/subscribe"), null, {
|
||||
|
@ -485,10 +534,23 @@ export default {
|
|||
},
|
||||
});
|
||||
} else {
|
||||
this.handleLocalSubscriptions(this.channelId);
|
||||
if (!this.handleLocalSubscriptions(this.channelId)) return;
|
||||
}
|
||||
this.subscribed = !this.subscribed;
|
||||
},
|
||||
handleClick(event) {
|
||||
if (!event || !event.target) return;
|
||||
var target = event.target;
|
||||
if (
|
||||
!target.nodeName == "A" ||
|
||||
!target.getAttribute("href") ||
|
||||
!target.innerText.match(/(?:[\d]{1,2}:)?(?:[\d]{1,2}):(?:[\d]{1,2})/)
|
||||
)
|
||||
return;
|
||||
const time = parseInt(target.getAttribute("href").match(/(?<=t=)\d+/)[0]);
|
||||
this.navigate(time);
|
||||
event.preventDefault();
|
||||
},
|
||||
handleScroll() {
|
||||
if (this.loading || !this.comments || !this.comments.nextpage) return;
|
||||
if (window.innerHeight + window.scrollY >= this.$refs.comments?.offsetHeight - window.innerHeight) {
|
||||
|
@ -498,7 +560,8 @@ export default {
|
|||
}).then(json => {
|
||||
this.comments.nextpage = json.nextpage;
|
||||
this.loading = false;
|
||||
json.comments.map(comment => this.comments.comments.push(comment));
|
||||
this.rewriteComments(json.comments);
|
||||
this.comments.comments = this.comments.comments.concat(json.comments);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -511,6 +574,68 @@ export default {
|
|||
onTimeUpdate(time) {
|
||||
this.currentTime = time;
|
||||
},
|
||||
onVideoEnded() {
|
||||
if (
|
||||
!this.selectedAutoLoop &&
|
||||
this.selectedAutoPlay &&
|
||||
(this.playlist?.relatedStreams?.length > 0 || this.video.relatedStreams.length > 0)
|
||||
) {
|
||||
this.showToast();
|
||||
}
|
||||
},
|
||||
showToast() {
|
||||
this.counter = this.defaultCounter;
|
||||
if (this.counter < 1) {
|
||||
this.navigateNext();
|
||||
return;
|
||||
}
|
||||
if (this.timeoutCounter) clearInterval(this.timeoutCounter);
|
||||
this.timeoutCounter = setInterval(() => {
|
||||
this.counter--;
|
||||
if (this.counter === 0) {
|
||||
this.dismiss();
|
||||
this.navigateNext();
|
||||
}
|
||||
}, 1000);
|
||||
this.shouldShowToast = true;
|
||||
},
|
||||
dismiss() {
|
||||
clearInterval(this.timeoutCounter);
|
||||
this.shouldShowToast = false;
|
||||
},
|
||||
navigateNext() {
|
||||
const params = this.$route.query;
|
||||
let url = this.playlist?.relatedStreams?.[this.index]?.url ?? this.video.relatedStreams[0].url;
|
||||
const searchParams = new URLSearchParams();
|
||||
for (var param in params)
|
||||
switch (param) {
|
||||
case "v":
|
||||
case "t":
|
||||
break;
|
||||
case "index":
|
||||
if (this.index < this.playlist.relatedStreams.length) searchParams.set("index", this.index + 1);
|
||||
break;
|
||||
case "list":
|
||||
if (this.index < this.playlist.relatedStreams.length) searchParams.set("list", params.list);
|
||||
break;
|
||||
default:
|
||||
searchParams.set(param, params[param]);
|
||||
break;
|
||||
}
|
||||
// save the fullscreen state
|
||||
searchParams.set("fullscreen", this.$refs.videoPlayer.$ui.getControls().isFullScreenEnabled());
|
||||
const paramStr = searchParams.toString();
|
||||
if (paramStr.length > 0) url += "&" + paramStr;
|
||||
this.$router.push(url);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.v-enter-from,
|
||||
.v-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(100%) scale(0.5);
|
||||
}
|
||||
</style>
|
||||
|
|
1
src/locales/ang.json
Normal file
1
src/locales/ang.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -4,15 +4,16 @@
|
|||
"login": "تسجيل الدخول",
|
||||
"register": "إنشاء حساب",
|
||||
"preferences": "الإعدادات",
|
||||
"history": "تاريخ التصفح",
|
||||
"history": "سجل المشاهدة",
|
||||
"subscriptions": "الاشتراكات",
|
||||
"playlists": "قوائم التشغيل",
|
||||
"feed": "التغذية",
|
||||
"feed": "محتوى الاشتراكات",
|
||||
"account": "الحساب",
|
||||
"instance": "الخادم",
|
||||
"player": "المشغل",
|
||||
"livestreams": "البث المباشر",
|
||||
"channels": "القنوات"
|
||||
"channels": "القنوات",
|
||||
"bookmarks": "الاشارات المرجعيه"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "شاهد عبر"
|
||||
|
@ -41,7 +42,7 @@
|
|||
"enable_sponsorblock": "تفعيل مانع الإعلانات",
|
||||
"auto": "تلقائي",
|
||||
"dark": "داكن",
|
||||
"search": "بحث",
|
||||
"search": "بحث (Ctrl+K)",
|
||||
"autoplay_video": "تشغيل تلقائي",
|
||||
"audio_only": "صوت فقط",
|
||||
"default_quality": "الجودة الأساسية",
|
||||
|
@ -117,7 +118,19 @@
|
|||
"reply_count": "{count} الردود",
|
||||
"minimize_comments_default": "تصغير التعليقات بشكل افتراضي",
|
||||
"minimize_comments": "تصغير التعليقات",
|
||||
"show_watch_on_youtube": "عرض زر مشاهدة على يوتيوب"
|
||||
"show_watch_on_youtube": "عرض زر مشاهدة على يوتيوب",
|
||||
"minimize_chapters_default": "تصغير الفصول بشكل افتراضي",
|
||||
"no_valid_playlists": "لا يحتوي الملف على قوائم تشغيل صالحة!",
|
||||
"with_playlist": "المشاركة مع قائمة التشغيل",
|
||||
"bookmark_playlist": "الاشاره المرجعيه",
|
||||
"playlist_bookmarked": "تم وضعها في الاشارات المرجعية",
|
||||
"skip_button_only": "إظهار زر التخطي",
|
||||
"skip_automatically": "تلقائيا",
|
||||
"min_segment_length": "الحد الأدنى لطول الفصل (بالثواني)",
|
||||
"skip_segment": "تخطي الجزء",
|
||||
"show_less": "عرض أقل",
|
||||
"autoplay_next_countdown": "العد التنازلي الافتراضي حتى الفيديو التالي ( ثانية )",
|
||||
"dismiss": "تجاهل"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "المقاطع الإعلانية",
|
||||
|
@ -127,7 +140,9 @@
|
|||
"views": "{views} عدد المشاهدات",
|
||||
"shorts": "فديوهات قصيرة",
|
||||
"videos": "الفيديوات",
|
||||
"live": "{0} مباشر"
|
||||
"live": "{0} مباشر",
|
||||
"all": "الكل",
|
||||
"category": "الفئة"
|
||||
},
|
||||
"search": {
|
||||
"channels": "يوتيوب: القنوات",
|
||||
|
@ -169,6 +184,9 @@
|
|||
"preferences_note": "ملاحظة: يتم حفظ التفضيلات في وحدة التخزين المحلية في متصفحك. سيؤدي حذف بيانات المتصفح إلى إعادة تعيينها.",
|
||||
"page_not_found": "لم يتم العثور على الصفحة",
|
||||
"copied": "نسخ!",
|
||||
"cannot_copy": "لا يمكن نسخه!"
|
||||
"cannot_copy": "لا يمكن نسخه!",
|
||||
"local_storage": "يتطلب هذا الإجراء التخزين المحلي، هل يتم تمكين ملفات تعريف الارتباط؟",
|
||||
"register_no_email_note": "لا ينصح باستخدام البريد الإلكتروني كاسم مستخدم. المضي قدما على أي حال؟",
|
||||
"next_video_countdown": "تشغيل الفيديو التالي بعد { 0 } ق"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,131 +1,147 @@
|
|||
{
|
||||
"titles": {
|
||||
"trending": "Trenddə olan",
|
||||
"login": "Daxil olun",
|
||||
"register": "Qeydiyyatdan keçin",
|
||||
"login": "Daxil ol",
|
||||
"register": "Qeydiyyatdan keç",
|
||||
"feed": "Axın",
|
||||
"preferences": "Seçimlər",
|
||||
"preferences": "Üstünlüklər",
|
||||
"history": "Tarixçə",
|
||||
"subscriptions": "Abunəliklər",
|
||||
"playlists": "Pleylistlər",
|
||||
"playlists": "Oynatma Siyahıları",
|
||||
"account": "Hesab",
|
||||
"instance": "Nümunə",
|
||||
"player": "Oynadıcı"
|
||||
"player": "Oynadıcı",
|
||||
"livestreams": "Canlı Yayımlar",
|
||||
"channels": "Kanallar",
|
||||
"bookmarks": "Əlfəcinlər"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0} saytında baxın"
|
||||
"watch_on": "{0} saytında bax"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "Abunə Olun - {count}",
|
||||
"unsubscribe": "Abunəlikdən Çıxın- {count}",
|
||||
"subscribe": "Abunə Ol - {count}",
|
||||
"unsubscribe": "Abunəlikdən Çıx - {count}",
|
||||
"view_subscriptions": "Abunəliklərə Baxın",
|
||||
"sort_by": "Sıralama qaydası:",
|
||||
"sort_by": "Çeşidlə:",
|
||||
"most_recent": "Ən Yeni",
|
||||
"least_recent": "Ən Köhnə",
|
||||
"channel_name_asc": "Kanal Adı (A-Z)",
|
||||
"channel_name_desc": "Kanal Adı (Z-A)",
|
||||
"back": "Geri",
|
||||
"uses_api_from": "API-dən istifadə edir ",
|
||||
"enable_sponsorblock": "SponsorBlok'u Aktivləşdirin",
|
||||
"skip_sponsors": "Sponsorları Ötürün",
|
||||
"skip_intro": "Fasilə/Giriş Animasiyasını Ötür",
|
||||
"skip_outro": "Bitiş Kartları/Kanal Nişanı Seqmentlərini Ötür",
|
||||
"skip_preview": "Önbaxışı/Anonsu Ötürün",
|
||||
"skip_interaction": "İnteraksiya Xatırlatıcısını Ötürün(Abunə Olun)",
|
||||
"skip_self_promo": "Ödənişsiz/Özünü Reklamı Ötürün",
|
||||
"skip_non_music": "Musiqisizliyi Ötür: Musiqi Olmayan Bölmə",
|
||||
"enable_sponsorblock": "SponsorBlok'u Aktivləşdir",
|
||||
"skip_sponsors": "Sponsorları Ötür",
|
||||
"skip_intro": "Fasilə/Giriş Animasiyasın Ötür",
|
||||
"skip_outro": "Son Kartları/Kreditləri Ötür",
|
||||
"skip_preview": "Önbaxışı/Anonsu Ötür",
|
||||
"skip_interaction": "Əlaqələndirmə Xatırladıcısın Ötür(Abunə Ol)",
|
||||
"skip_self_promo": "Ödənilməmiş/Özünü Reklamı Ötür",
|
||||
"skip_non_music": "Musiqini Ötür: Musiqisiz Bölmə",
|
||||
"skip_highlight": "Anonsu Ötür",
|
||||
"skip_filler_tangent": "Doldurucu Səhnələri Ötür",
|
||||
"theme": "Mövzu",
|
||||
"theme": "Tema",
|
||||
"auto": "Avtomatik",
|
||||
"dark": "Qaranlıq",
|
||||
"light": "İşıqlı",
|
||||
"autoplay_video": "Videonu Avto-oynat",
|
||||
"audio_only": "Yalnız Səs",
|
||||
"default_quality": "Defolt Keyfiyyət",
|
||||
"buffering_goal": "Tamponlama Məqsədi (saniyələrlə)",
|
||||
"export_to_json": "JSON-a İxrac Edin",
|
||||
"import_from_json": "JSON/CSV-dan İdxal Edin",
|
||||
"default_quality": "Standart Keyfiyyət",
|
||||
"buffering_goal": "Tamponlama hədəfi (saniyələrlə)",
|
||||
"export_to_json": "JSON-a İxrac Et",
|
||||
"import_from_json": "JSON/CSV-dan İdxal Et",
|
||||
"loop_this_video": "Bu Videonu Təkrarla",
|
||||
"auto_play_next_video": "Növbəti Videonu Avto-Oynat",
|
||||
"donations": "İnkişaf ianələri",
|
||||
"minimize_description": "Açıqlamanı Kiçildin",
|
||||
"show_description": "Açıqlamanı Göstərin",
|
||||
"minimize_recommendations": "Tövsiyələri ən aza endirin",
|
||||
"show_recommendations": "Tövsiyələri Göstərin",
|
||||
"disable_lbry": "Yayım üçün LBRY-ni Söndürün",
|
||||
"enable_lbry_proxy": "LBRY üçün Proksi-ni Aktivləşdirin",
|
||||
"view_ssl_score": "SSL Nəticəsinə Baxın",
|
||||
"search": "Axtarın",
|
||||
"minimize_description": "Açıqlamanı Kiçilt",
|
||||
"show_description": "Açıqlamanı Göstər",
|
||||
"minimize_recommendations": "Tövsiyələri Kiçilt",
|
||||
"show_recommendations": "Tövsiyələri Göstər",
|
||||
"disable_lbry": "Yayım üçün LBRY-ni deaktiv et",
|
||||
"enable_lbry_proxy": "LBRY üçün Proksi-ni Aktivləşdir",
|
||||
"view_ssl_score": "SSL Nəticəsinə Bax",
|
||||
"search": "Axtarış (Ctrl+K)",
|
||||
"filter": "Filtr",
|
||||
"loading": "Yüklənir...",
|
||||
"clear_history": "Tarixçəni Təmizləyin",
|
||||
"hide_replies": "Cavabları Gizlədin",
|
||||
"clear_history": "Tarixçəni Təmizlə",
|
||||
"hide_replies": "Cavabları Gizlət",
|
||||
"load_more_replies": "Daha Çox Cavab Yüklə",
|
||||
"add_to_playlist": "Pleylistə Əlavə Edin",
|
||||
"remove_from_playlist": "Pleylistdən Silin",
|
||||
"delete_playlist_video_confirm": "Video pleylistdən silinsin?",
|
||||
"create_playlist": "Pleylist Yaradın",
|
||||
"delete_playlist": "Pleylisti Silin",
|
||||
"select_playlist": "Pleylist Seçin",
|
||||
"delete_playlist_confirm": "Bu pleylist silinsin?",
|
||||
"please_select_playlist": "Lütfən, pleylist seçin",
|
||||
"add_to_playlist": "Oynatma siyahısına əlavə et",
|
||||
"remove_from_playlist": "Oynatma siyahısından təmizlə",
|
||||
"delete_playlist_video_confirm": "Video oynatma siyahısından silinsin?",
|
||||
"create_playlist": "Oynatma Siyahısı Yarat",
|
||||
"delete_playlist": "Oynatma Siyahısın Sil",
|
||||
"select_playlist": "Oynatma Siyahısı Seç",
|
||||
"delete_playlist_confirm": "Bu oynatma siyahısı silinsin?",
|
||||
"please_select_playlist": "Xahiş edilir, oynatma siyahısı seç",
|
||||
"country_selection": "Ölkə Seçimi",
|
||||
"default_homepage": "Defolt Əsas Səhifə",
|
||||
"show_comments": "Şərhləri Göstərin",
|
||||
"default_homepage": "Standart Əsas Səhifə",
|
||||
"show_comments": "Şərhləri Göstər",
|
||||
"instance_selection": "Nümunə Seçimi",
|
||||
"minimize_description_default": "Açıqlamanı Defolt Olaraq Kiçildin",
|
||||
"minimize_description_default": "Açıqlamanı Standart Olaraq Kiçilt",
|
||||
"language_selection": "Dil Seçimi",
|
||||
"instances_list": "Nümunələr Siyahısı",
|
||||
"show_more": "Daha Çox Göstər",
|
||||
"show_more": "Daha çox göstər",
|
||||
"no": "Xeyr",
|
||||
"store_watch_history": "Baxış Tarixçəsini Saxlayın",
|
||||
"enabled_codecs": "Aktiv Kodeklər (Birdən çox)",
|
||||
"store_watch_history": "Baxış Tarixçəsin Saxla",
|
||||
"enabled_codecs": "Aktiv Kodlayıcılar (Çoxlu)",
|
||||
"yes": "Bəli",
|
||||
"show_markers": "Oynadıcıda Markerləri Göstərin",
|
||||
"delete_account": "Hesabı Silin",
|
||||
"logout": "Bu cihazdan çıxın",
|
||||
"minimize_recommendations_default": "Defolt olaraq Tövsiyələri minimuma endir",
|
||||
"download_as_txt": ".txt kimi endirin",
|
||||
"reset_preferences": "Seçimləri sıfırlayın",
|
||||
"confirm_reset_preferences": "Seçimləri sıfırlamaq istədiyinizə əminsiniz?",
|
||||
"backup_preferences": "Yedəkləmə seçimləri",
|
||||
"restore_preferences": "Seçimləri bərpa edin",
|
||||
"show_markers": "Oynadıcıda Markerləri Göstər",
|
||||
"delete_account": "Hesabı Sil",
|
||||
"logout": "Bu cihazdan çıx",
|
||||
"minimize_recommendations_default": "Standart olaraq Tövsiyələri kiçilt",
|
||||
"download_as_txt": ".txt kimi endir",
|
||||
"reset_preferences": "Üstünlükləri sıfırla",
|
||||
"confirm_reset_preferences": "Seçimlərinizi sıfırlamaq istədiyinizə əminsiniz?",
|
||||
"backup_preferences": "Nüsxələmə seçimləri",
|
||||
"restore_preferences": "Seçimləri bərpa et",
|
||||
"invalidate_session": "Bütün cihazlardan çıxın",
|
||||
"different_auth_instance": "Doğrulama üçün fərqli bir nümunədən istifadə edin",
|
||||
"instance_auth_selection": "Doğrulama Nümunəsi Seçilməsi",
|
||||
"clone_playlist": "Pleylist Klonlanması",
|
||||
"different_auth_instance": "Təsdiqləmə üçün fərqli nümunə istifadə et",
|
||||
"instance_auth_selection": "Təsdiqləmə Nümunəsi Seçimi",
|
||||
"clone_playlist": "Oynatma Siyahısın Klonla",
|
||||
"clone_playlist_success": "Uğurla klonlandı!",
|
||||
"rename_playlist": "Pleylistin adını dəyiş",
|
||||
"rename_playlist": "Oynatma siyahısın yenidən adlandır",
|
||||
"time_code": "Vaxt kodu (saniyələrlə)",
|
||||
"store_search_history": "Axtarış tarixçəsini saxla",
|
||||
"documentation": "Sertifikatlaşdırma",
|
||||
"documentation": "Sənədləşdirmə",
|
||||
"status_page": "Vəziyyət",
|
||||
"source_code": "Mənbə kodu",
|
||||
"instance_donations": "Nümunə ianələri",
|
||||
"hide_watched": "Axında baxılan videoları gizlədin",
|
||||
"hide_watched": "Axında baxılan videoları gizlət",
|
||||
"show_chapters": "Bölmələr",
|
||||
"new_playlist_name": "Yeni pleylist adı",
|
||||
"share": "Paylaşın",
|
||||
"with_timecode": "Vaxt kodu ilə paylaşın",
|
||||
"follow_link": "Linki izləyin",
|
||||
"piped_link": "Piped linki",
|
||||
"copy_link": "Linki kopyalayın",
|
||||
"new_playlist_name": "Yeni oynatma siyahısı adı",
|
||||
"share": "Paylaş",
|
||||
"with_timecode": "Vaxt kodu ilə paylaş",
|
||||
"follow_link": "Bağlantını izlə",
|
||||
"piped_link": "Piped bağlantısı",
|
||||
"copy_link": "Bağlantını kopyala",
|
||||
"back_to_home": "Evə qayıt",
|
||||
"reply_count": "{count} cavab",
|
||||
"minimize_comments_default": "Şərhləri standart olaraq kiçilt",
|
||||
"minimize_comments": "Şərhləri Kiçilt"
|
||||
"minimize_comments": "Şərhləri Kiçilt",
|
||||
"minimize_chapters_default": "Standart olaraq bölmələri kiçilt",
|
||||
"show_watch_on_youtube": "YouTube-da Baxış düyməsin göstər",
|
||||
"no_valid_playlists": "Faylın etibarlı oynatma siyahıları yoxdur!",
|
||||
"with_playlist": "Oynatma siyahısıyla paylaş",
|
||||
"bookmark_playlist": "Əlfəcin",
|
||||
"playlist_bookmarked": "Əlfəcinləndi",
|
||||
"skip_button_only": "Ötürmə düyməsin göstər",
|
||||
"skip_automatically": "Avtomatik olaraq",
|
||||
"min_segment_length": "Minimum Seqment Uzunluğu (saniyələrlə)",
|
||||
"skip_segment": "Seqmenti ötür",
|
||||
"show_less": "Daha az göstər",
|
||||
"autoplay_next_countdown": "Növbəti videoya qədər standart geri sayım (saniyə)",
|
||||
"dismiss": "Rədd et"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Tərəfindən Sabitləndi {author}",
|
||||
"disabled": "Şərhlər yükləyici tərəfindən deaktiv edilib.",
|
||||
"loading": "Şərhlər yüklənir...",
|
||||
"user_disabled": "Şərhlər tənzimləmələrdə deaktiv edilib."
|
||||
"pinned_by": "{author} tərəfindən sabitlənib",
|
||||
"disabled": "Şərhlər yükləyici tərəfindən bağlanıb.",
|
||||
"loading": "Şərhlər yüklənilir...",
|
||||
"user_disabled": "Şərhlər tənzimləmələrdə qeyri-aktiv edilib."
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Nümunə Adı",
|
||||
"instance_locations": "Nümunə Məkanları",
|
||||
"has_cdn": "CDN varmı?",
|
||||
"has_cdn": "CDN Varmı?",
|
||||
"registered_users": "Qeydiyyatdan Keçmiş İstifadəçilər",
|
||||
"version": "Versiya",
|
||||
"up_to_date": "Güncəllənib?",
|
||||
|
@ -140,21 +156,23 @@
|
|||
"views": "{views} baxış",
|
||||
"watched": "Baxılıb",
|
||||
"sponsor_segments": "Sponsorlar Seqmentləri",
|
||||
"ratings_disabled": "Reytinqlər Deaktivdir",
|
||||
"chapters": "Bölümlər",
|
||||
"ratings_disabled": "Reytinqlər Qeyri-aktivdir",
|
||||
"chapters": "Bölmələr",
|
||||
"live": "{0} Canlı",
|
||||
"shorts": "Qısa"
|
||||
"shorts": "Qısa",
|
||||
"all": "Hamısı",
|
||||
"category": "Kateqoriya"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Bunu nəzərdə tutursunuz: {0}?",
|
||||
"all": "YouTube: Hamısı",
|
||||
"videos": "YouTube: Videolar",
|
||||
"channels": "YouTube: Kanallar",
|
||||
"playlists": "YouTube: Pleylistlər",
|
||||
"playlists": "YouTube: Oynatma siyahıları",
|
||||
"music_songs": "YT Music: Mahnılar",
|
||||
"music_videos": "YT Music: Videolar",
|
||||
"music_albums": "YT Music: Albomlar",
|
||||
"music_playlists": "YT Music: Pleylistlər"
|
||||
"music_playlists": "YT Music: Oynatma Siyahıları"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abunə oldu: {0}"
|
||||
|
@ -163,9 +181,12 @@
|
|||
"preferences_note": "Qeyd: seçimlər brauzerinizin yerli yaddaşında saxlanılır. Brauzer məlumatlarınızın silinməsi onları sıfırlayacaq."
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Qeyd: Seçimlər brauzerinizin yerli yaddaşında saxlanılır. Brauzer məlumatlarınızın silinməsi onları sıfırlayacaq.",
|
||||
"preferences_note": "Qeyd: Seçimlər brauzerinizin öz yaddaşında saxlanılır. Brauzer məlumatınızın silinməsi onları sıfırlayacaq.",
|
||||
"page_not_found": "Səhifə tapılmadı",
|
||||
"copied": "Kopyalandı!",
|
||||
"cannot_copy": "Kopyalanmır!"
|
||||
"copied": "Nüsxələndi!",
|
||||
"cannot_copy": "Nüsxələnmir!",
|
||||
"local_storage": "Bu fəaliyyət yerli yaddaş tələb edir, məlumat bazası aktivdir?",
|
||||
"register_no_email_note": "E-poçt-u istifadəçi adı kimi istifadə etmək tövsiyə edilmir. Baxmayaraq ki, davam edilsin?",
|
||||
"next_video_countdown": "Növbəti video {0} saniyəyə oynadılır"
|
||||
}
|
||||
}
|
||||
|
|
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": "Използването на имейл като потребителско име не се препоръчва. Продължете все пак?"
|
||||
}
|
||||
}
|
|
@ -47,7 +47,7 @@
|
|||
"country_selection": "Izbor zemalja",
|
||||
"minimize_description_default": "Umanji Opis po podrazumijevanim podešavanjima",
|
||||
"no": "Ne",
|
||||
"donations": "Donacije",
|
||||
"donations": "Donacije za razvoj",
|
||||
"show_description": "Prikaži opis",
|
||||
"load_more_replies": "Učitajte još odgovora",
|
||||
"enabled_codecs": "Omogućeni kodeci (množina)",
|
||||
|
@ -63,9 +63,53 @@
|
|||
"view_ssl_score": "Pogledajte SSL rezultat",
|
||||
"hide_replies": "Sakrijte odgovore",
|
||||
"remove_from_playlist": "Uklonite iz popisa snimaka",
|
||||
"delete_playlist_video_confirm": "Jel baš želite ukloniti ovaj video iz ovog popisa snimaka?",
|
||||
"delete_playlist_video_confirm": "Uklonite ovaj video iz popisa snimaka?",
|
||||
"select_playlist": "Odaberite popis snimaka",
|
||||
"delete_playlist_confirm": "Jeste li sigurni da želite izbrisati ovaj popis snimaka?"
|
||||
"delete_playlist_confirm": "Izbrisati ovaj popis snimaka?",
|
||||
"show_markers": "Prikaži markere na Pokretniku",
|
||||
"share": "Podijeli",
|
||||
"invalidate_session": "Odjavite se sa svih uređaja",
|
||||
"show_chapters": "Poglavlja",
|
||||
"status_page": "Status",
|
||||
"source_code": "Izvorni kod",
|
||||
"clone_playlist_success": "Uspješno klonirano!",
|
||||
"store_search_history": "Pohrani historiju pretraživanja",
|
||||
"minimize_chapters_default": "Smanjite poglavlja po zadanom",
|
||||
"show_watch_on_youtube": "Prikaži „Gledaj na YouTube-u” dugme",
|
||||
"different_auth_instance": "Koristite drugu instancu za autentifikaciju",
|
||||
"rename_playlist": "Preimenuj listu izvođenja",
|
||||
"new_playlist_name": "Novi naziv liste izvođenja",
|
||||
"with_timecode": "Podijelite s vremenskim kodom",
|
||||
"piped_link": "Piped poveznica",
|
||||
"follow_link": "Prati poveznicu",
|
||||
"time_code": "Vremenski kod (u sekundama)",
|
||||
"hide_watched": "Sakrijte gledane videozapise u sažetku sadržaja",
|
||||
"instance_donations": "Donacije za instancu",
|
||||
"reply_count": "{count} odgovora",
|
||||
"logout": "Odjavite se sa ovog uređaja",
|
||||
"download_as_txt": "Preuzmite kao .txt",
|
||||
"backup_preferences": "Spremi sigurnosnu kopiju postavki",
|
||||
"instance_auth_selection": "Odabir instance autentikacije",
|
||||
"restore_preferences": "Vrati postavke",
|
||||
"back_to_home": "Povratak na početnu",
|
||||
"copy_link": "Kopiraj poveznicu",
|
||||
"no_valid_playlists": "Datoteka ne sadrži važeće liste za reprodukciju!",
|
||||
"with_playlist": "Podijeli sa listom izvođenja",
|
||||
"clone_playlist": "Kloniraj listu za reprodukciju",
|
||||
"documentation": "Dokumentacija",
|
||||
"confirm_reset_preferences": "Jeste li sigurni da želite obnoviti svoje postavke?",
|
||||
"minimize_comments_default": "Po zadanom smanjite komentare",
|
||||
"minimize_comments": "Minimizirajte komentare",
|
||||
"delete_account": "Izbriši račun",
|
||||
"minimize_recommendations_default": "Smanjite preporuke po zadanom",
|
||||
"reset_preferences": "Vrati postavke na zadano",
|
||||
"bookmark_playlist": "Bilježak",
|
||||
"playlist_bookmarked": "Obilježeno",
|
||||
"show_less": "Prikaži manje",
|
||||
"skip_button_only": "Prikaži dugme za preskakanje",
|
||||
"skip_automatically": "Automatski",
|
||||
"min_segment_length": "Najmanja dužina segmenta (u sekundama)",
|
||||
"skip_segment": "Preskoči segment"
|
||||
},
|
||||
"titles": {
|
||||
"register": "Registrirajte se",
|
||||
|
@ -75,7 +119,13 @@
|
|||
"feed": "Novosti",
|
||||
"preferences": "Podešavanja",
|
||||
"playlists": "Popisi Snimaka",
|
||||
"subscriptions": "Pretplate"
|
||||
"subscriptions": "Pretplate",
|
||||
"instance": "Instanca",
|
||||
"account": "Račun",
|
||||
"player": "Pokretnik",
|
||||
"channels": "Kanali",
|
||||
"livestreams": "Prijenosi uživo",
|
||||
"bookmarks": "Bilješci"
|
||||
},
|
||||
"search": {
|
||||
"music_songs": "YT Music: Pjesme",
|
||||
|
@ -111,9 +161,26 @@
|
|||
"ratings_disabled": "Ocjene su isključene",
|
||||
"watched": "Pogledano",
|
||||
"videos": "Video zapisi",
|
||||
"live": "{0} Uživo"
|
||||
"live": "{0} Uživo",
|
||||
"shorts": "Kratki videi",
|
||||
"category": "Kategorija",
|
||||
"all": "Sve"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Prikačeno od {author}"
|
||||
"pinned_by": "Prikačeno od {author}",
|
||||
"disabled": "Komentari su onemogućeni od strane prijenosnika.",
|
||||
"loading": "Učitavanje komentara...",
|
||||
"user_disabled": "Komentari su onemogućeni u postavkama."
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Pretplaćeni ste na: {0}"
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Napomena: Preferencije se čuvaju u lokalnom skladištu vašeg pretraživača. Brisanje podataka vašeg preglednika će ih resetirati.",
|
||||
"cannot_copy": "Nije moguće kopirati!",
|
||||
"page_not_found": "Stranica nije pronađena",
|
||||
"copied": "Kopirano!",
|
||||
"local_storage": "Ova radnja zahtijeva lokalno pohranjivanje, jesu li kolačići omogućeni?",
|
||||
"register_no_email_note": "Korištenje e-maila kao korisničko ime se ne preporučuje. Svejedno nastaviti?"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
"playlists": "Llistes de reproducció",
|
||||
"account": "Compte",
|
||||
"instance": "Instància",
|
||||
"player": "Reproductor"
|
||||
"player": "Reproductor",
|
||||
"livestreams": "Retransmissió en directe",
|
||||
"channels": "Canals",
|
||||
"bookmarks": "Marcadors"
|
||||
},
|
||||
"actions": {
|
||||
"channel_name_desc": "Nom del Canal (Z-A)",
|
||||
|
@ -40,7 +43,7 @@
|
|||
"enabled_codecs": "Còdecs Habilitats (Múltiple)",
|
||||
"instances_list": "Llista d'Instàncies",
|
||||
"instance_selection": "Selecció d'Instàncies",
|
||||
"show_more": "Mostrar Més",
|
||||
"show_more": "Mostrar més",
|
||||
"yes": "Sí",
|
||||
"no": "No",
|
||||
"export_to_json": "Exportar a JSON",
|
||||
|
@ -108,7 +111,21 @@
|
|||
"show_chapters": "Capítols",
|
||||
"status_page": "Estat",
|
||||
"source_code": "Codi font",
|
||||
"documentation": "Documentació"
|
||||
"documentation": "Documentació",
|
||||
"show_watch_on_youtube": "Mostra el botó \"Veure a Youtube\"",
|
||||
"reply_count": "{count} respostes",
|
||||
"minimize_comments_default": "Minimitzar els comentaris per defecte",
|
||||
"minimize_comments": "Minimitza els comentaris",
|
||||
"no_valid_playlists": "L'arxiu no conté llistes de reproducció vàlides!",
|
||||
"bookmark_playlist": "Marcador",
|
||||
"playlist_bookmarked": "Afegit a marcadors",
|
||||
"minimize_chapters_default": "Minimitzar capítols per defecte",
|
||||
"skip_button_only": "Mostra el botó de saltar",
|
||||
"skip_automatically": "Automàticament",
|
||||
"min_segment_length": "Longitud de segment mínima (en segons)",
|
||||
"skip_segment": "Saltar segment",
|
||||
"with_playlist": "Comparteix amb llista de reproducció",
|
||||
"show_less": "Mostrar menys"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Fixat per {author}",
|
||||
|
@ -133,7 +150,9 @@
|
|||
"live": "{0} En Directe",
|
||||
"videos": "Vídeos",
|
||||
"views": "{views} visualitzacions",
|
||||
"shorts": "Curts"
|
||||
"shorts": "Curts",
|
||||
"all": "Tot",
|
||||
"category": "Categoria"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Volies dir: {0}?",
|
||||
|
@ -163,6 +182,8 @@
|
|||
"preferences_note": "Nota: les preferències es desen a l'emmagatzematge local del navegador. Si elimineu les dades del navegador, es restabliran.",
|
||||
"page_not_found": "No s'ha torbat la pàgina",
|
||||
"copied": "Copiat!",
|
||||
"cannot_copy": "No es pot copiar!"
|
||||
"cannot_copy": "No es pot copiar!",
|
||||
"local_storage": "Aquesta acció requereix emmagatzematge local, estan les cookies habilitades?",
|
||||
"register_no_email_note": "Utilitzar un correu elextrònic com a usuari no és recomanable. Continuar de totes maneres?"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"instance": "Instance",
|
||||
"player": "Přehrávač",
|
||||
"livestreams": "Živé přenosy",
|
||||
"channels": "Kanály"
|
||||
"channels": "Kanály",
|
||||
"bookmarks": "Záložky"
|
||||
},
|
||||
"actions": {
|
||||
"loop_this_video": "Přehrávat video ve smyčce",
|
||||
|
@ -59,7 +60,7 @@
|
|||
"disable_lbry": "Zakázat LBRY pro streamování",
|
||||
"enable_lbry_proxy": "Povolit proxy pro LBRY",
|
||||
"view_ssl_score": "Zobrazit stav SSL",
|
||||
"search": "Vyhledat",
|
||||
"search": "Vyhledávání (Ctrl+K)",
|
||||
"filter": "Filtr",
|
||||
"loading": "Načítání...",
|
||||
"clear_history": "Smazat historii",
|
||||
|
@ -113,7 +114,20 @@
|
|||
"status_page": "Stav",
|
||||
"reply_count": "{count} odpovědí",
|
||||
"minimize_comments_default": "Ve výchozím nastavení skrýt komentáře",
|
||||
"minimize_comments": "Skrýt komentáře"
|
||||
"minimize_comments": "Skrýt komentáře",
|
||||
"show_watch_on_youtube": "Zobrazit tlačítko Sledovat na YouTube",
|
||||
"minimize_chapters_default": "Ve výchozím nastavení skrýt kapitoly",
|
||||
"no_valid_playlists": "Soubor neobsahuje platné playlisty!",
|
||||
"with_playlist": "Sdílet s playlistem",
|
||||
"bookmark_playlist": "Záložka",
|
||||
"playlist_bookmarked": "Uloženo",
|
||||
"skip_automatically": "Automaticky",
|
||||
"skip_segment": "Přeskočit segment",
|
||||
"skip_button_only": "Zobrazit tlačítko přeskočení",
|
||||
"min_segment_length": "Minimální délka segmentu (v sekundách)",
|
||||
"show_less": "Zobrazit méně",
|
||||
"autoplay_next_countdown": "Výchozí odpočet do dalšího videa (v sekundách)",
|
||||
"dismiss": "Zavřít"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Sledovat na {0}"
|
||||
|
@ -145,7 +159,9 @@
|
|||
"ratings_disabled": "Hodnocení zakázáno",
|
||||
"chapters": "Kapitoly",
|
||||
"live": "{0} Živě",
|
||||
"shorts": "Shorts"
|
||||
"shorts": "Shorts",
|
||||
"all": "Vše",
|
||||
"category": "Kategorie"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Mysleli jste: {0}?",
|
||||
|
@ -168,6 +184,9 @@
|
|||
"preferences_note": "Poznámka: předvolby se ukládají do místního úložiště prohlížeče. Vymazáním dat prohlížeče budou obnoveny.",
|
||||
"page_not_found": "Stránka nenalezena",
|
||||
"copied": "Zkopírováno!",
|
||||
"cannot_copy": "Nelze zkopírovat!"
|
||||
"cannot_copy": "Nelze zkopírovat!",
|
||||
"local_storage": "Tato akce vyžaduje localStorage, jsou povoleny cookies?",
|
||||
"register_no_email_note": "Použití e-mailu jako uživatelského jména se nedoporučuje. Chcete přesto pokračovat?",
|
||||
"next_video_countdown": "Přehrávání dalšího videa za {0}s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"actions": {
|
||||
"skip_outro": "Abspann überspringen",
|
||||
"skip_non_music": "Musik überspringen: Nicht-Musik-Bereich",
|
||||
"skip_outro": "Endkarten und Abspann überspringen",
|
||||
"skip_non_music": "Musik: Nicht-Musik-Abschnitte überspringen",
|
||||
"skip_self_promo": "Unbezahlte Werbung/Eigenwerbung überspringen",
|
||||
"skip_interaction": "Interaktionserinnerung überspringen (Abonnieren)",
|
||||
"skip_preview": "Vorschau/Rückschau überspringen",
|
||||
"skip_interaction": "Interaktionserinnerungen überspringen (Daumen hoch, abonnieren, ...)",
|
||||
"skip_preview": "Vorschau und Rückblick überspringen",
|
||||
"instances_list": "Liste der Instanzen",
|
||||
"language_selection": "Sprachauswahl",
|
||||
"store_watch_history": "Wiedergabeverlauf speichern",
|
||||
"minimize_description_default": "Beschreibung standardmäßig minimieren",
|
||||
"show_comments": "Kommentare anzeigen",
|
||||
"default_homepage": "Standard-Startseite",
|
||||
"default_homepage": "Startseite",
|
||||
"country_selection": "Länderauswahl",
|
||||
"buffering_goal": "Pufferungsziel (in Sekunden)",
|
||||
"default_quality": "Standardqualität",
|
||||
|
@ -20,9 +20,9 @@
|
|||
"dark": "Dunkel",
|
||||
"auto": "Automatisch",
|
||||
"theme": "Farbschema",
|
||||
"skip_intro": "Pausen-/Intro-Animation überspringen",
|
||||
"skip_sponsors": "Sponsoren überspringen",
|
||||
"enable_sponsorblock": "Sponsorblock einschalten",
|
||||
"skip_intro": "Unterbrechungen und Intro-Animation überspringen",
|
||||
"skip_sponsors": "Gesponsorte Videoabschnitte überspringen",
|
||||
"enable_sponsorblock": "SponsorBlock verwenden",
|
||||
"uses_api_from": "Verwendet die API von ",
|
||||
"back": "Zurück",
|
||||
"channel_name_desc": "Kanalname (Z-A)",
|
||||
|
@ -30,13 +30,13 @@
|
|||
"least_recent": "Am wenigsten neu",
|
||||
"most_recent": "Am Neuesten",
|
||||
"sort_by": "Sortieren nach:",
|
||||
"view_subscriptions": "Abonnements anzeigen",
|
||||
"view_subscriptions": "Abos anzeigen",
|
||||
"unsubscribe": "Deabonnieren - {count}",
|
||||
"subscribe": "Abonnieren - {count}",
|
||||
"enabled_codecs": "Aktivierte Codecs (mehrere)",
|
||||
"enabled_codecs": "Aktivierte Codecs (Auswahl mehrerer Codecs möglich)",
|
||||
"enable_lbry_proxy": "Proxy für LBRY einschalten",
|
||||
"disable_lbry": "LBRY für Streaming deaktivieren",
|
||||
"instance_selection": "Instanzauswahl",
|
||||
"instance_selection": "Instanz auswählen",
|
||||
"show_description": "Beschreibung anzeigen",
|
||||
"minimize_description": "Beschreibung minimieren",
|
||||
"show_recommendations": "Empfehlungen anzeigen",
|
||||
|
@ -51,32 +51,32 @@
|
|||
"yes": "Ja",
|
||||
"loading": "Wird geladen…",
|
||||
"filter": "Filtern",
|
||||
"search": "Suchen",
|
||||
"search": "Suchen (Strg+K)",
|
||||
"view_ssl_score": "SSL-Bewertung anzeigen",
|
||||
"clear_history": "Verlauf löschen",
|
||||
"hide_replies": "Antworten ausblenden",
|
||||
"load_more_replies": "Mehr Antworten laden",
|
||||
"skip_highlight": "Höhepunkt überspringen",
|
||||
"skip_filler_tangent": "Lückenfüller überspringen",
|
||||
"delete_playlist_confirm": "Diese Wiedergabeliste löschen?",
|
||||
"remove_from_playlist": "Aus Wiedergabeliste entfernen",
|
||||
"add_to_playlist": "Zur Wiedergabeliste hinzufügen",
|
||||
"create_playlist": "Wiedergabeliste erstellen",
|
||||
"delete_playlist_video_confirm": "Video aus Wiedergabeliste entfernen?",
|
||||
"delete_playlist": "Wiedergabeliste löschen",
|
||||
"please_select_playlist": "Bitte wählen Sie eine Wiedergabeliste",
|
||||
"select_playlist": "Wählen Sie eine Wiedergabeliste",
|
||||
"delete_playlist_confirm": "Diese Playlist löschen?",
|
||||
"remove_from_playlist": "Aus Playlist entfernen",
|
||||
"add_to_playlist": "Zur Playlist hinzufügen",
|
||||
"create_playlist": "Playlist erstellen",
|
||||
"delete_playlist_video_confirm": "Video aus Playlist entfernen?",
|
||||
"delete_playlist": "Playlist löschen",
|
||||
"please_select_playlist": "Bitte wähle eine Playlist",
|
||||
"select_playlist": "Wähle eine Playlist",
|
||||
"show_markers": "Markierungen auf dem Player anzeigen",
|
||||
"delete_account": "Konto löschen",
|
||||
"logout": "Von diesem Gerät abmelden",
|
||||
"minimize_recommendations_default": "Empfehlungen standardmäßig minimieren",
|
||||
"invalidate_session": "Von allen Geräte abmelden",
|
||||
"invalidate_session": "Von allen Geräten abmelden",
|
||||
"different_auth_instance": "Eine andere Instanz für die Authentifizierung verwenden",
|
||||
"instance_auth_selection": "Auswahl der Autentifizierungsinstanz",
|
||||
"clone_playlist": "Wiedergabeliste klonen",
|
||||
"clone_playlist_success": "Erfolgreich geklont!",
|
||||
"rename_playlist": "Wiedergabeliste umbenennen",
|
||||
"new_playlist_name": "Neuer Name der Wiedergabeliste",
|
||||
"clone_playlist": "Playlist duplizieren",
|
||||
"clone_playlist_success": "Erfolgreich dupliziert!",
|
||||
"rename_playlist": "Playlist umbenennen",
|
||||
"new_playlist_name": "Neuer Name der Playlist",
|
||||
"piped_link": "Piped-Link",
|
||||
"download_as_txt": "Als .txt herunterladen",
|
||||
"back_to_home": "Zurück zur Startseite",
|
||||
|
@ -84,7 +84,7 @@
|
|||
"with_timecode": "Mit Zeitstempel teilen",
|
||||
"follow_link": "Link öffnen",
|
||||
"copy_link": "Link kopieren",
|
||||
"time_code": "Zeitstempel (in sekunden)",
|
||||
"time_code": "Zeitstempel (in Sekunden)",
|
||||
"reset_preferences": "Einstellungen zurücksetzen",
|
||||
"confirm_reset_preferences": "Bist du sicher, dass du deine Einstellungen zurücksetzen möchtest?",
|
||||
"backup_preferences": "Einstellungen sichern",
|
||||
|
@ -92,11 +92,26 @@
|
|||
"show_chapters": "Kapitel",
|
||||
"source_code": "Quellcode",
|
||||
"store_search_history": "Suchverlauf speichern",
|
||||
"hide_watched": "Gesehene Videos im Feed ausblenden",
|
||||
"hide_watched": "Gesehene Videos im Abo-Feed ausblenden",
|
||||
"reply_count": "{count} Antworten",
|
||||
"instance_donations": "Instanz-Spenden",
|
||||
"documentation": "Dokumentation",
|
||||
"status_page": "Status"
|
||||
"status_page": "Status",
|
||||
"minimize_chapters_default": "Kapitel standardmäßig minimieren",
|
||||
"minimize_comments_default": "Kommentare standardmäßig minimieren",
|
||||
"minimize_comments": "Kommentare minimieren",
|
||||
"no_valid_playlists": "Die Datei enthält keine gültigen Playlists!",
|
||||
"show_watch_on_youtube": "Schaltfläche „Auf YouTube ansehen“ anzeigen",
|
||||
"with_playlist": "Mit Playlist teilen",
|
||||
"playlist_bookmarked": "Markiert",
|
||||
"bookmark_playlist": "Lesezeichen",
|
||||
"skip_segment": "Abschnitt überspringen",
|
||||
"skip_automatically": "Automatisch",
|
||||
"min_segment_length": "Minimale Abschnittlänge (in Sekunden)",
|
||||
"skip_button_only": "Überspringen-Schaltfläche anzeigen",
|
||||
"show_less": "Weniger anzeigen",
|
||||
"autoplay_next_countdown": "Anzahl der Sekunden bis das nächste Video automatisch startet",
|
||||
"dismiss": "Ablehnen"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Auf {0} ansehen"
|
||||
|
@ -104,25 +119,30 @@
|
|||
"titles": {
|
||||
"history": "Verlauf",
|
||||
"preferences": "Einstellungen",
|
||||
"feed": "Abonnements",
|
||||
"feed": "Abos",
|
||||
"register": "Registrieren",
|
||||
"login": "Anmelden",
|
||||
"trending": "Trends",
|
||||
"subscriptions": "Abonnements",
|
||||
"playlists": "Wiedergabelisten",
|
||||
"subscriptions": "Abos",
|
||||
"playlists": "Playlists",
|
||||
"account": "Konto",
|
||||
"player": "Player",
|
||||
"instance": "Instanz"
|
||||
"instance": "Instanz",
|
||||
"livestreams": "Livestreams",
|
||||
"channels": "Kanäle",
|
||||
"bookmarks": "Lesezeichen"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "Sponsoren-Segmente",
|
||||
"sponsor_segments": "Sponsoren-Abschnitte",
|
||||
"watched": "Angesehen",
|
||||
"views": "{views} Aufrufe",
|
||||
"videos": "Videos",
|
||||
"ratings_disabled": "Bewertungen deaktiviert",
|
||||
"live": "{0} Live",
|
||||
"chapters": "Kapitel",
|
||||
"shorts": "Shorts"
|
||||
"shorts": "Shorts",
|
||||
"all": "Alle",
|
||||
"category": "Kategorie"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "SSL-Bewertung",
|
||||
|
@ -137,30 +157,33 @@
|
|||
"pinned_by": "Angeheftet von {author}",
|
||||
"user_disabled": "Kommentare wurden in den Einstellungen deaktiviert.",
|
||||
"disabled": "Kommentare wurden vom Autor deaktiviert.",
|
||||
"loading": "Kommentare werden geladen …"
|
||||
"loading": "Kommentare werden geladen…"
|
||||
},
|
||||
"login": {
|
||||
"password": "Passwort",
|
||||
"username": "Anmeldename"
|
||||
"username": "Benutzername"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Hast du gemeint: {0}?",
|
||||
"all": "YouTube: Alle",
|
||||
"videos": "YouTube: Videos",
|
||||
"channels": "YouTube: Kanäle",
|
||||
"playlists": "YouTube: Wiedergabelisten",
|
||||
"playlists": "YouTube: Playlists",
|
||||
"music_songs": "YT Music: Lieder",
|
||||
"music_videos": "YT Music: Videos",
|
||||
"music_albums": "YT Music: Alben",
|
||||
"music_playlists": "YT Music: Wiedergabelisten"
|
||||
"music_playlists": "YT Music: Playlists"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Aboniert bei: {0}"
|
||||
"subscribed_channels_count": "Anzahl Abos: {0}"
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Achtung: Einstellung werden lokal in deinem Browser gespeichert. Wenn du deine Browserdaten löschst werden sie auch gelöscht.",
|
||||
"preferences_note": "Achtung: Die Einstellung werden lokal in deinem Browser gespeichert. Wenn du deine Browserdaten löschst, werden auch deine Einstellungen zurückgesetzt.",
|
||||
"page_not_found": "Seite nicht gefunden",
|
||||
"copied": "Kopiert!",
|
||||
"cannot_copy": "Kopieren nicht möglich!"
|
||||
"cannot_copy": "Kopieren nicht möglich!",
|
||||
"local_storage": "Diese Aktion erfordert „localStorage“, sind Cookies aktiviert?",
|
||||
"register_no_email_note": "Es wird nicht empfohlen, eine E-Mail als Benutzernamen zu verwenden. Trotzdem fortfahren?",
|
||||
"next_video_countdown": "Nächstes Video startet in {0}s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"instance": "Instance",
|
||||
"player": "Player",
|
||||
"livestreams": "Livestreams",
|
||||
"channels": "Channels"
|
||||
"channels": "Channels",
|
||||
"bookmarks": "Bookmarks"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Watch on {0}"
|
||||
|
@ -29,6 +30,8 @@
|
|||
"back": "Back",
|
||||
"uses_api_from": "Uses the API from ",
|
||||
"enable_sponsorblock": "Enable Sponsorblock",
|
||||
"skip_button_only": "Show skip button",
|
||||
"skip_automatically": "Automatically",
|
||||
"skip_sponsors": "Skip Sponsors",
|
||||
"skip_intro": "Skip Intermission/Intro Animation",
|
||||
"skip_outro": "Skip Endcards/Credits",
|
||||
|
@ -39,11 +42,14 @@
|
|||
"skip_highlight": "Skip Highlight",
|
||||
"skip_filler_tangent": "Skip Filler Tangent",
|
||||
"show_markers": "Show Markers on Player",
|
||||
"min_segment_length": "Minimum Segment Length (in seconds)",
|
||||
"skip_segment": "Skip Segment",
|
||||
"theme": "Theme",
|
||||
"auto": "Auto",
|
||||
"dark": "Dark",
|
||||
"light": "Light",
|
||||
"autoplay_video": "Autoplay Video",
|
||||
"autoplay_next_countdown": "Default Countdown until next video (in seconds)",
|
||||
"audio_only": "Audio Only",
|
||||
"default_quality": "Default Quality",
|
||||
"buffering_goal": "Buffering Goal (in seconds)",
|
||||
|
@ -73,7 +79,7 @@
|
|||
"disable_lbry": "Disable LBRY for Streaming",
|
||||
"enable_lbry_proxy": "Enable Proxy for LBRY",
|
||||
"view_ssl_score": "View SSL Score",
|
||||
"search": "Search",
|
||||
"search": "Search (Ctrl+K)",
|
||||
"filter": "Filter",
|
||||
"loading": "Loading...",
|
||||
"clear_history": "Clear History",
|
||||
|
@ -114,13 +120,20 @@
|
|||
"show_chapters": "Chapters",
|
||||
"store_search_history": "Store Search history",
|
||||
"hide_watched": "Hide watched videos in the feed",
|
||||
"mark_as_watched": "Mark as Watched",
|
||||
"mark_as_unwatched": "Mark as Unwatched",
|
||||
"documentation": "Documentation",
|
||||
"status_page": "Status",
|
||||
"source_code": "Source code",
|
||||
"instance_donations": "Instance donations",
|
||||
"reply_count": "{count} replies",
|
||||
"mark_as_watched": "Mark as Watched",
|
||||
"mark_as_unwatched": "Mark as Unwatched"
|
||||
"no_valid_playlists": "The file doesn't contain valid playlists!",
|
||||
"with_playlist": "Share with playlist",
|
||||
"bookmark_playlist": "Bookmark",
|
||||
"playlist_bookmarked": "Bookmarked",
|
||||
"dismiss": "Dismiss",
|
||||
"show_more": "Show more",
|
||||
"show_less": "Show less"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Pinned by {author}",
|
||||
|
@ -149,7 +162,9 @@
|
|||
"ratings_disabled": "Ratings Disabled",
|
||||
"chapters": "Chapters",
|
||||
"live": "{0} Live",
|
||||
"shorts": "Shorts"
|
||||
"shorts": "Shorts",
|
||||
"all": "All",
|
||||
"category": "Category"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Did you mean: {0}?",
|
||||
|
@ -169,6 +184,9 @@
|
|||
"preferences_note": "Note: preferences are saved in the local storage of your browser. Deleting your browser data will reset them.",
|
||||
"page_not_found": "Page not found",
|
||||
"copied": "Copied!",
|
||||
"cannot_copy": "Can't copy!"
|
||||
"cannot_copy": "Can't copy!",
|
||||
"local_storage": "This action requires localStorage, are cookies enabled?",
|
||||
"register_no_email_note": "Using an e-mail as username is not recommended. Proceed anyways?",
|
||||
"next_video_countdown": "Playing next video in {0}s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"player": "Ludilo",
|
||||
"instance": "Nodo",
|
||||
"channels": "Kanaloj",
|
||||
"livestreams": "Tujelsendoj"
|
||||
"livestreams": "Tujelsendoj",
|
||||
"bookmarks": "Legosignoj"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Vidi en {0}"
|
||||
|
@ -38,18 +39,18 @@
|
|||
"light": "Hela",
|
||||
"autoplay_video": "Aŭtomate Ludi Videon",
|
||||
"audio_only": "Nur Sono",
|
||||
"default_quality": "Defaŭlta Kvalito",
|
||||
"default_quality": "Implicita Kvalito",
|
||||
"country_selection": "Landa Elekto",
|
||||
"default_homepage": "Defaŭlta Ĉefpaĝo",
|
||||
"default_homepage": "Implicita Ĉefpaĝo",
|
||||
"show_comments": "Montri Komentojn",
|
||||
"language_selection": "Lingva Elekto",
|
||||
"donations": "Donacoj por programado",
|
||||
"show_more": "Montri Pli",
|
||||
"show_more": "Montri pli",
|
||||
"yes": "Jes",
|
||||
"no": "Ne",
|
||||
"show_chapters": "Sekcioj",
|
||||
"filter": "Filtri",
|
||||
"search": "Serĉi",
|
||||
"search": "Serĉi (Ctrl+K)",
|
||||
"hide_replies": "Kaŝi Respondojn",
|
||||
"add_to_playlist": "Aldoni al ludlisto",
|
||||
"delete_playlist": "Forigi Ludliston",
|
||||
|
@ -113,11 +114,23 @@
|
|||
"skip_interaction": "Preterpasi Interagan Memorigon (Aboni)",
|
||||
"store_watch_history": "Konservi Vidhistorion",
|
||||
"logout": "Elsaluti el ĉi tiu aparato",
|
||||
"minimize_description_default": "Defaŭlte Plejetigi Priskribon",
|
||||
"minimize_recommendations_default": "Defaŭlte Plejetigi Rekomendojn",
|
||||
"minimize_comments_default": "Defaŭlte Plejetigi Komentojn",
|
||||
"minimize_description_default": "Implicite Plejetigi Priskribon",
|
||||
"minimize_recommendations_default": "Implicite Plejetigi Rekomendojn",
|
||||
"minimize_comments_default": "Implicite Plejetigi Komentojn",
|
||||
"minimize_comments": "Plejetigi Komentojn",
|
||||
"show_watch_on_youtube": "Montri «Vidi en Youtube»-butonon"
|
||||
"show_watch_on_youtube": "Montri «Vidi en Youtube»-butonon",
|
||||
"minimize_chapters_default": "Implicite plejetigi ĉapitrojn",
|
||||
"no_valid_playlists": "La dosiero ne enhavas validajn ludlistojn!",
|
||||
"with_playlist": "Konigi kun ludlisto",
|
||||
"playlist_bookmarked": "Legosignita",
|
||||
"bookmark_playlist": "Legosigno",
|
||||
"skip_automatically": "Aŭtomate",
|
||||
"skip_button_only": "Montri preterpasi-butonon",
|
||||
"min_segment_length": "Minimuma Segmenta Daŭro (en sekundoj)",
|
||||
"skip_segment": "Preterpasi Segmenton",
|
||||
"show_less": "Montri malpli",
|
||||
"dismiss": "Nuligi",
|
||||
"autoplay_next_countdown": "Implicita retronombrado ĝis sekva video (en sekundoj)"
|
||||
},
|
||||
"video": {
|
||||
"chapters": "Sekcioj",
|
||||
|
@ -127,7 +140,9 @@
|
|||
"sponsor_segments": "Sponsoraj Segmentoj",
|
||||
"watched": "Viditaj",
|
||||
"ratings_disabled": "Taksadoj Malebligitaj",
|
||||
"shorts": "Mallongaj"
|
||||
"shorts": "Mallongaj",
|
||||
"all": "Ĉiuj",
|
||||
"category": "Kategorio"
|
||||
},
|
||||
"search": {
|
||||
"music_albums": "YT Music: Albumoj",
|
||||
|
@ -144,7 +159,10 @@
|
|||
"copied": "Kopiita!",
|
||||
"cannot_copy": "Ne povas kopii!",
|
||||
"preferences_note": "Noto: la agordoj estas konservitaj en la loka memoro de via retumilo. Forigi la datumojn de via retumilo restarigos ilin.",
|
||||
"page_not_found": "Paĝo ne trovita"
|
||||
"page_not_found": "Paĝo ne trovita",
|
||||
"local_storage": "Ĉi tiu ago postulas localStorage, ĉu kuketoj estas ebligitaj?",
|
||||
"register_no_email_note": "Uzi retadreson kiel uzantnomon ne estas rekomendita. Ĉu daŭrigi ĉiuokaze?",
|
||||
"next_video_countdown": "Oni ludos la sekvan videon post {0}s"
|
||||
},
|
||||
"login": {
|
||||
"username": "Uzantnomo",
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
"ratings_disabled": "Valoraciones Desactivadas",
|
||||
"chapters": "Capítulos",
|
||||
"live": "{0} Directo",
|
||||
"shorts": "Cortos"
|
||||
"shorts": "Cortos",
|
||||
"all": "Todos",
|
||||
"category": "Categoría"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "Puntuación SSL",
|
||||
|
@ -40,7 +42,7 @@
|
|||
"instance_selection": "Selección de instancias",
|
||||
"enabled_codecs": "Códecs habilitados (múltiples)",
|
||||
"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",
|
||||
"minimize_description_default": "Minimizar la descripción por defecto",
|
||||
"show_comments": "Mostrar comentarios",
|
||||
|
@ -74,7 +76,7 @@
|
|||
"subscribe": "Suscribirme - {count}",
|
||||
"loading": "Cargando…",
|
||||
"filter": "Filtrar",
|
||||
"search": "Buscar",
|
||||
"search": "Buscar (Ctrl+K)",
|
||||
"view_ssl_score": "Ver la puntuación SSL",
|
||||
"minimize_recommendations": "Minimizar recomendaciones",
|
||||
"show_recommendations": "Mostrar recomendaciones",
|
||||
|
@ -124,7 +126,19 @@
|
|||
"reply_count": "{count} respuestas",
|
||||
"minimize_comments_default": "Minimizar comentarios por defecto",
|
||||
"minimize_comments": "Minimizar comentarios",
|
||||
"show_watch_on_youtube": "Mostrar botón Ver en YouTube"
|
||||
"show_watch_on_youtube": "Mostrar botón Ver en YouTube",
|
||||
"minimize_chapters_default": "Minimiza capítulos por defecto",
|
||||
"no_valid_playlists": "¡El archivo no contiene listas de reproducción válidas!",
|
||||
"with_playlist": "Compartir con lista de reproducción",
|
||||
"playlist_bookmarked": "Marcado",
|
||||
"bookmark_playlist": "Marcador",
|
||||
"skip_button_only": "Muestra botón de saltar",
|
||||
"skip_automatically": "Automáticamente",
|
||||
"min_segment_length": "Mínima Duración de Segmento (en segundos)",
|
||||
"skip_segment": "Saltar Segmento",
|
||||
"show_less": "Mostrar menos",
|
||||
"autoplay_next_countdown": "Cuenta atrás predeterminada antes del siguiente vídeo (en segundos)",
|
||||
"dismiss": "Cancelar"
|
||||
},
|
||||
"titles": {
|
||||
"feed": "Fuente web",
|
||||
|
@ -139,7 +153,8 @@
|
|||
"instance": "Instancia",
|
||||
"player": "Reproductor",
|
||||
"livestreams": "Directos",
|
||||
"channels": "Canales"
|
||||
"channels": "Canales",
|
||||
"bookmarks": "Marcadores"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Ver en {0}"
|
||||
|
@ -166,6 +181,9 @@
|
|||
"preferences_note": "Nota: las preferencias se guardan en el almacenamiento local de tu navegador. Al borrar los datos del navegador se restablecerán.",
|
||||
"page_not_found": "Página no encontrada",
|
||||
"copied": "¡Copiado!",
|
||||
"cannot_copy": "¡No se puede copiar!"
|
||||
"cannot_copy": "¡No se puede copiar!",
|
||||
"local_storage": "Esta acción requiere «localStorage», ¿están activadas las «cookies»?",
|
||||
"register_no_email_note": "No se recomienda usar un correo electrónico como nombre de usuario. ¿Continuar de todos modos?",
|
||||
"next_video_countdown": "El próximo vídeo se reproducirá en {0}s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,40 @@
|
|||
"skip_highlight": "Ohita kohokohta",
|
||||
"skip_filler_tangent": "Ohita epäolennainen",
|
||||
"enabled_codecs": "Käytössä olevat koodekit (useita)",
|
||||
"show_markers": "Näytä merkit soittimessa"
|
||||
"show_markers": "Näytä merkit soittimessa",
|
||||
"confirm_reset_preferences": "Oletko varma, että haluat palauttaa asetukset?",
|
||||
"back_to_home": "Takaisin kotisivuun",
|
||||
"minimize_recommendations_default": "Minimoi suositukset oletusarvoisesti",
|
||||
"with_timecode": "Jaa aikakoodilla",
|
||||
"documentation": "Dokumentaatio",
|
||||
"piped_link": "Piped-linkki",
|
||||
"store_search_history": "Tallenna hakuhistoria",
|
||||
"minimize_chapters_default": "Minimoi luvut oletusarvoisesti",
|
||||
"show_watch_on_youtube": "Näytä Katso YouTubessa -painike",
|
||||
"different_auth_instance": "Käytä eri instanssia todennukseen",
|
||||
"download_as_txt": "Lataa .txt-tiedostona",
|
||||
"rename_playlist": "Nimeä soittolista uudelleen",
|
||||
"show_chapters": "Luvut",
|
||||
"minimize_comments": "Minimoi kommentit",
|
||||
"minimize_comments_default": "Minimoi kommentit oletusarvoisesti",
|
||||
"delete_account": "Poista tili",
|
||||
"clone_playlist_success": "Onnistunut kloonaus!",
|
||||
"reset_preferences": "Nollaa asetukset",
|
||||
"copy_link": "Kopioi linkki",
|
||||
"status_page": "Tila",
|
||||
"source_code": "Lähdekoodi",
|
||||
"instance_donations": "Instanssille lahjoitukset",
|
||||
"no_valid_playlists": "Tiedosto ei sisällä kelvollisia soittolistoja!",
|
||||
"share": "Jaa",
|
||||
"reply_count": "{count} vastausta",
|
||||
"hide_watched": "Piilota katsotut videot syötteessä",
|
||||
"time_code": "Aikakoodi (sekunteina)",
|
||||
"follow_link": "Avaa linkki",
|
||||
"new_playlist_name": "Soittolistan uusi nimi",
|
||||
"invalidate_session": "Kirjaudu ulos kaikista laitteista",
|
||||
"logout": "Kirjaudu ulos tästä laitteesta",
|
||||
"backup_preferences": "Varmuuskopiointiasetukset",
|
||||
"restore_preferences": "Palauta asetukset"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Katso sivustolla {0}"
|
||||
|
@ -102,7 +135,11 @@
|
|||
"register": "Rekisteröidy",
|
||||
"login": "Kirjaudu sisään",
|
||||
"trending": "Nousussa",
|
||||
"playlists": "Soittolistat"
|
||||
"playlists": "Soittolistat",
|
||||
"player": "Toistin",
|
||||
"instance": "Instanssi",
|
||||
"account": "Tili",
|
||||
"channels": "Kanavat"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Tarkoititko: {0}?",
|
||||
|
@ -116,6 +153,15 @@
|
|||
"music_playlists": "YT Music: Soittolistat"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Kiinnitti {author}"
|
||||
"pinned_by": "Kiinnitti {author}",
|
||||
"loading": "Ladataan kommentteja…",
|
||||
"user_disabled": "Kommentit on poistettu käytöstä asetuksista.",
|
||||
"disabled": "Lataaja on poistanut kommentit käytöstä."
|
||||
},
|
||||
"info": {
|
||||
"page_not_found": "Sivua ei löydy",
|
||||
"copied": "Kopioitu!",
|
||||
"cannot_copy": "Ei voi kopioida!",
|
||||
"local_storage": "Tämä toiminto vaatii localStorage, ovatko evästeet käytössä?"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"instance": "Instance",
|
||||
"player": "Lecteur",
|
||||
"livestreams": "Diffusions en direct",
|
||||
"channels": "Chaînes"
|
||||
"channels": "Chaînes",
|
||||
"bookmarks": "Marque-pages"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "S'abonner - {count}",
|
||||
|
@ -114,7 +115,17 @@
|
|||
"reply_count": "{count} réponses",
|
||||
"minimize_comments_default": "Minimiser les commentaires par défaut",
|
||||
"minimize_comments": "Minimiser les commentaires",
|
||||
"show_watch_on_youtube": "Afficher le bouton Regarder sur YouTube"
|
||||
"show_watch_on_youtube": "Afficher le bouton Regarder sur YouTube",
|
||||
"minimize_chapters_default": "Minimiser les chapitres par défaut",
|
||||
"no_valid_playlists": "Le fichier ne contient pas de listes de lecture valides !",
|
||||
"bookmark_playlist": "Marque-page",
|
||||
"playlist_bookmarked": "Dans les marque-pages",
|
||||
"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",
|
||||
"show_less": "Afficher moins"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Regarder sur {0}"
|
||||
|
@ -127,7 +138,9 @@
|
|||
"ratings_disabled": "Évaluations désactivées",
|
||||
"chapters": "Chapitres",
|
||||
"live": "{0} en direct",
|
||||
"shorts": "Courtes"
|
||||
"shorts": "Courtes",
|
||||
"all": "Tout",
|
||||
"category": "Catégorie"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "Score SSL",
|
||||
|
@ -169,6 +182,8 @@
|
|||
"preferences_note": "Remarque : les préférences sont enregistrées dans la mémoire locale de votre navigateur. La suppression des données de votre navigateur les réinitialisera.",
|
||||
"page_not_found": "Page non trouvée",
|
||||
"copied": "Copié !",
|
||||
"cannot_copy": "Impossible de copier !"
|
||||
"cannot_copy": "Impossible de copier !",
|
||||
"local_storage": "Cette action nécessite localStorage, les cookies sont-ils activés ?",
|
||||
"register_no_email_note": "Il n'est pas recommandé d'utiliser une adresse courriel omme nom d'utilisateur. Continuer quand même ?"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"playlists": "רשימות נגינה",
|
||||
"instance": "עותק",
|
||||
"livestreams": "שידורים חיים",
|
||||
"channels": "ערוצים"
|
||||
"channels": "ערוצים",
|
||||
"bookmarks": "סימניות"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "לצפות ב־{0}"
|
||||
|
@ -52,7 +53,7 @@
|
|||
"instances_list": "רשימת עותקים",
|
||||
"enabled_codecs": "מפענחים פעילים (מגוון)",
|
||||
"instance_selection": "בחירת עותק",
|
||||
"show_more": "להציג עוד",
|
||||
"show_more": "להציג יותר",
|
||||
"yes": "כן",
|
||||
"no": "לא",
|
||||
"export_to_json": "ייצוא ל־JSON",
|
||||
|
@ -99,7 +100,7 @@
|
|||
"disable_lbry": "השבתת הזרמה עם LBRY",
|
||||
"enable_lbry_proxy": "הפעלת מתווך ל־LBRY",
|
||||
"view_ssl_score": "הצגת דירוג SSL",
|
||||
"search": "חיפוש",
|
||||
"search": "חיפוש (Ctrl+K)",
|
||||
"loop_this_video": "ניגון הסרטון בלולאה",
|
||||
"minimize_recommendations": "מזעור המלצות",
|
||||
"rename_playlist": "שינוי שם רשימת נגינה",
|
||||
|
@ -116,7 +117,20 @@
|
|||
"instance_donations": "תרומות להפעלה",
|
||||
"reply_count": "{count} תגובות",
|
||||
"minimize_comments_default": "צמצום הערות כברירת מחדל",
|
||||
"minimize_comments": "צמצום הערות"
|
||||
"minimize_comments": "צמצום הערות",
|
||||
"minimize_chapters_default": "מזעור הפרקים כברירת מחדל",
|
||||
"show_watch_on_youtube": "הצגת כפתור לצפייה ב־YouTube",
|
||||
"no_valid_playlists": "הקובץ לא מכיל רשימות נגינה תקפות!",
|
||||
"with_playlist": "שיתוף עם רשימת נגינה",
|
||||
"playlist_bookmarked": "נוסף לסימניות",
|
||||
"bookmark_playlist": "סימנייה",
|
||||
"skip_button_only": "הצגת כפתור דילוג",
|
||||
"min_segment_length": "אורך מקטע מזערי (בשניות)",
|
||||
"skip_segment": "דילוג על מקטע",
|
||||
"skip_automatically": "אוטומטית",
|
||||
"show_less": "להציג פחות",
|
||||
"autoplay_next_countdown": "ספירה לאחור כברירת מחדל עד לסרטון הבא (בשניות)",
|
||||
"dismiss": "התעלמות"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "ננעץ על ידי {author}",
|
||||
|
@ -145,7 +159,9 @@
|
|||
"ratings_disabled": "הדירוגים מושבתים",
|
||||
"chapters": "פרקים",
|
||||
"live": "{0} בשידור חי",
|
||||
"shorts": "קצרצרים"
|
||||
"shorts": "קצרצרים",
|
||||
"all": "הכול",
|
||||
"category": "קטגוריה"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "האם התכוונת לביטוי {0}?",
|
||||
|
@ -162,7 +178,10 @@
|
|||
"preferences_note": "לתשומת לבך: ההעדפות נשמרות באחסון המקומי של הדפדפן שלך. מחיקת נתוני הדפדפן שלך תאפס אותם.",
|
||||
"page_not_found": "העמוד לא נמצא",
|
||||
"copied": "הועתק!",
|
||||
"cannot_copy": "לא ניתן להעתיק!"
|
||||
"cannot_copy": "לא ניתן להעתיק!",
|
||||
"local_storage": "פעולה זו דורשת אחסון מקומי (localStorage), האם עוגיות פעילות?",
|
||||
"register_no_email_note": "לא מומלץ להשתמש בכתובת דוא״ל כשם משתמש. להמשיך בכל זאת?",
|
||||
"next_video_countdown": "הסרטון הבא יתנגן בעוד {0} שניות"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "נרשמת אל: {0}"
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
"preferences": "प्राथमिकताएँ",
|
||||
"subscriptions": "सदस्यता",
|
||||
"feed": "फ़ीड",
|
||||
"playlists": "प्लेलिस्ट"
|
||||
"playlists": "प्लेलिस्ट",
|
||||
"livestreams": "लाइव स्ट्रीम",
|
||||
"channels": "चैनल",
|
||||
"player": "चालक",
|
||||
"account": "खाता"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "सदस्यता लें - {count}",
|
||||
|
@ -64,7 +68,11 @@
|
|||
"create_playlist": "प्लेलिस्ट बनायें",
|
||||
"select_playlist": "एक प्लेलिस्ट चुनें",
|
||||
"please_select_playlist": "कृपया एक प्लेलिस्ट चुनें",
|
||||
"delete_playlist": "प्लेलिस्ट हटाएं"
|
||||
"delete_playlist": "प्लेलिस्ट हटाएं",
|
||||
"enable_sponsorblock": "विज्ञापन प्रतिबंध करें",
|
||||
"default_homepage": "स्वतः निर्धारित मुख्यपृष्ठ",
|
||||
"sort_by": "वर्गीकरण:",
|
||||
"skip_automatically": "स्वतः"
|
||||
},
|
||||
"video": {
|
||||
"views": "{views} बार देखा गया",
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
"watched": "Gledano",
|
||||
"views": "{views} gledanja",
|
||||
"videos": "Videa",
|
||||
"ratings_disabled": "Ocjenjivanje isključeno",
|
||||
"ratings_disabled": "Ocjene su isključene",
|
||||
"chapters": "Poglavlja",
|
||||
"live": "{0} uživo",
|
||||
"shorts": "Kratka videa"
|
||||
"shorts": "Kratka videa",
|
||||
"all": "Sva",
|
||||
"category": "Kategorija"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "SSL ocjena",
|
||||
|
@ -20,13 +22,13 @@
|
|||
},
|
||||
"comment": {
|
||||
"pinned_by": "Prikvačio korisnik {author}",
|
||||
"disabled": "Prijenosnik onemogućuje komentare.",
|
||||
"loading": "Učitavanje komentara …",
|
||||
"disabled": "Prijenosnik je isključio komentare.",
|
||||
"loading": "Učitavanje komentara...",
|
||||
"user_disabled": "Komentari su isključeni u postavkama."
|
||||
},
|
||||
"actions": {
|
||||
"enable_lbry_proxy": "Uključi proxy za LBRY",
|
||||
"disable_lbry": "Onemogući LBRY za prijenos",
|
||||
"disable_lbry": "Isključi LBRY za prijenos",
|
||||
"minimize_description_default": "Standardno sakrij opis",
|
||||
"minimize_description": "Sakrij opis",
|
||||
"show_description": "Prikaži opis",
|
||||
|
@ -41,7 +43,7 @@
|
|||
"yes": "Da",
|
||||
"show_more": "Prikaži više",
|
||||
"instance_selection": "Izbor instance",
|
||||
"enabled_codecs": "Uključeni kodeki (višestruki)",
|
||||
"enabled_codecs": "Uključeni kodeki (moguće je odabrati nekoliko kodeka)",
|
||||
"instances_list": "Popis instanci",
|
||||
"language_selection": "Izbor jezika",
|
||||
"store_watch_history": "Spremi povijest gledanja",
|
||||
|
@ -69,28 +71,28 @@
|
|||
"view_subscriptions": "Pogledaj pretplate",
|
||||
"unsubscribe": "Otkaži pretplatu – {count}",
|
||||
"subscribe": "Pretplati se – {count}",
|
||||
"skip_interaction": "Preskoči podsjetnik za interakciju (zahtijeva pretplatu)",
|
||||
"skip_interaction": "Preskoči podsjetnik za interakciju (pretplata)",
|
||||
"skip_outro": "Preskoči odjavnu špicu",
|
||||
"skip_intro": "Preskoči pauzu i uvodnu animaciju",
|
||||
"skip_sponsors": "Preskoči sponzore",
|
||||
"enable_sponsorblock": "Uključi blok sponsora",
|
||||
"loading": "Učitavanje…",
|
||||
"filter": "Filtar",
|
||||
"search": "Pretraga",
|
||||
"search": "Pretraga (Ctrl+K)",
|
||||
"view_ssl_score": "Pogledaj SSL ocjenu",
|
||||
"hide_replies": "Sakrij odgovore",
|
||||
"load_more_replies": "Prikaži više odgovora",
|
||||
"clear_history": "Obriši povijest",
|
||||
"skip_highlight": "Preskoči isticanje",
|
||||
"skip_filler_tangent": "Preskoči nebitne međudijelove",
|
||||
"delete_playlist_confirm": "Izbrisati ovu playlistu?",
|
||||
"remove_from_playlist": "Ukloni iz playliste",
|
||||
"create_playlist": "Stvori playlistu",
|
||||
"delete_playlist": "Izbriši playlistu",
|
||||
"add_to_playlist": "Dodaj u playlistu",
|
||||
"select_playlist": "Odaberi playlistu",
|
||||
"please_select_playlist": "Odaberi playlistu",
|
||||
"delete_playlist_video_confirm": "Ukloniti video iz playliste?",
|
||||
"skip_filler_tangent": "Preskoči prazne umetke",
|
||||
"delete_playlist_confirm": "Izbrisati ovaj popis snimaka?",
|
||||
"remove_from_playlist": "Ukloni iz popisa snimaka",
|
||||
"create_playlist": "Stvori popis snimaka",
|
||||
"delete_playlist": "Izbriši popis snimaka",
|
||||
"add_to_playlist": "Dodaj u popis snimaka",
|
||||
"select_playlist": "Odaberi popis snimaka",
|
||||
"please_select_playlist": "Odaberi popis snimaka",
|
||||
"delete_playlist_video_confirm": "Ukloniti video iz popisa snimaka?",
|
||||
"show_markers": "Prikaži oznake na playeru",
|
||||
"delete_account": "Izbriši račun",
|
||||
"logout": "Odjavi se s ovog uređaja",
|
||||
|
@ -98,7 +100,7 @@
|
|||
"invalidate_session": "Odjavi sve uređaje",
|
||||
"different_auth_instance": "Koristi drugu instancu za autentifikaciju",
|
||||
"instance_auth_selection": "Odabir instance autentifikacije",
|
||||
"clone_playlist": "Dupliciraj playlistu",
|
||||
"clone_playlist": "Dupliciraj popis snimaka",
|
||||
"clone_playlist_success": "Dupliciranje uspjelo!",
|
||||
"download_as_txt": "Preuzmi kao .txt",
|
||||
"reset_preferences": "Resetiraj postavke",
|
||||
|
@ -117,14 +119,26 @@
|
|||
"show_chapters": "Poglavlja",
|
||||
"documentation": "Dokumentacija",
|
||||
"source_code": "Izvorni kod",
|
||||
"instance_donations": "Donacije instace",
|
||||
"instance_donations": "Donacije instance",
|
||||
"store_search_history": "Spremi povijest pretrage",
|
||||
"hide_watched": "Sakrij gledana videa u novostima",
|
||||
"status_page": "Stanje",
|
||||
"reply_count": "{count} odgovora",
|
||||
"minimize_comments_default": "Standardno sakrij komentare",
|
||||
"minimize_comments": "Sakrij komentare",
|
||||
"show_watch_on_youtube": "Prikaži gumb „Gledaj na YouTubeu”"
|
||||
"show_watch_on_youtube": "Prikaži gumb „Gledaj na YouTubeu”",
|
||||
"minimize_chapters_default": "Standardno sakrij poglavlja",
|
||||
"no_valid_playlists": "Datoteka ne sadrži ispravne popise snimaka!",
|
||||
"with_playlist": "Dijeli s popisom snimaka",
|
||||
"playlist_bookmarked": "Zabilježeno",
|
||||
"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)",
|
||||
"show_less": "Prikaži manje",
|
||||
"autoplay_next_countdown": "Standardno odbrojavanje do sljedećeg videa (u sekundama)",
|
||||
"dismiss": "Odbaci"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Gledaj na {0}"
|
||||
|
@ -137,12 +151,13 @@
|
|||
"register": "Registracija",
|
||||
"login": "Prijava",
|
||||
"trending": "U trendu",
|
||||
"playlists": "Playliste",
|
||||
"playlists": "Popisi snimaka",
|
||||
"account": "Račun",
|
||||
"instance": "Instanca",
|
||||
"player": "Player",
|
||||
"channels": "Kanali",
|
||||
"livestreams": "Prijenosi uživo"
|
||||
"livestreams": "Prijenosi uživo",
|
||||
"bookmarks": "Zabilješke"
|
||||
},
|
||||
"login": {
|
||||
"password": "Lozinka",
|
||||
|
@ -153,14 +168,14 @@
|
|||
"all": "YouTube: Sve",
|
||||
"videos": "YouTube: Videa",
|
||||
"channels": "YouTube: Kanali",
|
||||
"playlists": "YouTube: Playliste",
|
||||
"playlists": "YouTube: Popisi snimaka",
|
||||
"music_songs": "YT Music: Pjesme",
|
||||
"music_videos": "YT Music: Videa",
|
||||
"music_albums": "YT Music: Albumi",
|
||||
"music_playlists": "YT Music: Playliste"
|
||||
"music_playlists": "YT Music: Popisi snimaka"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Pretplata na: {0}"
|
||||
"subscribed_channels_count": "Broj pretplata: {0}"
|
||||
},
|
||||
"information": {
|
||||
"preferences_note": "Napomena: postavke se spremaju u lokalno spremište preglednika. Brisanje podataka preglednika resetira postavke."
|
||||
|
@ -169,6 +184,9 @@
|
|||
"preferences_note": "Napomena: postavke se spremaju u lokalno spremište tvog preglednika. Brisanje podataka preglednika će ih resetirati.",
|
||||
"page_not_found": "Stranica nije pronađena",
|
||||
"copied": "Kopirano!",
|
||||
"cannot_copy": "Nije moguće kopirati!"
|
||||
"cannot_copy": "Nije moguće kopirati!",
|
||||
"local_storage": "Ova radnja zahtijeva lokalno spremište. Jesu li kolačići uključeni?",
|
||||
"register_no_email_note": "Korištenje e-mail adrese kao korisničkog imena se ne preporučuje. Svejedno nastaviti?",
|
||||
"next_video_countdown": "Reprodukcija sljedećeg videa za {0} s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,11 @@
|
|||
"subscriptions": "Feliratkozások",
|
||||
"playlists": "Lejátszási listák",
|
||||
"trending": "Felkapott",
|
||||
"account": "Fiók"
|
||||
"account": "Fiók",
|
||||
"player": "Lejátszó",
|
||||
"instance": "Szerver",
|
||||
"livestreams": "Élő adások",
|
||||
"channels": "Csatornák"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "Feliratkozás - {count}",
|
||||
|
@ -51,7 +55,7 @@
|
|||
"instance_selection": "Példány kiválasztása",
|
||||
"skip_filler_tangent": "Témától eltérő töltelék/viccek",
|
||||
"loop_this_video": "Videó ismétlése",
|
||||
"donations": "Támogatások",
|
||||
"donations": "Fejlesztési támogatások",
|
||||
"minimize_description": "Leírás minimalizálása",
|
||||
"show_recommendations": "Javaslatok megjelenítése",
|
||||
"enable_lbry_proxy": "Proxy engedélyezése a LBRY számára",
|
||||
|
@ -85,7 +89,35 @@
|
|||
"different_auth_instance": "Másik példány használata a hitelesítéshez",
|
||||
"instance_auth_selection": "Autentikációs példány kiválasztása",
|
||||
"clone_playlist": "Lejátszási lista klónozása",
|
||||
"clone_playlist_success": "Sikeresen klónozva!"
|
||||
"clone_playlist_success": "Sikeresen klónozva!",
|
||||
"reset_preferences": "Alaphelyzetbe állítás",
|
||||
"restore_preferences": "Beállítások betöltése fájlból",
|
||||
"rename_playlist": "Átnevez",
|
||||
"instance_donations": "Szerver adományozások",
|
||||
"piped_link": "Piped link",
|
||||
"time_code": "Idő kód (másodpercekben)",
|
||||
"show_chapters": "Fejezetek",
|
||||
"download_as_txt": "Letöltés szövegdokumentumként",
|
||||
"source_code": "A szoftver kódja",
|
||||
"reply_count": "{count} hozzászólások",
|
||||
"documentation": "Dokumentáció",
|
||||
"minimize_chapters_default": "Mindig tüntesd el a fejezeteket",
|
||||
"hide_watched": "Ne mutassa a látott videókat a felíratkozásoknál",
|
||||
"show_watch_on_youtube": "Mutasd a \"Lejátszás Youtube-on\" gombot",
|
||||
"confirm_reset_preferences": "Biztos alaphelyzetbe állítod?",
|
||||
"backup_preferences": "Beállítások mentése",
|
||||
"new_playlist_name": "Új lejátszási lista név",
|
||||
"share": "Megosztás",
|
||||
"with_timecode": "Megosztás & videó kezdés ettől a ponttól",
|
||||
"store_search_history": "Mentse a keresési előzményeket",
|
||||
"follow_link": "Követések link",
|
||||
"copy_link": "Link másolása",
|
||||
"status_page": "Státusz",
|
||||
"no_valid_playlists": "Nincs a fájlban egy valós lejátszási lista se!",
|
||||
"with_playlist": "Megosztás lejátszási listával",
|
||||
"minimize_comments_default": "Mindig tüntesd el a kommenteket",
|
||||
"minimize_comments": "Kommentek eltüntetése",
|
||||
"back_to_home": "Vissza a főoldalra"
|
||||
},
|
||||
"video": {
|
||||
"ratings_disabled": "Értékelések Letiltva",
|
||||
|
@ -129,5 +161,15 @@
|
|||
"disabled": "A hozzászólásokat a feltöltő letiltotta.",
|
||||
"user_disabled": "A beállításoknál a megjegyzések le vannak tiltva.",
|
||||
"loading": "Kommentek betöltése..."
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Feliratkozva: {0} csatornára"
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Figyelem: A beállításaid a böngésződ tárhelyére vannak mentve. Ha törlöd őket el fognak tűnni a beállításaid.",
|
||||
"copied": "Másolva!",
|
||||
"local_storage": "Ennek a beállításnak szüksége van a \"lokális tárhely\" funkcióra, be vannak a sütik kapcsolva?",
|
||||
"cannot_copy": "Nem lehet másolni!",
|
||||
"page_not_found": "Oldnal nem található"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"account": "Akun",
|
||||
"player": "Pemain",
|
||||
"livestreams": "Siaran Langsung",
|
||||
"channels": "Saluran"
|
||||
"channels": "Saluran",
|
||||
"bookmarks": "Markah"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Tonton di {0}"
|
||||
|
@ -49,7 +50,7 @@
|
|||
"instances_list": "Daftar Instansi",
|
||||
"enabled_codecs": "Kodek yang Diaktifkan (Beberapa)",
|
||||
"instance_selection": "Pemilihan Instansi",
|
||||
"show_more": "Tampilkan Lebih Banyak",
|
||||
"show_more": "Tampilkan lebih banyak",
|
||||
"yes": "Iya",
|
||||
"no": "Tidak",
|
||||
"import_from_json": "Impor dari JSON/CSV",
|
||||
|
@ -63,7 +64,7 @@
|
|||
"disable_lbry": "Nonaktifkan LBRY untuk Streaming",
|
||||
"enable_lbry_proxy": "Aktifkan Proksi untuk LBRY",
|
||||
"view_ssl_score": "Tampilkan Skor SSL",
|
||||
"search": "Telusuri",
|
||||
"search": "Telusuri (Ctrl+K)",
|
||||
"filter": "Saring",
|
||||
"loading": "Memuat...",
|
||||
"clear_history": "Hapus Riwayat",
|
||||
|
@ -111,12 +112,25 @@
|
|||
"store_search_history": "Simpan riwayat pencarian",
|
||||
"documentation": "Dokumentasi",
|
||||
"instance_donations": "Donasi instansi",
|
||||
"hide_watched": "Sembunyikan video yang telah ditonton di umpan",
|
||||
"hide_watched": "Sembunyikan video yang sudah ditonton dari umpan",
|
||||
"status_page": "Status",
|
||||
"source_code": "Kode sumber",
|
||||
"reply_count": "{count} balasan",
|
||||
"minimize_comments_default": "Kecilkan Komentar secara bawaan",
|
||||
"minimize_comments": "Kecilkan Komentar"
|
||||
"minimize_comments": "Kecilkan Komentar",
|
||||
"show_watch_on_youtube": "Tampilkan tombol Tonton di YouTube",
|
||||
"minimize_chapters_default": "Kecilkan Bab secara bawaan",
|
||||
"no_valid_playlists": "Berkas ini tidak berisi daftar putar yang valid!",
|
||||
"with_playlist": "Bagikan dengan daftar putar",
|
||||
"playlist_bookmarked": "Dimarkahi",
|
||||
"bookmark_playlist": "Markahi",
|
||||
"skip_button_only": "Tampilkan tombol lewati",
|
||||
"skip_automatically": "Secara otomatis",
|
||||
"min_segment_length": "Panjang Segmen Minimum (dalam detik)",
|
||||
"skip_segment": "Lewati Segmen",
|
||||
"show_less": "Tampilkan lebih sedikit",
|
||||
"autoplay_next_countdown": "Hitungan mundur bawaan sebelum video berikutnya (dalam detik)",
|
||||
"dismiss": "Abaikan"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Dipasangi pin oleh {author}",
|
||||
|
@ -128,7 +142,7 @@
|
|||
"instance_name": "Nama Instansi",
|
||||
"ssl_score": "Skor SSL",
|
||||
"instance_locations": "Lokasi Instansi",
|
||||
"has_cdn": "Mempunyai CDN?",
|
||||
"has_cdn": "Memakai CDN?",
|
||||
"up_to_date": "Sudah terkini?",
|
||||
"version": "Versi",
|
||||
"registered_users": "Pengguna Terdaftar"
|
||||
|
@ -145,7 +159,9 @@
|
|||
"ratings_disabled": "Penilaian Dinonaktifkan",
|
||||
"chapters": "Bagian",
|
||||
"live": "{0} Langsung",
|
||||
"shorts": "Shorts"
|
||||
"shorts": "Shorts",
|
||||
"all": "Semua",
|
||||
"category": "Kategori"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Apakah Anda bermaksud: {0}?",
|
||||
|
@ -168,6 +184,9 @@
|
|||
"page_not_found": "Laman tidak ditemukan",
|
||||
"preferences_note": "Catatan: preferensi disimpan dalam penyimpanan lokal peramban Anda. Menghapus data peramban Anda akan mengatur ulang.",
|
||||
"copied": "Disalin!",
|
||||
"cannot_copy": "Tidak dapat menyalin!"
|
||||
"cannot_copy": "Tidak dapat menyalin!",
|
||||
"local_storage": "Tindakan ini membutuhkan localStorage, apakah kuki diaktifkan?",
|
||||
"register_no_email_note": "Menggunakan surel sebagai nama pengguna tidak disarankan. Lanjut?",
|
||||
"next_video_countdown": "Memutar video berikutnya dalam {0} detik"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
"playlists": "Spilunarlistar",
|
||||
"player": "Spilari",
|
||||
"account": "Reikningur",
|
||||
"instance": "Tilvik"
|
||||
"instance": "Tilvik",
|
||||
"livestreams": "Útsendingar í beinni",
|
||||
"channels": "Rásir"
|
||||
},
|
||||
"actions": {
|
||||
"sort_by": "Raða eftir:",
|
||||
|
@ -111,7 +113,9 @@
|
|||
"show_chapters": "Kaflar",
|
||||
"reply_count": "{count} svör",
|
||||
"minimize_comments_default": "Fela ummæli sjálfgefið",
|
||||
"minimize_comments": "Fela ummæli"
|
||||
"minimize_comments": "Fela ummæli",
|
||||
"show_watch_on_youtube": "Sýna hnapp til að horfa á YouTube",
|
||||
"minimize_chapters_default": "Lágmarka kafla sjálfgefið"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Horfa á {0}"
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
"instance_selection": "Selezione dell'istanza",
|
||||
"loading": "Caricamento…",
|
||||
"filter": "Filtra",
|
||||
"search": "Cerca",
|
||||
"search": "Cerca (Ctrl+K)",
|
||||
"view_ssl_score": "Visualizza il punteggio SSL",
|
||||
"clear_history": "Cancella la cronologia",
|
||||
"load_more_replies": "Carica più risposte",
|
||||
|
@ -94,7 +94,23 @@
|
|||
"status_page": "Stato",
|
||||
"documentation": "Documentazione",
|
||||
"source_code": "Codice sorgente",
|
||||
"reply_count": "{count} risposte"
|
||||
"reply_count": "{count} risposte",
|
||||
"hide_watched": "Nascondi i video guardati nel feed",
|
||||
"show_watch_on_youtube": "Mostra il bottone guarda su Youtube",
|
||||
"instance_donations": "Donazioni istanza",
|
||||
"minimize_comments_default": "Minimizza i commenti per impostazione predefinita",
|
||||
"minimize_comments": "Minimizza i commenti",
|
||||
"minimize_chapters_default": "Minimizza i capitoli per impostazione predefinita",
|
||||
"no_valid_playlists": "Il file non contiene playlist valide!",
|
||||
"bookmark_playlist": "Segnalibro",
|
||||
"with_playlist": "Condividi con la playlist",
|
||||
"playlist_bookmarked": "Nei segnalibri",
|
||||
"min_segment_length": "Lunghezza minima del segmento (in secondi)",
|
||||
"skip_automatically": "Automaticamente",
|
||||
"skip_button_only": "Mostra pulsante di salto",
|
||||
"skip_segment": "Salta segmento",
|
||||
"show_less": "Mostra meno",
|
||||
"autoplay_next_countdown": "Conto alla rovescia predefinito prima del video successivo (in secondi)"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Guarda su {0}"
|
||||
|
@ -112,7 +128,8 @@
|
|||
"instance": "Istanza",
|
||||
"player": "Riproduttore",
|
||||
"livestreams": "Streaming live",
|
||||
"channels": "Canali"
|
||||
"channels": "Canali",
|
||||
"bookmarks": "Segnalibri"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "Segmenti sponsor",
|
||||
|
@ -122,7 +139,9 @@
|
|||
"ratings_disabled": "Valutazioni disabilitate",
|
||||
"live": "{0} Diretta",
|
||||
"chapters": "Capitoli",
|
||||
"shorts": "Short"
|
||||
"shorts": "Short",
|
||||
"all": "Tutti",
|
||||
"category": "Categoria"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "Valutazione SSL",
|
||||
|
@ -164,6 +183,9 @@
|
|||
"page_not_found": "Pagina non trovata",
|
||||
"preferences_note": "Nota: le preferenze sono salvate nella memoria locale del tuo browser. L'eliminazione dei dati del tuo browser le ripristinerà.",
|
||||
"copied": "Copiato!",
|
||||
"cannot_copy": "Impossibile copiare!"
|
||||
"cannot_copy": "Impossibile copiare!",
|
||||
"local_storage": "Questa azione richiede localStorage, i cookie sono abilitati?",
|
||||
"register_no_email_note": "L'utilizzo di un indirizzo e-mail come nome utente è sconsigliato. Continuare comunque?",
|
||||
"next_video_countdown": "Riproduzione prossimo video tra {0}s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
{
|
||||
"titles": {
|
||||
"trending": "トレンド",
|
||||
"trending": "急上昇",
|
||||
"login": "ログイン",
|
||||
"register": "新規登録",
|
||||
"feed": "フィード",
|
||||
"preferences": "設定",
|
||||
"history": "履歴",
|
||||
"subscriptions": "サブスクリプション",
|
||||
"playlists": "再生リスト"
|
||||
"subscriptions": "登録チャンネル",
|
||||
"playlists": "再生リスト",
|
||||
"account": "アカウント",
|
||||
"player": "プレイヤー",
|
||||
"instance": "インスタンス",
|
||||
"channels": "チャンネル",
|
||||
"livestreams": "ライブ配信",
|
||||
"bookmarks": "ブックマーク"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0}で見る"
|
||||
|
@ -15,35 +21,35 @@
|
|||
"actions": {
|
||||
"subscribe": "チャンネル登録 - {count}",
|
||||
"unsubscribe": "登録解除 - {count}",
|
||||
"view_subscriptions": "サブスクリプションを見る",
|
||||
"view_subscriptions": "登録チャンネルを見る",
|
||||
"sort_by": "表示順:",
|
||||
"most_recent": "新しい順",
|
||||
"least_recent": "古い順",
|
||||
"channel_name_asc": "チャンネル名順",
|
||||
"channel_name_desc": "チャンネル名逆順",
|
||||
"channel_name_asc": "チャンネル名 (AからZ)",
|
||||
"channel_name_desc": "チャンネル名 (ZからA)",
|
||||
"back": "戻る",
|
||||
"uses_api_from": "API使用元 ",
|
||||
"enable_sponsorblock": "広告ブロックをオン",
|
||||
"enable_sponsorblock": "SponsorBlock を有効化",
|
||||
"skip_sponsors": "広告をスキップ",
|
||||
"skip_intro": "イントロ部分をスキップする",
|
||||
"skip_outro": "クレジット部分をスキップする",
|
||||
"skip_preview": "Skip プレビュー・要約をスキップ",
|
||||
"skip_interaction": "自己宣伝シーンをスキップ",
|
||||
"skip_self_promo": "プロモーションをスキップ",
|
||||
"skip_non_music": "音楽以外のセクションをスキップ",
|
||||
"skip_intro": "休止時間/導入アニメをスキップ",
|
||||
"skip_outro": "終了シーン/クレジットをスキップ",
|
||||
"skip_preview": "プレビュー/要約をスキップ",
|
||||
"skip_interaction": "チャンネル登録など操作を求める自己宣伝をスキップ",
|
||||
"skip_self_promo": "無報酬/自己の宣伝をスキップ",
|
||||
"skip_non_music": "音楽: 非音楽部分をスキップ",
|
||||
"theme": "テーマ",
|
||||
"auto": "自動",
|
||||
"dark": "ダークテーマ",
|
||||
"light": "ライトテーマ",
|
||||
"autoplay_video": "自動再生",
|
||||
"dark": "ダーク",
|
||||
"light": "ライト",
|
||||
"autoplay_video": "動画を自動再生",
|
||||
"audio_only": "音声のみ",
|
||||
"default_quality": "デフォルトの画質",
|
||||
"buffering_goal": "バッファリング目標値(秒単位)",
|
||||
"default_quality": "標準の画質",
|
||||
"buffering_goal": "バッファリング目標値 (秒)",
|
||||
"country_selection": "国の選択",
|
||||
"default_homepage": "デフォルトのホームページ",
|
||||
"default_homepage": "ホームに表示するページ",
|
||||
"show_comments": "コメントを表示",
|
||||
"minimize_description_default": "デフォルトで詳細を最小化",
|
||||
"store_watch_history": "視聴履歴を記録する",
|
||||
"minimize_description_default": "最初から説明を最小化",
|
||||
"store_watch_history": "再生履歴を保存する",
|
||||
"language_selection": "言語の選択",
|
||||
"instances_list": "インスタンス一覧",
|
||||
"enabled_codecs": "コーデックの有効化 (複数選択)",
|
||||
|
@ -51,70 +57,130 @@
|
|||
"show_more": "もっと見る",
|
||||
"yes": "はい",
|
||||
"no": "いいえ",
|
||||
"export_to_json": "JSONファイルに出力",
|
||||
"import_from_json": "JSON/CSVファイルを読み込む",
|
||||
"loop_this_video": "ループ再生",
|
||||
"auto_play_next_video": "自動再生",
|
||||
"donations": "寄付",
|
||||
"minimize_description": "最小化",
|
||||
"show_description": "詳細",
|
||||
"export_to_json": "JSONに出力",
|
||||
"import_from_json": "JSON/CSVを読み込む",
|
||||
"loop_this_video": "この動画をループ再生",
|
||||
"auto_play_next_video": "次の動画を自動再生",
|
||||
"donations": "開発者に寄付",
|
||||
"minimize_description": "説明を最小化",
|
||||
"show_description": "説明を表示",
|
||||
"minimize_recommendations": "おすすめを最小化",
|
||||
"show_recommendations": "おすすめを見る",
|
||||
"disable_lbry": "ストリーミングのLBRYを無効化",
|
||||
"enable_lbry_proxy": "LBRYプロキシをオン",
|
||||
"view_ssl_score": "SSLスコアを見る",
|
||||
"search": "検索",
|
||||
"view_ssl_score": "SSLの評価を表示",
|
||||
"search": "検索 (Ctrl+K)",
|
||||
"filter": "フィルター",
|
||||
"loading": "読込中…",
|
||||
"clear_history": "履歴を消去",
|
||||
"loading": "読み込み中…",
|
||||
"clear_history": "再生履歴を削除",
|
||||
"hide_replies": "返信を非表示",
|
||||
"load_more_replies": "もっと見る",
|
||||
"skip_filler_tangent": "無関係なコンテンツをスキップ",
|
||||
"skip_highlight": "要点をスキップ",
|
||||
"load_more_replies": "返信をもっと見る",
|
||||
"skip_filler_tangent": "無関係な談話をスキップ",
|
||||
"skip_highlight": "ハイライトをスキップ",
|
||||
"add_to_playlist": "再生リストに追加",
|
||||
"create_playlist": "新しい再生リストを作成",
|
||||
"create_playlist": "再生リストを作成",
|
||||
"remove_from_playlist": "再生リストから削除",
|
||||
"delete_playlist_video_confirm": "再生リストからこの動画を削除してもよろしいですか?",
|
||||
"delete_playlist_video_confirm": "再生リストからこの動画を削除しますか?",
|
||||
"delete_playlist": "再生リストを削除",
|
||||
"please_select_playlist": "再生リストを選択してください",
|
||||
"show_markers": "プレーヤーにマーカーを表示",
|
||||
"show_markers": "プレイヤーに目印の区切りを表示",
|
||||
"select_playlist": "再生リストを選択",
|
||||
"delete_playlist_confirm": "再生リストを削除してもよろしいですか?"
|
||||
"delete_playlist_confirm": "再生リストを削除しますか?",
|
||||
"delete_account": "アカウントを削除する",
|
||||
"store_search_history": "検索履歴を保存する",
|
||||
"show_chapters": "チャプター",
|
||||
"status_page": "状態",
|
||||
"source_code": "ソースコード",
|
||||
"instance_donations": "インスタンスに寄付",
|
||||
"minimize_comments": "コメントを最小化",
|
||||
"share": "共有",
|
||||
"with_timecode": "タイムコード付きで共有",
|
||||
"different_auth_instance": "認証に別のインスタンスを使う",
|
||||
"download_as_txt": ".txtでダウンロード",
|
||||
"logout": "このデバイスでログアウト",
|
||||
"minimize_recommendations_default": "最初からおすすめを最小化",
|
||||
"hide_watched": "再生済みの動画をフィードに表示しない",
|
||||
"minimize_chapters_default": "最初からチャプターを最小化",
|
||||
"show_watch_on_youtube": "「YouTubeで見る」ボタンを表示する",
|
||||
"invalidate_session": "すべてのデバイスでログアウトする",
|
||||
"instance_auth_selection": "認証インスタンスの選択",
|
||||
"clone_playlist_success": "複製に成功しました!",
|
||||
"backup_preferences": "設定をバックアップ",
|
||||
"restore_preferences": "設定を復元",
|
||||
"back_to_home": "ホームに戻る",
|
||||
"copy_link": "リンクをコピー",
|
||||
"time_code": "タイムコード (秒)",
|
||||
"documentation": "ドキュメント",
|
||||
"reset_preferences": "設定を初期化",
|
||||
"confirm_reset_preferences": "設定をリセットしますか?",
|
||||
"rename_playlist": "再生リスト名を変更する",
|
||||
"piped_link": "Pipedリンク",
|
||||
"new_playlist_name": "新しい再生リスト名",
|
||||
"follow_link": "リンクに従う",
|
||||
"reply_count": "{count} 件の返信",
|
||||
"clone_playlist": "再生リストを複製",
|
||||
"minimize_comments_default": "最初からコメントを最小化",
|
||||
"no_valid_playlists": "このファイルは有効な再生リストではありません!",
|
||||
"playlist_bookmarked": "ブックマーク完了",
|
||||
"bookmark_playlist": "ブックマーク",
|
||||
"with_playlist": "再生リストで共有",
|
||||
"skip_automatically": "自動",
|
||||
"skip_button_only": "スキップボタン表示",
|
||||
"skip_segment": "ここをスキップ",
|
||||
"min_segment_length": "最小の区切りの長さ (秒)",
|
||||
"show_less": "少なく見る"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "固定されたコメント {author}"
|
||||
"pinned_by": "{author} によって固定",
|
||||
"loading": "コメントを読み込み中...",
|
||||
"user_disabled": "コメントは設定で無効になっています。",
|
||||
"disabled": "コメントは投稿者によって無効化されています。"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "インスタンス名",
|
||||
"instance_locations": "インスタンスの場所",
|
||||
"has_cdn": "CDNの有無",
|
||||
"ssl_score": "SSLスコア",
|
||||
"registered_users": "登録済みユーザー",
|
||||
"ssl_score": "SSLの評価",
|
||||
"registered_users": "登録ユーザー数",
|
||||
"version": "バージョン",
|
||||
"up_to_date": "最新か否か"
|
||||
"up_to_date": "最新?"
|
||||
},
|
||||
"login": {
|
||||
"username": "ユーザー名",
|
||||
"password": "パスワード"
|
||||
},
|
||||
"video": {
|
||||
"videos": "ビデオ",
|
||||
"views": "{views} 視聴",
|
||||
"watched": "視聴済み",
|
||||
"videos": "動画",
|
||||
"views": "{views} 回再生",
|
||||
"watched": "再生済み",
|
||||
"sponsor_segments": "スポンサーによる広告",
|
||||
"ratings_disabled": "評価は無効化されています",
|
||||
"chapters": "チャプター",
|
||||
"live": "{0}ライブ"
|
||||
"live": "{0} ライブ配信",
|
||||
"shorts": "ショート",
|
||||
"all": "すべて",
|
||||
"category": "分類"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "もしかして: {0}?",
|
||||
"all": "Youtube: 全て",
|
||||
"videos": "Youtube: ビデオ",
|
||||
"channels": "Youtube: チャンネル",
|
||||
"playlists": "Youtube: 再生リスト",
|
||||
"did_you_mean": "もしかして: {0}?",
|
||||
"all": "YouTube: すべて",
|
||||
"videos": "YouTube: 動画",
|
||||
"channels": "YouTube: チャンネル",
|
||||
"playlists": "YouTube: 再生リスト",
|
||||
"music_songs": "YT Music: 音楽",
|
||||
"music_videos": "YT Music: ビデオ",
|
||||
"music_videos": "YT Music: 動画",
|
||||
"music_albums": "YT Music: アルバム",
|
||||
"music_playlists": "YT Music: 再生リスト"
|
||||
},
|
||||
"info": {
|
||||
"page_not_found": "ページが見つかりません",
|
||||
"copied": "コピーしました!",
|
||||
"cannot_copy": "コピーできません!",
|
||||
"preferences_note": "注意: 設定は、お使いのブラウザの保存領域に保存されます。ブラウザのデータを削除すると初期化されます。",
|
||||
"local_storage": "この操作にはlocalStorageが必要です。Cookieは有効ですか?",
|
||||
"register_no_email_note": "Eメールアドレスをユーザー名として使用することは推奨されていません。それでも続行しますか?"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "チャンネル登録: {0}"
|
||||
}
|
||||
}
|
||||
|
|
175
src/locales/kab.json
Normal file
175
src/locales/kab.json
Normal file
|
@ -0,0 +1,175 @@
|
|||
{
|
||||
"titles": {
|
||||
"login": "Aseqdac",
|
||||
"register": "Jerred",
|
||||
"preferences": "Ismenyifen",
|
||||
"history": "Amazray",
|
||||
"subscriptions": "Ijerriden",
|
||||
"account": "Amiḍan",
|
||||
"channels": "Ibuda",
|
||||
"playlists": "Tabdert n tɣuri",
|
||||
"instance": "Tummant",
|
||||
"player": "Ameɣri",
|
||||
"livestreams": "Azuzer usrid",
|
||||
"bookmarks": "Ticraḍ",
|
||||
"feed": "Amultaɣ",
|
||||
"trending": "Tiddin"
|
||||
},
|
||||
"actions": {
|
||||
"dark": "Ubrik",
|
||||
"language_selection": "Afran n tutlayt",
|
||||
"yes": "Ih",
|
||||
"no": "Uhu",
|
||||
"search": "Nadi",
|
||||
"filter": "Imsizdeg",
|
||||
"loading": "Asali...",
|
||||
"delete_playlist_confirm": "Kkes tabdart-a n tɣuri?",
|
||||
"share": "Bḍu",
|
||||
"documentation": "Tasemlit",
|
||||
"status_page": "État",
|
||||
"least_recent": "N melmi kna",
|
||||
"channel_name_desc": "Isem n ubadu (A-Z)",
|
||||
"channel_name_asc": "Isem n ubadu (A-z)",
|
||||
"back": "Tuɣalin",
|
||||
"uses_api_from": "Isseqdac API n: ",
|
||||
"enable_sponsorblock": "Rmed amsewḥal n udellel",
|
||||
"skip_sponsors": "Zgel adellel",
|
||||
"add_to_playlist": "Rnu ɣer tebdart n tɣuri",
|
||||
"hide_replies": "Ffer tiririyin",
|
||||
"load_more_replies": "Sali-d ugar n tririyin",
|
||||
"remove_from_playlist": "Kkes seg tebdart n tɣuri",
|
||||
"delete_playlist_video_confirm": "Kkes tavidyut seg tebdart n tɣuri?",
|
||||
"create_playlist": "Rnu tabdart n tɣuri",
|
||||
"subscribe": "Qqen - {count}",
|
||||
"unsubscribe": "Sefsex tuqqna n - {count}",
|
||||
"view_subscriptions": "Wali imuktaɣen",
|
||||
"sort_by": "Semyizwer s:",
|
||||
"most_recent": "Amaynut akk",
|
||||
"theme": "Asentel",
|
||||
"auto": "Awurman",
|
||||
"delete_playlist": "Kkes tabdart n tɣuri",
|
||||
"select_playlist": "Fren tabdart n tɣuri",
|
||||
"please_select_playlist": "Ttxil-k·m fren tabdart n tɣuri",
|
||||
"delete_account": "Kkes amiḍan",
|
||||
"logout": "Ffeɣ seg yibenk-a",
|
||||
"light": "D ameceɛlal",
|
||||
"autoplay_video": "Taɣuri tawurmant n tvidyut",
|
||||
"audio_only": "Ameslaw kan",
|
||||
"default_quality": "Taɣara tuzwirt",
|
||||
"auto_play_next_video": "Taɣuri tawurmant n tvidyut tuḍfirt",
|
||||
"donations": "Tawsa i usnefli",
|
||||
"disable_lbry": "Sens LBRY i usuddem",
|
||||
"enable_lbry_proxy": "Rmed apṛuksi i LBRY",
|
||||
"view_ssl_score": "Sken agmuḍ SSL",
|
||||
"show_recommendations": "Sken iwellihen",
|
||||
"clear_history": "Sfeḍ azray",
|
||||
"copy_link": "Nɣel aseɣwen",
|
||||
"time_code": "Tangalt n wakud (s tsinin)",
|
||||
"show_more": "Sken ugar",
|
||||
"export_to_json": "Sifeḍ ɣer JSON",
|
||||
"minimize_comments": "Semẓi iwenniten",
|
||||
"show_comments": "Sken iwenniten",
|
||||
"minimize_description": "Semẓi aglam",
|
||||
"show_description": "Sken aglam",
|
||||
"minimize_recommendations": "Semẓi iwellihen",
|
||||
"reply_count": "{count} tririyin",
|
||||
"bookmark_playlist": "Tacreḍt",
|
||||
"playlist_bookmarked": "Yettwacreḍ",
|
||||
"instances_list": "Tabdart n tummanin",
|
||||
"country_selection": "Afran n tmurt",
|
||||
"default_homepage": "Asebter agejdan amezwer",
|
||||
"instance_selection": "Afran n tummant",
|
||||
"import_from_json": "Kter seg JSON/CSV",
|
||||
"store_search_history": "Ḥrez azray n unadi",
|
||||
"instance_donations": "Tawsa n tummant",
|
||||
"source_code": "Tangalt taɣbalut",
|
||||
"minimize_description_default": "Semẓi aglam s wudem amezwer",
|
||||
"skip_highlight": "Zgel asebruraq",
|
||||
"minimize_comments_default": "Semẓi iwenniten s wudem amezwer",
|
||||
"store_watch_history": "Ḥrez azray n tmeẓriwt",
|
||||
"loop_this_video": "Err tavidyut-a d taẓayert",
|
||||
"minimize_recommendations_default": "Semẓi iwellihen s wudem amezwer",
|
||||
"no_valid_playlists": "Afaylu ulac deg-s tibdarin n tɣuri timeɣta!",
|
||||
"with_playlist": "Bḍu s tebdart n tɣuri",
|
||||
"skip_preview": "Zgel Taskant/Agzul",
|
||||
"skip_outro": "Zgel ismawen n taggara",
|
||||
"minimize_chapters_default": "Semẓi ixfawen s wudem uzwir",
|
||||
"confirm_reset_preferences": "D tidet tebɣiḍ ad twennzeḍ ismenyifen-ik•im?",
|
||||
"backup_preferences": "Ḥrez ismenyifen",
|
||||
"restore_preferences": "Err-d ismenyifen",
|
||||
"back_to_home": "Uɣal ɣer ugejdan",
|
||||
"rename_playlist": "Beddel isem i tebdart n tɣuri",
|
||||
"follow_link": "Ḍfer aseɣwen",
|
||||
"show_chapters": "Ixfawen",
|
||||
"show_watch_on_youtube": "Sken taqeffalt Wali ɣef YouTube",
|
||||
"reset_preferences": "Wennez ismenyifen",
|
||||
"new_playlist_name": "Isem amaynut n tebdart n tɣuri",
|
||||
"with_timecode": "Bḍu s tengalt n wakud",
|
||||
"hide_watched": "Ffer tividyutin yemmeẓren deg usuddel",
|
||||
"skip_interaction": "Zgel ismektiyen n umyigew (Multeɣ)",
|
||||
"enabled_codecs": "Isettengal ttwaremden (aṭas)",
|
||||
"buffering_goal": "Iswi n uḥraz akudan (s tsinin)",
|
||||
"skip_non_music": "Zgel aẓawan: tafrant ur nelli d aẓawan",
|
||||
"show_markers": "Sken ticraḍ ɣef umeɣri",
|
||||
"instance_auth_selection": "Tafrant n tummant n usesteb",
|
||||
"invalidate_session": "Ffeɣ seg meṛṛa ibenkan",
|
||||
"different_auth_instance": "Seqdec tummant tayeḍ i usesteb",
|
||||
"download_as_txt": "Sader am.txt",
|
||||
"piped_link": "Aseɣwen n Piped",
|
||||
"clone_playlist": "Tabdart n tɣuri yemtawan"
|
||||
},
|
||||
"preferences": {
|
||||
"version": "Lqem",
|
||||
"has_cdn": "Ɣur-s CDN?",
|
||||
"registered_users": "Iseqdacen yettwajerrden",
|
||||
"up_to_date": "D amaynut?",
|
||||
"ssl_score": "Agmuḍ SSL",
|
||||
"instance_name": "Isem n tummant",
|
||||
"instance_locations": "Idgan n tummant"
|
||||
},
|
||||
"login": {
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Awal n uɛeddi"
|
||||
},
|
||||
"video": {
|
||||
"videos": "Tividyutin",
|
||||
"views": "{views} tmeẓriwin",
|
||||
"watched": "Yemẓer",
|
||||
"shorts": "Tiwezlanin",
|
||||
"live": "{0} srid",
|
||||
"sponsor_segments": "Inegzumen n udellel",
|
||||
"chapters": "Ixfawen",
|
||||
"ratings_disabled": "Iktazalen ttwasensen"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Wali deg {0}"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Isenteḍ-itt {author}",
|
||||
"loading": "Asali n yiwenniten...",
|
||||
"disabled": "Ameskar issens iwenniten.",
|
||||
"user_disabled": "Nsan yiwenniten deg Yiɣewwaren."
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Tebɣiḍ ad d-tiniḍ: {0}?",
|
||||
"music_playlists": "YT Music: Tibdarin n tɣuri",
|
||||
"all": "YouTube: Akk",
|
||||
"videos": "YouTube: Tividyutin",
|
||||
"channels": "YouTube: Ibuda",
|
||||
"music_videos": "YT Music: Tividyutin",
|
||||
"playlists": "YouTube: Tibdarin n tɣuri",
|
||||
"music_songs": "YT Music: Tizlatin",
|
||||
"music_albums": "YT Music: Albumen"
|
||||
},
|
||||
"info": {
|
||||
"copied": "Yettwanɣel!",
|
||||
"page_not_found": "Ur yettwaf ara usebter",
|
||||
"cannot_copy": "D awezɣi ad d-yettwanɣel!",
|
||||
"register_no_email_note": "Aseqdec n yimayl am yisem n useqdac, ur yettusireg ara. Kemmel ɣas akken?",
|
||||
"local_storage": "Tigawt-a aḥraz adigan, inagan n tuqqna remden?",
|
||||
"preferences_note": "Tamawt: ismenyifen ttwaskelsen deg uklas adigan n yiminig-ik·im. Tukksa n yisefka yiminig-ik·im ad ten-iwennez."
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Imulteɣ ɣer: {0}"
|
||||
}
|
||||
}
|
|
@ -73,12 +73,12 @@
|
|||
"remove_from_playlist": "Pašalinti iš grojaraščio",
|
||||
"confirm_reset_preferences": "Ar tikrai norite iš naujo nustatyti nuostatas?",
|
||||
"reset_preferences": "Iš naujo nustatyti nuostatas",
|
||||
"backup_preferences": "Atsarginės kopijos nuostatos",
|
||||
"backup_preferences": "Atsarginė nuostatų kopija",
|
||||
"source_code": "Pirminis kodas",
|
||||
"documentation": "Dokumentacija",
|
||||
"with_timecode": "Dalintis su laiko kodu",
|
||||
"reply_count": "{count} atsakymų",
|
||||
"show_chapters": "Skyriai",
|
||||
"reply_count": "{count} atsakymai",
|
||||
"show_chapters": "Skirsniai",
|
||||
"piped_link": "Piped nuoroda",
|
||||
"rename_playlist": "Pervardyti grojaraštį",
|
||||
"follow_link": "Sekti nuorodą",
|
||||
|
@ -99,7 +99,9 @@
|
|||
"time_code": "Laiko kodas (sekundėmis)",
|
||||
"minimize_comments_default": "Suskleisti komentarus automatiškai",
|
||||
"minimize_comments": "Suskleisti komentarus",
|
||||
"show_watch_on_youtube": "Rodyti mygtuką „Žiūrėti YouTube“"
|
||||
"show_watch_on_youtube": "Rodyti mygtuką „Žiūrėti YouTube“",
|
||||
"minimize_chapters_default": "Suskleisti skirsnius automatiškai",
|
||||
"no_valid_playlists": "Faile nėra galiojančių grojaraščių!"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Žiūrėti per {0}"
|
||||
|
@ -131,7 +133,7 @@
|
|||
"comment": {
|
||||
"pinned_by": "Prisegė {author}",
|
||||
"loading": "Įkeliami komentarai...",
|
||||
"disabled": "Komentarai yra išjungti įkėlėjo.",
|
||||
"disabled": "Įkėlėjas išjungė komentarus.",
|
||||
"user_disabled": "Komentarai yra išjungti nustatymuose."
|
||||
},
|
||||
"video": {
|
||||
|
@ -140,7 +142,7 @@
|
|||
"sponsor_segments": "Rėmėjų segmentai",
|
||||
"watched": "Žiūrėta",
|
||||
"ratings_disabled": "Įvertinimai išjungti",
|
||||
"chapters": "Skyriai",
|
||||
"chapters": "Skirsniai",
|
||||
"live": "{0} tiesiogiai",
|
||||
"shorts": "Trumpi filmukai"
|
||||
},
|
||||
|
@ -163,7 +165,8 @@
|
|||
"copied": "Nukopijuota!",
|
||||
"cannot_copy": "Negalima kopijuoti!",
|
||||
"page_not_found": "Puslapis nerastas",
|
||||
"preferences_note": "Pastaba: nuostatos išsaugomos vietinėje naršyklės atmintyje. Ištrynus naršyklės duomenis, jie bus nustatyti iš naujo."
|
||||
"preferences_note": "Pastaba: nuostatos išsaugomos vietinėje naršyklės atmintyje. Ištrynus naršyklės duomenis, jos bus nustatytos iš naujo.",
|
||||
"local_storage": "Šiam veiksmui reikia localStorage, ar slapukai įjungti?"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Prenumeruojama: {0}"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"actions": {
|
||||
"skip_sponsors": "Sponsors Overslaan",
|
||||
"skip_outro": "Eindkaarten/Credits overslaan",
|
||||
"skip_outro": "Eindkaarten/Credits Overslaan",
|
||||
"add_to_playlist": "Aan Afspeellijst Toevoegen",
|
||||
"sort_by": "Sorteer op:",
|
||||
"buffering_goal": "Bufferdoel (in seconden)",
|
||||
|
@ -20,7 +20,7 @@
|
|||
"skip_self_promo": "Onbetaalde/Zelf-promotie Overslaan",
|
||||
"skip_highlight": "Markering Overslaan",
|
||||
"skip_interaction": "Interactieherinnering Overslaan (Abonneren)",
|
||||
"show_more": "Toon Meer",
|
||||
"show_more": "Toon meer",
|
||||
"unsubscribe": "Afmelden - {count}",
|
||||
"view_subscriptions": "Abonnementen Bekijken",
|
||||
"enable_sponsorblock": "Sponsorblok Inschakelen",
|
||||
|
@ -30,7 +30,7 @@
|
|||
"light": "Licht",
|
||||
"default_quality": "Standaard Kwaliteit",
|
||||
"loop_this_video": "Deze Video Herhalen",
|
||||
"donations": "Donaties",
|
||||
"donations": "Ontwikkelingsdonaties",
|
||||
"minimize_description": "Beschrijving Minimaliseren",
|
||||
"show_description": "Toon Beschrijving",
|
||||
"minimize_recommendations": "Aanbevelingen Minimaliseren",
|
||||
|
@ -57,15 +57,59 @@
|
|||
"auto_play_next_video": "Volgende Video Automatisch Afspelen",
|
||||
"remove_from_playlist": "Uit Afspeellijst Verwijderen",
|
||||
"select_playlist": "Selecteer een Afspeellijst",
|
||||
"delete_playlist_confirm": "Weet u zeker dat u deze afspeellijst wilt verwijderen?",
|
||||
"please_select_playlist": "Kies een afspeellijst a.u.b.",
|
||||
"delete_playlist_confirm": "Deze afspeellijst verwijderen?",
|
||||
"please_select_playlist": "Selecteer een afspeellijst alsjeblief",
|
||||
"instance_selection": "Instantie Selectie",
|
||||
"import_from_json": "Importeren uit JSON/CSV",
|
||||
"clear_history": "Geschiedenis Wissen",
|
||||
"load_more_replies": "Laad meer Antwoorden",
|
||||
"delete_playlist_video_confirm": "Weet u zeker dat u deze video uit deze afspeellijst wilt verwijderen?",
|
||||
"delete_playlist_video_confirm": "Video uit deze afspeellijst verwijderen?",
|
||||
"create_playlist": "Afspeellijst Maken",
|
||||
"delete_playlist": "Afspeellijst Verwijderen"
|
||||
"delete_playlist": "Afspeellijst Verwijderen",
|
||||
"show_markers": "Laat markeringen op speler zien",
|
||||
"store_search_history": "Zoekgeschiedenis Opslaan",
|
||||
"minimize_chapters_default": "Hoofdstukken Standaard Minimaliseren",
|
||||
"show_watch_on_youtube": "Toon Bekijk op YouTube knop",
|
||||
"restore_preferences": "Voorkeuren herstellen",
|
||||
"with_timecode": "Delen met tijdcode",
|
||||
"piped_link": "Piped link",
|
||||
"follow_link": "Volg link",
|
||||
"copy_link": "Link kopiëren",
|
||||
"hide_watched": "Verberg bekeken video's in de feed",
|
||||
"minimize_comments": "Opmerkingen minimaliseren",
|
||||
"instance_auth_selection": "Selectie authenticatie-instantie",
|
||||
"clone_playlist": "Afspeellijst dupliceren",
|
||||
"download_as_txt": "Downloaden als .txt",
|
||||
"rename_playlist": "Afspeellijst hernoemen",
|
||||
"new_playlist_name": "Nieuwe afspeellijstnaam",
|
||||
"share": "Delen",
|
||||
"documentation": "Documentatie",
|
||||
"status_page": "Status",
|
||||
"time_code": "Tijdcode (in seconden)",
|
||||
"show_chapters": "Hoofdstukken",
|
||||
"source_code": "Broncode",
|
||||
"instance_donations": "Instantie donaties",
|
||||
"reply_count": "{count} antwoorden",
|
||||
"no_valid_playlists": "Het bestand bevat geen geldige afspeellijsten!",
|
||||
"clone_playlist_success": "Dupliceren gelukt!",
|
||||
"reset_preferences": "Voorkeuren herstellen",
|
||||
"back_to_home": "Terug naar de start",
|
||||
"minimize_comments_default": "Opmerkingen Standaard Minimaliseren",
|
||||
"delete_account": "Account Verwijderen",
|
||||
"logout": "Uitloggen op dit apparaat",
|
||||
"minimize_recommendations_default": "Aanbevelingen Standaard Minimaliseren",
|
||||
"confirm_reset_preferences": "Weet u zeker dat u uw voorkeuren opnieuw wilt instellen?",
|
||||
"backup_preferences": "Back-up voorkeuren",
|
||||
"invalidate_session": "Uitloggen op alle apparaten",
|
||||
"different_auth_instance": "Gebruik een andere instantie voor authenticatie",
|
||||
"with_playlist": "Delen met afspeellijst",
|
||||
"playlist_bookmarked": "Bladwijzer gemaakt",
|
||||
"bookmark_playlist": "Bladwijzer",
|
||||
"skip_automatically": "Automatisch",
|
||||
"skip_button_only": "toon de overslaan knop",
|
||||
"min_segment_length": "Minimale segmentlengte (in seconden)",
|
||||
"skip_segment": "segment overslaan",
|
||||
"show_less": "Toon minder"
|
||||
},
|
||||
"titles": {
|
||||
"register": "Registreren",
|
||||
|
@ -74,8 +118,14 @@
|
|||
"preferences": "Voorkeuren",
|
||||
"history": "Geschiedenis",
|
||||
"subscriptions": "Abonnementen",
|
||||
"trending": "Trending",
|
||||
"playlists": "Afspeellijsten"
|
||||
"trending": "populair",
|
||||
"playlists": "Afspeellijsten",
|
||||
"account": "profiel",
|
||||
"instance": "Instantie",
|
||||
"player": "Speler",
|
||||
"livestreams": "Livestreams",
|
||||
"channels": "Kanalen",
|
||||
"bookmarks": "Bladwijzers"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Kijk op {0}"
|
||||
|
@ -102,7 +152,10 @@
|
|||
"watched": "Gekeken",
|
||||
"sponsor_segments": "Sponsorsegmenten",
|
||||
"ratings_disabled": "Beoordelingen Uitgeschakeld",
|
||||
"live": "{0} Live"
|
||||
"live": "{0} Live",
|
||||
"shorts": "Shorts",
|
||||
"category": "Categorie",
|
||||
"all": "Alle"
|
||||
},
|
||||
"preferences": {
|
||||
"has_cdn": "Heeft CDN?",
|
||||
|
@ -114,6 +167,20 @@
|
|||
"ssl_score": "SSL-score"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Vastgemaakt door {author}"
|
||||
"pinned_by": "Vastgemaakt door {author}",
|
||||
"user_disabled": "Opmerkingen zijn uitgeschakeld in de instellingen.",
|
||||
"loading": "Opmerkingen laden...",
|
||||
"disabled": "Reacties zijn uitgeschakeld door de uploader."
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Let op: voorkeuren worden opgeslagen in de lokale opslag van uw browser. Als u uw browsergegevens verwijdert, worden ze opnieuw ingesteld.",
|
||||
"copied": "Gekopieerd!",
|
||||
"cannot_copy": "Kan niet kopiëren!",
|
||||
"page_not_found": "Pagina niet gevonden",
|
||||
"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": {
|
||||
"subscribed_channels_count": "Geabonneerd op: {0}"
|
||||
}
|
||||
}
|
||||
|
|
189
src/locales/oc.json
Normal file
189
src/locales/oc.json
Normal file
|
@ -0,0 +1,189 @@
|
|||
{
|
||||
"titles": {
|
||||
"login": "Se connectar",
|
||||
"feed": "Flux",
|
||||
"preferences": "Preferéncias",
|
||||
"history": "Istoric",
|
||||
"account": "Compte",
|
||||
"instance": "Instància",
|
||||
"player": "Lector",
|
||||
"livestreams": "Dirèctes",
|
||||
"channels": "Canals",
|
||||
"trending": "Tendéncias",
|
||||
"register": "S’inscriure",
|
||||
"subscriptions": "Abonaments",
|
||||
"playlists": "Listas de lecturas",
|
||||
"bookmarks": "Marcapaginas"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Agachar sus {0}"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "S’abonar - {count}",
|
||||
"unsubscribe": "Se desabonar - {count}",
|
||||
"view_subscriptions": "Veire los abonaments",
|
||||
"sort_by": "Triar per :",
|
||||
"most_recent": "Mai recents",
|
||||
"least_recent": "Mens recents",
|
||||
"channel_name_asc": "Nom del canal (A-Z)",
|
||||
"channel_name_desc": "Nom del canal (Z-A)",
|
||||
"back": "Tornar",
|
||||
"skip_outro": "Passar los crèdits a la fin",
|
||||
"skip_preview": "Passar l’apercebut / resumit",
|
||||
"uses_api_from": "Utiliza l’API de ",
|
||||
"skip_intro": "Passar l’animacion d’entracte / Introduccion",
|
||||
"enable_sponsorblock": "Activar Sponsorblock",
|
||||
"skip_sponsors": "Passar las promocions",
|
||||
"show_comments": "Mostrar los comentaris",
|
||||
"minimize_description": "Minimizar la descripcion",
|
||||
"show_description": "Mostrar la descripcion",
|
||||
"show_recommendations": "Mostrar las recomandacions",
|
||||
"minimize_recommendations": "Minimizar las recomandacions",
|
||||
"enable_lbry_proxy": "Activar lo servidor mandatari per LBRY",
|
||||
"view_ssl_score": "Mostrar l’avaloracion SSL",
|
||||
"search": "Recercar (Ctrl+K)",
|
||||
"filter": "Filtrar",
|
||||
"disable_lbry": "Desactivar LBRY per la difusion en dirècte",
|
||||
"loading": "Cargament…",
|
||||
"clear_history": "Netejar l’istoric",
|
||||
"hide_replies": "Rescondre las responsas",
|
||||
"load_more_replies": "Cargar mai de responsas",
|
||||
"remove_from_playlist": "Levar de la lista de lectura",
|
||||
"add_to_playlist": "Apondre a la listra de lectura",
|
||||
"minimize_comments": "Minimizar los comentaris",
|
||||
"theme": "Tèma",
|
||||
"language_selection": "Seleccion de la lenga",
|
||||
"loop_this_video": "Legir en bocla la vidèo",
|
||||
"reset_preferences": "Restablir las preferéncias",
|
||||
"auto": "Auto",
|
||||
"dark": "Escur",
|
||||
"light": "Clar",
|
||||
"donations": "Don pel desvolopament",
|
||||
"backup_preferences": "Salvagardar las preferéncias",
|
||||
"share": "Partejar",
|
||||
"documentation": "Documentacion",
|
||||
"source_code": "Còdi font",
|
||||
"restore_preferences": "Restablir las preferéncias",
|
||||
"skip_interaction": "Ignorar los rapèls d’interaccion (S’abonar)",
|
||||
"show_markers": "Mostrar los marcadors sul lector",
|
||||
"default_quality": "Qualitat per defaut",
|
||||
"buffering_goal": "Objectiu de mesa en memòria tampon (en segondas)",
|
||||
"minimize_description_default": "Minimizar la descripcion per defaut",
|
||||
"instances_list": "Lista d’instàncias",
|
||||
"enabled_codecs": "Codecs activats (multiples)",
|
||||
"yes": "Òc",
|
||||
"no": "Non",
|
||||
"export_to_json": "Exportar en JSON",
|
||||
"import_from_json": "Importar d’un JSON/CSV",
|
||||
"auto_play_next_video": "Legir la vidèo seguenta automaticament",
|
||||
"create_playlist": "Crear una lista de lectura",
|
||||
"delete_playlist": "Levar de la lista de lectura",
|
||||
"select_playlist": "Seleccionatz una lista de lectura",
|
||||
"delete_playlist_confirm": "Suprimir aquesta lista de lectura ?",
|
||||
"clone_playlist": "Clonar la lista de lectura",
|
||||
"instance_auth_selection": "Seleccion de l’instància d’autentificacion",
|
||||
"clone_playlist_success": "Clonatge capitat !",
|
||||
"follow_link": "Dobrir lo ligam",
|
||||
"skip_self_promo": "Sautar la promocion gratuita / autopromocion",
|
||||
"skip_non_music": "Sautar la musica : seccion non musicala",
|
||||
"skip_highlight": "Ignorar los tempses fòrts",
|
||||
"skip_filler_tangent": "Sautar la tangenta d’emplenament",
|
||||
"autoplay_video": "Legir automaticament la vidèo",
|
||||
"audio_only": "Sonque àudio",
|
||||
"minimize_comments_default": "Minimizar los comentaris per defaut",
|
||||
"instance_selection": "Seleccion d’instàncias",
|
||||
"please_select_playlist": "Seleccionatz una lista de lectura",
|
||||
"show_watch_on_youtube": "Mostrar lo boton « Veire sus YouTube »",
|
||||
"invalidate_session": "Se desconnectar de totes los aparelhs",
|
||||
"different_auth_instance": "Utilizar una instància diferenta per l’autentificacion",
|
||||
"back_to_home": "Tornar a l’acuèlh",
|
||||
"rename_playlist": "Renomenar la lista de lectura",
|
||||
"new_playlist_name": "Nom novèl de la lista de lectura",
|
||||
"with_timecode": "Partejar amb còdi orari",
|
||||
"piped_link": "Ligam cap a Piped",
|
||||
"show_chapters": "Capítols",
|
||||
"country_selection": "Seleccion del país",
|
||||
"default_homepage": "Pagina d’acuèlh per defaut",
|
||||
"minimize_recommendations_default": "Minimizar las recomandacions per defaut",
|
||||
"store_watch_history": "Servar l’istoric de visualizacion",
|
||||
"show_more": "Ne mostrar mai",
|
||||
"delete_playlist_video_confirm": "Levar aquesta vidèo de la lista de lectura ?",
|
||||
"delete_account": "Suprimir lo compte",
|
||||
"logout": "Se desconnectar d’aqueste aparelh",
|
||||
"minimize_chapters_default": "Minimizar los capítols per defaut",
|
||||
"download_as_txt": "Telecargar coma .txt",
|
||||
"copy_link": "Copiar lo ligam",
|
||||
"time_code": "Moment (en segondas)",
|
||||
"store_search_history": "Gardar l’istoric de recèrca",
|
||||
"confirm_reset_preferences": "Volètz vertadièrament reïnicializar las preferéncias ?",
|
||||
"hide_watched": "Rescondre las vidèos vistas al flux",
|
||||
"reply_count": "{count} responsas",
|
||||
"with_playlist": "Partejar amb una lista de lectura",
|
||||
"playlist_bookmarked": "Marcat",
|
||||
"bookmark_playlist": "Marcapagina",
|
||||
"status_page": "Estat",
|
||||
"no_valid_playlists": "Lo fichièr conten pas cap de lista de lectura valida !",
|
||||
"instance_donations": "Dons d’instància",
|
||||
"skip_button_only": "Afichar lo boton per sautar",
|
||||
"skip_automatically": "Automaticament",
|
||||
"min_segment_length": "Durada minimum de segment (en segondas)",
|
||||
"skip_segment": "Sautar lo segment",
|
||||
"show_less": "Ne mostrar mens",
|
||||
"autoplay_next_countdown": "Descompte per defaut abans de passar a la vidèo seguenta (en segondas)",
|
||||
"dismiss": "Ignorar"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_locations": "Localizacion de l’instància",
|
||||
"registered_users": "Utilizaires inscriches",
|
||||
"instance_name": "Nom de l’instància",
|
||||
"has_cdn": "A un CDN ?",
|
||||
"version": "Version",
|
||||
"up_to_date": "Actualizat ?",
|
||||
"ssl_score": "Marca SSL"
|
||||
},
|
||||
"login": {
|
||||
"username": "Nom d’utilizaire",
|
||||
"password": "Senhal"
|
||||
},
|
||||
"video": {
|
||||
"views": "{views} visualizacions",
|
||||
"watched": "Vista",
|
||||
"ratings_disabled": "Avaloracions desactivadas",
|
||||
"sponsor_segments": "Segments de sponsors",
|
||||
"live": "{0} en dirècte",
|
||||
"shorts": "Corts",
|
||||
"chapters": "Capítols",
|
||||
"videos": "Vidèos",
|
||||
"all": "Totas",
|
||||
"category": "Categoria"
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Nòta : las preferéncias son gardadas dins l’espaci d’emmagazinatge del navegador. La supression de las donadas del navegador las restablirà.",
|
||||
"copied": "Copiat !",
|
||||
"page_not_found": "Pagina pas trobada",
|
||||
"cannot_copy": "Còpia impossibla !",
|
||||
"local_storage": "Aquesta accion requerís lo localStorage, son activats los cookies ?",
|
||||
"register_no_email_note": "Es pas recomandat d’utilizar una adreça electronica coma nom d’utilizaire. Contunhar çaquelà ?",
|
||||
"next_video_countdown": "La vidèo seguenta començarà d’aquí {0}s"
|
||||
},
|
||||
"comment": {
|
||||
"disabled": "L’autor a desactivat los comentaris.",
|
||||
"loading": "Cargament dels comentaris…",
|
||||
"user_disabled": "Los comentaris son desactivats als paramètres.",
|
||||
"pinned_by": "Penjat per {author}"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Voliatz dire : {0} ?",
|
||||
"channels": "YouTube : Canals",
|
||||
"videos": "YouTube : Vidèos",
|
||||
"all": "YouTube : Tot",
|
||||
"playlists": "YouTube : Listas de lectura",
|
||||
"music_songs": "YT Music : Cançons",
|
||||
"music_videos": "YT Music : Vidèos",
|
||||
"music_albums": "YT Music : Albums",
|
||||
"music_playlists": "YT Music : Listas de lectura"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abonat a : {0}"
|
||||
}
|
||||
}
|
|
@ -1 +1,186 @@
|
|||
{}
|
||||
{
|
||||
"titles": {
|
||||
"login": "ଲଗ୍ ଇନ୍",
|
||||
"feed": "ଫିଡ୍",
|
||||
"trending": "ଟ୍ରେଣ୍ଡିଂ",
|
||||
"register": "ପଂଜିକରଣ",
|
||||
"preferences": "ପସନ୍ଦ",
|
||||
"history": "ଇତିହାସ",
|
||||
"subscriptions": "ଅନୁସୃତ ଗୁଡ଼ିକ",
|
||||
"playlists": "ପ୍ଲେଲିଷ୍ଟ ଗୁଡ଼ିକ",
|
||||
"instance": "ଉଦାହରଣ",
|
||||
"account": "ଆକାଉଣ୍ଟ",
|
||||
"player": "ପ୍ଲେୟାର",
|
||||
"livestreams": "ସିଧାପ୍ରସାରଣ ଗୁଡ଼ିକ",
|
||||
"channels": "ସ୍ରୋତ ଗୁଡ଼ିକ",
|
||||
"bookmarks": "ବୁକମାର୍କଗୁଡିକ"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0} ରେ ଦେଖନ୍ତୁ"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "ସଦସ୍ୟତା - {count}",
|
||||
"unsubscribe": "ସଦସ୍ୟତା ରଦ୍ଦ କରନ୍ତୁ - {count}",
|
||||
"view_subscriptions": "ସଦସ୍ୟତା ଗୁଡ଼ିକ ଦେଖନ୍ତୁ",
|
||||
"sort_by": "ଏହି କ୍ରମରେ ସଜାନ୍ତୁ:",
|
||||
"most_recent": "ସଦ୍ୟତମ",
|
||||
"uses_api_from": "ରୁ API ବ୍ୟବହାର କରେ ",
|
||||
"enable_sponsorblock": "ପ୍ରଯୋଜକ ବନ୍ଦ ସକ୍ଷମ କରନ୍ତୁ",
|
||||
"skip_intro": "ଇଣ୍ଟରମିସନ୍ / ଇଣ୍ଟ୍ରୋ ଆନିମେସନ୍ ଛାଡିଦିଅ",
|
||||
"default_homepage": "ଡିଫଲ୍ଟ ମୂଳପୃଷ୍ଠା",
|
||||
"minimize_comments_default": "ଡିଫଲ୍ଟ ଭାବରେ ମନ୍ତବ୍ୟଗୁଡିକୁ କମ୍ କରନ୍ତୁ",
|
||||
"show_description": "ବର୍ଣ୍ଣନା ଦେଖାନ୍ତୁ",
|
||||
"minimize_recommendations": "ସୁପାରିଶକୁ କମ୍ କରନ୍ତୁ",
|
||||
"show_recommendations": "ସୁପାରିଶଗୁଡିକ ଦେଖାନ୍ତୁ",
|
||||
"disable_lbry": "ଷ୍ଟ୍ରିମିଂ ପାଇଁ LBRY ଅକ୍ଷମ କରନ୍ତୁ",
|
||||
"search": "ସନ୍ଧାନ କରନ୍ତୁ (Ctrl+K)",
|
||||
"rename_playlist": "ପ୍ଲେ ଲିଷ୍ଟର ନାମ ପରିବର୍ତ୍ତନ କରନ୍ତୁ",
|
||||
"new_playlist_name": "ନୂତନ ପ୍ଲେଲିଷ୍ଟ ନାମ",
|
||||
"channel_name_asc": "ସ୍ରୋତ ର ନାମ (A-Z)",
|
||||
"least_recent": "ସର୍ବନିମ୍ନ ସାମ୍ପ୍ରତିକ",
|
||||
"channel_name_desc": "ସ୍ରୋତ ର ନାମ (Z-A)",
|
||||
"back": "ପଛକୁ ଯାଆନ୍ତୁ",
|
||||
"skip_sponsors": "ପ୍ରଯୋଜକମାନଙ୍କୁ ଛାଡ଼ିଦିଅ",
|
||||
"skip_outro": "ଏଣ୍ଡକାର୍ଡ / କ୍ରେଡିଟ୍ ଛାଡିଦିଅ",
|
||||
"skip_preview": "ପୂର୍ବାବଲୋକନ / ପୁନଃପ୍ରକାଶକୁ ଛାଡିଦିଅ",
|
||||
"restore_preferences": "ପସନ୍ଦଗୁଡିକ ପୁନରୁଦ୍ଧାର କରନ୍ତୁ",
|
||||
"skip_interaction": "ପାରସ୍ପରିକ ସ୍ମାରକକୁ ଏଡ଼ାଇ ଦିଅନ୍ତୁ (ସବସ୍କ୍ରାଇବ କରନ୍ତୁ)",
|
||||
"skip_self_promo": "ଅନାଦେୟ / ଆତ୍ମ ପଦୋନ୍ନତି ଛାଡିଦିଅ",
|
||||
"skip_non_music": "ସଙ୍ଗୀତ ପରିତ୍ୟାଗ କରନ୍ତୁ: ଅଣ-ସଙ୍ଗୀତ ବିଭାଗ",
|
||||
"skip_highlight": "ହାଇଲାଇଟ୍ କୁ ଛାଡିଦିଅ",
|
||||
"auto": "ସ୍ଵତଃ",
|
||||
"skip_filler_tangent": "ଫିଲର୍ ଟାଙ୍ଗେଣ୍ଟ୍ ଛାଡିଦିଅ",
|
||||
"default_quality": "ଡିଫଲ୍ଟ ଗୁଣବତ୍ତା",
|
||||
"show_markers": "ପ୍ଲେୟାରରେ ମାର୍କର୍ସ ଦେଖାନ୍ତୁ",
|
||||
"theme": "ଥିମ୍",
|
||||
"dark": "ଅନ୍ଧାର",
|
||||
"light": "ଉଜ୍ଜଳ",
|
||||
"autoplay_video": "ଅଟୋପ୍ଲେ ଭିଡିଓ",
|
||||
"enabled_codecs": "ସକ୍ଷମ କୋଡେକସ୍ (ଏକାଧିକ)",
|
||||
"audio_only": "କେବଳ ସ୍ୱର",
|
||||
"language_selection": "ଭାଷା ଚୟନ",
|
||||
"show_more": "ଅଧିକ ଦେଖାନ୍ତୁ",
|
||||
"buffering_goal": "ବଫରିଂ ଲକ୍ଷ୍ୟ (ସେକେଣ୍ଡରେ)",
|
||||
"country_selection": "ଦେଶ ଚୟନ",
|
||||
"minimize_description_default": "ଡିଫଲ୍ଟ ଭାବରେ ବର୍ଣ୍ଣନାକୁ କମ୍ କରନ୍ତୁ",
|
||||
"store_watch_history": "ଦେଖିଥିବା ଭିଡିଓ ଗୁଡ଼ିକର ଇତିହାସ ରଖନ୍ତୁ",
|
||||
"instances_list": "ଉଦାହରଣ ତାଲିକା",
|
||||
"instance_selection": "ଇନଷ୍ଟାନ୍ସ ଚୟନ",
|
||||
"yes": "ହଁ",
|
||||
"import_from_json": "JSON / CSV ରୁ ଆମଦାନୀ କରନ୍ତୁ",
|
||||
"no": "ନାହିଁ",
|
||||
"export_to_json": "JSON କୁ ରପ୍ତାନି କରନ୍ତୁ",
|
||||
"loop_this_video": "ଏହି ଭିଡିଓକୁ ଲୁପ୍ କରନ୍ତୁ",
|
||||
"auto_play_next_video": "ପରବର୍ତ୍ତୀ ଭିଡିଓ ସ୍ଵତଃ ଚଲାନ୍ତୁ",
|
||||
"donations": "ବିକାଶ ପାଇଁ ଦାନ",
|
||||
"minimize_comments": "ମନ୍ତବ୍ୟଗୁଡିକୁ କମ୍ କରନ୍ତୁ",
|
||||
"show_comments": "ମନ୍ତବ୍ୟଗୁଡିକ ଦେଖାନ୍ତୁ",
|
||||
"delete_playlist_video_confirm": "ପ୍ଲେ ଲିଷ୍ଟରୁ ଭିଡିଓ ଅପସାରଣ କରିବେ କି?",
|
||||
"minimize_description": "ବର୍ଣ୍ଣନାକୁ କମ୍ କରନ୍ତୁ",
|
||||
"view_ssl_score": "SSL ସ୍କୋର ଦେଖନ୍ତୁ",
|
||||
"loading": "ଲୋଡ୍ ହେଉଛି...",
|
||||
"enable_lbry_proxy": "LBRY ପାଇଁ ପ୍ରକ୍ସି ସକ୍ଷମ କରନ୍ତୁ",
|
||||
"filter": "ଫିଲ୍ଟର୍ କରନ୍ତୁ",
|
||||
"load_more_replies": "ଅଧିକ ଉତ୍ତର ଲୋଡ୍ କରନ୍ତୁ",
|
||||
"clear_history": "ଇତିହାସ ସଫା କରନ୍ତୁ",
|
||||
"hide_replies": "ଉତ୍ତରଗୁଡିକ ଲୁଚାନ୍ତୁ",
|
||||
"remove_from_playlist": "ପ୍ଲେ ଲିଷ୍ଟରୁ ହଟାନ୍ତୁ",
|
||||
"add_to_playlist": "ପ୍ଲେ ଲିଷ୍ଟରେ ଯୋଡନ୍ତୁ",
|
||||
"create_playlist": "ପ୍ଲେଲିଷ୍ଟ ସୃଷ୍ଟି କରନ୍ତୁ",
|
||||
"please_select_playlist": "ଦୟାକରି ଏକ ପ୍ଲେଲିଷ୍ଟ ଚୟନ କରନ୍ତୁ",
|
||||
"delete_playlist": "ପ୍ଲେ ଲିଷ୍ଟ ଡିଲିଟ୍ କରନ୍ତୁ",
|
||||
"show_watch_on_youtube": "ୟୁଟ୍ୟୁବ୍ ବଟନ୍ ରେ ୱାଚ୍ ଦେଖାନ୍ତୁ",
|
||||
"reset_preferences": "ପସନ୍ଦଗୁଡିକ ପୁନଃସେଟ୍ କରନ୍ତୁ",
|
||||
"share": "ଅଂଶୀଦାର କରନ୍ତୁ",
|
||||
"select_playlist": "ଏକ ପ୍ଲେଲିଷ୍ଟ ଚୟନ କରନ୍ତୁ",
|
||||
"delete_playlist_confirm": "ଏହି ପ୍ଲେଲିଷ୍ଟ ବିଲୋପ କରିବେ କି?",
|
||||
"delete_account": "ଖାତା ବିଲୋପ କରନ୍ତୁ",
|
||||
"logout": "ଏହି ଉପକରଣରୁ ଲଗଆଉଟ୍ କରନ୍ତୁ",
|
||||
"minimize_recommendations_default": "ଡିଫଲ୍ଟ ଭାବରେ ସୁପାରିଶକୁ କମ୍ କରନ୍ତୁ",
|
||||
"invalidate_session": "ସମସ୍ତ ଡିଭାଇସ୍ ରୁ ଲଗଆଉଟ୍ କରନ୍ତୁ",
|
||||
"download_as_txt": ".Txt ଭାବରେ ଡାଉନଲୋଡ୍ କରନ୍ତୁ",
|
||||
"instance_auth_selection": "ପ୍ରାମାଣିକିକରଣ ଇନଷ୍ଟାନ୍ସ ଚୟନ",
|
||||
"confirm_reset_preferences": "ଆପଣ ନିଶ୍ଚିତ କି ଆପଣ ଆପଣଙ୍କର ପସନ୍ଦଗୁଡିକ ପୁନଃ ସେଟ୍ କରିବାକୁ ଚାହୁଁଛନ୍ତି?",
|
||||
"status_page": "ସ୍ଥିତି",
|
||||
"different_auth_instance": "ପ୍ରାମାଣିକିକରଣ ପାଇଁ ଏକ ଭିନ୍ନ ଉଦାହରଣ ବ୍ୟବହାର କରନ୍ତୁ",
|
||||
"clone_playlist": "କ୍ଲୋନ୍ ପ୍ଲେଲିଷ୍ଟ୍",
|
||||
"clone_playlist_success": "ସଫଳତାର ସହିତ କ୍ଲୋନ ହୋଇଛି!",
|
||||
"backup_preferences": "ପସନ୍ଦ ଗୁଡ଼ିକର ନକଲ ସଂରକ୍ଷଣ କରନ୍ତୁ",
|
||||
"back_to_home": "ଘରକୁ ଫେରନ୍ତୁ",
|
||||
"show_chapters": "ଅଧ୍ୟାୟ ଗୁଡ଼ିକ",
|
||||
"store_search_history": "ସନ୍ଧାନ ଇତିହାସ ଗଚ୍ଛିତ କରନ୍ତୁ",
|
||||
"hide_watched": "ଫିଡରେ ଦେଖାଯାଇଥିବା ଭିଡିଓଗୁଡିକ ଲୁଚାନ୍ତୁ",
|
||||
"follow_link": "ଲିଙ୍କ୍ ଅନୁସରଣ କରନ୍ତୁ",
|
||||
"copy_link": "ଲିଙ୍କ୍ କପି କରନ୍ତୁ",
|
||||
"with_timecode": "ଟାଇମ୍ କୋଡ୍ ସହିତ ଅଂଶୀଦାର କରନ୍ତୁ",
|
||||
"piped_link": "ପାଇପ୍ ଲିଙ୍କ୍",
|
||||
"time_code": "ସମୟ କୋଡ୍ (ସେକେଣ୍ଡରେ)",
|
||||
"source_code": "ଉତ୍ସ କୋଡ୍",
|
||||
"reply_count": "{count} ଉତ୍ତର",
|
||||
"documentation": "ଡକ୍ୟୁମେଣ୍ଟେସନ୍",
|
||||
"instance_donations": "ଇନଷ୍ଟାଣ୍ଟ ଦାନ ଗୁଡ଼ିକ",
|
||||
"minimize_chapters_default": "ଡିଫଲ୍ଟ ଭାବରେ ଅଧ୍ୟାୟଗୁଡ଼ିକୁ କମ୍ କରନ୍ତୁ",
|
||||
"no_valid_playlists": "ଫାଇଲ୍ ଟି ବୈଧ ପ୍ଲେଲିଷ୍ଟ ଧାରଣ କରେ ନାହିଁ!",
|
||||
"with_playlist": "ପ୍ଲେଲିଷ୍ଟ ସହିତ ଅଂଶୀଦାର କରନ୍ତୁ",
|
||||
"bookmark_playlist": "ବୁକମାର୍କ",
|
||||
"playlist_bookmarked": "ବୁକମାର୍କ ହୋଇଛି",
|
||||
"min_segment_length": "ସର୍ବନିମ୍ନ ସେଗମେଣ୍ଟ ଲମ୍ବ (ସେକେଣ୍ଡରେ)",
|
||||
"skip_button_only": "ସ୍କିପ୍ ବଟନ୍ ଦେଖାନ୍ତୁ",
|
||||
"skip_automatically": "ସ୍ୱୟଂଚାଳିତ ଭାବରେ",
|
||||
"skip_segment": "ସେଗମେଣ୍ଟକୁ ଏଡ଼ାଇଦିଅ",
|
||||
"show_less": "କମ୍ ଦେଖାନ୍ତୁ"
|
||||
},
|
||||
"comment": {
|
||||
"loading": "ମନ୍ତବ୍ୟ ଲୋଡ୍ ହେଉଛି ...",
|
||||
"user_disabled": "ମନ୍ତବ୍ୟଗୁଡିକ ସେଟିଂସମୂହରେ ଅକ୍ଷମ ହୋଇଛି ।",
|
||||
"pinned_by": "{author} ଙ୍କ ଦ୍ୱାରା ପିନ୍ ହୋଇଛି",
|
||||
"disabled": "ମନ୍ତବ୍ୟଗୁଡିକ ଅପଲୋଡର୍ ଦ୍ୱାରା ଅକ୍ଷମ ହୋଇଛି ।"
|
||||
},
|
||||
"video": {
|
||||
"views": "{views} ଦୃଶ୍ୟ",
|
||||
"watched": "ଦେଖାଯାଇଛି",
|
||||
"sponsor_segments": "ପ୍ରାୟୋଜକ ଖଣ୍ଡଗୁଡିକ",
|
||||
"shorts": "ସର୍ଟସ୍",
|
||||
"videos": "ଭିଡିଓ ଗୁଡିକ",
|
||||
"ratings_disabled": "ମୂଲ୍ୟାୟନ ଅକ୍ଷମ ହୋଇଛି",
|
||||
"chapters": "ଅଧ୍ୟାୟ ଗୁଡ଼ିକ",
|
||||
"live": "{0} ସିଧାପ୍ରସାରଣ",
|
||||
"all": "ସମସ୍ତ",
|
||||
"category": "ବର୍ଗ"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "ଆପଣ କହିବାକୁ ଚାହୁଁଛନ୍ତି କି: {0}?",
|
||||
"music_albums": "ୟୁଟିଉବ୍ ସଙ୍ଗୀତ: ଆଲବମ୍ ଗୁଡ଼ିକ",
|
||||
"music_playlists": "ୟୁଟିଉବ୍ ସଙ୍ଗୀତ: ପ୍ଲେଲିଷ୍ଟଗୁଡିକ",
|
||||
"music_videos": "ୟୁଟିଉବ୍ ସଙ୍ଗୀତ: ଭିଡିଓଗୁଡିକ",
|
||||
"all": "ୟୁଟ୍ୟୁବ୍: ସମସ୍ତ",
|
||||
"videos": "ୟୁଟ୍ୟୁବ୍: ଭିଡିଓଗୁଡିକ",
|
||||
"channels": "ୟୁଟ୍ୟୁବ୍: ଚ୍ୟାନେଲଗୁଡିକ",
|
||||
"music_songs": "ୟୁଟିଉବ୍ ସଙ୍ଗୀତ: ଗୀତ ଗୁଡ଼ିକ",
|
||||
"playlists": "ୟୁଟ୍ୟୁବ୍: ପ୍ଲେଲିଷ୍ଟଗୁଡିକ"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "ସଦସ୍ୟତା: {0}"
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "ଟିପନ୍ତୁ: ପସନ୍ଦଗୁଡିକ ଆପଣଙ୍କ ବ୍ରାଉଜରର ସ୍ଥାନୀୟ ଷ୍ଟୋରେଜ୍ ରେ ସେଭ୍ ହୋଇଛି । ଆପଣଙ୍କର ବ୍ରାଉଜର୍ ଡାଟା ଡିଲିଟ୍ କରିବା ସେଗୁଡ଼ିକୁ ପୁନଃସେଟ୍ କରିବ ।",
|
||||
"copied": "କପି ହୋଇଛି!",
|
||||
"cannot_copy": "କପି କରିପାରିବ ନାହିଁ!",
|
||||
"page_not_found": "ପୃଷ୍ଠାଟି ମିଳିଲା ନାହିଁ",
|
||||
"local_storage": "ଏହି କ୍ରିୟା ଲୋକାଲ୍ ଷ୍ଟୋରେଜ୍ ଆବଶ୍ୟକ କରେ, କୁକିଜ୍ ସକ୍ଷମ ଅଛି କି?",
|
||||
"register_no_email_note": "ଉପଯୋଗକର୍ତ୍ତା ନାମ ଭାବରେ ଏକ ଇ-ମେଲ୍ ବ୍ୟବହାର କରିବା ସୁପାରିଶ କରାଯାଏ ନାହିଁ । ଯେକୌଣସି ପ୍ରକାରେ ଅଗ୍ରଗତି କରନ୍ତୁ?"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "ଇନଷ୍ଟାନ୍ସ ନାମ",
|
||||
"registered_users": "ପଞ୍ଜୀକୃତ ଉପଭୋକ୍ତା",
|
||||
"version": "ସଂସ୍କରଣ",
|
||||
"instance_locations": "ଇନଷ୍ଟାନ୍ସ ଅବସ୍ଥାନ",
|
||||
"has_cdn": "CDN ଅଛି କି?",
|
||||
"up_to_date": "ଅଦ୍ୟାବଧି?",
|
||||
"ssl_score": "SSL ସ୍କୋର"
|
||||
},
|
||||
"login": {
|
||||
"password": "ପାସୱାର୍ଡ",
|
||||
"username": "ଉପଯୋଗକର୍ତ୍ତା ନାମ"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,14 +7,20 @@
|
|||
"preferences": "Ustawienia",
|
||||
"history": "Historia",
|
||||
"subscriptions": "Lista kanałów",
|
||||
"playlists": "Playlisty"
|
||||
"playlists": "Playlisty",
|
||||
"player": "Odtwarzacz",
|
||||
"account": "Konto",
|
||||
"instance": "Instancja",
|
||||
"livestreams": "Na żywo",
|
||||
"channels": "Kanały",
|
||||
"bookmarks": "Zakładki"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Obejrzyj na {0}"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "Subskrybuj - {count}",
|
||||
"unsubscribe": "Anuluj subskrypcję - {count}",
|
||||
"unsubscribe": "Odsubskrybuj - {count}",
|
||||
"view_subscriptions": "Zarządzaj subskrybcjami",
|
||||
"sort_by": "Sortuj:",
|
||||
"most_recent": "Najnowsze",
|
||||
|
@ -26,7 +32,7 @@
|
|||
"enable_sponsorblock": "Włącz SponsorBlock",
|
||||
"skip_sponsors": "Pomijaj segmenty sponsorowane",
|
||||
"skip_intro": "Pomijaj czołówkę",
|
||||
"skip_outro": "Pomijaj tyłówkę",
|
||||
"skip_outro": "Pomiń karty końcowe / Podziękowania",
|
||||
"skip_preview": "Pomijaj podgląd/podsumowanie",
|
||||
"skip_interaction": "Pomijaj prośby o interakcję/subskrybcję",
|
||||
"skip_self_promo": "Pomijaj autopromocję",
|
||||
|
@ -34,7 +40,7 @@
|
|||
"skip_highlight": "Przechodź do meritum filmu",
|
||||
"skip_filler_tangent": "Pomijaj wstawki humorystyczne",
|
||||
"theme": "Motyw",
|
||||
"auto": "Automatyczny",
|
||||
"auto": "Automatyczna",
|
||||
"dark": "Ciemny",
|
||||
"light": "Jasny",
|
||||
"autoplay_video": "Autoodtwarzanie",
|
||||
|
@ -43,9 +49,9 @@
|
|||
"buffering_goal": "Cel buforowania (w sekundach)",
|
||||
"country_selection": "Wybór kraju",
|
||||
"default_homepage": "Domyślna strona główna",
|
||||
"show_comments": "Pokazuj komentarze",
|
||||
"minimize_description_default": "Zawsze chowaj opis",
|
||||
"store_watch_history": "Zapisuj historię oglądania",
|
||||
"show_comments": "Pokaż komentarze",
|
||||
"minimize_description_default": "Ukryj opis",
|
||||
"store_watch_history": "Zapamiętaj historię oglądania",
|
||||
"language_selection": "Wybór języka",
|
||||
"instances_list": "Lista instancji",
|
||||
"enabled_codecs": "Włączone kodeki (lista wielokrotnego wyboru)",
|
||||
|
@ -58,36 +64,85 @@
|
|||
"loop_this_video": "Zapętlaj ten film",
|
||||
"auto_play_next_video": "Autoodtwarzanie następnego filmu",
|
||||
"donations": "Wsparcie",
|
||||
"minimize_description": "Schowaj opis",
|
||||
"minimize_description": "Ukryj opis",
|
||||
"show_description": "Pokaż opis",
|
||||
"minimize_recommendations": "Minimalizuj rekomendacje",
|
||||
"show_recommendations": "Pokaż rekomendacje",
|
||||
"disable_lbry": "Wyłącz LBRY dla streaming-u",
|
||||
"minimize_recommendations": "Ukryj proponowane",
|
||||
"show_recommendations": "Pokaż proponowane",
|
||||
"disable_lbry": "Wyłącz LBRY dla przesyłania strumieniowego",
|
||||
"enable_lbry_proxy": "Włącz proxy dla LBRY",
|
||||
"view_ssl_score": "Pokaż ocenę SSL",
|
||||
"search": "Szukaj",
|
||||
"search": "Szukaj (Ctrl+K)",
|
||||
"filter": "Filtruj",
|
||||
"loading": "Ładowanie...",
|
||||
"clear_history": "Wyczyść historię",
|
||||
"hide_replies": "Schowaj odpowiedzi",
|
||||
"hide_replies": "Ukryj odpowiedzi",
|
||||
"load_more_replies": "Pokaż więcej odpowiedzi",
|
||||
"add_to_playlist": "Dodaj do playlisty",
|
||||
"remove_from_playlist": "Usuń z playlisty",
|
||||
"delete_playlist_video_confirm": "Czy jesteś pewien, że chcesz usunąć ten film z tej playlisty?",
|
||||
"delete_playlist_video_confirm": "Usunąć film z playlisty?",
|
||||
"create_playlist": "Stwórz playlistę",
|
||||
"delete_playlist": "Usuń playlistę",
|
||||
"select_playlist": "Wybierz playlistę",
|
||||
"delete_playlist_confirm": "Czy jesteś pewien, że chcesz usunąć tę playlistę?",
|
||||
"please_select_playlist": "Musisz wybrać playlistę"
|
||||
"delete_playlist_confirm": "Usunąć tę playlistę?",
|
||||
"please_select_playlist": "Musisz wybrać playlistę",
|
||||
"confirm_reset_preferences": "Zresetować ustawienia?",
|
||||
"show_watch_on_youtube": "Przycisk „Oglądaj na YouTube”",
|
||||
"restore_preferences": "Przywróć ustawienia z kopii zapasowej",
|
||||
"clone_playlist_success": "Pomyślnie sklonowano!",
|
||||
"copy_link": "Skopiuj link",
|
||||
"documentation": "Dokumentacja",
|
||||
"instance_donations": "Darowizny na rzecz instancji",
|
||||
"back_to_home": "Idź do strony głównej",
|
||||
"instance_auth_selection": "Wybrana instancja autoryzacyjna",
|
||||
"time_code": "Kod czasowy (w sekundach)",
|
||||
"show_markers": "Pokaż segmenty na odtwarzaczu",
|
||||
"store_search_history": "Zapamiętaj historię wyszukiwania",
|
||||
"hide_watched": "Ukryj obejrzane filmy",
|
||||
"source_code": "Kod źródłowy",
|
||||
"show_chapters": "Rozdziały",
|
||||
"minimize_chapters_default": "Ukryj rozdziały",
|
||||
"rename_playlist": "Zmień nazwę playlisty",
|
||||
"follow_link": "Otwórz link",
|
||||
"minimize_comments_default": "Ukryj sekcję komentarzy",
|
||||
"minimize_comments": "Ukryj komentarze",
|
||||
"delete_account": "Usuń konto",
|
||||
"logout": "Wyloguj się z tego urządzenia",
|
||||
"minimize_recommendations_default": "Ukryj proponowane filmy",
|
||||
"invalidate_session": "Wyloguj się ze wszystkich urządzeń",
|
||||
"different_auth_instance": "Użyj innej instancji do obsługi konta Piped",
|
||||
"clone_playlist": "Sklonuj playlistę",
|
||||
"backup_preferences": "Pobierz kopię zapasową ustawień",
|
||||
"download_as_txt": "Pobierz jako .txt",
|
||||
"reset_preferences": "Zresetuj ustawienia",
|
||||
"new_playlist_name": "Nowa nazwa playlisty",
|
||||
"share": "Udostępnij",
|
||||
"with_timecode": "Udostępnij z kodem czasowym",
|
||||
"piped_link": "Link Piped",
|
||||
"status_page": "Status",
|
||||
"reply_count": "{count} odpowiedzi",
|
||||
"no_valid_playlists": "Ten plik nie zawiera poprawnych playlist!",
|
||||
"with_playlist": "Udostępnij z playlistą",
|
||||
"playlist_bookmarked": "Dodano do zakładek",
|
||||
"bookmark_playlist": "Zakładka",
|
||||
"skip_button_only": "Pokaż przycisk pomijania",
|
||||
"skip_automatically": "Automatycznie",
|
||||
"min_segment_length": "Minimalna długość segmentu (w sekundach)",
|
||||
"skip_segment": "Pomiń segment",
|
||||
"show_less": "Pokaż mniej",
|
||||
"autoplay_next_countdown": "Domyślne odliczanie do następnego filmu (w sekundach)",
|
||||
"dismiss": "Odrzuć"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Przypięty przez {author}"
|
||||
"pinned_by": "Przypięty przez {author}",
|
||||
"disabled": "Komentarze zostały wyłączone przez twórcę.",
|
||||
"loading": "Wczytywanie komentarzy...",
|
||||
"user_disabled": "Komentarze wyłączone w ustawieniach."
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Nazwa instancji",
|
||||
"instance_locations": "Lokalizacje instancji",
|
||||
"has_cdn": "Używa CDN?",
|
||||
"registered_users": "Il. zarej. uż.",
|
||||
"registered_users": "Zarejestrowani użytkownicy",
|
||||
"version": "Wersja",
|
||||
"up_to_date": "Aktualna?",
|
||||
"ssl_score": "Ocena SSL"
|
||||
|
@ -103,7 +158,10 @@
|
|||
"sponsor_segments": "Segmenty sponsorowane",
|
||||
"ratings_disabled": "Ocenianie wyłączone",
|
||||
"chapters": "Rozdziały",
|
||||
"live": "{0} Na żywo"
|
||||
"live": "{0} na żywo",
|
||||
"shorts": "Krótkie wideo",
|
||||
"all": "Wszystkie",
|
||||
"category": "Kategoria"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Czy chodziło ci o: {0}?",
|
||||
|
@ -115,5 +173,17 @@
|
|||
"music_videos": "YT Music: Teledyski",
|
||||
"music_albums": "YT Music: Albumy",
|
||||
"music_playlists": "YT Music: Playlisty"
|
||||
},
|
||||
"info": {
|
||||
"cannot_copy": "Nie można skopiować!",
|
||||
"copied": "Skopiowano!",
|
||||
"page_not_found": "Strona nie znaleziona",
|
||||
"preferences_note": "Uwaga: ustawienia są zapisywane w lokalnej pamięci przeglądarki. Usunięcie danych przeglądarki spowoduje ich zresetowanie.",
|
||||
"local_storage": "Ta akcja wymaga dostępu do lokalnej pamięci, czy pliki cookie są włączone?",
|
||||
"register_no_email_note": "Użycie adresu email jako nazwy użytkownika jest niezalecane. Kontynuować mimo to?",
|
||||
"next_video_countdown": "Odtwarzanie następnego filmu za {0} s"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Licznik subskrybcji: {0}"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,142 +1,189 @@
|
|||
{
|
||||
"titles": {
|
||||
"trending": "Tendências",
|
||||
"preferences": "Preferências",
|
||||
"preferences": "Configurações",
|
||||
"subscriptions": "Subscrições",
|
||||
"login": "Entrar",
|
||||
"login": "Iniciar Sessão",
|
||||
"register": "Registar",
|
||||
"history": "Histórico",
|
||||
"feed": "Feed",
|
||||
"playlists": "Listas de reprodução",
|
||||
"feed": "Conteúdo",
|
||||
"playlists": "Listas de Reprodução",
|
||||
"account": "Conta",
|
||||
"instance": "Instância",
|
||||
"player": "Reprodutor"
|
||||
"player": "Reprodutor",
|
||||
"livestreams": "Transmissões ao vivo",
|
||||
"channels": "Canais",
|
||||
"bookmarks": "Marcadores"
|
||||
},
|
||||
"actions": {
|
||||
"sort_by": "Ordenar por:",
|
||||
"most_recent": "Mais recentes",
|
||||
"least_recent": "Menos recentes",
|
||||
"channel_name_asc": "Nome do canal (A-Z)",
|
||||
"back": "Recuar",
|
||||
"uses_api_from": "Utiliza a API de ",
|
||||
"enable_sponsorblock": "Ativar 'Sponsorblock'",
|
||||
"skip_intro": "Ignorar intervalo/animação de abertura",
|
||||
"skip_outro": "Ignorar cartões finais/créditos",
|
||||
"skip_preview": "Ignorar pré-visualização/resumo",
|
||||
"most_recent": "Mais Recente",
|
||||
"least_recent": "Menos Recente",
|
||||
"channel_name_asc": "Nome do Canal (A-Z)",
|
||||
"back": "Voltar",
|
||||
"uses_api_from": "Utiliza a \"API\" de ",
|
||||
"enable_sponsorblock": "Ativar \"SponsorBlock\"",
|
||||
"skip_intro": "Saltar Intermissão/Animação de Introdução",
|
||||
"skip_outro": "Saltar \"Endcards\"/Créditos",
|
||||
"skip_preview": "Saltar Pré-Visualização/Recapitulação",
|
||||
"auto": "Automático",
|
||||
"dark": "Escuro",
|
||||
"autoplay_video": "Reprodução automática",
|
||||
"audio_only": "Apenas áudio",
|
||||
"default_quality": "Qualidade padrão",
|
||||
"country_selection": "Seleção de país",
|
||||
"default_homepage": "Página inicial padrão",
|
||||
"show_comments": "Mostrar comentários",
|
||||
"minimize_description_default": "Minimizar descrição por definição",
|
||||
"store_watch_history": "Guardar histórico de visualizações",
|
||||
"instances_list": "Lista de instâncias",
|
||||
"enabled_codecs": "Codificadores ativados (Vários)",
|
||||
"instance_selection": "Seleção de instância",
|
||||
"autoplay_video": "Reproduzir Vídeo Automaticamente",
|
||||
"audio_only": "Apenas Áudio",
|
||||
"default_quality": "Qualidade Padrão",
|
||||
"country_selection": "Seleção de País",
|
||||
"default_homepage": "Página Inicial Padrão",
|
||||
"show_comments": "Mostrar Comentários",
|
||||
"minimize_description_default": "Minimizar Descrição por defeito",
|
||||
"store_watch_history": "Guardar Histórico de Visualizações",
|
||||
"instances_list": "Lista de Instâncias",
|
||||
"enabled_codecs": "\"Codecs\" Activados (Vários)",
|
||||
"instance_selection": "Seleção de Instância",
|
||||
"show_more": "Mostrar mais",
|
||||
"import_from_json": "Importar de JSON/CSV",
|
||||
"export_to_json": "Exportar para JSON",
|
||||
"loop_this_video": "Repetir este vídeo",
|
||||
"auto_play_next_video": "Reproduzir próximo vídeo automaticamente",
|
||||
"donations": "Doações",
|
||||
"minimize_description": "Minimizar descrição",
|
||||
"show_description": "Mostrar descrição",
|
||||
"show_recommendations": "Mostrar recomendações",
|
||||
"disable_lbry": "Desativar LBRY para streaming",
|
||||
"enable_lbry_proxy": "Ativar proxy para LBRY",
|
||||
"view_ssl_score": "Ver valor SSL",
|
||||
"search": "Pesquisa",
|
||||
"loop_this_video": "Repetir este Vídeo",
|
||||
"auto_play_next_video": "Reproduzir Automaticamente o próximo Vídeo",
|
||||
"donations": "Doações de desenvolvimento",
|
||||
"minimize_description": "Minimizar Descrição",
|
||||
"show_description": "Mostrar Descrição",
|
||||
"show_recommendations": "Mostrar Recomendações",
|
||||
"disable_lbry": "Desactivar \"LBRY\" para Transmissão",
|
||||
"enable_lbry_proxy": "Activar \"Proxy\" para \"LBRY\"",
|
||||
"view_ssl_score": "Ver Pontuação \"SSL\"",
|
||||
"search": "Pesquisa (Ctrl+K)",
|
||||
"filter": "Filtrar",
|
||||
"loading": "A carregar...",
|
||||
"clear_history": "Limpar histórico",
|
||||
"loading": "A Carregar...",
|
||||
"clear_history": "Limpar Histórico",
|
||||
"subscribe": "Subscrever - {count}",
|
||||
"unsubscribe": "Cancelar subscrição - {count}",
|
||||
"view_subscriptions": "Ver subscrições",
|
||||
"channel_name_desc": "Nome do canal (Z-A)",
|
||||
"skip_sponsors": "Ignorar publicidade",
|
||||
"unsubscribe": "Anular subscrição - {count}",
|
||||
"view_subscriptions": "Ver Subscrições",
|
||||
"channel_name_desc": "Nome do Canal (Z-A)",
|
||||
"skip_sponsors": "Saltar Patrocínios",
|
||||
"yes": "Sim",
|
||||
"skip_non_music": "Música: ignorar secção não musical",
|
||||
"skip_non_music": "Saltar Música: Secção Não-Musical",
|
||||
"no": "Não",
|
||||
"theme": "Tema",
|
||||
"language_selection": "Seleção de idioma",
|
||||
"minimize_recommendations": "Minimizar recomendações",
|
||||
"language_selection": "Seleção de Idioma",
|
||||
"minimize_recommendations": "Minimizar Recomendações",
|
||||
"light": "Claro",
|
||||
"hide_replies": "Ocultar respostas",
|
||||
"load_more_replies": "Carregar mais respostas",
|
||||
"skip_highlight": "Ignorar destaques",
|
||||
"skip_interaction": "Ignorar lembrete de Interação (Subscrição)",
|
||||
"skip_self_promo": "Ignorar promoção não paga/autopromoção",
|
||||
"buffering_goal": "Objetivo de memória (segundos)",
|
||||
"skip_filler_tangent": "Ignorar cenas desnecessárias",
|
||||
"hide_replies": "Ocultar Respostas",
|
||||
"load_more_replies": "Carregar mais Respostas",
|
||||
"skip_highlight": "Saltar Destaque",
|
||||
"skip_interaction": "Saltar Lembrete de Interação (Subscreve)",
|
||||
"skip_self_promo": "Saltar Promoção Não Paga/Auto-Promoção",
|
||||
"buffering_goal": "Objetivo de \"Buffering\" (em segundos)",
|
||||
"skip_filler_tangent": "Saltar Tangente \"Filler\"",
|
||||
"add_to_playlist": "Adicionar à lista de reprodução",
|
||||
"delete_playlist": "Eliminar lista de reprodução",
|
||||
"select_playlist": "Seleccione uma lista de reprodução",
|
||||
"delete_playlist_confirm": "Eliminar esta lista de reprodução?",
|
||||
"please_select_playlist": "Selecione uma lista de reprodução",
|
||||
"delete_playlist_video_confirm": "Remover vídeo da lista de reprodução?",
|
||||
"delete_playlist": "Apagar Lista de Reprodução",
|
||||
"select_playlist": "Selecionar uma Lista de Reprodução",
|
||||
"delete_playlist_confirm": "Apagar esta lista de reprodução?",
|
||||
"please_select_playlist": "Selecionar uma lista de reprodução se faz favor",
|
||||
"delete_playlist_video_confirm": "Remover o vídeo da lista de reprodução?",
|
||||
"remove_from_playlist": "Remover da lista de reprodução",
|
||||
"create_playlist": "Criar lista de reprodução",
|
||||
"create_playlist": "Criar Lista de Reprodução",
|
||||
"clone_playlist_success": "Clonada com sucesso!",
|
||||
"clone_playlist": "Clonar lista de reprodução",
|
||||
"show_markers": "Mostrar marcas no reprodutor",
|
||||
"delete_account": "Eliminar conta",
|
||||
"logout": "Terminar sessão neste dispositivo",
|
||||
"minimize_recommendations_default": "Minimizar recomendações por definição",
|
||||
"invalidate_session": "Terminar sessão em todos os dispositivos",
|
||||
"different_auth_instance": "Use uma instância diferente para autenticação",
|
||||
"instance_auth_selection": "Seleção de instância de autenticação",
|
||||
"confirm_reset_preferences": "Tem a certeza de que deseja restaurar as preferências originais?",
|
||||
"download_as_txt": "Descarregar como txt",
|
||||
"reset_preferences": "Repor definições originais",
|
||||
"restore_preferences": "Restaurar preferências"
|
||||
"clone_playlist": "Clonar Lista de Reprodução",
|
||||
"show_markers": "Mostrar Marcadores no Leitor",
|
||||
"delete_account": "Apagar Conta",
|
||||
"logout": "Terminar sessão neste aparelho",
|
||||
"minimize_recommendations_default": "Minimizar Recomendações por defeito",
|
||||
"invalidate_session": "Terminar sessão em todos os aparelhos",
|
||||
"different_auth_instance": "Usar uma instância diferente para autenticação",
|
||||
"instance_auth_selection": "Selecção da Instância para Autenticação",
|
||||
"confirm_reset_preferences": "Tem a certeza que quer redefinir as suas configurações?",
|
||||
"download_as_txt": "Descarregar como .txt",
|
||||
"reset_preferences": "Redefinir preferências",
|
||||
"restore_preferences": "Restaurar configurações",
|
||||
"follow_link": "Seguir ligação",
|
||||
"piped_link": "Ligação do Piped",
|
||||
"backup_preferences": "Exportar configurações",
|
||||
"store_search_history": "Armazenar Histórico de Pesquisa",
|
||||
"hide_watched": "Ocultar vídeos assistidos no feed",
|
||||
"documentation": "Documentação",
|
||||
"status_page": "Estado",
|
||||
"source_code": "Código-fonte",
|
||||
"instance_donations": "Doações de instâncias",
|
||||
"minimize_chapters_default": "Minimizar Capítulos por padrão",
|
||||
"show_watch_on_youtube": "Mostrar Botão Assistir no YouTube",
|
||||
"new_playlist_name": "Novo nome da lista de reprodução",
|
||||
"minimize_comments": "Minimizar Comentários",
|
||||
"back_to_home": "Voltar ao início",
|
||||
"rename_playlist": "Renomear",
|
||||
"copy_link": "Copiar ligação",
|
||||
"time_code": "Código de tempo (em segundos)",
|
||||
"minimize_comments_default": "Minimizar Comentários por defeito",
|
||||
"share": "Partilhar",
|
||||
"with_timecode": "Partilhar com código de tempo",
|
||||
"show_chapters": "Capítulos",
|
||||
"reply_count": "{count} respostas",
|
||||
"no_valid_playlists": "O ficheiro não contém listas de reprodução válidas!",
|
||||
"with_playlist": "Partilhar com lista de reprodução",
|
||||
"playlist_bookmarked": "Marcado",
|
||||
"bookmark_playlist": "Marcador",
|
||||
"skip_button_only": "Mostrar botão saltar",
|
||||
"skip_automatically": "Automaticamente",
|
||||
"min_segment_length": "Comprimento Mínimo do Segmento (em segundos)",
|
||||
"skip_segment": "Saltar Segmento",
|
||||
"show_less": "Mostrar menos",
|
||||
"dismiss": "Ignorar",
|
||||
"autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Nome da instância",
|
||||
"instance_locations": "Localizações da instância",
|
||||
"ssl_score": "Valor SSL",
|
||||
"has_cdn": "Tem CDN?",
|
||||
"instance_name": "Nome da Instância",
|
||||
"instance_locations": "Localizações da Instância",
|
||||
"ssl_score": "Pontuação \"SSL\"",
|
||||
"has_cdn": "Tem \"CDN\"?",
|
||||
"version": "Versão",
|
||||
"registered_users": "Utilizadores registados",
|
||||
"up_to_date": "Atualizado?"
|
||||
"registered_users": "Utilizadores Registados",
|
||||
"up_to_date": "Atualizada?"
|
||||
},
|
||||
"login": {
|
||||
"password": "Palavra-passe",
|
||||
"username": "Utilizador"
|
||||
"username": "Nome de utilizador"
|
||||
},
|
||||
"video": {
|
||||
"videos": "Vídeos",
|
||||
"views": "{views} visualizações",
|
||||
"watched": "Assistido",
|
||||
"sponsor_segments": "Segmentos de patrocínios",
|
||||
"ratings_disabled": "Avaliações desativadas",
|
||||
"watched": "Visto",
|
||||
"sponsor_segments": "Segmentos Patrocinados",
|
||||
"ratings_disabled": "Classificações Desactivadas",
|
||||
"chapters": "Capítulos",
|
||||
"live": "{0} em direto",
|
||||
"shorts": "Curtos"
|
||||
"live": "{0} em Direto",
|
||||
"shorts": "\"Shorts\"",
|
||||
"all": "Todos",
|
||||
"category": "Categoria"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Será que queria dizer: {0}?",
|
||||
"did_you_mean": "Será que querias dizer: {0}?",
|
||||
"all": "YouTube: Tudo",
|
||||
"videos": "YouTube: Vídeos",
|
||||
"channels": "YouTube: Canais",
|
||||
"music_songs": "YT Music: Músicas",
|
||||
"music_videos": "YT Music: Vídeos",
|
||||
"music_albums": "YT Music: Álbuns",
|
||||
"music_playlists": "YT Music: Listas de reprodução",
|
||||
"playlists": "YouTube: Listas de reprodução"
|
||||
"music_playlists": "YT Music: Listas de Reprodução",
|
||||
"playlists": "YouTube: Listas de Reprodução"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Ver em {0}"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Fixado por {author}",
|
||||
"disabled": "Os comentários form desativados pelo publicador.",
|
||||
"loading": "Carregando comentários...",
|
||||
"user_disabled": "Os comentários estão desativados nas definições."
|
||||
"pinned_by": "Afixado por {author}",
|
||||
"disabled": "Os comentários estão desactivados pelo dono do canal.",
|
||||
"loading": "A carregar comentários...",
|
||||
"user_disabled": "Os comentários estão desactivados nas definições."
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "{0} subscrito"
|
||||
"subscribed_channels_count": "Subscrito a: {0}"
|
||||
},
|
||||
"info": {
|
||||
"copied": "Copiada!",
|
||||
"cannot_copy": "Não foi possível copiar!",
|
||||
"page_not_found": "Página não encontrada",
|
||||
"local_storage": "Esta ação requer localStorage, os cookies estão ativados?",
|
||||
"preferences_note": "Nota: as configurações são guardadas no armazenamento local to seu navegador. Eliminar os dados de navegação irá redefini-las.",
|
||||
"register_no_email_note": "Não recomendamos utilizar um endereço de email como nome de utilizador. Continuar?",
|
||||
"next_video_countdown": "A reproduzir o vídeo seguinte em {0}s"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
{
|
||||
"actions": {
|
||||
"view_subscriptions": "Ver inscrições",
|
||||
"view_subscriptions": "Ver Inscrições",
|
||||
"back": "Voltar",
|
||||
"most_recent": "Mais recente",
|
||||
"least_recent": "Menos recente",
|
||||
"most_recent": "Mais Recente",
|
||||
"least_recent": "Menos Recente",
|
||||
"sort_by": "Ordenar por:",
|
||||
"channel_name_asc": "Nome do Canal (A-Z)",
|
||||
"channel_name_desc": "Nome do Canal (Z-A)",
|
||||
"dark": "Escuro",
|
||||
"light": "Claro",
|
||||
"show_comments": "Mostrar comentários",
|
||||
"show_comments": "Exibir Comentários",
|
||||
"country_selection": "Seleção de País",
|
||||
"default_homepage": "Página inicial (padrão)",
|
||||
"default_quality": "Qualidade padrão",
|
||||
"autoplay_video": "Reprodução automática",
|
||||
"minimize_description_default": "Minimizar descrição por padrão",
|
||||
"default_homepage": "Página Inicial Padrão",
|
||||
"default_quality": "Qualidade Padrão",
|
||||
"autoplay_video": "Reprodução Automática",
|
||||
"minimize_description_default": "Minimizar Descrição por padrão",
|
||||
"theme": "Tema",
|
||||
"audio_only": "Apenas áudio",
|
||||
"audio_only": "Apenas Áudio",
|
||||
"subscribe": "Inscrever-se - {count}",
|
||||
"unsubscribe": "Desinscrever-se - {count}",
|
||||
"skip_sponsors": "Pular patrocinadores",
|
||||
"skip_sponsors": "Pular Patrocinadores",
|
||||
"auto": "Automático",
|
||||
"uses_api_from": "Usa a API de ",
|
||||
"enable_sponsorblock": "Habilitar Sponsorblock",
|
||||
"enable_sponsorblock": "Ativar Sponsorblock",
|
||||
"skip_interaction": "Pular Lembrete de Interação (Inscrever-se)",
|
||||
"skip_self_promo": "Pular Promoção não paga/Autopromoção",
|
||||
"show_markers": "Exibir marcadores no player",
|
||||
"show_markers": "Exibir Marcadores no Player",
|
||||
"skip_intro": "Pular Intervalo/Introdução Animada",
|
||||
"skip_outro": "Pular Créditos/Cartões finais",
|
||||
"skip_preview": "Pular Recapitulação",
|
||||
"skip_highlight": "Pular destaque",
|
||||
"buffering_goal": "Cache de buffer (em segundos)",
|
||||
"skip_preview": "Pular Pré-Visualização/Recapitulação",
|
||||
"skip_highlight": "Pular Destaque",
|
||||
"buffering_goal": "Cache de Buffer (em segundos)",
|
||||
"skip_non_music": "Pular Música: Seção não Musical",
|
||||
"skip_filler_tangent": "Pular Enchimento Tangencial",
|
||||
"enabled_codecs": "Habilitar Codecs (Múltiplos)",
|
||||
"enabled_codecs": "Codecs Ativados (Múltiplos)",
|
||||
"language_selection": "Seleção de Idioma",
|
||||
"yes": "Sim",
|
||||
"show_more": "Mostrar mais",
|
||||
"export_to_json": "Exportar para JSON",
|
||||
"donations": "Doações de desenvolvimento",
|
||||
"minimize_recommendations": "Recolher recomendações",
|
||||
"minimize_recommendations": "Minimizar Recomendações",
|
||||
"loading": "Carregando...",
|
||||
"hide_replies": "Esconder respostas",
|
||||
"minimize_description": "Esconder descrição",
|
||||
"load_more_replies": "Exibir mais respostas",
|
||||
"hide_replies": "Ocultar Respostas",
|
||||
"minimize_description": "Minimizar Descrição",
|
||||
"load_more_replies": "Carregar mais Respostas",
|
||||
"create_playlist": "Criar Playlist",
|
||||
"delete_playlist": "Excluir Playlist",
|
||||
"select_playlist": "Selecionar uma Playlist",
|
||||
|
@ -53,20 +53,20 @@
|
|||
"please_select_playlist": "Por favor, selecione uma playlist",
|
||||
"remove_from_playlist": "Remover da playlist",
|
||||
"view_ssl_score": "Ver Pontuação SSL",
|
||||
"disable_lbry": "Desabilitar LBRY para Streaming",
|
||||
"enable_lbry_proxy": "Habilitar proxy para LBRY",
|
||||
"disable_lbry": "Desativar LBRY para Streaming",
|
||||
"enable_lbry_proxy": "Ativar Proxy para LBRY",
|
||||
"import_from_json": "Importar de JSON/CSV",
|
||||
"loop_this_video": "Repetir este Vídeo",
|
||||
"instances_list": "Lista de Instâncias",
|
||||
"clear_history": "Limpar Histórico",
|
||||
"search": "Pesquisar",
|
||||
"search": "Pesquisar (Ctrl+K)",
|
||||
"no": "Não",
|
||||
"show_description": "Exibir descrição",
|
||||
"show_description": "Exibir Descrição",
|
||||
"instance_selection": "Seleção de Instância",
|
||||
"auto_play_next_video": "Autoreproduzir vídeo seguinte",
|
||||
"auto_play_next_video": "Autorreproduzir Próximo Vídeo",
|
||||
"filter": "Filtro",
|
||||
"store_watch_history": "Salvar Histórico de Exibição",
|
||||
"show_recommendations": "Mostrar recomendações",
|
||||
"show_recommendations": "Exibir Recomendações",
|
||||
"minimize_comments_default": "Minimizar Comentários por padrão",
|
||||
"minimize_comments": "Minimizar Comentários",
|
||||
"different_auth_instance": "Use uma instância diferente para autenticação",
|
||||
|
@ -81,7 +81,7 @@
|
|||
"status_page": "Estado",
|
||||
"source_code": "Código fonte",
|
||||
"instance_donations": "Doações de instâncias",
|
||||
"instance_auth_selection": "Seleção de iIstância de Autenticação",
|
||||
"instance_auth_selection": "Seleção de Instância de Autenticação",
|
||||
"clone_playlist_success": "Clonada com sucesso!",
|
||||
"download_as_txt": "Baixar como .txt",
|
||||
"restore_preferences": "Restaurar preferências",
|
||||
|
@ -91,7 +91,7 @@
|
|||
"new_playlist_name": "Novo nome da playlist",
|
||||
"with_timecode": "Compartilhar com código de tempo",
|
||||
"piped_link": "Link do Piped",
|
||||
"follow_link": "Siguir link",
|
||||
"follow_link": "Seguir link",
|
||||
"time_code": "Código de tempo (em segundos)",
|
||||
"show_chapters": "Capítulos",
|
||||
"confirm_reset_preferences": "Tem certeza de que deseja redefinir suas preferências?",
|
||||
|
@ -99,7 +99,19 @@
|
|||
"documentation": "Documentação",
|
||||
"reply_count": "{count} respostas",
|
||||
"minimize_recommendations_default": "Minimizar Recomendações por padrão",
|
||||
"show_watch_on_youtube": "Mostrar Botão Assistir no YouTube"
|
||||
"show_watch_on_youtube": "Mostrar Botão Assistir no YouTube",
|
||||
"minimize_chapters_default": "Minimizar Capítulos por padrão",
|
||||
"no_valid_playlists": "O arquivo não contém playlists válidas!",
|
||||
"with_playlist": "Compartilhar com playlist",
|
||||
"bookmark_playlist": "Favorito",
|
||||
"playlist_bookmarked": "Favoritado",
|
||||
"skip_automatically": "Automaticamente",
|
||||
"skip_segment": "Ignorar Segmento",
|
||||
"min_segment_length": "Comprimento Mínimo do Segmento (em segundos)",
|
||||
"skip_button_only": "Mostrar botão pular",
|
||||
"show_less": "Mostrar menos",
|
||||
"autoplay_next_countdown": "Contagem regressiva padrão até o próximo vídeo (em segundos)",
|
||||
"dismiss": "Liberar"
|
||||
},
|
||||
"titles": {
|
||||
"history": "Histórico",
|
||||
|
@ -114,10 +126,11 @@
|
|||
"player": "Player",
|
||||
"account": "Conta",
|
||||
"channels": "Canais",
|
||||
"livestreams": "Transmissões ao vivo"
|
||||
"livestreams": "Transmissões ao vivo",
|
||||
"bookmarks": "Favoritos"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Assistir no"
|
||||
"watch_on": "Assistir no {0}"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Fixado por {author}",
|
||||
|
@ -126,7 +139,7 @@
|
|||
"loading": "Carregando comentários..."
|
||||
},
|
||||
"preferences": {
|
||||
"registered_users": "Usuários cadastrados",
|
||||
"registered_users": "Usuários Registrados",
|
||||
"version": "Versão",
|
||||
"instance_name": "Nome da Instância",
|
||||
"instance_locations": "Localizações da Instância",
|
||||
|
@ -144,9 +157,11 @@
|
|||
"chapters": "Capítulos",
|
||||
"live": "{0} Ao vivo",
|
||||
"watched": "Assistido",
|
||||
"ratings_disabled": "Avaliações desabilitadas",
|
||||
"sponsor_segments": "Segmentos de patrocinadores",
|
||||
"shorts": "Shorts"
|
||||
"ratings_disabled": "Avaliações Desativadas",
|
||||
"sponsor_segments": "Segmentos de Patrocinadores",
|
||||
"shorts": "Shorts",
|
||||
"all": "Todos",
|
||||
"category": "Categoria"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Você quis dizer: {0}?",
|
||||
|
@ -163,7 +178,10 @@
|
|||
"copied": "Copiado!",
|
||||
"cannot_copy": "Não foi possível copiar!",
|
||||
"preferences_note": "Nota: as preferências são salvas no armazenamento local do seu navegador. A exclusão dos dados do seu navegador irá redefini-los.",
|
||||
"page_not_found": "página não encontrada"
|
||||
"page_not_found": "página não encontrada",
|
||||
"local_storage": "Esta ação requer localStorage, os cookies estão ativados?",
|
||||
"register_no_email_note": "Usar um e-mail como nome de usuário não é recomendado. Continuar mesmo assim?",
|
||||
"next_video_countdown": "Reproduzindo o próximo vídeo em {0}s"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Inscrito em: {0}"
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
"playlists": "Listas de Reprodução",
|
||||
"account": "Conta",
|
||||
"instance": "Instância",
|
||||
"player": "Reprodutor"
|
||||
"player": "Reprodutor",
|
||||
"livestreams": "Transmissões ao vivo",
|
||||
"channels": "Canais",
|
||||
"bookmarks": "Marcadores"
|
||||
},
|
||||
"actions": {
|
||||
"view_subscriptions": "Ver Subscrições",
|
||||
|
@ -43,17 +46,17 @@
|
|||
"language_selection": "Seleção de Idioma",
|
||||
"enabled_codecs": "\"Codecs\" Activados (Vários)",
|
||||
"instance_selection": "Seleção de Instância",
|
||||
"show_more": "Mostrar Mais",
|
||||
"show_more": "Mostrar mais",
|
||||
"import_from_json": "Importar de JSON/CSV",
|
||||
"loop_this_video": "Repetir este Vídeo",
|
||||
"auto_play_next_video": "Reproduzir Automaticamente o próximo Vídeo",
|
||||
"donations": "Doações",
|
||||
"donations": "Doações de desenvolvimento",
|
||||
"minimize_description": "Minimizar Descrição",
|
||||
"show_description": "Mostrar Descrição",
|
||||
"minimize_recommendations": "Minimizar Recomendações",
|
||||
"show_recommendations": "Mostrar Recomendações",
|
||||
"view_ssl_score": "Ver Pontuação \"SSL\"",
|
||||
"search": "Procurar",
|
||||
"search": "Pesquisa (Ctrl+K)",
|
||||
"hide_replies": "Ocultar Respostas",
|
||||
"load_more_replies": "Carregar mais Respostas",
|
||||
"unsubscribe": "Anular subscrição - {count}",
|
||||
|
@ -69,7 +72,7 @@
|
|||
"no": "Não",
|
||||
"filter": "Filtrar",
|
||||
"clear_history": "Limpar Histórico",
|
||||
"disable_lbry": "Desactivar \"LBRY\" para Transmissão",
|
||||
"disable_lbry": "Desactivar \"LBRY\" para \"Streaming\"",
|
||||
"loading": "A Carregar...",
|
||||
"please_select_playlist": "Selecionar uma lista de reprodução se faz favor",
|
||||
"select_playlist": "Selecionar uma Lista de Reprodução",
|
||||
|
@ -102,7 +105,29 @@
|
|||
"reset_preferences": "Redefinir preferências",
|
||||
"backup_preferences": "Exportar configurações",
|
||||
"back_to_home": "Voltar ao início",
|
||||
"minimize_comments_default": "Minimizar Comentários por defeito"
|
||||
"minimize_comments_default": "Minimizar Comentários por defeito",
|
||||
"store_search_history": "Armazenar Histórico de Pesquisa",
|
||||
"minimize_chapters_default": "Minimizar Capítulos por padrão",
|
||||
"show_watch_on_youtube": "Mostrar Botão Assistir no YouTube",
|
||||
"show_chapters": "Capítulos",
|
||||
"hide_watched": "Ocultar vídeos assistidos no feed",
|
||||
"documentation": "Documentação",
|
||||
"status_page": "Estado",
|
||||
"minimize_comments": "Minimizar Comentários",
|
||||
"reply_count": "{count} respostas",
|
||||
"source_code": "Código-fonte",
|
||||
"instance_donations": "Doações de instâncias",
|
||||
"no_valid_playlists": "O ficheiro não contém listas de reprodução válidas!",
|
||||
"bookmark_playlist": "Marcador",
|
||||
"playlist_bookmarked": "Marcado",
|
||||
"with_playlist": "Partilhar com lista de reprodução",
|
||||
"skip_button_only": "Mostrar botão saltar",
|
||||
"skip_automatically": "Automaticamente",
|
||||
"min_segment_length": "Comprimento Mínimo do Segmento (em segundos)",
|
||||
"skip_segment": "Saltar Segmento",
|
||||
"show_less": "Mostrar menos",
|
||||
"autoplay_next_countdown": "Predefinição Contagem decrescente até ao próximo vídeo (em segundos)",
|
||||
"dismiss": "Ignorar"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Afixado por {author}",
|
||||
|
@ -131,7 +156,9 @@
|
|||
"ratings_disabled": "Classificações Desactivadas",
|
||||
"chapters": "Capítulos",
|
||||
"live": "{0} em Direto",
|
||||
"shorts": "\"Shorts\""
|
||||
"shorts": "\"Shorts\"",
|
||||
"all": "Todos",
|
||||
"category": "Categoria"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Será que querias dizer: {0}?",
|
||||
|
@ -154,6 +181,9 @@
|
|||
"preferences_note": "Nota: as configurações são guardadas no armazenamento local to seu navegador. Eliminar os dados de navegação irá redefini-las.",
|
||||
"page_not_found": "Página não encontrada",
|
||||
"copied": "Copiada!",
|
||||
"cannot_copy": "Não foi possível copiar!"
|
||||
"cannot_copy": "Não foi possível copiar!",
|
||||
"local_storage": "Esta ação requer localStorage, os cookies estão ativados?",
|
||||
"register_no_email_note": "A utilização de um e-mail como nome de utilizador não é recomendada. Proceder de qualquer forma?",
|
||||
"next_video_countdown": "A reproduzir o vídeo seguinte em {0}s"
|
||||
}
|
||||
}
|
||||
|
|
189
src/locales/ro.json
Normal file
189
src/locales/ro.json
Normal file
|
@ -0,0 +1,189 @@
|
|||
{
|
||||
"actions": {
|
||||
"back_to_home": "Înapoi acasă",
|
||||
"store_search_history": "Rețineți istoricul de căutări",
|
||||
"with_timecode": "Distribuiți cu timpul de cod",
|
||||
"piped_link": "Link Piped",
|
||||
"time_code": "Cod de timp (secunde)",
|
||||
"show_chapters": "Capitole",
|
||||
"search": "Căutare (Ctrl+K)",
|
||||
"logout": "Deconectați-vă de pe acest dispozitiv",
|
||||
"add_to_playlist": "Adăugare în playlist",
|
||||
"remove_from_playlist": "Ștergere din playlist",
|
||||
"create_playlist": "Creați playlist",
|
||||
"delete_playlist": "Ștergeți playlist",
|
||||
"delete_playlist_confirm": "Ștergeți acest playlist?",
|
||||
"please_select_playlist": "Vă rugăm să alegeți un playlist",
|
||||
"minimize_recommendations_default": "Minimizați recomandările în mod implicit",
|
||||
"subscribe": "Abonare - {count}",
|
||||
"least_recent": "Cele mai vechi",
|
||||
"channel_name_asc": "Numele canalului (A-Z)",
|
||||
"channel_name_desc": "Nume canalului (Z-A)",
|
||||
"back": "Înapoi",
|
||||
"uses_api_from": "Se folosește API-ul de la ",
|
||||
"enable_sponsorblock": "Activați Sponsorblock",
|
||||
"skip_intro": "Omitere pauze/animații de intro",
|
||||
"skip_preview": "Omitere previzualizare/recapitulare",
|
||||
"skip_self_promo": "Omitere promoție neplătită/autopromovare",
|
||||
"skip_non_music": "Omitere muzică: Secțiune non-muzicală",
|
||||
"skip_highlight": "Omitere evidențiere",
|
||||
"show_markers": "Se afișează marcatori în player",
|
||||
"dark": "Întunecat",
|
||||
"auto": "Auto",
|
||||
"audio_only": "Doar audio",
|
||||
"default_quality": "Calitate implicită",
|
||||
"country_selection": "Selecție țară",
|
||||
"default_homepage": "Pagina principală implicită",
|
||||
"minimize_comments_default": "Minimizați comentariile în mod implicit",
|
||||
"minimize_description_default": "Minimizați descrierea în mod implicit",
|
||||
"language_selection": "Selecție limbă",
|
||||
"instances_list": "Listă de Instanțe",
|
||||
"enabled_codecs": "Codecuri activate (multiple)",
|
||||
"loop_this_video": "Repetare video",
|
||||
"donations": "Donații pentru dezvoltare",
|
||||
"show_recommendations": "Afișați recomandările",
|
||||
"disable_lbry": "Dezactivați LBRY pentru streaming",
|
||||
"enable_lbry_proxy": "Activați proxy pentru LBRY",
|
||||
"view_ssl_score": "Vedeți scorul SSL",
|
||||
"filter": "Filtru",
|
||||
"loading": "Se încarcă...",
|
||||
"clear_history": "Ștergeți istoricul",
|
||||
"hide_replies": "Ascundeți răspunsurile",
|
||||
"load_more_replies": "Mai multe răspunsuri",
|
||||
"delete_playlist_video_confirm": "Ștergeți videoclipul din playlist?",
|
||||
"select_playlist": "Selectați un playlist",
|
||||
"delete_account": "Ștergeți-vă contul",
|
||||
"show_watch_on_youtube": "Afișați butonul „Vizionați pe YouTube”",
|
||||
"invalidate_session": "Deconectați toate dispozitivele",
|
||||
"instance_auth_selection": "Selecție instanță de autentificare",
|
||||
"clone_playlist_success": "Clonată cu succes!",
|
||||
"reset_preferences": "Resetați preferințele",
|
||||
"confirm_reset_preferences": "Sunteți sigur că doriți să vă resetați preferințele?",
|
||||
"rename_playlist": "Redenumiți playlist-ul",
|
||||
"new_playlist_name": "Numele playlist-ului nou",
|
||||
"share": "Distribuiți",
|
||||
"follow_link": "Urmați link-ul",
|
||||
"copy_link": "Copiați link-ul",
|
||||
"hide_watched": "Ascundeți videoclipurile vizionate din flux",
|
||||
"documentation": "Documentație",
|
||||
"status_page": "Status",
|
||||
"source_code": "Cod sursă",
|
||||
"instance_donations": "Donații instanță",
|
||||
"reply_count": "{count} răspunsuri",
|
||||
"minimize_chapters_default": "Minimizați capitolele în mod implicit",
|
||||
"skip_sponsors": "Omitere sponsori",
|
||||
"different_auth_instance": "Folosiți o instanță diferită pentru autentificare",
|
||||
"clone_playlist": "Clonați lista de redare",
|
||||
"backup_preferences": "Faceți backup la preferințe",
|
||||
"unsubscribe": "Dezabonare - {count}",
|
||||
"view_subscriptions": "Vedeți abonamentele",
|
||||
"sort_by": "Sortare după:",
|
||||
"download_as_txt": "Descărcați ca .txt",
|
||||
"most_recent": "Cele mai recente",
|
||||
"skip_outro": "Omitere carduri de sfârșit/mulțumiri",
|
||||
"skip_interaction": "Omitere reamintiri de interacțiune (abonare)",
|
||||
"light": "Luminat",
|
||||
"restore_preferences": "Restaurați preferințele",
|
||||
"skip_filler_tangent": "Omitere tangentă de umplere",
|
||||
"theme": "Temă",
|
||||
"autoplay_video": "Redare automată video",
|
||||
"buffering_goal": "Obiectiv de tamponare (în secunde)",
|
||||
"instance_selection": "Selecție instanță",
|
||||
"store_watch_history": "Rețineți istoricul de vizionări",
|
||||
"minimize_comments": "Minimizați comentariile",
|
||||
"minimize_description": "Minimizați descrierea",
|
||||
"show_more": "Mai mult",
|
||||
"no": "Nu",
|
||||
"export_to_json": "Exportați ca JSON",
|
||||
"import_from_json": "Importați din JSON/CSV",
|
||||
"auto_play_next_video": "Redați automat următorul video",
|
||||
"minimize_recommendations": "Minimizați recomandările",
|
||||
"yes": "Da",
|
||||
"show_comments": "Afișați comentariile",
|
||||
"show_description": "Afișați descrierea",
|
||||
"bookmark_playlist": "Marcați",
|
||||
"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": "Omitere segment",
|
||||
"skip_button_only": "Afișați butonul de omitere",
|
||||
"with_playlist": "Distribuiți cu playlist",
|
||||
"playlist_bookmarked": "Marcat",
|
||||
"show_less": "Mai puțin",
|
||||
"autoplay_next_countdown": "Numărătoarea inversă implicită până la următorul videoclip (în secunde)",
|
||||
"dismiss": "Concediază"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "Scor SSL",
|
||||
"version": "Versiune",
|
||||
"up_to_date": "Actualizat?",
|
||||
"instance_name": "Nume instanță",
|
||||
"instance_locations": "Locațiile instanței",
|
||||
"has_cdn": "Are CDN?",
|
||||
"registered_users": "Utilizatori înregistrați"
|
||||
},
|
||||
"comment": {
|
||||
"user_disabled": "Comentariile sunt dezactivate în setări.",
|
||||
"pinned_by": "Fixat de {author}",
|
||||
"disabled": "Comentariile sunt dezactivate de către autor.",
|
||||
"loading": "Se încarcă comentariile..."
|
||||
},
|
||||
"video": {
|
||||
"views": "{views} vizionări",
|
||||
"chapters": "Capitole",
|
||||
"shorts": "Shorts",
|
||||
"watched": "Vizionat",
|
||||
"sponsor_segments": "Segmente sponsori",
|
||||
"ratings_disabled": "Evaluări dezactivate",
|
||||
"live": "{0} în direct",
|
||||
"videos": "Videoclipuri",
|
||||
"category": "Categorie",
|
||||
"all": "Tot"
|
||||
},
|
||||
"login": {
|
||||
"username": "Nume de utilizator",
|
||||
"password": "Parolă"
|
||||
},
|
||||
"search": {
|
||||
"videos": "YouTube: Videoclipuri",
|
||||
"music_playlists": "YT Music: Liste de redare",
|
||||
"did_you_mean": "Vă refereați la: {0}?",
|
||||
"all": "YouTube: Toate",
|
||||
"channels": "YouTube: Canale",
|
||||
"playlists": "YouTube: Liste de redare",
|
||||
"music_songs": "YT Music: Muzică",
|
||||
"music_videos": "YT Music: Videoclipuri",
|
||||
"music_albums": "YT Music: Albume"
|
||||
},
|
||||
"info": {
|
||||
"cannot_copy": "Nu s-a putut copia!",
|
||||
"preferences_note": "Notă: preferințele sunt salvate în memoria locală a browserului dvs. Ștergerea datelor din browserul dvs. le va reseta.",
|
||||
"page_not_found": "Pagina nu a fost găsită",
|
||||
"copied": "Copiat!",
|
||||
"register_no_email_note": "Utilizarea unui e-mail ca nume de utilizator nu este recomandată. Continuați oricum?",
|
||||
"local_storage": "Această acțiune necesită localStorage, sunt activate cookie-urile?",
|
||||
"next_video_countdown": "Redarea următorului videoclip în {0}s"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abonat la: {0}"
|
||||
},
|
||||
"titles": {
|
||||
"register": "Înregistrare",
|
||||
"history": "Istoric",
|
||||
"subscriptions": "Abonamente",
|
||||
"playlists": "Liste de redare",
|
||||
"account": "Cont",
|
||||
"instance": "Instanță",
|
||||
"login": "Autentificare",
|
||||
"feed": "Flux",
|
||||
"trending": "Tendințe",
|
||||
"livestreams": "Fluxuri live",
|
||||
"channels": "Canale",
|
||||
"preferences": "Preferințe",
|
||||
"player": "Player-ul",
|
||||
"bookmarks": "Marcaje"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Vizionați pe {0}"
|
||||
}
|
||||
}
|
|
@ -5,12 +5,15 @@
|
|||
"register": "Регистрация",
|
||||
"feed": "Подписки",
|
||||
"preferences": "Настройки",
|
||||
"history": "История просмотров",
|
||||
"subscriptions": "Ваши подписки",
|
||||
"history": "История",
|
||||
"subscriptions": "Подписки",
|
||||
"playlists": "Плейлисты",
|
||||
"account": "Аккаунт",
|
||||
"player": "Плеер",
|
||||
"instance": "Сервер"
|
||||
"instance": "Сервер",
|
||||
"livestreams": "Прямые трансляции",
|
||||
"channels": "Каналы",
|
||||
"bookmarks": "Закладки"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Смотреть на {0}"
|
||||
|
@ -25,7 +28,7 @@
|
|||
"channel_name_asc": "Имя канала (А-Я)",
|
||||
"channel_name_desc": "Имя канала (Я-А)",
|
||||
"back": "Назад",
|
||||
"uses_api_from": "Использовать API, предоставляемое ",
|
||||
"uses_api_from": "Использовать API ",
|
||||
"enable_sponsorblock": "Включить Sponsorblock",
|
||||
"skip_sponsors": "Пропускать спонсорскую рекламу",
|
||||
"skip_intro": "Пропускать заставку/интро",
|
||||
|
@ -64,9 +67,9 @@
|
|||
"minimize_recommendations": "Свернуть рекомендации",
|
||||
"show_recommendations": "Показать рекомендации",
|
||||
"disable_lbry": "Отключить LBRY для стриминга",
|
||||
"enable_lbry_proxy": "Проксировать видео с LBRY",
|
||||
"enable_lbry_proxy": "Проксировать видео для LBRY",
|
||||
"view_ssl_score": "Посмотреть настройки SSL",
|
||||
"search": "Поиск",
|
||||
"search": "Поиск (Ctrl+K)",
|
||||
"filter": "Фильтр",
|
||||
"loading": "Загрузка...",
|
||||
"clear_history": "Очистить историю",
|
||||
|
@ -82,49 +85,60 @@
|
|||
"select_playlist": "Выбрать плейлист",
|
||||
"delete_playlist_confirm": "Удалить этот плейлист?",
|
||||
"delete_playlist_video_confirm": "Удалить видео из плейлиста?",
|
||||
"show_markers": "Показать Mаркеры Hа Проигрывателе",
|
||||
"show_markers": "Показать маркеры на проигрывателе",
|
||||
"delete_account": "Удалить аккаунт",
|
||||
"logout": "Выйти из этого устройства",
|
||||
"download_as_txt": "Скачать как .txt",
|
||||
"minimize_recommendations_default": "Скрыть Рекомендации по умолчанию",
|
||||
"invalidate_session": "Выйти из всех устройств",
|
||||
"different_auth_instance": "Использовать другие средства аутентификации",
|
||||
"instance_auth_selection": "Выбор средств аутентификации",
|
||||
"different_auth_instance": "Использовать другое зеркало для аутентификации",
|
||||
"instance_auth_selection": "Выбор зеркала аутентификации",
|
||||
"clone_playlist": "Клонировать плейлист",
|
||||
"clone_playlist_success": "Клонирование прошло успешно!",
|
||||
"show_chapters": "Части",
|
||||
"clone_playlist_success": "Успешно клонировано!",
|
||||
"show_chapters": "Главы",
|
||||
"rename_playlist": "Переименовать плейлист",
|
||||
"new_playlist_name": "Новое название плейлиста",
|
||||
"share": "Поделиться",
|
||||
"with_timecode": "Поделиться с отметкой времени",
|
||||
"with_timecode": "Поделиться с таймкодом",
|
||||
"piped_link": "Ссылка Piped",
|
||||
"follow_link": "Ссылка подписки",
|
||||
"follow_link": "Перейти по ссылке",
|
||||
"copy_link": "Скопировать ссылку",
|
||||
"time_code": "Тайм-код (в секундах)",
|
||||
"time_code": "Таймкод (в секундах)",
|
||||
"reset_preferences": "Сбросить настройки",
|
||||
"confirm_reset_preferences": "Вы уверены, что хотите сбросить настройки?",
|
||||
"backup_preferences": "Настройки бэкапов",
|
||||
"backup_preferences": "Бэкап настроек",
|
||||
"restore_preferences": "Восстановить настройки",
|
||||
"back_to_home": "Вернутся на главную",
|
||||
"back_to_home": "Назад на главную",
|
||||
"store_search_history": "Хранить историю поиска",
|
||||
"hide_watched": "Скрыть просмотренные видео в ленте",
|
||||
"status_page": "Статус",
|
||||
"source_code": "Исходный код",
|
||||
"documentation": "Пожертвования сервера",
|
||||
"instance_donations": "Пожертвования сервера",
|
||||
"documentation": "Документация",
|
||||
"instance_donations": "Пожертвования зеркала",
|
||||
"reply_count": "{count} ответов",
|
||||
"minimize_comments_default": "Сворачивать комментарии по умолчанию",
|
||||
"minimize_comments": "Свернуть комментарии"
|
||||
"minimize_comments": "Свернуть комментарии",
|
||||
"show_watch_on_youtube": "Показать кнопку Смотреть на YouTube",
|
||||
"minimize_chapters_default": "Скрывать главы по умолчанию",
|
||||
"no_valid_playlists": "Файл не содержит действующих плейлистов!",
|
||||
"with_playlist": "Поделиться с плейлистом",
|
||||
"bookmark_playlist": "Закладка",
|
||||
"playlist_bookmarked": "В закладках",
|
||||
"skip_automatically": "Автоматически",
|
||||
"min_segment_length": "Минимальная длина сегмента (в секундах)",
|
||||
"skip_button_only": "Показать кнопку \"Пропустить\"",
|
||||
"skip_segment": "Пропустить сегмент",
|
||||
"show_less": "Показать меньше"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Прикреплено пользователем {author}",
|
||||
"pinned_by": "Закреплено пользователем {author}",
|
||||
"loading": "Загрузка комментариев...",
|
||||
"user_disabled": "Комментарии отключены в настройках.",
|
||||
"disabled": "Коментарии отключены автором."
|
||||
"disabled": "Комментарии отключены автором."
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Название",
|
||||
"instance_locations": "Местоположение",
|
||||
"instance_name": "Имя зеркала",
|
||||
"instance_locations": "Местоположения зеркала",
|
||||
"has_cdn": "Имеется CDN?",
|
||||
"ssl_score": "Оценка настроек SSL",
|
||||
"registered_users": "Зарегистрировано пользователей",
|
||||
|
@ -132,7 +146,7 @@
|
|||
"up_to_date": "Версия актуальна?"
|
||||
},
|
||||
"login": {
|
||||
"username": "Аккаунт на Piped",
|
||||
"username": "Имя пользователя",
|
||||
"password": "Пароль"
|
||||
},
|
||||
"video": {
|
||||
|
@ -143,7 +157,9 @@
|
|||
"ratings_disabled": "Оценки отключены",
|
||||
"live": "{0} В эфире",
|
||||
"chapters": "Содержание",
|
||||
"shorts": "Shorts"
|
||||
"shorts": "Shorts",
|
||||
"all": "Все",
|
||||
"category": "Категория"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Может быть вы имели в виду: {0}?",
|
||||
|
@ -160,9 +176,11 @@
|
|||
"subscribed_channels_count": "Подписан на: {0}"
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Примечание: настройки сохранены в локальном хранилище браузера. При удалении данных браузера они будут удалены.",
|
||||
"preferences_note": "Примечание: настройки сохранены в локальном хранилище браузера. Удаление данных вашего браузера сбросит их.",
|
||||
"copied": "Скопировано!",
|
||||
"cannot_copy": "Не получилось скопировать!",
|
||||
"page_not_found": "Страница не найдена"
|
||||
"cannot_copy": "Не удалось скопировать!",
|
||||
"page_not_found": "Страница не найдена",
|
||||
"local_storage": "Это действие требует разрешения localStorage, включены ли cookie-файлы?",
|
||||
"register_no_email_note": "Использование электронной почты в качестве имени пользователя не рекомендуется. Продолжить?"
|
||||
}
|
||||
}
|
||||
|
|
186
src/locales/si.json
Normal file
186
src/locales/si.json
Normal file
|
@ -0,0 +1,186 @@
|
|||
{
|
||||
"titles": {
|
||||
"trending": "නැගී එන",
|
||||
"login": "ඇතුළු වන්න",
|
||||
"register": "ලියාපදිංචි වන්න",
|
||||
"preferences": "සැකසුම්",
|
||||
"history": "ඉතිහාසය",
|
||||
"subscriptions": "දායකත්ව",
|
||||
"account": "ගිණුම",
|
||||
"player": "වාදකය",
|
||||
"livestreams": "සජීවී ප්රවාහ",
|
||||
"channels": "නාලිකා",
|
||||
"playlists": "වාදන ලැයිස්තු",
|
||||
"instance": "සේවාදායකය",
|
||||
"bookmarks": "පොත් සලකුණු",
|
||||
"feed": "නවතම"
|
||||
},
|
||||
"actions": {
|
||||
"subscribe": "දායකවන්න - {count}",
|
||||
"unsubscribe": "දායක නොවන්න - {count}",
|
||||
"most_recent": "නවතම",
|
||||
"least_recent": "පැරණිතම",
|
||||
"channel_name_asc": "නාලිකාවේ නම (A-Z)",
|
||||
"channel_name_desc": "නාලිකාවේ නම (Z-A)",
|
||||
"back": "ආපසු",
|
||||
"skip_sponsors": "අනුග්රහ මඟ හරින්න",
|
||||
"skip_outro": "අවසන් කාඩ්පත/දායක ලැයිස්තුව මඟ හරින්න",
|
||||
"skip_preview": "පෙරදසුන/සාරාංශය මඟ හරින්න",
|
||||
"skip_self_promo": "නොගෙවූ/ස්වයං ප්රවර්ධන මඟ හරින්න",
|
||||
"skip_filler_tangent": "අදාළ නොවන කොටස් මඟහරින්න",
|
||||
"theme": "පෙනුම",
|
||||
"dark": "අඳුරු",
|
||||
"light": "එළිය",
|
||||
"autoplay_video": "ස්වයංක්රීයව වීඩියෝව වාදනය කරන්න",
|
||||
"auto": "ස්වයං තේරීම",
|
||||
"default_quality": "පෙරනිමි ගුණත්වය",
|
||||
"default_homepage": "පෙරනිමි මුල් පිටුව",
|
||||
"show_markers": "වාදකයේ මාකර් පෙන්වන්න",
|
||||
"buffering_goal": "බෆරින් ඉලක්කය (තත්පර වලින්)",
|
||||
"enable_sponsorblock": "Sponsorblock සබල කරන්න",
|
||||
"sort_by": "තේරීම:",
|
||||
"skip_highlight": "ඉස්මතු කිරීම් මඟ හරින්න",
|
||||
"language_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": "අදහස් පෙන්වන්න",
|
||||
"minimize_description": "විස්තරය සඟවන්න",
|
||||
"show_description": "විස්තරය පෙන්වන්න",
|
||||
"minimize_recommendations": "නිර්දේශ සඟවන්න",
|
||||
"show_recommendations": "නිර්දේශ පෙන්වන්න",
|
||||
"store_watch_history": "නැරඹීමේ ඉතිහාසය ගබඩා කරන්න",
|
||||
"enabled_codecs": "සබල කර ඇති කෝඩෙක්ස් (බහු)",
|
||||
"minimize_description_default": "පෙරනිමියෙන් විස්තරය සඟවන්න",
|
||||
"instances_list": "සේවාදායක ලැයිස්තුව",
|
||||
"instance_selection": "සේවාදායකය තේරීම",
|
||||
"view_ssl_score": "SSL ලකුණු බලන්න",
|
||||
"search": "සොයන්න (Ctrl+K)",
|
||||
"loading": "පූරණය වෙමින්...",
|
||||
"hide_replies": "පිළිතුරු සඟවන්න",
|
||||
"load_more_replies": "තවත් පිළිතුරු පූරණය කරන්න",
|
||||
"add_to_playlist": "වාදන ලැයිස්තුවට එක් කරන්න",
|
||||
"create_playlist": "වාදන ලැයිස්තුව සාදන්න",
|
||||
"delete_playlist": "වාදන ලැයිස්තුව මකන්න",
|
||||
"select_playlist": "වාදන ලැයිස්තුවක් තෝරන්න",
|
||||
"please_select_playlist": "කරුණාකර වාදන ලැයිස්තුවක් තෝරන්න",
|
||||
"delete_account": "ගිණුම මකන්න",
|
||||
"logout": "මෙම උපාංගයෙන් වරනය වන්න",
|
||||
"minimize_recommendations_default": "පෙරනිමියෙන් නිර්දේශ සඟවන්න",
|
||||
"invalidate_session": "සියලුම උපාංග වලින් වරනය වන්න",
|
||||
"clone_playlist": "වාදන ලැයිස්තුව ක්ලෝනය කරන්න",
|
||||
"download_as_txt": ".txt ලෙස බාගන්න",
|
||||
"reset_preferences": "සැකසුම් නැවත සකසන්න",
|
||||
"backup_preferences": "සැකසුම් උපස්ථ කරන්න",
|
||||
"restore_preferences": "සැකසුම් නැවත පිහිටුවන්න",
|
||||
"back_to_home": "ආපසු මුල් පිටුවට",
|
||||
"rename_playlist": "වාදන ලැයිස්තුව නැවත නම් කරන්න",
|
||||
"share": "බෙදාගන්න",
|
||||
"with_timecode": "කාල කේතය සමඟ බෙදා ගන්න",
|
||||
"piped_link": "පයිප්ඩ් සබැඳිය",
|
||||
"copy_link": "සබැඳිය පිටපත් කරන්න",
|
||||
"time_code": "කාල කේතය (තත්පර වලින්)",
|
||||
"show_chapters": "පරිච්ඡේද",
|
||||
"status_page": "තත්ත්වය",
|
||||
"source_code": "ප්රභව කේතය",
|
||||
"documentation": "ප්රලේඛනය",
|
||||
"reply_count": "පිළිතුරු {count}",
|
||||
"with_playlist": "වාදන ලැයිස්තුව සමඟ බෙදා ගන්න",
|
||||
"bookmark_playlist": "පොත් සලකුණ",
|
||||
"show_watch_on_youtube": "YouTube එකේ නරඹන්න බොත්තම පෙන්වන්න",
|
||||
"filter": "පෙරහන",
|
||||
"instance_donations": "සේවාදායක පරිත්යාග",
|
||||
"instance_auth_selection": "සත්යතාව තහවුරු කිරීම සඳහා සේවාදායකයක් තේරීම",
|
||||
"view_subscriptions": "දායකත්ව බලන්න",
|
||||
"uses_api_from": "මොවුන්ගේ API භාවිතා වේ ",
|
||||
"skip_intro": "විරාම/හඳුන්වාදීමේ සජීවිකරණය මඟ හරින්න",
|
||||
"skip_interaction": "අන්තර් ක්රියා මතක් කිරීම මඟ හරින්න (දායක වන්න)",
|
||||
"skip_non_music": "ගීත: ගීතය නොවන කොටස මඟ හරින්න",
|
||||
"remove_from_playlist": "වාදන ලැයිස්තුවෙන් ඉවත් කරන්න",
|
||||
"audio_only": "ශ්රව්ය පමණක්",
|
||||
"country_selection": "රට තේරීම",
|
||||
"minimize_comments_default": "පෙරනිමියෙන් අදහස් සඟවන්න",
|
||||
"clear_history": "ඉතිහාසය හිස් කරන්න",
|
||||
"disable_lbry": "ප්රවාහය සඳහා LBRY අබල කරන්න",
|
||||
"delete_playlist_video_confirm": "වාදන ලැයිස්තුවෙන් වීඩියෝව ඉවත් කරන්නද?",
|
||||
"delete_playlist_confirm": "මෙම වාදන ලැයිස්තුව මකන්නද?",
|
||||
"minimize_chapters_default": "පෙරනිමියෙන් පරිච්ඡේද සඟවන්න",
|
||||
"clone_playlist_success": "සාර්ථකව ක්ලෝන කරන ලදී!",
|
||||
"confirm_reset_preferences": "ඔබට ඔබේ සැකසුම් යළි සැකසීමට අවශ්ය බව විශ්වාසද?",
|
||||
"new_playlist_name": "නව වාදන ලැයිස්තුවේ නම",
|
||||
"follow_link": "සබැඳිය අනුගමනය කරන්න",
|
||||
"store_search_history": "සෙවුම් ඉතිහාසය ගබඩා කරන්න",
|
||||
"no_valid_playlists": "ගොනුවේ වලංගු වාදන ලැයිස්තු අඩංගු නොවේ!",
|
||||
"playlist_bookmarked": "පොත් සලකුණු කර ඇත",
|
||||
"enable_lbry_proxy": "LBRY සඳහා Proxy සබල කරන්න",
|
||||
"different_auth_instance": "සත්යතාව තහවුරු කිරීම සඳහා වෙනත් සේවාදායකයක් භාවිතා කරන්න",
|
||||
"hide_watched": "නවතම කොටසෙහි නැරඹූ වීඩියෝ සඟවන්න",
|
||||
"skip_button_only": "මඟ හරින්න බොත්තම පෙන්වන්න",
|
||||
"skip_automatically": "ස්වයංක්රීයව",
|
||||
"skip_segment": "කොටස මඟ හරින්න",
|
||||
"min_segment_length": "අවම කොටස් දිග (තත්පර වලින්)",
|
||||
"show_less": "අඩුවෙන් පෙන්වන්න"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0} එකේ නරඹන්න"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "{author} විසින් අමුණන ලදී",
|
||||
"loading": "අදහස් පූරණය වෙමින්...",
|
||||
"disabled": "උඩුගත කරන්නා විසින් අදහස් අබල කර ඇත.",
|
||||
"user_disabled": "සැකසුම් තුළ අදහස් අබල කර ඇත."
|
||||
},
|
||||
"preferences": {
|
||||
"has_cdn": "CDN තිබේද?",
|
||||
"version": "නිකුතු අංකය",
|
||||
"up_to_date": "යාවත්කාලීනද?",
|
||||
"instance_name": "සේවාදායකයේ නම",
|
||||
"registered_users": "ලියාපදිංචි පරිශීලකයන්",
|
||||
"ssl_score": "SSL ලකුණු",
|
||||
"instance_locations": "සේවාදායක ස්ථාන"
|
||||
},
|
||||
"login": {
|
||||
"username": "පරිශීලක නාමය",
|
||||
"password": "මුරපදය"
|
||||
},
|
||||
"video": {
|
||||
"videos": "වීඩියෝ",
|
||||
"views": "බැලීම් {views}",
|
||||
"watched": "නැරඹුවා",
|
||||
"sponsor_segments": "අනුග්රාහක අංශ",
|
||||
"chapters": "පරිච්ඡේද",
|
||||
"shorts": "කෙටි වීඩියෝ",
|
||||
"ratings_disabled": "ශ්රේණිගත කිරීම් අබල කර ඇත",
|
||||
"live": "{0} සජීවී",
|
||||
"all": "සියල්ල",
|
||||
"category": "කාණ්ඩය"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "ඔබ අදහස් කළේ: {0}?",
|
||||
"videos": "YouTube: වීඩියෝ",
|
||||
"playlists": "YouTube: වාදන ලැයිස්තු",
|
||||
"music_songs": "YT Music: ගීත",
|
||||
"music_videos": "YT Music: වීඩියෝ",
|
||||
"music_albums": "YT Music: ඇල්බම",
|
||||
"music_playlists": "YT Music: වාදන ලැයිස්තු",
|
||||
"channels": "YouTube: නාලිකා",
|
||||
"all": "YouTube: සියල්ල"
|
||||
},
|
||||
"info": {
|
||||
"page_not_found": "පිටුව හමු නොවීය",
|
||||
"copied": "පිටපත් කළා!",
|
||||
"cannot_copy": "පිටපත් කළ නොහැක!",
|
||||
"local_storage": "මෙම ක්රියාවට localStorage අවශ්ය වේ, cookies සබල කර තිබේද?",
|
||||
"register_no_email_note": "පරිශීලක නාමය ලෙස විද්යුත් තැපෑලක් භාවිතා කිරීම නිර්දේශ නොකරයි. කෙසේ හෝ ඉදිරියට යන්නද?",
|
||||
"preferences_note": "සටහන: සැකසුම් ඔබගේ බ්රවුසරයේ දේශීය ගබඩාවේ සුරකිනු ලැබේ. ඔබගේ බ්රවුසර දත්ත මැකීමෙන් ඒවා නැවත සකසනු ඇත."
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "දායක වූයේ: {0}"
|
||||
}
|
||||
}
|
|
@ -7,7 +7,9 @@
|
|||
"ratings_disabled": "Оцене су онемогућене",
|
||||
"chapters": "Поглавља",
|
||||
"live": "{0} Уживо",
|
||||
"shorts": "Kratki video snimci"
|
||||
"shorts": "Кратки видео снимци",
|
||||
"all": "Све",
|
||||
"category": "Категорија"
|
||||
},
|
||||
"actions": {
|
||||
"view_ssl_score": "Погледај SSL скор/оцену",
|
||||
|
@ -76,7 +78,7 @@
|
|||
"add_to_playlist": "Додај у попис снимака",
|
||||
"delete_playlist_confirm": "Избрисати овај попис снимака?",
|
||||
"please_select_playlist": "Молим вас одаберите попис снимака",
|
||||
"show_markers": "Prikaži obeleživače na plejeru",
|
||||
"show_markers": "Прикажи обиљеживаче на покретнику",
|
||||
"delete_account": "Обриши налог",
|
||||
"logout": "Одјава са овог уређаја",
|
||||
"minimize_recommendations_default": "Умањи Препоруке као Подразумевано",
|
||||
|
@ -108,7 +110,18 @@
|
|||
"new_playlist_name": "Ново име плејлисте",
|
||||
"minimize_comments_default": "Подразумевано умањи коментаре",
|
||||
"minimize_comments": "Умањи коментаре",
|
||||
"reply_count": "{count} одговора"
|
||||
"reply_count": "{count} одговора",
|
||||
"minimize_chapters_default": "Умањи поглавља подразумевано",
|
||||
"show_watch_on_youtube": "Прикажите \"Гредај на YouTube-у\" дугме",
|
||||
"no_valid_playlists": "Датотека не садржи важеће пописе снимака!",
|
||||
"with_playlist": "Делите са пописом снимака",
|
||||
"playlist_bookmarked": "Обиљежено",
|
||||
"bookmark_playlist": "Биљежак",
|
||||
"show_less": "Прикажи мање",
|
||||
"skip_button_only": "Прикажи дугме за прескакање",
|
||||
"skip_automatically": "Аутоматски",
|
||||
"min_segment_length": "Најмања дужина сегмента (у секундама)",
|
||||
"skip_segment": "Прескочи сегмент"
|
||||
},
|
||||
"preferences": {
|
||||
"instance_locations": "Локација инстанце",
|
||||
|
@ -145,11 +158,14 @@
|
|||
"playlists": "Пописи Снимака",
|
||||
"account": "Рачун",
|
||||
"instance": "Инстанца",
|
||||
"player": "Плејер"
|
||||
"player": "Покретник",
|
||||
"livestreams": "Уживо преноси",
|
||||
"channels": "Канали",
|
||||
"bookmarks": "Биљешци"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Закачено од {author}",
|
||||
"disabled": "Отпремалац је онемогућио коментаре.",
|
||||
"disabled": "Преносник је онемогућио коментаре.",
|
||||
"user_disabled": "Коментари су онемогућени у подешавањима.",
|
||||
"loading": "Учитавање коментара..."
|
||||
},
|
||||
|
@ -163,6 +179,8 @@
|
|||
"page_not_found": "Страница није пронађена",
|
||||
"copied": "Копирано!",
|
||||
"cannot_copy": "Није могуће копирати!",
|
||||
"preferences_note": "Напомена: подешавања се чувају у локалној меморији вашег претраживача. Брисање података прегледача ће их ресетовати."
|
||||
"preferences_note": "Напомена: подешавања се чувају у локалној меморији вашег претраживача. Брисање података прегледача ће их ресетовати.",
|
||||
"local_storage": "Ова радња захтева локално складиште, да ли су колачићи омогућени ?",
|
||||
"register_no_email_note": "Коришћење е-поруке као корисничког имена се не препоручује. Желите ли ипак наставити?"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,5 +142,8 @@
|
|||
},
|
||||
"information": {
|
||||
"preferences_note": "Observera: inställningar sparas i webbläsarens lokala lagring. Om du raderar dina webbläsardata återställs de."
|
||||
},
|
||||
"info": {
|
||||
"register_no_email_note": "Det rekommenderas inte att använda e-post som användarnamn. Fortsätt ändå?"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"show_comments": "Yorumları Göster",
|
||||
"default_homepage": "Öntanımlı Ana Sayfa",
|
||||
"country_selection": "Ülke Seçimi",
|
||||
"buffering_goal": "Arabelleğe Alma Hedefi (saniye cinsinden)",
|
||||
"buffering_goal": "Arabelleğe Alma Hedefi (Saniye Cinsinden)",
|
||||
"default_quality": "Öntanımlı Kalite",
|
||||
"audio_only": "Yalnızca Ses",
|
||||
"autoplay_video": "Videoyu Otomatik Oynat",
|
||||
|
@ -31,25 +31,25 @@
|
|||
"most_recent": "En Yeni",
|
||||
"sort_by": "Sıralama ölçütü:",
|
||||
"view_subscriptions": "Abonelikleri Görüntüle",
|
||||
"unsubscribe": "Abonelikten çık - {count}",
|
||||
"subscribe": "Abone ol - {count}",
|
||||
"unsubscribe": "Abonelikten Çık - {count}",
|
||||
"subscribe": "Abone Ol - {count}",
|
||||
"enabled_codecs": "Etkin Çözücüler (Birden Çok)",
|
||||
"enable_lbry_proxy": "LBRY için Vekil Sunucuyu Etkinleştir",
|
||||
"disable_lbry": "Akış için LBRY'yi Devre Dışı Bırak",
|
||||
"show_description": "Açıklamayı Göster",
|
||||
"minimize_description": "Açıklamayı Küçült",
|
||||
"donations": "Geliştirme bağışları",
|
||||
"donations": "Geliştirme Bağışları",
|
||||
"auto_play_next_video": "Sonraki Videoyu Otomatik Oynat",
|
||||
"loop_this_video": "Bu Videoyu Döngüye Al",
|
||||
"import_from_json": "JSON/CSV dosyasından içe aktar",
|
||||
"import_from_json": "JSON/CSV Dosyasından İçe Aktar",
|
||||
"export_to_json": "JSON Olarak Dışa Aktar",
|
||||
"no": "Hayır",
|
||||
"yes": "Evet",
|
||||
"show_more": "Daha Fazla Göster",
|
||||
"show_more": "Daha fazla göster",
|
||||
"instance_selection": "Örnek Seçimi",
|
||||
"loading": "Yükleniyor...",
|
||||
"filter": "Filtrele",
|
||||
"search": "Ara",
|
||||
"search": "Ara (Ctrl+K)",
|
||||
"view_ssl_score": "SSL Puanını Görüntüle",
|
||||
"minimize_recommendations": "Önerileri Küçült",
|
||||
"show_recommendations": "Önerileri Göster",
|
||||
|
@ -60,55 +60,67 @@
|
|||
"skip_filler_tangent": "Doldurma Sahnelerini Atla",
|
||||
"delete_playlist_confirm": "Bu oynatma listesi silinsin mi?",
|
||||
"delete_playlist_video_confirm": "Video oynatma listesinden kaldırılsın mı?",
|
||||
"remove_from_playlist": "Oynatma listesinden kaldır",
|
||||
"remove_from_playlist": "Oynatma Listesinden Kaldır",
|
||||
"delete_playlist": "Oynatma Listesini Sil",
|
||||
"add_to_playlist": "Oynatma listesine ekle",
|
||||
"add_to_playlist": "Oynatma Listesine Ekle",
|
||||
"create_playlist": "Oynatma Listesi Oluştur",
|
||||
"select_playlist": "Oynatma Listesi Seç",
|
||||
"please_select_playlist": "Lütfen bir oynatma listesi seçin",
|
||||
"please_select_playlist": "Lütfen Bir Oynatma Listesi Seçin",
|
||||
"show_markers": "Oynatıcıda İşaretçileri Göster",
|
||||
"delete_account": "Hesabı Sil",
|
||||
"logout": "Bu aygıttan oturumu kapat",
|
||||
"logout": "Bu Aygıttan Oturumu Kapat",
|
||||
"minimize_recommendations_default": "Önerileri Öntanımlı Olarak Küçült",
|
||||
"different_auth_instance": "Kimlik doğrulama için farklı bir örnek kullan",
|
||||
"invalidate_session": "Tüm aygıtlardan oturumu kapat",
|
||||
"different_auth_instance": "Kimlik Doğrulama İçin Farklı Bir Örnek Kullan",
|
||||
"invalidate_session": "Tüm Aygıtlardan Oturumu Kapat",
|
||||
"instance_auth_selection": "Kimlik Doğrulama Örneği Seçimi",
|
||||
"clone_playlist": "Oynatma Listesini Kopyala",
|
||||
"clone_playlist_success": "Başarıyla kopyalandı!",
|
||||
"download_as_txt": ".txt olarak indir",
|
||||
"reset_preferences": "Tercihleri sıfırla",
|
||||
"download_as_txt": ".txt Olarak İndir",
|
||||
"reset_preferences": "Tercihleri Sıfırla",
|
||||
"confirm_reset_preferences": "Tercihlerinizi sıfırlamak istediğinize emin misiniz?",
|
||||
"backup_preferences": "Tercihleri yedekle",
|
||||
"restore_preferences": "Tercihleri geri yükle",
|
||||
"back_to_home": "Ana sayfaya dön",
|
||||
"follow_link": "Bağlantıyı takip et",
|
||||
"copy_link": "Bağlantıyı kopyala",
|
||||
"time_code": "Zaman kodu (saniye cinsinden)",
|
||||
"with_timecode": "Zaman koduyla paylaş",
|
||||
"piped_link": "Piped bağlantısı",
|
||||
"backup_preferences": "Tercihleri Yedekle",
|
||||
"restore_preferences": "Tercihleri Geri Yükle",
|
||||
"back_to_home": "Ana Sayfaya Dön",
|
||||
"follow_link": "Bağlantıyı Takip Et",
|
||||
"copy_link": "Bağlantıyı Kopyala",
|
||||
"time_code": "Zaman Kodu (Saniye Cinsinden)",
|
||||
"with_timecode": "Zaman Koduyla Paylaş",
|
||||
"piped_link": "Piped Bağlantısı",
|
||||
"share": "Paylaş",
|
||||
"rename_playlist": "Oynatma listesini yeniden adlandır",
|
||||
"new_playlist_name": "Yeni oynatma listesi adı",
|
||||
"rename_playlist": "Oynatma Listesini Yeniden Adlandır",
|
||||
"new_playlist_name": "Yeni Oynatma Listesi Adı",
|
||||
"show_chapters": "Bölümler",
|
||||
"store_search_history": "Arama geçmişini sakla",
|
||||
"hide_watched": "Akışta izlenen videoları gizle",
|
||||
"source_code": "Kaynak kodu",
|
||||
"store_search_history": "Arama Geçmişini Sakla",
|
||||
"hide_watched": "Akışta İzlenen Videoları Gizle",
|
||||
"source_code": "Kaynak Kodu",
|
||||
"documentation": "Belgelendirme",
|
||||
"instance_donations": "Örnek bağışları",
|
||||
"instance_donations": "Örnek Bağışları",
|
||||
"status_page": "Durum",
|
||||
"reply_count": "{count} yanıt",
|
||||
"reply_count": "{count} Yanıt",
|
||||
"minimize_comments": "Yorumları Küçült",
|
||||
"minimize_comments_default": "Yorumları Öntanımlı Olarak Küçült",
|
||||
"show_watch_on_youtube": "YouTube'da İzle düğmesini göster"
|
||||
"show_watch_on_youtube": "YouTube'da İzle Düğmesini Göster",
|
||||
"minimize_chapters_default": "Bölümleri Öntanımlı Olarak Küçült",
|
||||
"no_valid_playlists": "Dosya geçerli oynatma listeleri içermiyor!",
|
||||
"with_playlist": "Oynatma listesiyle paylaş",
|
||||
"bookmark_playlist": "Yer imlerine ekle",
|
||||
"playlist_bookmarked": "Yer imlerine eklendi",
|
||||
"min_segment_length": "En Küçük Bölüm Uzunluğu (saniye cinsinden)",
|
||||
"skip_segment": "Bölümü Atla",
|
||||
"skip_button_only": "Atla düğmesini göster",
|
||||
"skip_automatically": "Otomatik olarak",
|
||||
"show_less": "Daha az göster",
|
||||
"dismiss": "Kapat",
|
||||
"autoplay_next_countdown": "Bir sonraki videoya kadar öntanımlı geri sayım (saniye cinsinden)"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "{0} üzerinde izle"
|
||||
"watch_on": "{0} Üzerinde İzle"
|
||||
},
|
||||
"titles": {
|
||||
"history": "Geçmiş",
|
||||
"preferences": "Tercihler",
|
||||
"feed": "Akış",
|
||||
"register": "Kaydol",
|
||||
"register": "Kayıt Ol",
|
||||
"login": "Oturum Aç",
|
||||
"trending": "Öne Çıkanlar",
|
||||
"subscriptions": "Abonelikler",
|
||||
|
@ -117,17 +129,20 @@
|
|||
"instance": "Örnek",
|
||||
"player": "Oynatıcı",
|
||||
"livestreams": "Canlı Yayınlar",
|
||||
"channels": "Kanallar"
|
||||
"channels": "Kanallar",
|
||||
"bookmarks": "Yer İmleri"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "Sponsorlar Bölümleri",
|
||||
"watched": "İzlendi",
|
||||
"views": "{views} izlenme",
|
||||
"videos": "Videolar",
|
||||
"views": "{views} İzlenme",
|
||||
"videos": "Video",
|
||||
"ratings_disabled": "Derecelendirmeler Devre Dışı",
|
||||
"chapters": "Bölümler",
|
||||
"live": "{0} Canlı",
|
||||
"shorts": "Kısa çekimler"
|
||||
"shorts": "Kısa çekimler",
|
||||
"all": "Tümü",
|
||||
"category": "Kategori"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "SSL Puanı",
|
||||
|
@ -136,17 +151,17 @@
|
|||
"instance_name": "Örnek Adı",
|
||||
"registered_users": "Kayıtlı Kullanıcılar",
|
||||
"version": "Sürüm",
|
||||
"up_to_date": "Güncel mi?"
|
||||
"up_to_date": "Güncel Mi?"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Şunun tarafından sabitlendi {author}",
|
||||
"pinned_by": "Şunun Tarafından Sabitlendi {author}",
|
||||
"loading": "Yorumlar yükleniyor...",
|
||||
"user_disabled": "Yorumlar ayarlarda devre dışı bırakıldı.",
|
||||
"disabled": "Yorumlar yükleyen tarafından devre dışı bırakıldı."
|
||||
},
|
||||
"login": {
|
||||
"password": "Parola",
|
||||
"username": "Kullanıcı adı"
|
||||
"username": "Kullanıcı Adı"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Bunu mu demek istediniz: {0}?",
|
||||
|
@ -160,15 +175,18 @@
|
|||
"music_albums": "YT Müzik: Albümler"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Abone olunan: {0}"
|
||||
"subscribed_channels_count": "Abone Olunan: {0}"
|
||||
},
|
||||
"information": {
|
||||
"preferences_note": "Not: Tercihler tarayıcınızın yerel depolama alanına kaydedilir. Tarayıcı verilerinizi silmek onları sıfırlayacaktır."
|
||||
},
|
||||
"info": {
|
||||
"preferences_note": "Not: Tercihler tarayıcınızın yerel depolama alanına kaydedilir. Tarayıcı verilerinizi silmek onları sıfırlayacaktır.",
|
||||
"page_not_found": "Sayfa bulunamadı",
|
||||
"page_not_found": "Sayfa Bulunamadı",
|
||||
"copied": "Kopyalandı!",
|
||||
"cannot_copy": "Kopyalanamıyor!"
|
||||
"cannot_copy": "Kopyalanamıyor!",
|
||||
"local_storage": "Bu eylem yerel depolama gerektirir, çerezler etkin mi?",
|
||||
"register_no_email_note": "Kullanıcı adı olarak e-posta kullanılması tavsiye edilmez. Yine de devam edilsin mi?",
|
||||
"next_video_countdown": "Sonraki video {0}s içinde oynatılıyor"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,98 +3,153 @@
|
|||
"watch_on": "Дивитися на {0}"
|
||||
},
|
||||
"login": {
|
||||
"username": "Назва аккаунта Piped",
|
||||
"username": "Ім'я користувача",
|
||||
"password": "Пароль"
|
||||
},
|
||||
"actions": {
|
||||
"unsubscribe": "Відписатись - {count}",
|
||||
"unsubscribe": "Відписатися - {count}",
|
||||
"back": "Назад",
|
||||
"skip_intro": "Пропускати заставку/інтро",
|
||||
"skip_intro": "Пропускати паузу/заставку",
|
||||
"dark": "Темна",
|
||||
"view_subscriptions": "Продивитися підписки",
|
||||
"channel_name_asc": "Назва каналу (A-Z)",
|
||||
"uses_api_from": "Використовувати API з ",
|
||||
"view_subscriptions": "Переглянути Підписки",
|
||||
"channel_name_asc": "Назвою каналу (А-Я)",
|
||||
"uses_api_from": "Використовує API від ",
|
||||
"enable_sponsorblock": "Увімкнути Sponsorblock",
|
||||
"skip_outro": "Пропускати кінцівку/титри",
|
||||
"skip_preview": "Пропускати короткий вміст поточного епізода або повтор частини минулого",
|
||||
"skip_self_promo": "Пропускати саморекламу",
|
||||
"autoplay_video": "Автоматичний програш відео",
|
||||
"audio_only": "Лише звук",
|
||||
"default_homepage": "За замовчуванням відкривати",
|
||||
"show_comments": "Показувати коментарі",
|
||||
"store_watch_history": "Зберігати історию переглянутих відео",
|
||||
"skip_outro": "Пропускати кінцеву заставку/титри",
|
||||
"skip_preview": "Пропускати попередній перегляд/короткий зміст",
|
||||
"skip_self_promo": "Пропускати саморекламу/рекомендацію",
|
||||
"autoplay_video": "Автоматичне відтворення відео",
|
||||
"audio_only": "Лише аудіо",
|
||||
"default_homepage": "Домашня сторінка за замовчуванням",
|
||||
"show_comments": "Показати коментарі",
|
||||
"store_watch_history": "Зберігати історію перегляду",
|
||||
"language_selection": "Вибір мови",
|
||||
"instance_selection": "Вибір копії сервіса Piped",
|
||||
"instance_selection": "Вибір екземпляра",
|
||||
"show_more": "Показати більше",
|
||||
"no": "Ні",
|
||||
"export_to_json": "Експорт в JSON",
|
||||
"export_to_json": "Експортувати в JSON",
|
||||
"minimize_description": "Згорнути опис",
|
||||
"show_recommendations": "Показати рекомендації",
|
||||
"enable_lbry_proxy": "Проксувати відео з LBRY",
|
||||
"search": "Пошук",
|
||||
"enable_lbry_proxy": "Увімкнути проксі для LBRY",
|
||||
"search": "Пошук (Ctrl+K)",
|
||||
"clear_history": "Очистити історію перегляду",
|
||||
"load_more_replies": "Завантажити більше відповідей",
|
||||
"subscribe": "Підписатись - {count}",
|
||||
"sort_by": "Відсортувати по:",
|
||||
"most_recent": "Найновіші",
|
||||
"channel_name_desc": "Назва каналу (Z-A)",
|
||||
"least_recent": "Найстарші",
|
||||
"subscribe": "Підписатися - {count}",
|
||||
"sort_by": "Сортувати за:",
|
||||
"most_recent": "Найновішими",
|
||||
"channel_name_desc": "Назвою каналу (Я-А)",
|
||||
"least_recent": "Найстарішими",
|
||||
"minimize_recommendations": "Згорнути рекомендації",
|
||||
"skip_sponsors": "Пропускати спонсорську рекламу",
|
||||
"skip_interaction": "Пропускати прохання підписатися",
|
||||
"skip_non_music": "Пропускати тишу в музикальних відео",
|
||||
"skip_interaction": "Пропускати нагадування про взаємодію (підписка)",
|
||||
"skip_non_music": "Пропускати сегменти без музики в музикальних відео",
|
||||
"theme": "Тема",
|
||||
"auto": "Авто",
|
||||
"light": "Світла",
|
||||
"buffering_goal": "Розмір буфера відео (в секундах)",
|
||||
"instances_list": "Список копій сервіса Piped",
|
||||
"enabled_codecs": "Увімкнені кодеки (Можно вибрати декілька)",
|
||||
"buffering_goal": "Розмір буфера відео (у секундах)",
|
||||
"instances_list": "Список екземплярів",
|
||||
"enabled_codecs": "Увімкнені кодеки (можна вибрати декілька)",
|
||||
"default_quality": "Якість за замовчуванням",
|
||||
"country_selection": "Вибір країни (для трендів)",
|
||||
"minimize_description_default": "Не розгортати опис за замовчуванням",
|
||||
"yes": "Так",
|
||||
"import_from_json": "Імпорт з JSON/CSV",
|
||||
"loop_this_video": "Повтор поточного відео",
|
||||
"auto_play_next_video": "Одразу програвати наступне рекомендоване відео",
|
||||
"donations": "Пожертвування",
|
||||
"import_from_json": "Імпортувати з JSON/CSV",
|
||||
"loop_this_video": "Зациклити це відео",
|
||||
"auto_play_next_video": "Автоматичне відтворення наступного відео",
|
||||
"donations": "Пожертвування на розробку",
|
||||
"show_description": "Показати опис",
|
||||
"disable_lbry": "Вимкнути LBRY для стримінгу",
|
||||
"filter": "Фільтр",
|
||||
"view_ssl_score": "Продивитися оцінку SSL",
|
||||
"view_ssl_score": "Переглянути оцінку SSL",
|
||||
"loading": "Завантаження...",
|
||||
"hide_replies": "Сховати відповіді",
|
||||
"skip_highlight": "Пропустити Хайлайт",
|
||||
"remove_from_playlist": "Видалити з плейлісту",
|
||||
"add_to_playlist": "Додати до плейлісту",
|
||||
"create_playlist": "Створити Плейліст",
|
||||
"delete_playlist_confirm": "Чи ви певні що хочете видалити цей плейліст?",
|
||||
"skip_filler_tangent": "Пропускати Нерелевантне",
|
||||
"delete_playlist_video_confirm": "Чи певні ви що хочете видалити це відео з плейлісту?",
|
||||
"delete_playlist": "Видалити Плейліст",
|
||||
"select_playlist": "Вибрати Плейліст",
|
||||
"please_select_playlist": "Будь ласка виберіть плейліст"
|
||||
"skip_highlight": "Пропускати основне",
|
||||
"remove_from_playlist": "Видалити зі списку відтворення",
|
||||
"add_to_playlist": "Додати до списку відтворення",
|
||||
"create_playlist": "Створити список відтворення",
|
||||
"delete_playlist_confirm": "Видалити цей список відтворення?",
|
||||
"skip_filler_tangent": "Пропускати дотичне наповнення/жарти",
|
||||
"delete_playlist_video_confirm": "Видалити відео зі списку відтворення?",
|
||||
"delete_playlist": "Видалити список відтворення",
|
||||
"select_playlist": "Вибрати список відтворення",
|
||||
"please_select_playlist": "Будь ласка, виберіть список відтворення",
|
||||
"confirm_reset_preferences": "Ви впевнені, що бажаєте скинути свої налаштування?",
|
||||
"show_markers": "Показувати маркери на Програвачі",
|
||||
"minimize_recommendations_default": "Згортати рекомендації за замовчуванням",
|
||||
"logout": "Вийти з цього пристрою",
|
||||
"backup_preferences": "Налаштування резервного копіювання",
|
||||
"download_as_txt": "Завантажити як .txt",
|
||||
"rename_playlist": "Перейменувати список відтворення",
|
||||
"show_chapters": "Розділи",
|
||||
"invalidate_session": "Вийти з усіх пристроїв",
|
||||
"clone_playlist": "Клонувати список відтворення",
|
||||
"reset_preferences": "Скинути налаштування",
|
||||
"back_to_home": "Повернутися на головну",
|
||||
"share": "Поділитися",
|
||||
"with_timecode": "Поділитися з відміткою часу",
|
||||
"piped_link": "Посилання Piped",
|
||||
"follow_link": "Перейти за посиланням",
|
||||
"instance_donations": "Пожертвування екземпляра",
|
||||
"copy_link": "Копіювати посилання",
|
||||
"store_search_history": "Зберігати історію пошуку",
|
||||
"documentation": "Документація",
|
||||
"instance_auth_selection": "Вибір екземпляра для автентифікації",
|
||||
"minimize_chapters_default": "Згортати розділи за замовчуванням",
|
||||
"show_watch_on_youtube": "Показати кнопку Дивитися на YouTube",
|
||||
"restore_preferences": "Відновити налаштування",
|
||||
"different_auth_instance": "Використовувати інший екземпляр для автентифікації",
|
||||
"clone_playlist_success": "Успішно клоновано!",
|
||||
"hide_watched": "Сховати переглянуті відео в стрічці",
|
||||
"status_page": "Статус",
|
||||
"source_code": "Вихідний код",
|
||||
"new_playlist_name": "Нова назва списку відтворення",
|
||||
"time_code": "Відмітка часу (у секундах)",
|
||||
"reply_count": "{count} відповідей",
|
||||
"minimize_comments_default": "Згортати коментарі за замовчуванням",
|
||||
"minimize_comments": "Згорнути коментарі",
|
||||
"delete_account": "Видалити обліковий запис",
|
||||
"no_valid_playlists": "Файл не містить дійсних списків відтворення!",
|
||||
"bookmark_playlist": "Закладка",
|
||||
"playlist_bookmarked": "Додано в закладки",
|
||||
"with_playlist": "Поділитися зі списком відтворення",
|
||||
"skip_button_only": "Показати кнопку пропуску",
|
||||
"skip_segment": "Пропустити сегмент",
|
||||
"skip_automatically": "Автоматично",
|
||||
"min_segment_length": "Мінімальна довжина сегмента (у секундах)",
|
||||
"show_less": "Показати менше",
|
||||
"dismiss": "Відхилити",
|
||||
"autoplay_next_countdown": "Зворотний відлік до наступного відео (у секундах)"
|
||||
},
|
||||
"titles": {
|
||||
"register": "Реєстрація",
|
||||
"feed": "Підписки",
|
||||
"preferences": "Налаштування",
|
||||
"history": "Історія переглядів",
|
||||
"history": "Історія перегляду",
|
||||
"subscriptions": "Канали, на які ви підписані",
|
||||
"trending": "Тренди",
|
||||
"login": "Логін",
|
||||
"playlists": "Плейлісти"
|
||||
"playlists": "Списки відтворення",
|
||||
"instance": "Екземпляр",
|
||||
"player": "Програвач",
|
||||
"account": "Обліковий запис",
|
||||
"livestreams": "Наживо",
|
||||
"channels": "Канали",
|
||||
"bookmarks": "Закладки"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Прикріплено користувачем {author}"
|
||||
"pinned_by": "Прикріплено користувачем {author}",
|
||||
"loading": "Завантаження коментарів...",
|
||||
"disabled": "Коментарі вимкнені автором.",
|
||||
"user_disabled": "Коментарі вимкнені в налаштуваннях."
|
||||
},
|
||||
"preferences": {
|
||||
"instance_locations": "Місцезнаходження копії сервісу",
|
||||
"instance_locations": "Місцезнаходження екземпляру",
|
||||
"ssl_score": "Оцінка SSL",
|
||||
"instance_name": "Назва копії сервісу",
|
||||
"instance_name": "Назва екземпляру",
|
||||
"has_cdn": "Використовує CDN?",
|
||||
"version": "Версія",
|
||||
"up_to_date": "Версія Актуальна?",
|
||||
"registered_users": "Зареєстровано Користувачей"
|
||||
"up_to_date": "Версія актуальна?",
|
||||
"registered_users": "Зареєстровано користувачей"
|
||||
},
|
||||
"video": {
|
||||
"videos": "Відео",
|
||||
|
@ -103,17 +158,32 @@
|
|||
"sponsor_segments": "Рекламні сегменти",
|
||||
"ratings_disabled": "Оцінки вимкнені",
|
||||
"chapters": "Розділи",
|
||||
"live": "{0} Наживо"
|
||||
"live": "{0} Наживо",
|
||||
"shorts": "Shorts",
|
||||
"all": "Усі",
|
||||
"category": "Категорія"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Можливо, ви мали на увазі: {0}?",
|
||||
"music_playlists": "YT Music: Плейлісти",
|
||||
"music_playlists": "YT Music: Списки відтворення",
|
||||
"all": "YouTube: Все",
|
||||
"videos": "YouTube: Відео",
|
||||
"channels": "YouTube: Канали",
|
||||
"music_songs": "YT Music: Пісні",
|
||||
"music_videos": "TY Music: Відео",
|
||||
"playlists": "YouTube: Плейлісти",
|
||||
"playlists": "YouTube: Списки відтворення",
|
||||
"music_albums": "YT Music: Альбоми"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Підписано на: {0}"
|
||||
},
|
||||
"info": {
|
||||
"copied": "Скопійовано!",
|
||||
"cannot_copy": "Не вийшло скопіювати!",
|
||||
"page_not_found": "Сторінка не знайдена",
|
||||
"preferences_note": "Примітка: налаштування зберігаються в локальній пам'яті вашого браузера. Видалення даних браузера призведе до їх скидання.",
|
||||
"local_storage": "Ця дія потребує localStorage, чи ввімкнуті файли cookie?",
|
||||
"register_no_email_note": "Використання електронної пошти як імені користувача не рекомендується. Все одно продовжити?",
|
||||
"next_video_countdown": "Наступне відео через {0} секунд"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
"auto": "Tự động",
|
||||
"buffering_goal": "Bộ nhớ đệm (tính bằng giây)",
|
||||
"least_recent": "Ít nhất gần đây",
|
||||
"skip_intro": "Bỏ qua gián đoạn/Giới thiệu hoạt ảnh",
|
||||
"skip_outro": "Bỏ qua màn hình kết thúc/Tín dụng",
|
||||
"skip_intro": "Bỏ qua gián đoạn/hoạt hình intro",
|
||||
"skip_outro": "Bỏ qua màn hình kết thúc/danh đề",
|
||||
"skip_interaction": "Bỏ qua lời nhắc tương tác (Đăng ký)",
|
||||
"skip_preview": "Bỏ qua xem trước/Tóm tắt",
|
||||
"skip_self_promo": "Bỏ qua thanh toán/Tự quảng cáo",
|
||||
"skip_preview": "Bỏ qua xem trước/tóm tắt",
|
||||
"skip_self_promo": "Bỏ qua thanh toán/quảng cáo cho bản thân",
|
||||
"skip_non_music": "Bỏ qua âm nhạc: Phần không phải âm nhạc",
|
||||
"skip_highlight": "Bỏ qua phần đánh dấu",
|
||||
"skip_filler_tangent": "Bỏ qua những đoạn không liên quan",
|
||||
|
@ -28,7 +28,7 @@
|
|||
"show_comments": "Hiển thị bình luận",
|
||||
"store_watch_history": "Lịch sử xem trên cửa hà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",
|
||||
"import_from_json": "Nhập từ JSON/CSV",
|
||||
"loop_this_video": "Lặp lại video này",
|
||||
|
@ -41,7 +41,7 @@
|
|||
"minimize_recommendations": "Giảm thiểu các đề xuất",
|
||||
"show_recommendations": "Hiển thị các đề xuất",
|
||||
"disable_lbry": "Tắt LBRY để phát trực tuyến",
|
||||
"enable_lbry_proxy": "Bật Proxy cho LBRY",
|
||||
"enable_lbry_proxy": "Bật proxy cho LBRY",
|
||||
"view_ssl_score": "Hiện thị điểm số SSL",
|
||||
"search": "Tìm kiếm",
|
||||
"filter": "Bộ lọc",
|
||||
|
@ -53,34 +53,65 @@
|
|||
"light": "Sáng",
|
||||
"audio_only": "Chỉ có âm thanh",
|
||||
"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ó",
|
||||
"enabled_codecs": "Mã hóa được kích hoạt (Nhiều)",
|
||||
"enabled_codecs": "Các codec được bật (Nhiều)",
|
||||
"export_to_json": "Xuất định dạng JSON",
|
||||
"no": "Không"
|
||||
"no": "Không",
|
||||
"remove_from_playlist": "Xóa khỏi danh sách phát",
|
||||
"add_to_playlist": "Thêm vào danh sách phát",
|
||||
"delete_playlist_video_confirm": "Bạn có chắc là muốn xóa video khỏi danh sách phát này không?",
|
||||
"delete_playlist_confirm": "Bạn có chắc là bạn muốn xóa danh sách phát này không?",
|
||||
"create_playlist": "Tạo danh sách phát",
|
||||
"delete_playlist": "Xóa danh sách phát",
|
||||
"select_playlist": "Chọn một danh sách phát",
|
||||
"please_select_playlist": "Hãy chọn một danh sách phát",
|
||||
"copy_link": "Sao chép liên kết",
|
||||
"source_code": "Mã nguồn",
|
||||
"piped_link": "Liên kết Piped",
|
||||
"share": "Chia sẻ",
|
||||
"minimize_comments_default": "Thu nhỏ bình luận theo mặc định",
|
||||
"download_as_txt": "Tải về dưới định dạng .txt",
|
||||
"delete_account": "Xóa tài khoản",
|
||||
"minimize_recommendations_default": "Thu nhỏ đề xuất theo mặc định",
|
||||
"logout": "Đăng xuất khỏi thiết bị này",
|
||||
"minimize_comments": "Thu nhỏ bình luận",
|
||||
"reply_count": "{count} phản hồi",
|
||||
"status_page": "Trạng thái",
|
||||
"new_playlist_name": "Tên danh sách phát mới",
|
||||
"skip_automatically": "Tự động"
|
||||
},
|
||||
"titles": {
|
||||
"register": "Đăng ký",
|
||||
"preferences": "Sở thích",
|
||||
"preferences": "Cài đặt",
|
||||
"history": "Lịch sử",
|
||||
"subscriptions": "Đăng ký",
|
||||
"trending": "Xu hướng",
|
||||
"login": "Đăng nhập",
|
||||
"feed": "Mới nhất"
|
||||
"feed": "Mới nhất",
|
||||
"playlists": "Danh sách phát",
|
||||
"account": "Tài khoản",
|
||||
"channels": "Kênh",
|
||||
"instance": "Instance",
|
||||
"player": "Trình phát video",
|
||||
"livestreams": "Phát sóng trực tiếp"
|
||||
},
|
||||
"player": {
|
||||
"watch_on": "Xem trên {0}"
|
||||
},
|
||||
"comment": {
|
||||
"pinned_by": "Được ghim bởi {author}"
|
||||
"pinned_by": "Được ghim bởi {author}",
|
||||
"loading": "Đang tải bình luận...",
|
||||
"user_disabled": "Bình luận đã được tắt trong cài đặt.",
|
||||
"disabled": "Bình luận đã bị tắt bởi người đăng video."
|
||||
},
|
||||
"preferences": {
|
||||
"instance_name": "Tên phiên bản",
|
||||
"instance_locations": "Vị trí phiên bản",
|
||||
"instance_name": "Tên instance",
|
||||
"instance_locations": "Vị trí instance",
|
||||
"has_cdn": "Có CDN?",
|
||||
"registered_users": "Người dùng đã đăng ký",
|
||||
"version": "Phiên bản",
|
||||
"up_to_date": "Cập nhật?",
|
||||
"up_to_date": "Đã được cập nhật?",
|
||||
"ssl_score": "Điểm SSL"
|
||||
},
|
||||
"login": {
|
||||
|
@ -94,7 +125,9 @@
|
|||
"ratings_disabled": "Xếp hạng đã tắt",
|
||||
"live": "{0} Trực tiếp",
|
||||
"chapters": "Chương",
|
||||
"videos": "Video"
|
||||
"videos": "Video",
|
||||
"shorts": "Shorts",
|
||||
"all": "Tất cả"
|
||||
},
|
||||
"search": {
|
||||
"did_you_mean": "Ý của bạn là: {0}?",
|
||||
|
@ -106,5 +139,13 @@
|
|||
"videos": "YouTube: Video",
|
||||
"music_videos": "YT Music: Video",
|
||||
"music_albums": "YT Music: Album"
|
||||
},
|
||||
"info": {
|
||||
"copied": "Đã sao chép!",
|
||||
"cannot_copy": "Không thể sao chép!",
|
||||
"page_not_found": "Không tìm thấy trang"
|
||||
},
|
||||
"subscriptions": {
|
||||
"subscribed_channels_count": "Đã đăng ký cho: {0}"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,12 +44,12 @@
|
|||
"least_recent": "最早的",
|
||||
"most_recent": "最新的",
|
||||
"sort_by": "排序:",
|
||||
"view_subscriptions": "查看订阅",
|
||||
"view_subscriptions": "查看订阅列表",
|
||||
"unsubscribe": "取消订阅 - {count}",
|
||||
"subscribe": "订购 - {count}",
|
||||
"subscribe": "订阅 - {count}",
|
||||
"loading": "正在加载...",
|
||||
"filter": "筛选",
|
||||
"search": "搜索",
|
||||
"search": "搜索 (Ctrl+K)",
|
||||
"view_ssl_score": "查看 SSL 得分",
|
||||
"minimize_recommendations": "最小化建议",
|
||||
"show_recommendations": "显示推荐",
|
||||
|
@ -99,7 +99,17 @@
|
|||
"reply_count": "{count} 条回复",
|
||||
"minimize_comments": "最小化评论",
|
||||
"minimize_comments_default": "默认最小化评论",
|
||||
"show_watch_on_youtube": "显示“在 YouTube 上观看”按钮"
|
||||
"show_watch_on_youtube": "显示“在 YouTube 上观看”按钮",
|
||||
"minimize_chapters_default": "默认最小化章节",
|
||||
"no_valid_playlists": "此文件不包含有效的播放列表!",
|
||||
"with_playlist": "分享播放列表",
|
||||
"playlist_bookmarked": "已加入书签",
|
||||
"bookmark_playlist": "书签",
|
||||
"skip_automatically": "自动",
|
||||
"min_segment_length": "最小分段长度(以秒为单位)",
|
||||
"skip_segment": "跳过分段",
|
||||
"skip_button_only": "显示跳过按钮",
|
||||
"show_less": "显示更少"
|
||||
},
|
||||
"video": {
|
||||
"sponsor_segments": "赞助商部分",
|
||||
|
@ -109,7 +119,9 @@
|
|||
"live": "{0} 直播",
|
||||
"chapters": "章节",
|
||||
"ratings_disabled": "已禁用评价",
|
||||
"shorts": "短视频"
|
||||
"shorts": "短视频",
|
||||
"all": "全部",
|
||||
"category": "类别"
|
||||
},
|
||||
"preferences": {
|
||||
"ssl_score": "SSL 分数",
|
||||
|
@ -130,8 +142,8 @@
|
|||
"watch_on": "在 {0} 观看"
|
||||
},
|
||||
"titles": {
|
||||
"feed": "RSS 订阅源",
|
||||
"subscriptions": "订阅",
|
||||
"feed": "订阅流",
|
||||
"subscriptions": "订阅列表",
|
||||
"history": "历史",
|
||||
"preferences": "设置",
|
||||
"register": "注册",
|
||||
|
@ -142,7 +154,8 @@
|
|||
"instance": "实例",
|
||||
"player": "播放器",
|
||||
"livestreams": "直播",
|
||||
"channels": "频道"
|
||||
"channels": "频道",
|
||||
"bookmarks": "书签"
|
||||
},
|
||||
"login": {
|
||||
"password": "密码",
|
||||
|
@ -169,6 +182,8 @@
|
|||
"preferences_note": "注意:首选项保存在浏览器的本地存储中。删除浏览器数据会重置它们。",
|
||||
"page_not_found": "未找到页面",
|
||||
"copied": "已复制!",
|
||||
"cannot_copy": "无法复制!"
|
||||
"cannot_copy": "无法复制!",
|
||||
"local_storage": "此操作需要本地存储,是否启用了Cookie?",
|
||||
"register_no_email_note": "不建议使用电子邮件作为用户名。仍要继续吗?"
|
||||
}
|
||||
}
|
||||
|
|
58
src/main.js
58
src/main.js
|
@ -21,6 +21,7 @@ import {
|
|||
faBook,
|
||||
faServer,
|
||||
faDonate,
|
||||
faBookmark,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { faGithub, faBitcoin, faYoutube } from "@fortawesome/free-brands-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
|
@ -48,6 +49,7 @@ library.add(
|
|||
faBook,
|
||||
faServer,
|
||||
faDonate,
|
||||
faBookmark,
|
||||
);
|
||||
|
||||
import router from "@/router/router.js";
|
||||
|
@ -120,8 +122,12 @@ const mixin = {
|
|||
purifyHTML(original) {
|
||||
return DOMPurify.sanitize(original);
|
||||
},
|
||||
setPreference(key, value) {
|
||||
if (localStorage) localStorage.setItem(key, value);
|
||||
setPreference(key, value, disableAlert = false) {
|
||||
try {
|
||||
localStorage.setItem(key, value);
|
||||
} catch {
|
||||
if (!disableAlert) alert(this.$t("info.local_storage"));
|
||||
}
|
||||
},
|
||||
getPreferenceBoolean(key, defaultVal) {
|
||||
var value;
|
||||
|
@ -155,7 +161,17 @@ const mixin = {
|
|||
(value = new URLSearchParams(window.location.search).get(key)) !== null ||
|
||||
(this.testLocalStorage && (value = localStorage.getItem(key)) !== null)
|
||||
) {
|
||||
return Number(value);
|
||||
const num = Number(value);
|
||||
return isNaN(num) ? defaultVal : num;
|
||||
} else return defaultVal;
|
||||
},
|
||||
getPreferenceJSON(key, defaultVal) {
|
||||
var value;
|
||||
if (
|
||||
(value = new URLSearchParams(window.location.search).get(key)) !== null ||
|
||||
(this.testLocalStorage && (value = localStorage.getItem(key)) !== null)
|
||||
) {
|
||||
return JSON.parse(value);
|
||||
} else return defaultVal;
|
||||
},
|
||||
apiUrl() {
|
||||
|
@ -192,19 +208,26 @@ const mixin = {
|
|||
});
|
||||
},
|
||||
async updateWatched(videos) {
|
||||
if (window.db) {
|
||||
if (window.db && this.getPreferenceBoolean("watchHistory", false)) {
|
||||
var tx = window.db.transaction("watch_history", "readonly");
|
||||
var store = tx.objectStore("watch_history");
|
||||
videos.map(async video => {
|
||||
var request = store.get(video.url.substr(-11));
|
||||
request.onsuccess = function (event) {
|
||||
video.watched = Boolean(event.target.result);
|
||||
if (event.target.result) {
|
||||
video.watched = true;
|
||||
video.currentTime = event.target.result.currentTime;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
getLocalSubscriptions() {
|
||||
return JSON.parse(localStorage.getItem("localSubscriptions"));
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem("localSubscriptions"));
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
isSubscribedLocally(channelId) {
|
||||
const localSubscriptions = this.getLocalSubscriptions();
|
||||
|
@ -214,19 +237,25 @@ const mixin = {
|
|||
handleLocalSubscriptions(channelId) {
|
||||
var localSubscriptions = this.getLocalSubscriptions() ?? [];
|
||||
if (localSubscriptions.includes(channelId))
|
||||
localSubscriptions.splice(localSubscriptions.indexOf(channelId));
|
||||
localSubscriptions.splice(localSubscriptions.indexOf(channelId), 1);
|
||||
else localSubscriptions.push(channelId);
|
||||
// Sort for better cache hits
|
||||
localSubscriptions.sort();
|
||||
localStorage.setItem("localSubscriptions", JSON.stringify(localSubscriptions));
|
||||
try {
|
||||
localStorage.setItem("localSubscriptions", JSON.stringify(localSubscriptions));
|
||||
return true;
|
||||
} catch {
|
||||
alert(this.$t("info.local_storage"));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getUnauthenticatedChannels() {
|
||||
const localSubscriptions = this.getLocalSubscriptions() ?? [];
|
||||
return localSubscriptions.join(",");
|
||||
},
|
||||
/* generate a temporary file and ask the user to download it */
|
||||
download(text, filename, type) {
|
||||
var file = new Blob([text], { type: type });
|
||||
download(text, filename, mimeType) {
|
||||
var file = new Blob([text], { type: mimeType });
|
||||
|
||||
const elem = document.createElement("a");
|
||||
|
||||
|
@ -235,6 +264,15 @@ const mixin = {
|
|||
elem.click();
|
||||
elem.remove();
|
||||
},
|
||||
rewriteDescription(text) {
|
||||
return this.urlify(text)
|
||||
.replaceAll(/(?:http(?:s)?:\/\/)?(?:www\.)?youtube\.com(\/[/a-zA-Z0-9_?=&-]*)/gm, "$1")
|
||||
.replaceAll(
|
||||
/(?:http(?:s)?:\/\/)?(?:www\.)?youtu\.be\/(?:watch\?v=)?([/a-zA-Z0-9_?=&-]*)/gm,
|
||||
"/watch?v=$1",
|
||||
)
|
||||
.replaceAll("\n", "<br>");
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
authenticated(_this) {
|
||||
|
|
|
@ -27,7 +27,7 @@ const routes = [
|
|||
component: () => import("../components/PlaylistPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "/:path(v|w|embed|shorts|watch)/:v?",
|
||||
path: "/:path(v|w|embed|live|shorts|watch)/:v?",
|
||||
name: "WatchVideo",
|
||||
component: () => import("../components/WatchVideo.vue"),
|
||||
},
|
||||
|
@ -41,6 +41,11 @@ const routes = [
|
|||
name: "Channel",
|
||||
component: () => import("../components/ChannelPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "/@:channelId",
|
||||
name: "Channel handle",
|
||||
component: () => import("../components/ChannelPage.vue"),
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
{ "code": "SR", "name": "Suriname" },
|
||||
{ "code": "SY", "name": "Syrien" },
|
||||
{ "code": "TJ", "name": "Tadschikistan" },
|
||||
{ "code": "TW", "name": "Taiwan" },
|
||||
{ "code": "TZ", "name": "Tansania" },
|
||||
{ "code": "TH", "name": "Thailand" },
|
||||
{ "code": "TG", "name": "Togo" },
|
||||
|
|
|
@ -176,6 +176,7 @@
|
|||
{ "code": "TH", "name": "Ταϊλάνδη" },
|
||||
{ "code": "TZ", "name": "Τανζανία" },
|
||||
{ "code": "TJ", "name": "Τατζικιστάν" },
|
||||
{ "code": "TW", "name": "Ταϊβάν" },
|
||||
{ "code": "JM", "name": "Τζαμάικα" },
|
||||
{ "code": "DJ", "name": "Τζιμπουτί" },
|
||||
{ "code": "TO", "name": "Τόγκα" },
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
{ "code": "SE", "name": "Sweden" },
|
||||
{ "code": "CH", "name": "Switzerland" },
|
||||
{ "code": "SY", "name": "Syrian Arab Republic" },
|
||||
{ "code": "TW", "name": "Taiwan" },
|
||||
{ "code": "TJ", "name": "Tajikistan" },
|
||||
{ "code": "TZ", "name": "Tanzania, United Republic of" },
|
||||
{ "code": "TH", "name": "Thailand" },
|
||||
|
|
|
@ -172,6 +172,7 @@
|
|||
{ "code": "CH", "name": "Suiza" },
|
||||
{ "code": "SR", "name": "Surinam" },
|
||||
{ "code": "TH", "name": "Tailandia" },
|
||||
{ "code": "TW", "name": "Taiwán" },
|
||||
{ "code": "TZ", "name": "Tanzania" },
|
||||
{ "code": "TJ", "name": "Tayikistán" },
|
||||
{ "code": "TL", "name": "Timor Oriental" },
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
{ "code": "SY", "name": "Syrie" },
|
||||
{ "code": "TJ", "name": "Tadjikistan" },
|
||||
{ "code": "TZ", "name": "Tanzanie" },
|
||||
{ "code": "TW", "name": "Taïwan" },
|
||||
{ "code": "TD", "name": "Tchad" },
|
||||
{ "code": "CZ", "name": "Tchéquie" },
|
||||
{ "code": "TH", "name": "Thaïlande" },
|
||||
|
|
|
@ -172,6 +172,7 @@
|
|||
{ "code": "CH", "name": "Svizzera" },
|
||||
{ "code": "SZ", "name": "eSwatini" },
|
||||
{ "code": "TJ", "name": "Tagikistan" },
|
||||
{ "code": "TW", "name": "Taiwan" },
|
||||
{ "code": "TZ", "name": "Tanzania" },
|
||||
{ "code": "TH", "name": "Thailandia" },
|
||||
{ "code": "TL", "name": "Timor Est" },
|
||||
|
|
|
@ -170,6 +170,7 @@
|
|||
{ "code": "TJ", "name": "Tadžikija" },
|
||||
{ "code": "TZ", "name": "Tanzanija" },
|
||||
{ "code": "TH", "name": "Tailandas" },
|
||||
{ "code": "TW", "name": "Taivanas" },
|
||||
{ "code": "TL", "name": "Rytų Timoras" },
|
||||
{ "code": "TG", "name": "Togas" },
|
||||
{ "code": "TO", "name": "Tonga" },
|
||||
|
|
|
@ -167,6 +167,7 @@
|
|||
{ "code": "SE", "name": "Szwecja" },
|
||||
{ "code": "TJ", "name": "Tadżykistan" },
|
||||
{ "code": "TH", "name": "Tajlandia" },
|
||||
{ "code": "TW", "name": "Tajwan" },
|
||||
{ "code": "TZ", "name": "Tanzania" },
|
||||
{ "code": "TL", "name": "Timor Wschodni" },
|
||||
{ "code": "TG", "name": "Togo" },
|
||||
|
|
|
@ -173,6 +173,7 @@
|
|||
{ "code": "CH", "name": "Švajčiarsko" },
|
||||
{ "code": "SE", "name": "Švédsko" },
|
||||
{ "code": "TJ", "name": "Tadžikistan" },
|
||||
{ "code": "TW", "name": "Taiwan" },
|
||||
{ "code": "IT", "name": "Taliansko" },
|
||||
{ "code": "TZ", "name": "Tanzánia" },
|
||||
{ "code": "TH", "name": "Thajsko" },
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
{ "code": "SY", "name": "Сиријска Арапска Република" },
|
||||
{ "code": "TJ", "name": "Таџикистан" },
|
||||
{ "code": "TZ", "name": "Танзанија" },
|
||||
{ "code": "TW", "name": "Тајван" },
|
||||
{ "code": "TH", "name": "Тајланд" },
|
||||
{ "code": "TL", "name": "Тимор-Лесте" },
|
||||
{ "code": "TG", "name": "Того" },
|
||||
|
|
|
@ -180,6 +180,7 @@
|
|||
{ "code": "TR", "name": "土耳其" },
|
||||
{ "code": "TM", "name": "土庫曼" },
|
||||
{ "code": "TV", "name": "吐瓦魯" },
|
||||
{ "code": "TW", "name": "台灣" },
|
||||
{ "code": "UG", "name": "烏干達" },
|
||||
{ "code": "UA", "name": "烏克蘭" },
|
||||
{ "code": "AE", "name": "阿聯" },
|
||||
|
|
|
@ -4,187 +4,204 @@ import { Buffer } from "buffer";
|
|||
window.Buffer = Buffer;
|
||||
import { json2xml } from "xml-js";
|
||||
|
||||
const DashUtils = {
|
||||
generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
||||
const generatedJSON = this.generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
||||
return json2xml(generatedJSON);
|
||||
},
|
||||
generate_xmljs_json_from_data(VideoFormatArray, VideoLength) {
|
||||
const convertJSON = {
|
||||
declaration: {
|
||||
attributes: {
|
||||
version: "1.0",
|
||||
encoding: "utf-8",
|
||||
},
|
||||
export function generate_dash_file_from_formats(VideoFormats, VideoLength) {
|
||||
const generatedJSON = generate_xmljs_json_from_data(VideoFormats, VideoLength);
|
||||
return json2xml(generatedJSON);
|
||||
}
|
||||
|
||||
function 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),
|
||||
},
|
||||
],
|
||||
},
|
||||
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`,
|
||||
},
|
||||
],
|
||||
};
|
||||
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) {
|
||||
elements: [
|
||||
{
|
||||
type: "element",
|
||||
name: "Period",
|
||||
elements: generate_adaptation_set(VideoFormatArray),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
return convertJSON;
|
||||
}
|
||||
|
||||
function generate_adaptation_set(VideoFormatArray) {
|
||||
const adaptationSets = [];
|
||||
|
||||
let mimeAudioObjs = [];
|
||||
|
||||
VideoFormatArray.forEach(videoFormat => {
|
||||
// the dual formats should not be used
|
||||
if (
|
||||
(videoFormat.mimeType.includes("video") && !videoFormat.videoOnly) ||
|
||||
videoFormat.mimeType.includes("application")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const audioTrackId = videoFormat.audioTrackId;
|
||||
const mimeType = videoFormat.mimeType;
|
||||
|
||||
for (let i = 0; i < mimeAudioObjs.length; i++) {
|
||||
const mimeAudioObj = mimeAudioObjs[i];
|
||||
|
||||
if (mimeAudioObj.audioTrackId == audioTrackId && mimeAudioObj.mimeType == mimeType) {
|
||||
mimeAudioObj.videoFormats.push(videoFormat);
|
||||
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;
|
||||
mimeAudioObjs.push({
|
||||
audioTrackId,
|
||||
mimeType,
|
||||
videoFormats: [videoFormat],
|
||||
});
|
||||
});
|
||||
|
||||
mimeAudioObjs.forEach(mimeAudioObj => {
|
||||
const adapSet = {
|
||||
type: "element",
|
||||
name: "AdaptationSet",
|
||||
attributes: {
|
||||
id: mimeAudioObj.audioTrackId,
|
||||
lang: mimeAudioObj.audioTrackId?.substr(0, 2),
|
||||
mimeType: mimeAudioObj.mimeType,
|
||||
startWithSAP: "1",
|
||||
subsegmentAlignment: "true",
|
||||
},
|
||||
elements: [],
|
||||
};
|
||||
|
||||
let isVideoFormat = false;
|
||||
|
||||
if (mimeAudioObj.mimeType.includes("video")) {
|
||||
isVideoFormat = true;
|
||||
}
|
||||
|
||||
if (isVideoFormat) {
|
||||
adapSet.attributes.scanType = "progressive";
|
||||
}
|
||||
|
||||
for (var i = 0; i < mimeAudioObj.videoFormats.length; i++) {
|
||||
const videoFormat = mimeAudioObj.videoFormats[i];
|
||||
if (isVideoFormat) {
|
||||
adapSet.elements.push(generate_representation_video(videoFormat));
|
||||
} else {
|
||||
adapSet.elements.push(generate_representation_audio(videoFormat));
|
||||
}
|
||||
}
|
||||
|
||||
adaptationSets.push(adapSet);
|
||||
});
|
||||
return adaptationSets;
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
|
||||
function 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;
|
||||
}
|
||||
|
|
8
src/utils/Misc.js
Normal file
8
src/utils/Misc.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
export const isEmail = input => {
|
||||
// Taken from https://emailregex.com
|
||||
const result = input.match(
|
||||
//eslint-disable-next-line
|
||||
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
||||
);
|
||||
return result;
|
||||
};
|
|
@ -1,5 +1,12 @@
|
|||
{
|
||||
"github": {
|
||||
"silent": true
|
||||
}
|
||||
},
|
||||
"routes": [
|
||||
{
|
||||
"src": "/[^.]+",
|
||||
"dest": "/",
|
||||
"status": 200
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ export default defineConfig({
|
|||
registerType: "autoUpdate",
|
||||
workbox: {
|
||||
globPatterns: ["**/*.{js,css,html,ico,svg,png}", "manifest.webmanifest"],
|
||||
globIgnores: ["**/*legacy.*.js"],
|
||||
globIgnores: ["**/*-legacy-*.js"],
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: /https:\/\/[a-zA-Z./0-9_]*\.(?:otf|ttf)/i,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue