mirror of
https://github.com/iv-org/invidious.git
synced 2025-12-23 20:40:17 +00:00
Compare commits
25 Commits
v2.2025091
...
refactor-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ff616d9a4 | ||
|
|
bd2f00f6df | ||
|
|
d70b05e5c3 | ||
|
|
924ae11721 | ||
|
|
43f9af2015 | ||
|
|
4628f98eeb | ||
|
|
60b45290bd | ||
|
|
e5795cab3d | ||
|
|
b79177f07e | ||
|
|
7fe8f6f24e | ||
|
|
936c0ff61b | ||
|
|
802790e468 | ||
|
|
3dd68872f9 | ||
|
|
be9749aefd | ||
|
|
7cd974dc24 | ||
|
|
bf2eccbcaf | ||
|
|
586dfcc1e3 | ||
|
|
4e4a084f22 | ||
|
|
65e6929037 | ||
|
|
2f52ebc7e3 | ||
|
|
97b13c042e | ||
|
|
c86846e7b7 | ||
|
|
95a1f632d8 | ||
|
|
220adf53f4 | ||
|
|
c2ede1d2a5 |
@@ -25,7 +25,7 @@ Lint/NotNil:
|
||||
|
||||
Lint/SpecFilename:
|
||||
Excluded:
|
||||
- spec/parsers_helper.cr
|
||||
- spec/*_helper.cr
|
||||
|
||||
|
||||
#
|
||||
|
||||
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -1,3 +1,6 @@
|
||||
# Default and lowest precedence. If none of the below matches, @iv-org/developers would be requested for review.
|
||||
* @iv-org/developers
|
||||
|
||||
docker-compose.yml @unixfox
|
||||
docker/ @unixfox
|
||||
kubernetes/ @unixfox
|
||||
|
||||
57
.github/workflows/build-nightly-container.yml
vendored
57
.github/workflows/build-nightly-container.yml
vendored
@@ -17,26 +17,16 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
platform: linux/amd64
|
||||
name: "AMD64"
|
||||
dockerfile: "docker/Dockerfile"
|
||||
tag_suffix: ""
|
||||
# GitHub doesn't have a ubuntu-latest-arm runner
|
||||
- os: ubuntu-24.04-arm
|
||||
platform: linux/arm64/v8
|
||||
name: "ARM64"
|
||||
dockerfile: "docker/Dockerfile.arm64"
|
||||
tag_suffix: "-arm64"
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -53,22 +43,45 @@ jobs:
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: quay.io/invidious/invidious
|
||||
flavor: |
|
||||
suffix=${{ matrix.tag_suffix }}
|
||||
tags: |
|
||||
type=sha,format=short,prefix={{date 'YYYY.MM.DD'}}-,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
|
||||
type=raw,value=master,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
|
||||
labels: |
|
||||
quay.expires-after=12w
|
||||
|
||||
- name: Build and push Docker ${{ matrix.name }} image for Push Event
|
||||
- name: Build and push Docker AMD64 image for Push Event
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
file: docker/Dockerfile
|
||||
platforms: linux/amd64
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
build-args: |
|
||||
"release=1"
|
||||
|
||||
- name: Docker meta
|
||||
id: meta-arm64
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: quay.io/invidious/invidious
|
||||
flavor: |
|
||||
suffix=-arm64
|
||||
tags: |
|
||||
type=sha,format=short,prefix={{date 'YYYY.MM.DD'}}-,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
|
||||
type=raw,value=master,enable=${{ github.ref == format('refs/heads/{0}', 'master') }}
|
||||
labels: |
|
||||
quay.expires-after=12w
|
||||
|
||||
- name: Build and push Docker ARM64 image for Push Event
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile.arm64
|
||||
platforms: linux/arm64/v8
|
||||
labels: ${{ steps.meta-arm64.outputs.labels }}
|
||||
push: true
|
||||
tags: ${{ steps.meta-arm64.outputs.tags }}
|
||||
build-args: |
|
||||
"release=1"
|
||||
|
||||
57
.github/workflows/build-stable-container.yml
vendored
57
.github/workflows/build-stable-container.yml
vendored
@@ -8,26 +8,16 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
platform: linux/amd64
|
||||
name: "AMD64"
|
||||
dockerfile: "docker/Dockerfile"
|
||||
tag_suffix: ""
|
||||
# GitHub doesn't have a ubuntu-latest-arm runner
|
||||
- os: ubuntu-24.04-arm
|
||||
platform: linux/arm64/v8
|
||||
name: "ARM64"
|
||||
dockerfile: "docker/Dockerfile.arm64"
|
||||
tag_suffix: "-arm64"
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -46,21 +36,46 @@ jobs:
|
||||
images: quay.io/invidious/invidious
|
||||
flavor: |
|
||||
latest=false
|
||||
suffix=${{ matrix.tag_suffix }}
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=raw,value=latest
|
||||
labels: |
|
||||
quay.expires-after=12w
|
||||
|
||||
- name: Build and push Docker ${{ matrix.name }} image for Push Event
|
||||
- name: Build and push Docker AMD64 image for Push Event
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
file: docker/Dockerfile
|
||||
platforms: linux/amd64
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
build-args: |
|
||||
"release=1"
|
||||
|
||||
- name: Docker meta
|
||||
id: meta-arm64
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: quay.io/invidious/invidious
|
||||
flavor: |
|
||||
latest=false
|
||||
suffix=-arm64
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=raw,value=latest
|
||||
labels: |
|
||||
quay.expires-after=12w
|
||||
|
||||
- name: Build and push Docker ARM64 image for Push Event
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile.arm64
|
||||
platforms: linux/arm64/v8
|
||||
labels: ${{ steps.meta-arm64.outputs.labels }}
|
||||
push: true
|
||||
tags: ${{ steps.meta-arm64.outputs.tags }}
|
||||
build-args: |
|
||||
"release=1"
|
||||
|
||||
68
.github/workflows/ci.yml
vendored
68
.github/workflows/ci.yml
vendored
@@ -38,17 +38,16 @@ jobs:
|
||||
matrix:
|
||||
stable: [true]
|
||||
crystal:
|
||||
- 1.12.2
|
||||
- 1.13.3
|
||||
- 1.14.1
|
||||
- 1.15.1
|
||||
- 1.16.3
|
||||
- 1.12.1
|
||||
- 1.13.2
|
||||
- 1.14.0
|
||||
- 1.15.0
|
||||
include:
|
||||
- crystal: nightly
|
||||
stable: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -83,43 +82,46 @@ jobs:
|
||||
run: crystal build --warnings all --error-on-warnings --error-trace src/invidious.cr
|
||||
|
||||
build-docker:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
name: "AMD64"
|
||||
# GitHub doesn't have a ubuntu-latest-arm runner
|
||||
- os: ubuntu-24.04-arm
|
||||
name: "ARM64"
|
||||
|
||||
name: Test ${{ matrix.name }} Docker build
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Use ARM64 Dockerfile if ARM64
|
||||
if: ${{ matrix.name == 'ARM64' }}
|
||||
run: sed -i 's/Dockerfile/Dockerfile.arm64/' docker-compose.yml
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build Docker
|
||||
run: docker compose build
|
||||
|
||||
- name: Change hmac_key on docker-compose.yml
|
||||
run: sed -i '/hmac_key/s/CHANGE_ME!!/docker-build-hmac-key/' docker-compose.yml
|
||||
run: docker compose build --build-arg release=0
|
||||
|
||||
- name: Run Docker
|
||||
run: docker compose up -d
|
||||
|
||||
- name: Test Docker
|
||||
id: test
|
||||
run: curl -If http://localhost:3000 --retry 5 --retry-delay 1 --retry-all-errors
|
||||
run: while curl -Isf http://localhost:3000; do sleep 1; done
|
||||
|
||||
- name: Print Invidious container logs
|
||||
# Tells Github Actions to always run this step regardless of whether the previous step has failed
|
||||
# Without this expression this step would simply be skipped when the previous step fails.
|
||||
if: success() || steps.test.conclusion == 'failure'
|
||||
run: docker compose logs
|
||||
build-docker-arm64:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Docker ARM64 image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile.arm64
|
||||
platforms: linux/arm64/v8
|
||||
build-args: release=0
|
||||
|
||||
- name: Test Docker
|
||||
run: while curl -Isf http://localhost:3000; do sleep 1; done
|
||||
|
||||
lint:
|
||||
|
||||
@@ -128,7 +130,7 @@ jobs:
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 730
|
||||
|
||||
140
CHANGELOG.md
140
CHANGELOG.md
@@ -2,149 +2,11 @@
|
||||
|
||||
## vX.Y.0 (future)
|
||||
|
||||
## v2.20250913.0
|
||||
|
||||
### Wrap-up
|
||||
|
||||
This release primarily marks Invidious companion's ascend out of beta and its stable integration thereof into Invidious!
|
||||
|
||||
For those unaware Invidious companion is the successor to the `inv-sig-helper` tool, designed to securely pass YouTube's attestation checks and allow for the efficient retrieval and playback of video streams reliably.
|
||||
|
||||
Companion delivers YouTube fixes faster since it’s built on the community-driven [YouTube.js](https://github.com/LuanRT/YouTube.js) project, used by many open source projects such as [FreeTube](https://github.com/FreeTubeApp/FreeTube).
|
||||
|
||||
For more information see https://github.com/iv-org/invidious-companion and https://docs.invidious.io/installation/
|
||||
|
||||
But companion isn't the only new thing in this release!
|
||||
|
||||
Invidious will no longer error out completely as soon as a single item failed to parse in search results, channel pages, etc. Instead it now handles it gracefully by substituting those problematic items with an error card and rendering the page normally.
|
||||
|
||||
The player has gained some quality of life features such as being able to choose a default playlist for videos to be added to, or persisting caption appearance settings across the session.
|
||||
|
||||
Base Invidious video retrieval without Invidious companion has also been made more stable.
|
||||
|
||||
And finally a significant amount of bugs were fixed alongside many other minor improvements.
|
||||
|
||||
### New features & important changes
|
||||
#### For Users
|
||||
- DASH is now enabled by default due to YouTube's removal of the 720p non-dash streams
|
||||
- Javascript licencing info has been added to all of Invidious' scripts, restoring full compatibility with LibreJS
|
||||
- There is no longer an option for a text captcha during registration due to the shutdown (presumably) of the upstream service
|
||||
- Parse errors in feeds will no longer render the entire feed unusable and instead will substitute only the broken items with error cards
|
||||
- Keyboard shortcuts have been added to configure caption styles:
|
||||
- `-`,`=` can be used to change the font size
|
||||
- `o` can be used to cycle the opacity of the caption text
|
||||
- `w` can be used to cycle the opacity of the caption box
|
||||
- Caption styles changed through the VideoJS menu will now persist
|
||||
- You can now choose a default playlist to add videos to instead of needing to manually select one each time
|
||||
|
||||
#### For instance owners
|
||||
- Invidious companion support has been added to replace the deprecated inv-sig-helper
|
||||
- **DASH is now the default resolution! Please ensure that your instances can withstand the significantly higher bandwidth usage or manually configure your instance to use non-dash streams by default**
|
||||
- Invidious will now warn when it is unable to connect to the database instead of failing silently
|
||||
- **The text captcha during registration has been removed due to the shutdown (presumably) of the upstream service**
|
||||
|
||||
#### For developers
|
||||
- Dependabot has been added to keep Github Actions and Docker dependencies up-to-date.
|
||||
- CI version matrix has been bumped to the latest patch release for each minor version
|
||||
- The versions of Crystal that we test in CI/CD are now: `1.12.2`, `1.13.3`, `1.14.1`, `1.15.1`, `1.16.3`
|
||||
- `Kilt` is no longer a dependency of Invidious
|
||||
- The ARM64 docker image builds (and the test CI) has been changed to use Github's ARM64 runner instead of QEMU
|
||||
- **An "error" JSON object can now be returned in various API responses in-place of an item that has failed to parse**:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "parse-error",
|
||||
"errorMessage": "...",
|
||||
"errorBacktrace": "..."
|
||||
}
|
||||
```
|
||||
|
||||
### Bugs fixed
|
||||
#### User-side
|
||||
- Livestream will now be properly proxied again allowing playback from the UI
|
||||
- The proxy video preference for logged-in users will no longer get ignored when a default value is set by the instance
|
||||
- Fixes the missing `label` key error on select search results and other feeds
|
||||
- Invidious will no longer strip out spaces from search queries when navigating back from the preferences page
|
||||
- Restores functionality to the `subscriptions:true` search keyword
|
||||
- The channel RSS feeds will no longer have an empty title
|
||||
- Individual community posts can be viewed again
|
||||
- The playlists tab of channels can be viewed again
|
||||
- Fix incorrect dates, region, etc of videos
|
||||
- Various minor fixes were made to how video info is extracted in setups without Invidious companion to improve resiliency and chances of success
|
||||
- Fix issue where the notification count becomes `TRUE` rather than an actual number
|
||||
#### For instance owners
|
||||
- Fixed a minor typo in config.example.yml (`effet` -> `effect`)
|
||||
#### For developers
|
||||
- The docker image test CI will now properly check whether Invidious has started
|
||||
|
||||
### Full list of pull requests merged since the last release (newest first)
|
||||
|
||||
* Add Invidious companion support (https://github.com/iv-org/invidious/pull/4985, by @unixfox)
|
||||
* Bump shards.yml version to dev version (https://github.com/iv-org/invidious/pull/5206, by @syeopite)
|
||||
* chore: enforce 16 characters for invidious_companion_key (https://github.com/iv-org/invidious/pull/5220, by @unixfox)
|
||||
* chore: set dash by default (https://github.com/iv-org/invidious/pull/5216, by @unixfox)
|
||||
* Fix minor casing issues in brand names (https://github.com/iv-org/invidious/pull/5258, thanks @efb4f5ff-1298-471a-8973-3d47447115dc)
|
||||
* feat: route to invidious companion on downloads (https://github.com/iv-org/invidious/pull/5224, by @alexmaras)
|
||||
* Fix proxying live DASH streams (https://github.com/iv-org/invidious/pull/4589, thanks @absidue)
|
||||
* Reflect companion secret character limit in example config comment (https://github.com/iv-org/invidious/pull/5269, thanks @Vyquos)
|
||||
* chore: Add dependabot for docker and github actions (https://github.com/iv-org/invidious/pull/5285, by @unixfox)
|
||||
* Bump actions/stale from 8 to 9 (https://github.com/iv-org/invidious/pull/5291, thanks @dependabot[bot])
|
||||
* Bump actions/cache from 3 to 4 (https://github.com/iv-org/invidious/pull/5289, thanks @dependabot[bot])
|
||||
* Bump alpine from 3.20 to 3.21 in /docker (https://github.com/iv-org/invidious/pull/5288, thanks @dependabot[bot])
|
||||
* Bump docker/build-push-action from 5 to 6 (https://github.com/iv-org/invidious/pull/5287, thanks @dependabot[bot])
|
||||
* Bump crystal-lang/install-crystal from 1.8.0 to 1.8.2 (https://github.com/iv-org/invidious/pull/5286, thanks @dependabot[bot])
|
||||
* Bump crystallang/crystal from 1.12.2-alpine to 1.16.2-alpine in /docker (https://github.com/iv-org/invidious/pull/5290, thanks @dependabot[bot])
|
||||
* Bump crystallang/crystal from 1.16.2-alpine to 1.16.3-alpine in /docker (https://github.com/iv-org/invidious/pull/5301, thanks @dependabot[bot])
|
||||
* CI: Bump Crystal version matrix (https://github.com/iv-org/invidious/pull/5293, by @Fijxu)
|
||||
* fix(typo): 'Salect' -> 'Select' (https://github.com/iv-org/invidious/pull/5242, by @Fijxu)
|
||||
* fix: set CSP header after setting preferences of registered users (https://github.com/iv-org/invidious/pull/5275, by @Fijxu)
|
||||
* fix: safely access "label" key (https://github.com/iv-org/invidious/pull/5282, by @Fijxu)
|
||||
* Add missing javascript licenses (https://github.com/iv-org/invidious/pull/5292, by @Fijxu)
|
||||
* Add Javascript licence information automatically (https://github.com/iv-org/invidious/pull/5297, by @syeopite)
|
||||
* Remove text captcha due to textcaptcha.com being down (https://github.com/iv-org/invidious/pull/5308, by @Fijxu)
|
||||
* Release versioning maintenance (https://github.com/iv-org/invidious/pull/5310, by @syeopite)
|
||||
* Update Kemal to 1.6.0 and remove Kilt (https://github.com/iv-org/invidious/pull/5120, by @syeopite)
|
||||
* Translations update from Hosted Weblate (https://github.com/iv-org/invidious/pull/5192, thanks @weblate)
|
||||
* require base_job before the other jobs (https://github.com/iv-org/invidious/pull/5194, by @Fijxu)
|
||||
* Handle parse errors gracefully on timeline items (https://github.com/iv-org/invidious/pull/5196, by @syeopite)
|
||||
* fix: do not strip '+' character from referer (https://github.com/iv-org/invidious/pull/5276, by @Fijxu)
|
||||
* fix: pass user to `query.process` if present. (https://github.com/iv-org/invidious/pull/5277, by @Fijxu)
|
||||
* Add missing xml.text on "title" element for channels RSS (https://github.com/iv-org/invidious/pull/5320, by @Fijxu)
|
||||
* Remove `@iv-org/developers` from codeowners (https://github.com/iv-org/invidious/pull/5314, by @syeopite)
|
||||
* Make base-Invidious video info extraction more resilient (https://github.com/iv-org/invidious/pull/5312, by @syeopite)
|
||||
* Bump actions/checkout from 4 to 5 (https://github.com/iv-org/invidious/pull/5415, thanks @dependabot[bot])
|
||||
* Player: Add keyboard shortcuts to configure captions (https://github.com/iv-org/invidious/pull/5188, thanks @epicsam123)
|
||||
* CI: Use public ARM64 Github actions runners for ARM64 builds. (https://github.com/iv-org/invidious/pull/5305, by @Fijxu)
|
||||
* CI: Fix docker ci job not checking if Invidious starts successfully or not (https://github.com/iv-org/invidious/pull/5306, by @Fijxu)
|
||||
* YtAPI: Bump client versions (https://github.com/iv-org/invidious/pull/5325, by @Fijxu)
|
||||
* YTAPI: Add `TvSimply` client (https://github.com/iv-org/invidious/pull/5344, by @Fijxu)
|
||||
* Videos: Add fallback to TvSimply client (https://github.com/iv-org/invidious/pull/5345, by @Fijxu)
|
||||
* Show message when connection to the database is not possible (https://github.com/iv-org/invidious/pull/5346, by @Fijxu)
|
||||
* Channels: Fix fetching of individual community posts (https://github.com/iv-org/invidious/pull/5361, thanks @ChunkyProgrammer)
|
||||
* Videos: Fix missing .id to retrieve first playlist video ID (https://github.com/iv-org/invidious/pull/5366, by @SamantazFox)
|
||||
* HTML: Add Missing Noreferrers (https://github.com/iv-org/invidious/pull/5368, thanks @epicsam123)
|
||||
* Documentation: Fix typo (effet -> effect) (https://github.com/iv-org/invidious/pull/5369, thanks @nsunami)
|
||||
* Frontend: Fix notification count of `TRUE` (https://github.com/iv-org/invidious/pull/5391, thanks @fieryhenry)
|
||||
* Player: Persist caption settings (https://github.com/iv-org/invidious/pull/5417, thanks @p-himik)
|
||||
* Channels: Fix fetching channel playlists (https://github.com/iv-org/invidious/pull/5418, thanks @KrisVos130)
|
||||
* CI: fix wrong if statement for build-docker job (https://github.com/iv-org/invidious/pull/5442, by @Fijxu)
|
||||
* initial base_url companion support + proxy companion (https://github.com/iv-org/invidious/pull/5266, by @unixfox)
|
||||
* Prevent player microformat from being overwritten by the next microformat (https://github.com/iv-org/invidious/pull/5453, by @Fijxu)
|
||||
* Bump actions/stale from 9 to 10 (https://github.com/iv-org/invidious/pull/5457, thanks @dependabot[bot])
|
||||
* Better documentation for the specific case public_url with companion (https://github.com/iv-org/invidious/pull/5461, by @unixfox)
|
||||
* Add default playlist preference (https://github.com/iv-org/invidious/pull/5449, by @Fijxu)
|
||||
* Translations update from Hosted Weblate (https://github.com/iv-org/invidious/pull/5313, thanks to our many translators)
|
||||
* Release `v2.20250913.0` (https://github.com/iv-org/invidious/pull/5463, by @syeopite)
|
||||
|
||||
## v2.20250517.0
|
||||
|
||||
Inverse fallback for the YouTube client from TVHTML then MWEB. Fixes https://github.com/iv-org/invidious/issues/5273
|
||||
|
||||
## v2.20250504.0
|
||||
|
||||
Small release with quick workaround fix for issue #4251 (Nil assertion failed).
|
||||
|
||||
PR: https://github.com/iv-org/invidious/issues/5262
|
||||
PR: https://github.com/iv-org/invidious/issues/5263
|
||||
|
||||
## v2.20250314.0
|
||||
|
||||
|
||||
@@ -550,10 +550,6 @@ span > select {
|
||||
color: #565d64;
|
||||
}
|
||||
|
||||
.light-theme .error-card {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
.no-theme a:hover,
|
||||
.no-theme a:active,
|
||||
@@ -600,10 +596,6 @@ span > select {
|
||||
.light-theme .pure-menu-heading {
|
||||
color: #565d64;
|
||||
}
|
||||
|
||||
.no-theme .error-card {
|
||||
border: 1px solid black;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -666,10 +658,6 @@ body.dark-theme {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.dark-theme .error-card {
|
||||
border: 1px solid #5e5e5e;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.no-theme a:hover,
|
||||
.no-theme a:active,
|
||||
@@ -731,10 +719,6 @@ body.dark-theme {
|
||||
.no-theme footer a {
|
||||
color: #adadad !important;
|
||||
}
|
||||
|
||||
.no-theme .error-card {
|
||||
border: 1px solid #5e5e5e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -832,57 +816,3 @@ h1, h2, h3, h4, h5, p,
|
||||
#download_widget {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 25px;
|
||||
margin-bottom: 1em;
|
||||
border-radius: 10px;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.error-card > .explanation {
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
grid-template-rows: 1fr max-content;
|
||||
align-items: center;
|
||||
column-gap: 10px;
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.error-card > .explanation > i {
|
||||
color: #f44;
|
||||
font-size: 24px;
|
||||
grid-area: 1 / 1 / 2 / 2;
|
||||
}
|
||||
|
||||
.error-card > .explanation > h4 {
|
||||
grid-area: 1 / 2 / 2 / 3;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.error-card > .explanation > p {
|
||||
grid-area: 2 / 2 / 3 / 3;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.error-card details {
|
||||
margin-top: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error-card summary {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.error-card pre {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.error-issue-template {
|
||||
padding: 20px;
|
||||
background: rgba(0, 0, 0, 0.12345);
|
||||
}
|
||||
@@ -86,7 +86,6 @@ ul.vjs-menu-content::-webkit-scrollbar {
|
||||
background-color: rgba(0, 0, 0, 0.75) !important;
|
||||
border-radius: 9px !important;
|
||||
padding: 5px !important;
|
||||
line-height: 1.5 !important;
|
||||
}
|
||||
|
||||
.vjs-play-control,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#filters-collapse summary {
|
||||
summary {
|
||||
/* This should hide the marker */
|
||||
display: block;
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#filters-collapse summary::-webkit-details-marker,
|
||||
#filters-collapse summary::marker { display: none; }
|
||||
summary::-webkit-details-marker,
|
||||
summary::marker { display: none; }
|
||||
|
||||
#filters-collapse summary:before {
|
||||
summary:before {
|
||||
border-radius: 5px;
|
||||
content: "[ + ]";
|
||||
margin: -2px 10px 0 10px;
|
||||
@@ -20,7 +20,7 @@
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
#filters-collapse details[open] > summary:before { content: "[ − ]"; }
|
||||
details[open] > summary:before { content: "[ − ]"; }
|
||||
|
||||
|
||||
#filters-box {
|
||||
|
||||
@@ -77,7 +77,7 @@ function create_notification_stream(subscriptions) {
|
||||
function update_ticker_count() {
|
||||
var notification_ticker = document.getElementById('notification_ticker');
|
||||
|
||||
const notification_count = helpers.storage.get(STORAGE_KEY_NOTIF_COUNT) || 0;
|
||||
const notification_count = helpers.storage.get(STORAGE_KEY_STREAM);
|
||||
if (notification_count > 0) {
|
||||
notification_ticker.innerHTML =
|
||||
'<span id="notification_count">' + notification_count + '</span> <i class="icon ion-ios-notifications"></i>';
|
||||
|
||||
@@ -5,10 +5,6 @@ var video_data = JSON.parse(document.getElementById('video_data').textContent);
|
||||
var options = {
|
||||
liveui: true,
|
||||
playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0],
|
||||
fontPercent: [0.5, 0.75, 1.25, 1.5, 1.75, 2, 3, 4],
|
||||
windowOpacity: ['0', '0.5', '1'],
|
||||
textOpacity: ['0.5', '1'],
|
||||
persistTextTrackSettings: true,
|
||||
controlBar: {
|
||||
children: [
|
||||
'playToggle',
|
||||
@@ -184,7 +180,7 @@ var shareOptions = {
|
||||
};
|
||||
|
||||
if (location.pathname.startsWith('/embed/')) {
|
||||
var overlay_content = '<h1><a rel="noopener noreferrer" target="_blank" href="' + location.origin + '/watch?v=' + video_data.id + '">' + player_data.title + '</a></h1>';
|
||||
var overlay_content = '<h1><a rel="noopener" target="_blank" href="' + location.origin + '/watch?v=' + video_data.id + '">' + player_data.title + '</a></h1>';
|
||||
player.overlay({
|
||||
overlays: [
|
||||
{ start: 'loadstart', content: overlay_content, end: 'playing', align: 'top'},
|
||||
@@ -454,7 +450,7 @@ if (!video_data.params.listen && video_data.params.annotations) {
|
||||
if (target === 'current') {
|
||||
location.href = path;
|
||||
} else if (target === 'new') {
|
||||
open(path, '_blank', 'noopener,noreferrer');
|
||||
open(path, '_blank');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -589,13 +585,6 @@ const toggle_captions = (function () {
|
||||
};
|
||||
})();
|
||||
|
||||
// For real-time updates to captions (if currently showing)
|
||||
function update_captions() {
|
||||
if (document.body.querySelector('.vjs-text-track-cue')) {
|
||||
toggle_captions(); toggle_captions();
|
||||
}
|
||||
}
|
||||
|
||||
function toggle_fullscreen() {
|
||||
player.isFullscreen() ? player.exitFullscreen() : player.requestFullscreen();
|
||||
}
|
||||
@@ -608,34 +597,6 @@ function increase_playback_rate(steps) {
|
||||
player.playbackRate(options.playbackRates[newIndex]);
|
||||
}
|
||||
|
||||
function increase_caption_size(steps) {
|
||||
const maxIndex = options.fontPercent.length - 1;
|
||||
const fontPercent = player.textTrackSettings.getValues().fontPercent || 1.25;
|
||||
const curIndex = options.fontPercent.indexOf(fontPercent);
|
||||
let newIndex = curIndex + steps;
|
||||
newIndex = helpers.clamp(newIndex, 0, maxIndex);
|
||||
player.textTrackSettings.setValues({ fontPercent: options.fontPercent[newIndex] });
|
||||
update_captions();
|
||||
}
|
||||
|
||||
function toggle_caption_window() {
|
||||
const numOptions = options.windowOpacity.length;
|
||||
const windowOpacity = player.textTrackSettings.getValues().windowOpacity || '0';
|
||||
const curIndex = options.windowOpacity.indexOf(windowOpacity);
|
||||
const newIndex = (curIndex + 1) % numOptions;
|
||||
player.textTrackSettings.setValues({ windowOpacity: options.windowOpacity[newIndex] });
|
||||
update_captions();
|
||||
}
|
||||
|
||||
function toggle_caption_opacity() {
|
||||
const numOptions = options.textOpacity.length;
|
||||
const textOpacity = player.textTrackSettings.getValues().textOpacity || '1';
|
||||
const curIndex = options.textOpacity.indexOf(textOpacity);
|
||||
const newIndex = (curIndex + 1) % numOptions;
|
||||
player.textTrackSettings.setValues({ textOpacity: options.textOpacity[newIndex] });
|
||||
update_captions();
|
||||
}
|
||||
|
||||
addEventListener('keydown', function (e) {
|
||||
if (e.target.tagName.toLowerCase() === 'input') {
|
||||
// Ignore input when focus is on certain elements, e.g. form fields.
|
||||
@@ -731,12 +692,6 @@ addEventListener('keydown', function (e) {
|
||||
|
||||
case '>': action = increase_playback_rate.bind(this, 1); break;
|
||||
case '<': action = increase_playback_rate.bind(this, -1); break;
|
||||
|
||||
case '=': action = increase_caption_size.bind(this, 1); break;
|
||||
case '-': action = increase_caption_size.bind(this, -1); break;
|
||||
|
||||
case 'w': action = toggle_caption_window; break;
|
||||
case 'o': action = toggle_caption_opacity; break;
|
||||
|
||||
default:
|
||||
console.info('Unhandled key down event: %s:', decoratedKey, e);
|
||||
|
||||
@@ -141,7 +141,7 @@ function get_reddit_comments() {
|
||||
</b> \
|
||||
</p> \
|
||||
<b> \
|
||||
<a rel="noopener noreferrer" target="_blank" href="https://reddit.com{permalink}">{redditPermalinkText}</a> \
|
||||
<a rel="noopener" target="_blank" href="https://reddit.com{permalink}">{redditPermalinkText}</a> \
|
||||
</b> \
|
||||
</div> \
|
||||
<div>{contentHtml}</div> \
|
||||
|
||||
@@ -61,32 +61,31 @@ db:
|
||||
## When this setting is commented out, Invidious companion is not used.
|
||||
## Otherwise, Invidious will proxy the requests to Invidious companion.
|
||||
##
|
||||
## Note: multiple URL can be configured. In this case, Invidious will
|
||||
## Note: multiple URL can be configured. In this case, invidious will
|
||||
## randomly pick one every time video data needs to be retrieved. This
|
||||
## URL is then kept in the video metadata cache to allow video playback
|
||||
## to work. Once said cache has expired, requesting that video's data
|
||||
## again will cause a new companion URL to be picked.
|
||||
##
|
||||
## The parameter private_url is required for the internal communication
|
||||
## between Invidious companion and Invidious.
|
||||
## The parameter private_url needs to be configured for the internal
|
||||
## communication between the companion and Invidious.
|
||||
## And public_url is the public URL from which companion is listening
|
||||
## to the requests from the user(s).
|
||||
##
|
||||
## The optional parameter public_url is the public URL from which
|
||||
## Invidious companion is listening to the requests from the user(s).
|
||||
## When this setting is commented out, Invidious proxy all requests to
|
||||
## Invidious companion. Useful for simple setups.
|
||||
## Otherwise, requests from the user(s) will reach Invidious companion directly.
|
||||
## And you will need to configure a reverse proxy with separate routes
|
||||
## for Invidious and Invidious companion.
|
||||
## Read the post-install documentation for advanced reverse proxy
|
||||
## documentation: https://docs.invidious.io/installation/#post-install-configuration
|
||||
## If you are using a reverse proxy then you will probably need to
|
||||
## configure the public_url to be the same as the domain used for Invidious.
|
||||
## Also apply when used from an external IP address (without a domain).
|
||||
## Examples: https://MYINVIDIOUSDOMAIN or http://192.168.1.100:8282
|
||||
##
|
||||
## Both parameter can have identical URL when Invidious is hosted in
|
||||
## an internal network or at home or locally (localhost).
|
||||
##
|
||||
## Accepted values: "http(s)://<IP-HOSTNAME>:<Port>"
|
||||
## Default: <none>
|
||||
##
|
||||
#invidious_companion:
|
||||
# - private_url: "http://localhost:8282/companion"
|
||||
# # Uncomment for advanced reverse proxy configuration (see above).
|
||||
# # public_url: "http://localhost:8282/companion"
|
||||
# - private_url: "http://localhost:8282"
|
||||
# public_url: "http://localhost:8282"
|
||||
|
||||
##
|
||||
## API key for Invidious companion, used for securing the communication
|
||||
@@ -207,7 +206,7 @@ https_only: false
|
||||
#disable_proxy: false
|
||||
|
||||
##
|
||||
## Size of the HTTP pool used to connect to youtube. Each
|
||||
## Max size of the HTTP pool used to connect to youtube. Each
|
||||
## domain ('youtube.com', 'ytimg.com', ...) has its own pool.
|
||||
##
|
||||
## Accepted values: a positive integer
|
||||
@@ -215,6 +214,16 @@ https_only: false
|
||||
##
|
||||
#pool_size: 100
|
||||
|
||||
##
|
||||
## Amount of seconds to wait for a client to be free from the pool
|
||||
## before raising an error
|
||||
##
|
||||
##
|
||||
## Accepted values: a positive integer
|
||||
## Default: 5
|
||||
##
|
||||
#pool_checkout_timeout: 5
|
||||
|
||||
|
||||
##
|
||||
## Additional cookies to be sent when requesting the youtube API.
|
||||
@@ -866,7 +875,7 @@ default_user_preferences:
|
||||
##
|
||||
## Default dash video quality.
|
||||
##
|
||||
## Note: this setting only takes effect if the
|
||||
## Note: this setting only takes effet if the
|
||||
## 'quality' parameter is set to "dash".
|
||||
##
|
||||
## Accepted values:
|
||||
|
||||
@@ -14,10 +14,6 @@ services:
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:3000:3000"
|
||||
depends_on:
|
||||
invidious-db:
|
||||
condition: service_healthy
|
||||
restart: true
|
||||
environment:
|
||||
# Please read the following file for a comprehensive list of all available
|
||||
# configuration options and their associated syntax:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM crystallang/crystal:1.16.3-alpine AS builder
|
||||
FROM crystallang/crystal:1.16.2-alpine AS builder
|
||||
|
||||
RUN apk add --no-cache sqlite-static yaml-static
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "مُعرِّف المُستخدم",
|
||||
"Password": "كلمة المرور",
|
||||
"Time (h:mm:ss):": "الوقت (h:mm:ss):",
|
||||
"Text CAPTCHA": "نص الكابتشا",
|
||||
"Image CAPTCHA": "صورة الكابتشا",
|
||||
"Sign In": "إنشاء حساب",
|
||||
"Register": "التسجيل",
|
||||
"E-mail": "البريد الإلكتروني",
|
||||
@@ -152,8 +154,8 @@
|
||||
"View YouTube comments": "عرض تعليقات اليوتيوب",
|
||||
"View more comments on Reddit": "عرض المزيد من التعليقات على\\من موقع ريديت",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "عرض `x` تعليق",
|
||||
"": "عرض `x` تعليقات"
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "عرض `x` تعليقات",
|
||||
"": "عرض `x` تعليقات."
|
||||
},
|
||||
"View Reddit comments": "عرض تعليقات ريديت",
|
||||
"Hide replies": "إخفاء الردود",
|
||||
@@ -564,11 +566,5 @@
|
||||
"carousel_skip": "تخطي الكاروسيل",
|
||||
"carousel_go_to": "انتقل إلى الشريحة `x`",
|
||||
"preferences_preload_label": "التحميل المسبق لبيانات الفيديو: ",
|
||||
"Filipino (auto-generated)": "الفلبينية (المولدة تلقائيًا)",
|
||||
"channel_tab_courses_label": "الدورات",
|
||||
"channel_tab_posts_label": "المنشورات",
|
||||
"First page": "الصفحة الأولى",
|
||||
"timeline_parse_error_placeholder_heading": "غير قادر على تحليل العنصر",
|
||||
"timeline_parse_error_placeholder_message": "واجه Invidious خطأ أثناء محاولة تحليل هذا العنصر. لمزيد من المعلومات انظر أدناه:",
|
||||
"timeline_parse_error_show_technical_details": "عرض التفاصيل التقنية"
|
||||
"Filipino (auto-generated)": "الفلبينية (المولدة تلقائيًا)"
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
"Spanish (Spain)": "Испански (Испания)",
|
||||
"invidious": "Invidious",
|
||||
"crash_page_refresh": "пробвал да <a href=\"`x`\">опресниш страницата</a>",
|
||||
"Image CAPTCHA": "CAPTCHA с Изображение",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"Chinese (Hong Kong)": "Китайски (Хонг Конг)",
|
||||
"Import Invidious data": "Импортиране на Invidious JSON информацията",
|
||||
@@ -402,7 +403,7 @@
|
||||
"comments_view_x_replies": "Виж {{count}} отговор",
|
||||
"comments_view_x_replies_plural": "Виж {{count}} отговора",
|
||||
"footer_original_source_code": "Оригинален изходен код",
|
||||
"Import YouTube subscriptions": "Импортиране на YouTube-CSV/OPML абонаменти",
|
||||
"Import YouTube subscriptions": "Импортиране на YouTube/OPML абонаменти",
|
||||
"Lithuanian": "Литовски",
|
||||
"Nyanja": "Нянджа",
|
||||
"Updated `x` ago": "Актуализирано преди `x`",
|
||||
@@ -456,6 +457,7 @@
|
||||
"next_steps_error_message": "След което можеш да пробваш да: ",
|
||||
"Hide annotations": "Скрий анотации",
|
||||
"Standard YouTube license": "Стандартен YouTube лиценз",
|
||||
"Text CAPTCHA": "Текст CAPTCHA",
|
||||
"Log in/register": "Вход/регистрация",
|
||||
"Punjabi": "Пенджаби",
|
||||
"Change password": "Смяна на паролата",
|
||||
@@ -491,8 +493,5 @@
|
||||
"Add to playlist: ": "Добави към плейлист: ",
|
||||
"Answer": "Отговор",
|
||||
"Search for videos": "Търсене на видеа",
|
||||
"The Popular feed has been disabled by the administrator.": "Популярната страница е деактивирана от администратора.",
|
||||
"Filipino (auto-generated)": "Филипински (автоматично генериран)",
|
||||
"preferences_preload_label": "Предварително заредете видео данни: ",
|
||||
"First page": "Първа страница"
|
||||
"The Popular feed has been disabled by the administrator.": "Популярната страница е деактивирана от администратора."
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
"User ID": "ইউজার আইডি",
|
||||
"Password": "পাসওয়ার্ড",
|
||||
"Time (h:mm:ss):": "সময় (ঘণ্টা:মিনিট:সেকেন্ড):",
|
||||
"Text CAPTCHA": "টেক্সট ক্যাপচা",
|
||||
"Image CAPTCHA": "চিত্র ক্যাপচা",
|
||||
"Sign In": "সাইন ইন",
|
||||
"Register": "নিবন্ধন",
|
||||
"E-mail": "ই-মেইল",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ইউজার আইডি",
|
||||
"Password": "পাসওয়ার্ড",
|
||||
"Time (h:mm:ss):": "সময় (ঘণ্টা:মিনিট:সেকেন্ড):",
|
||||
"Text CAPTCHA": "টেক্সট ক্যাপচা",
|
||||
"Image CAPTCHA": "চিত্র ক্যাপচা",
|
||||
"Sign In": "সাইন ইন",
|
||||
"Register": "নিবন্ধন",
|
||||
"E-mail": "ই-মেইল",
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
"comments_points_count_plural": "{{count}} punts",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"Create playlist": "Crear llista de reproducció",
|
||||
"Text CAPTCHA": "Text CAPTCHA",
|
||||
"Next page": "Pàgina següent",
|
||||
"preferences_category_visual": "Preferències visuals",
|
||||
"preferences_unseen_only_label": "Mostra només no vistos: ",
|
||||
@@ -203,7 +204,7 @@
|
||||
"View JavaScript license information.": "Consulta la informació de la llicència de JavaScript.",
|
||||
"Playlist privacy": "Privacitat de la llista de reproducció",
|
||||
"search_message_no_results": "No s'han trobat resultats.",
|
||||
"search_message_use_another_instance": "També es pot <a href=\"`x`\">cercar en una altra instància</a>.",
|
||||
"search_message_use_another_instance": " També es pot <a href=\"`x`\">buscar en una altra instància</a>.",
|
||||
"Genre: ": "Gènere: ",
|
||||
"Hidden field \"challenge\" is a required field": "El camp ocult \"repte\" és un camp obligatori",
|
||||
"Burmese": "Birmà",
|
||||
@@ -386,6 +387,7 @@
|
||||
"Delete account?": "Esborrar compte?",
|
||||
"Please log in": "Si us plau inicieu sessió",
|
||||
"Import NewPipe data (.zip)": "Importar dades de NewPipe (.zip)",
|
||||
"Image CAPTCHA": "Imatge CAPTCHA",
|
||||
"channel_tab_streams_label": "Transmissions en directe",
|
||||
"preferences_category_misc": "Preferències diverses",
|
||||
"preferences_annotations_subscribed_label": "Mostra les anotacions per defecte dels canals subscrits? ",
|
||||
@@ -487,16 +489,5 @@
|
||||
"generic_button_delete": "Suprimeix",
|
||||
"Import YouTube watch history (.json)": "Importa l'historial de visualitzacions de YouTube (.json)",
|
||||
"Answer": "Resposta",
|
||||
"toggle_theme": "Commuta el tema",
|
||||
"Add to playlist": "Afegeix a la llista de reproducció",
|
||||
"Add to playlist: ": "Afegeix a la llista de reproducció: ",
|
||||
"Search for videos": "Cercar vídeos",
|
||||
"carousel_slide": "Diapositiva {{current}} de {{total}}",
|
||||
"preferences_preload_label": "Precarregar dades del vídeo: ",
|
||||
"carousel_go_to": "Anar a la diapositiva `x`",
|
||||
"First page": "Primera pàgina",
|
||||
"Filipino (auto-generated)": "Filipí (generat automàticament)",
|
||||
"channel_tab_courses_label": "Cursos",
|
||||
"channel_tab_posts_label": "Missatges",
|
||||
"carousel_skip": "Saltar l'exhibició"
|
||||
"toggle_theme": "Commuta el tema"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ID uživatele",
|
||||
"Password": "Heslo",
|
||||
"Time (h:mm:ss):": "Čas (h:mm:ss):",
|
||||
"Text CAPTCHA": "Textové CAPTCHA",
|
||||
"Image CAPTCHA": "Obrázkové CAPTCHA",
|
||||
"Sign In": "Přihlásit se",
|
||||
"Register": "Vytvořit účet",
|
||||
"E-mail": "E-mail",
|
||||
@@ -513,13 +515,5 @@
|
||||
"carousel_skip": "Přeskočit galerii",
|
||||
"carousel_go_to": "Přejít na snímek `x`",
|
||||
"preferences_preload_label": "Předem načíst data videa: ",
|
||||
"Filipino (auto-generated)": "Filipínština (vytvořeno automaticky)",
|
||||
"First page": "První stránka",
|
||||
"channel_tab_courses_label": "Kurzy",
|
||||
"channel_tab_posts_label": "Příspěvky",
|
||||
"timeline_parse_error_show_technical_details": "Zobrazit technické podrobnosti",
|
||||
"timeline_parse_error_placeholder_message": "Invidious narazil při pokusu o zpracování této položky na chybu. Další informace naleznete níže:",
|
||||
"timeline_parse_error_placeholder_heading": "Nepodařilo se zpracovat položku",
|
||||
"preferences_default_playlist": "Výchozí playlist: ",
|
||||
"preferences_default_playlist_none": "Nenastaven žádný výchozí playlist"
|
||||
"Filipino (auto-generated)": "Filipínština (vytvořeno automaticky)"
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
"An alternative front-end to YouTube": "Pen blaen amgen i YouTube",
|
||||
"source": "ffynhonnell",
|
||||
"Log in": "Mewngofnodi",
|
||||
"Log in/register": "Mewngofnodi/cofrestru",
|
||||
"Log in/register": "Mewngofnodi/Cofrestru",
|
||||
"User ID": "Enw defnyddiwr",
|
||||
"preferences_quality_option_dash": "DASH (ansawdd addasol)",
|
||||
"Sign In": "Mewngofnodi",
|
||||
@@ -162,6 +162,8 @@
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"invidious": "Invidious",
|
||||
"Text CAPTCHA": "CAPTCHA testun",
|
||||
"Image CAPTCHA": "CAPTCHA delwedd",
|
||||
"preferences_continue_label": "Chwarae'r fideo nesaf fel rhagosodiad: ",
|
||||
"preferences_continue_autoplay_label": "Chwarae'r fideo nesaf yn awtomatig: ",
|
||||
"preferences_listen_label": "Sain yn unig: ",
|
||||
@@ -379,32 +381,5 @@
|
||||
"channel_tab_channels_label": "Sianeli",
|
||||
"channel_tab_community_label": "Cymuned",
|
||||
"channel_tab_shorts_label": "Fideos byrion",
|
||||
"channel_tab_videos_label": "Fideos",
|
||||
"generic_playlists_count_0": "{{count}} rhestr chwarae",
|
||||
"generic_playlists_count_1": "{{count}} rhestr chwarae",
|
||||
"generic_playlists_count_2": "{{count}} rhestri chwarae",
|
||||
"generic_playlists_count_3": "{{count}} rhestri chwarae",
|
||||
"generic_playlists_count_4": "{{count}} rhestri chwarae",
|
||||
"generic_playlists_count_5": "{{count}} rhestri chwarae",
|
||||
"New passwords must match": "Rhaid i'r cyfrineiriau newydd cyfateb â'i gilydd",
|
||||
"last": "diwethaf",
|
||||
"First page": "Tudalen gyntaf",
|
||||
"preferences_preload_label": "Cynlwytho data fideo: ",
|
||||
"preferences_extend_desc_label": "Ymestyn disgrifiad fideo'n awtomatig: ",
|
||||
"preferences_vr_mode_label": "Fideos rhyngweithiol 360 gradd (angen WebGL): ",
|
||||
"preferences_video_loop_label": "Doleniwch bob amser: ",
|
||||
"Top enabled: ": "Tudalen fideos brig wedi'i alluogi: ",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Allforio tanysgrifiadau ar fformat OPML (i NewPipe a FreeTube)",
|
||||
"Export subscriptions as OPML": "Allforio tanysgrifiadau ar fformat OPML",
|
||||
"preferences_annotations_subscribed_label": "Ddangos nodiadau sianeli tanysgrifiwyd fel rhagosodiad? ",
|
||||
"Redirect homepage to feed: ": "Ailgyfeirio tudalen gartref i'r borthiant: ",
|
||||
"preferences_feed_menu_label": "Dewislen porthiant: ",
|
||||
"Login enabled: ": "Mewngofnodi wedi'i alluogi: ",
|
||||
"tokens_count_0": "",
|
||||
"tokens_count_1": "tocyn",
|
||||
"tokens_count_2": "",
|
||||
"tokens_count_3": "",
|
||||
"tokens_count_4": "tocynnau",
|
||||
"tokens_count_5": "",
|
||||
"Source available here.": "Tarddle ar gael yma."
|
||||
"channel_tab_videos_label": "Fideos"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Bruger ID",
|
||||
"Password": "Kodeord",
|
||||
"Time (h:mm:ss):": "Tid (t:mm:ss):",
|
||||
"Text CAPTCHA": "Tekst CAPTCHA",
|
||||
"Image CAPTCHA": "Billede CAPTCHA",
|
||||
"Sign In": "Log ind",
|
||||
"Register": "Registrer",
|
||||
"E-mail": "E-mail",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"Next page": "Nächste Seite",
|
||||
"Previous page": "Vorherige Seite",
|
||||
"First page": "Erste Seite",
|
||||
"Clear watch history?": "Wiedergabeverlauf löschen?",
|
||||
"Clear watch history?": "Verlauf löschen?",
|
||||
"New password": "Neues Passwort",
|
||||
"New passwords must match": "Neue Passwörter müssen übereinstimmen",
|
||||
"Authorize token?": "Token autorisieren?",
|
||||
@@ -40,6 +40,8 @@
|
||||
"User ID": "Benutzer-ID",
|
||||
"Password": "Passwort",
|
||||
"Time (h:mm:ss):": "Zeit (h:mm:ss):",
|
||||
"Text CAPTCHA": "Text CAPTCHA",
|
||||
"Image CAPTCHA": "Bild CAPTCHA",
|
||||
"Sign In": "Anmelden",
|
||||
"Register": "Registrieren",
|
||||
"E-mail": "E-Mail",
|
||||
@@ -106,11 +108,11 @@
|
||||
"Top enabled: ": "Top aktiviert? ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA aktiviert? ",
|
||||
"Login enabled: ": "Anmeldung aktiviert: ",
|
||||
"Registration enabled: ": "Registrierung aktiviert: ",
|
||||
"Report statistics: ": "Statistiken berichten: ",
|
||||
"Registration enabled: ": "Registrierung aktiviert? ",
|
||||
"Report statistics: ": "Statistiken berichten? ",
|
||||
"Save preferences": "Einstellungen speichern",
|
||||
"Subscription manager": "Abonnementverwaltung",
|
||||
"Token manager": "Tokenverwaltung",
|
||||
"Token manager": "Tokenverwalter",
|
||||
"Token": "Token",
|
||||
"Import/export": "Importieren/Exportieren",
|
||||
"unsubscribe": "abbestellen",
|
||||
@@ -120,20 +122,20 @@
|
||||
"Log out": "Abmelden",
|
||||
"Released under the AGPLv3 on Github.": "Auf GitHub unter der AGPLv3 Lizenz veröffentlicht.",
|
||||
"Source available here.": "Quellcode verfügbar hier.",
|
||||
"View JavaScript license information.": "Javascript-Lizenzinformationen anzeigen.",
|
||||
"View JavaScript license information.": "Javascript Lizenzinformationen anzeigen.",
|
||||
"View privacy policy.": "Datenschutzerklärung einsehen.",
|
||||
"Trending": "Angesagt",
|
||||
"Public": "Öffentlich",
|
||||
"Unlisted": "Nicht gelistet",
|
||||
"Unlisted": "Nicht aufgeführt",
|
||||
"Private": "Privat",
|
||||
"View all playlists": "Alle Wiedergabelisten anzeigen",
|
||||
"Updated `x` ago": "Aktualisiert vor `x`",
|
||||
"Delete playlist `x`?": "Wiedergabeliste `x` löschen?",
|
||||
"Updated `x` ago": "Aktualisiert `x` vor",
|
||||
"Delete playlist `x`?": "Wiedergabeliste löschen `x`?",
|
||||
"Delete playlist": "Wiedergabeliste löschen",
|
||||
"Create playlist": "Wiedergabeliste erstellen",
|
||||
"Title": "Titel",
|
||||
"Playlist privacy": "Wiedergabelisten-Privatsphäre",
|
||||
"Editing playlist `x`": "Wiedergabeliste `x` bearbeiten",
|
||||
"Playlist privacy": "Vertrauliche Wiedergabeliste",
|
||||
"Editing playlist `x`": "Wiedergabeliste bearbeiten `x`",
|
||||
"Show more": "Mehr anzeigen",
|
||||
"Show less": "Weniger anzeigen",
|
||||
"Watch on YouTube": "Video auf YouTube ansehen",
|
||||
@@ -149,12 +151,12 @@
|
||||
"Blacklisted regions: ": "Unerlaubte Regionen: ",
|
||||
"Shared `x`": "Geteilt `x`",
|
||||
"Premieres in `x`": "Premiere in `x`",
|
||||
"Premieres `x`": "Premiere `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hallo! Anscheinend hast du JavaScript deaktiviert. Klicke hier, um Kommentare anzuzeigen, beachte, dass es etwas länger dauern kann, um sie zu laden.",
|
||||
"Premieres `x`": "Erster Start `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hallo! Anscheinend haben Sie JavaScript deaktiviert. Klicken Sie hier um Kommentare anzuzeigen, beachten sie dass es etwas länger dauern kann um sie zu laden.",
|
||||
"View YouTube comments": "YouTube Kommentare anzeigen",
|
||||
"View more comments on Reddit": "Mehr Kommentare auf Reddit anzeigen",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` Kommentar anzeigen",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` Kommentare anzeigen",
|
||||
"": "`x` Kommentare anzeigen"
|
||||
},
|
||||
"View Reddit comments": "Reddit Kommentare anzeigen",
|
||||
@@ -182,7 +184,7 @@
|
||||
"Empty playlist": "Wiedergabeliste ist leer",
|
||||
"Not a playlist.": "Ungültige Wiedergabeliste.",
|
||||
"Playlist does not exist.": "Wiedergabeliste existiert nicht.",
|
||||
"Could not pull trending pages.": "Beliebt-Seiten konnten nicht geladen werden.",
|
||||
"Could not pull trending pages.": "Trendenz-Seiten konnten nicht geladen werden.",
|
||||
"Hidden field \"challenge\" is a required field": "Verstecktes Feld „challenge“ ist eine erforderliche Eingabe",
|
||||
"Hidden field \"token\" is a required field": "Verstecktes Feld „token“ ist eine erforderliche Eingabe",
|
||||
"Erroneous challenge": "Ungültiger Test",
|
||||
@@ -190,7 +192,7 @@
|
||||
"No such user": "Ungültiger Benutzer",
|
||||
"Token is expired, please try again": "Token ist abgelaufen, bitte erneut versuchen",
|
||||
"English": "Englisch",
|
||||
"English (auto-generated)": "Englisch (automatisch generiert)",
|
||||
"English (auto-generated)": "Englisch (automatisch erzeugt)",
|
||||
"Afrikaans": "Afrikaans",
|
||||
"Albanian": "Albanisch",
|
||||
"Amharic": "Amharisch",
|
||||
@@ -311,7 +313,7 @@
|
||||
"Download": "Herunterladen",
|
||||
"Download as: ": "Herunterladen als: ",
|
||||
"%A %B %-d, %Y": "%A %-d %B %Y",
|
||||
"(edited)": "(bearbeitet)",
|
||||
"(edited)": "(editiert)",
|
||||
"YouTube comment permalink": "YouTube-Kommentar Permalink",
|
||||
"permalink": "Permalink",
|
||||
"`x` marked it with a ❤": "`x` markierte es mit einem ❤",
|
||||
@@ -319,7 +321,7 @@
|
||||
"Video mode": "Videomodus",
|
||||
"channel_tab_videos_label": "Videos",
|
||||
"Playlists": "Wiedergabelisten",
|
||||
"channel_tab_community_label": "Community",
|
||||
"channel_tab_community_label": "Gemeinschaft",
|
||||
"search_filters_sort_option_relevance": "Relevanz",
|
||||
"search_filters_sort_option_rating": "Bewertung",
|
||||
"search_filters_sort_option_date": "Hochladedatum",
|
||||
@@ -327,7 +329,7 @@
|
||||
"search_filters_type_label": "Inhaltstyp",
|
||||
"search_filters_duration_label": "Dauer",
|
||||
"search_filters_features_label": "Eigenschaften",
|
||||
"search_filters_sort_label": "Sortieren nach",
|
||||
"search_filters_sort_label": "sortieren",
|
||||
"search_filters_date_option_hour": "Letzte Stunde",
|
||||
"search_filters_date_option_today": "Heute",
|
||||
"search_filters_date_option_week": "Diese Woche",
|
||||
@@ -339,7 +341,7 @@
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Anzeigen",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Untertitel/CC",
|
||||
"search_filters_features_option_subtitles": "Untertitel / CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Live",
|
||||
@@ -356,7 +358,7 @@
|
||||
"footer_modfied_source_code": "Modifizierter Quellcode",
|
||||
"footer_documentation": "Dokumentation",
|
||||
"footer_source_code": "Quellcode",
|
||||
"adminprefs_modified_source_code_url_label": "URL zum Repository des modifizierten Quellcodes",
|
||||
"adminprefs_modified_source_code_url_label": "URL zum Repositorie des modifizierten Quellcodes",
|
||||
"search_filters_duration_option_short": "Kurz (< 4 Minuten)",
|
||||
"preferences_region_label": "Land der Inhalte: ",
|
||||
"preferences_quality_option_dash": "DASH (adaptive Qualität)",
|
||||
@@ -395,7 +397,7 @@
|
||||
"generic_videos_count_plural": "{{count}} Videos",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} ungesehene Benachrichtung",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} ungesehene Benachrichtungen",
|
||||
"crash_page_refresh": "Versucht hast, <a href=\"`x`\">die Seite neu zu laden</a>",
|
||||
"crash_page_refresh": "Versucht haben, <a href=\"`x`\">die Seite neu zu laden</a>",
|
||||
"comments_view_x_replies": "{{count}} Antwort anzeigen",
|
||||
"comments_view_x_replies_plural": "{{count}} Antworten anzeigen",
|
||||
"generic_count_years": "{{count}} Jahr",
|
||||
@@ -404,15 +406,15 @@
|
||||
"generic_count_weeks_plural": "{{count}} Wochen",
|
||||
"generic_count_days": "{{count}} Tag",
|
||||
"generic_count_days_plural": "{{count}} Tage",
|
||||
"crash_page_before_reporting": "Bevor du einen Bug meldest, stelle sicher, dass du:",
|
||||
"crash_page_switch_instance": "Eine <a href=\"`x`\">andere Instanz</a> versucht hast",
|
||||
"crash_page_before_reporting": "Bevor Sie einen Bug melden, stellen Sie sicher, dass Sie:",
|
||||
"crash_page_switch_instance": "Eine <a href=\"`x`\">andere Instanz</a> versucht haben",
|
||||
"generic_count_hours": "{{count}} Stunde",
|
||||
"generic_count_hours_plural": "{{count}} Stunden",
|
||||
"generic_count_minutes": "{{count}} Minute",
|
||||
"generic_count_minutes_plural": "{{count}} Minuten",
|
||||
"crash_page_read_the_faq": "Das <a href=\"`x`\">FAQ</a> gelesen hast",
|
||||
"crash_page_search_issue": "Nach <a href=\"`x`\">bereits gemeldeten Bugs auf GitHub</a> gesucht hast",
|
||||
"crash_page_report_issue": "Wenn all dies nicht geholfen hat, <a href=\"`x`\">öffne bitte ein neues Problem (issue) auf GitHub</a> (vorzugsweise auf Englisch) und füge den folgenden Text in deine Nachricht ein (bitte übersetze diesen Text NICHT):",
|
||||
"crash_page_read_the_faq": "Das <a href=\"`x`\">FAQ</a> gelesen haben",
|
||||
"crash_page_search_issue": "Nach <a href=\"`x`\">bereits gemeldeten Bugs auf GitHub</a> gesucht haben",
|
||||
"crash_page_report_issue": "Wenn all dies nicht geholfen hat, <a href=\"`x`\">öffnen Sie bitte ein neues Problem (issue) auf Github</a> (vorzugsweise auf Englisch) und fügen Sie den folgenden Text in Ihre Nachricht ein (bitte übersetzen Sie diesen Text NICHT):",
|
||||
"generic_views_count": "{{count}} Aufruf",
|
||||
"generic_views_count_plural": "{{count}} Aufrufe",
|
||||
"generic_count_seconds": "{{count}} Sekunde",
|
||||
@@ -423,7 +425,7 @@
|
||||
"tokens_count_plural": "{{count}} Tokens",
|
||||
"comments_points_count": "{{count}} Punkt",
|
||||
"comments_points_count_plural": "{{count}} Punkte",
|
||||
"crash_page_you_found_a_bug": "Anscheinend hast du einen Fehler in Invidious gefunden!",
|
||||
"crash_page_you_found_a_bug": "Anscheinend haben Sie einen Fehler in Invidious gefunden!",
|
||||
"generic_count_months": "{{count}} Monat",
|
||||
"generic_count_months_plural": "{{count}} Monaten",
|
||||
"Cantonese (Hong Kong)": "Kantonesisch (Hong Kong)",
|
||||
@@ -453,8 +455,8 @@
|
||||
"Korean (auto-generated)": "Koreanisch (automatisch generiert)",
|
||||
"Portuguese (auto-generated)": "Portugiesisch (automatisch generiert)",
|
||||
"search_filters_title": "Filtern",
|
||||
"search_message_change_filters_or_query": "Versuche, deine Suchanfrage zu erweitern und/oder die Filter zu ändern.",
|
||||
"search_message_use_another_instance": "Du kannst auch <a href=\"`x`\">auf einer anderen Instanz suchen</a>.",
|
||||
"search_message_change_filters_or_query": "Versuchen Sie, Ihre Suchanfrage zu erweitern und/oder die Filter zu ändern.",
|
||||
"search_message_use_another_instance": "Sie können auch <a href=\"`x`\">auf einer anderen Instanz suchen</a>.",
|
||||
"Popular enabled: ": "„Beliebt“-Seite aktiviert: ",
|
||||
"search_message_no_results": "Keine Ergebnisse gefunden.",
|
||||
"search_filters_duration_option_medium": "Mittel (4 - 20 Minuten)",
|
||||
@@ -464,7 +466,7 @@
|
||||
"search_filters_duration_option_none": "Beliebige Länge",
|
||||
"search_filters_date_label": "Upload-Datum",
|
||||
"search_filters_date_option_none": "Beliebiges Datum",
|
||||
"error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. <a href=\"`x`\">Klicke hier, um zur Startseite der Wiedergabeliste zu gelangen.</a>",
|
||||
"error_video_not_in_playlist": "Das angeforderte Video existiert nicht in dieser Wiedergabeliste. <a href=\"`x`\">Klicken Sie hier, um zur Startseite der Wiedergabeliste zu gelangen.</a>",
|
||||
"channel_tab_shorts_label": "Shorts",
|
||||
"channel_tab_streams_label": "Livestreams",
|
||||
"Music in this video": "Musik in diesem Video",
|
||||
@@ -497,10 +499,5 @@
|
||||
"carousel_go_to": "Zu Element `x` springen",
|
||||
"carousel_slide": "Seite {{current}} von {{total}}",
|
||||
"carousel_skip": "Galerie überspringen",
|
||||
"Filipino (auto-generated)": "Philippinisch (automatisch generiert)",
|
||||
"channel_tab_courses_label": "Kurse",
|
||||
"channel_tab_posts_label": "Beiträge",
|
||||
"timeline_parse_error_show_technical_details": "Technische Details anzeigen",
|
||||
"timeline_parse_error_placeholder_heading": "Element kann nicht geparsed werden",
|
||||
"timeline_parse_error_placeholder_message": "Invidious ist beim Parsen dieses Elements auf einen Fehler gestossen. Für weitere Informationen siehe unten:"
|
||||
"Filipino (auto-generated)": "Philippinisch (automatisch generiert)"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Ταυτότητα χρήστη",
|
||||
"Password": "Κωδικός πρόσβασης",
|
||||
"Time (h:mm:ss):": "Ώρα (ω:λλ:δδ):",
|
||||
"Text CAPTCHA": "Κείμενο CAPTCHA",
|
||||
"Image CAPTCHA": "Εικόνα CAPTCHA",
|
||||
"Sign In": "Εγγραφή",
|
||||
"Register": "Εγγραφή",
|
||||
"E-mail": "Ηλεκτρονικό ταχυδρομείο",
|
||||
@@ -488,7 +490,7 @@
|
||||
"Search for videos": "Αναζήτηση βίντεο",
|
||||
"The Popular feed has been disabled by the administrator.": "Η δημοφιλής ροή έχει απενεργοποιηθεί από τον διαχειριστή.",
|
||||
"Answer": "Απάντηση",
|
||||
"Add to playlist": "Προσθήκη στην λίστα αναπαραγωγής",
|
||||
"Add to playlist": "Προσθήκη στην λίιστα αναπαραγωγής",
|
||||
"Add to playlist: ": "Προσθήκη στην λίστα αναπαραγωγής : ",
|
||||
"carousel_slide": "Εικόνα {{current}}απο {{total}}",
|
||||
"carousel_go_to": "Πήγαινε στην εικόνα`x`",
|
||||
@@ -496,8 +498,5 @@
|
||||
"Import YouTube watch history (.json)": "Εισαγωγή ιστορικού προβολής YouTube (.json)",
|
||||
"Filipino (auto-generated)": "Φιλιππινέζικα (αυτόματη παραγωγή)",
|
||||
"preferences_preload_label": "Προφόρτιση δεδομένων βίντεο: ",
|
||||
"carousel_skip": "Αποφυγή εμφάνισης εικόνων",
|
||||
"First page": "Πρώτη σελίδα",
|
||||
"channel_tab_courses_label": "Μαθήματα",
|
||||
"channel_tab_posts_label": "Δημοσιεύσεις"
|
||||
"carousel_skip": "Αποφυγή εμφάνισης εικόνων"
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
"User ID": "User ID",
|
||||
"Password": "Password",
|
||||
"Time (h:mm:ss):": "Time (h:mm:ss):",
|
||||
"Text CAPTCHA": "Text CAPTCHA",
|
||||
"Image CAPTCHA": "Image CAPTCHA",
|
||||
"Sign In": "Sign In",
|
||||
"Register": "Register",
|
||||
"E-mail": "E-mail",
|
||||
@@ -122,8 +124,6 @@
|
||||
"Redirect homepage to feed: ": "Redirect homepage to feed: ",
|
||||
"preferences_max_results_label": "Number of videos shown in feed: ",
|
||||
"preferences_sort_label": "Sort videos by: ",
|
||||
"preferences_default_playlist": "Default playlist: ",
|
||||
"preferences_default_playlist_none": "No default playlist set",
|
||||
"published": "published",
|
||||
"published - reverse": "published - reverse",
|
||||
"alphabetically": "alphabetically",
|
||||
@@ -501,8 +501,5 @@
|
||||
"toggle_theme": "Toggle Theme",
|
||||
"carousel_slide": "Slide {{current}} of {{total}}",
|
||||
"carousel_skip": "Skip the Carousel",
|
||||
"carousel_go_to": "Go to slide `x`",
|
||||
"timeline_parse_error_placeholder_heading": "Unable to parse item",
|
||||
"timeline_parse_error_placeholder_message": "Invidious encountered an error while trying to parse this item. For more information see below:",
|
||||
"timeline_parse_error_show_technical_details": "Show technical details"
|
||||
"carousel_go_to": "Go to slide `x`"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Uzula identigilo",
|
||||
"Password": "Pasvorto",
|
||||
"Time (h:mm:ss):": "Horo (h:mm:ss):",
|
||||
"Text CAPTCHA": "Teksta CAPTCHA",
|
||||
"Image CAPTCHA": "Bilda CAPTCHA",
|
||||
"Sign In": "Ensaluti",
|
||||
"Register": "Registriĝi",
|
||||
"E-mail": "Retpoŝto",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Nombre",
|
||||
"Password": "Contraseña",
|
||||
"Time (h:mm:ss):": "Hora (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA en texto",
|
||||
"Image CAPTCHA": "CAPTCHA en imagen",
|
||||
"Sign In": "Iniciar sesión",
|
||||
"Register": "Registrarse",
|
||||
"E-mail": "Correo",
|
||||
@@ -76,8 +78,6 @@
|
||||
"Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ",
|
||||
"preferences_max_results_label": "Número de videos mostrados en la fuente: ",
|
||||
"preferences_sort_label": "Ordenar los videos por: ",
|
||||
"preferences_default_playlist": "Lista de reproducción por defecto: ",
|
||||
"preferences_default_playlist_none": "Ninguna lista de reproducción por defecto establecida",
|
||||
"published": "fecha de publicación",
|
||||
"published - reverse": "fecha de publicación: orden inverso",
|
||||
"alphabetically": "alfabéticamente",
|
||||
@@ -187,10 +187,10 @@
|
||||
"Hidden field \"token\" is a required field": "El campo oculto «símbolo» es un campo obligatorio",
|
||||
"Erroneous challenge": "Desafío no válido",
|
||||
"Erroneous token": "Símbolo no válido",
|
||||
"No such user": "El usuario no existe",
|
||||
"No such user": "Usuario no existe",
|
||||
"Token is expired, please try again": "El símbolo ha caducado, inténtelo de nuevo",
|
||||
"English": "Inglés",
|
||||
"English (auto-generated)": "Inglés (generados automáticamente)",
|
||||
"English (auto-generated)": "Inglés (generado automáticamente)",
|
||||
"Afrikaans": "Afrikáans",
|
||||
"Albanian": "Albanés",
|
||||
"Amharic": "Amárico",
|
||||
@@ -276,7 +276,7 @@
|
||||
"Somali": "Somalí",
|
||||
"Southern Sotho": "Sesoto",
|
||||
"Spanish": "Español",
|
||||
"Spanish (Latin America)": "Español (Latinoamérica)",
|
||||
"Spanish (Latin America)": "Español (Hispanoamérica)",
|
||||
"Sundanese": "Sondanés",
|
||||
"Swahili": "Suajili",
|
||||
"Swedish": "Sueco",
|
||||
@@ -317,7 +317,7 @@
|
||||
"`x` marked it with a ❤": "`x` lo ha marcado con un ❤",
|
||||
"Audio mode": "Modo de audio",
|
||||
"Video mode": "Modo de video",
|
||||
"channel_tab_videos_label": "Vídeos",
|
||||
"channel_tab_videos_label": "Videos",
|
||||
"Playlists": "Listas de reproducción",
|
||||
"channel_tab_community_label": "Comunidad",
|
||||
"search_filters_sort_option_relevance": "Relevancia",
|
||||
@@ -412,8 +412,8 @@
|
||||
"generic_count_weeks_1": "{{count}} semanas",
|
||||
"generic_count_weeks_2": "{{count}} semanas",
|
||||
"generic_playlists_count_0": "{{count}} lista de reproducción",
|
||||
"generic_playlists_count_1": "{{count}} listas de reproducción",
|
||||
"generic_playlists_count_2": "{{count}} listas de reproducción",
|
||||
"generic_playlists_count_1": "{{count}} listas de reproducciones",
|
||||
"generic_playlists_count_2": "{{count}} listas de reproducciones",
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_videos_count_1": "{{count}} videos",
|
||||
"generic_videos_count_2": "{{count}} videos",
|
||||
@@ -437,7 +437,7 @@
|
||||
"generic_count_seconds_2": "{{count}} segundos",
|
||||
"crash_page_before_reporting": "Antes de notificar un error asegúrate de que has:",
|
||||
"crash_page_switch_instance": "probado a <a href=\"`x`\">usar otra instancia</a>",
|
||||
"crash_page_read_the_faq": "lee las <a href=\"`x`\">Preguntas Frecuentes</a>",
|
||||
"crash_page_read_the_faq": "leído las <a href=\"`x`\">Preguntas Frecuentes</a>",
|
||||
"crash_page_search_issue": "buscado <a href=\"`x`\">problemas existentes en GitHub</a>",
|
||||
"crash_page_you_found_a_bug": "¡Parece que has encontrado un error en Invidious!",
|
||||
"crash_page_refresh": "probado a <a href=\"`x`\">recargar la página</a>",
|
||||
@@ -463,7 +463,7 @@
|
||||
"Chinese (Hong Kong)": "Chino (Hong Kong)",
|
||||
"Chinese (China)": "Chino (China)",
|
||||
"Korean (auto-generated)": "Coreano (generados automáticamente)",
|
||||
"Spanish (Mexico)": "Español (México)",
|
||||
"Spanish (Mexico)": "Español (Méjico)",
|
||||
"Spanish (auto-generated)": "Español (generados automáticamente)",
|
||||
"preferences_watch_history_label": "Habilitar historial de reproducciones: ",
|
||||
"search_message_no_results": "No se han encontrado resultados.",
|
||||
@@ -480,7 +480,7 @@
|
||||
"tokens_count_2": "{{count}} tokens",
|
||||
"search_message_use_another_instance": "También puedes <a href=\"`x`\">buscar en otra instancia</a>.",
|
||||
"Popular enabled: ": "¿Habilitar la sección popular? ",
|
||||
"error_video_not_in_playlist": "El vídeo que has solicitado no existe en esta lista de reproducción. <a href=\"`x`\">Haz clic aquí para acceder a la página de inicio de la lista de reproducción.</a>",
|
||||
"error_video_not_in_playlist": "El video que solicitaste no existe en esta lista de reproducción. <a href=\"`x`\">Haz clic aquí para acceder a la página de inicio de la lista de reproducción.</a>",
|
||||
"channel_tab_streams_label": "Directos",
|
||||
"channel_tab_channels_label": "Canales",
|
||||
"channel_tab_shorts_label": "Cortos",
|
||||
@@ -500,7 +500,7 @@
|
||||
"generic_button_cancel": "Cancelar",
|
||||
"generic_button_rss": "RSS",
|
||||
"channel_tab_podcasts_label": "Podcasts",
|
||||
"channel_tab_releases_label": "Lanzamientos",
|
||||
"channel_tab_releases_label": "Publicaciones",
|
||||
"generic_channels_count_0": "{{count}} canal",
|
||||
"generic_channels_count_1": "{{count}} canales",
|
||||
"generic_channels_count_2": "{{count}} canales",
|
||||
@@ -515,11 +515,5 @@
|
||||
"carousel_skip": "Saltar el carrusel",
|
||||
"carousel_go_to": "Ir a la diapositiva `x`",
|
||||
"preferences_preload_label": "Precargar datos del vídeo: ",
|
||||
"Filipino (auto-generated)": "Filipino (generados automáticamente)",
|
||||
"channel_tab_posts_label": "Publicaciones",
|
||||
"First page": "Primera página",
|
||||
"channel_tab_courses_label": "Cursos",
|
||||
"timeline_parse_error_show_technical_details": "Enseñar detalles técnicos",
|
||||
"timeline_parse_error_placeholder_message": "Invidious ha encontrado un error al tratar de procesar este elemento. Para más información ver abajo:",
|
||||
"timeline_parse_error_placeholder_heading": "Imposible procesar este elemento"
|
||||
"Filipino (auto-generated)": "Filipino (generado automáticamente)"
|
||||
}
|
||||
|
||||
448
locales/et.json
448
locales/et.json
@@ -5,7 +5,7 @@
|
||||
"View channel on YouTube": "Vaata kanalit YouTube'is",
|
||||
"Log in": "Logi sisse",
|
||||
"Log in/register": "Logi sisse/registreeru",
|
||||
"Dark mode: ": "Tume kujundus: ",
|
||||
"Dark mode: ": "Tume režiim: ",
|
||||
"generic_videos_count": "{{count}} video",
|
||||
"generic_videos_count_plural": "{{count}} videot",
|
||||
"generic_subscribers_count": "{{count}} tellija",
|
||||
@@ -22,12 +22,12 @@
|
||||
"last": "viimane",
|
||||
"Next page": "Järgmine leht",
|
||||
"Previous page": "Eelmine leht",
|
||||
"Clear watch history?": "Kas kustutame vaatamiste ajaloo?",
|
||||
"Clear watch history?": "Kustuta vaatamiste ajalugu?",
|
||||
"New password": "Uus salasõna",
|
||||
"New passwords must match": "Uued salasõnad peavad ühtima",
|
||||
"Import and Export Data": "Impordi ja ekspordi andmed",
|
||||
"Import": "Impordi",
|
||||
"Import YouTube subscriptions": "Impordi CSV või OPML-vormingus Youtube'i tellimused",
|
||||
"Import YouTube subscriptions": "Impordi tellimused Youtube'ist/OPML-ist",
|
||||
"Import FreeTube subscriptions (.db)": "Impordi tellimused FreeTube'ist (.db)",
|
||||
"Import NewPipe data (.zip)": "Impordi NewPipe'i andmed (.zip)",
|
||||
"Export": "Ekspordi",
|
||||
@@ -37,9 +37,11 @@
|
||||
"History": "Ajalugu",
|
||||
"JavaScript license information": "JavaScripti litsentsi info",
|
||||
"source": "allikas",
|
||||
"User ID": "Kasutajatunnus",
|
||||
"User ID": "Kasutada ID",
|
||||
"Password": "Salasõna",
|
||||
"Time (h:mm:ss):": "Aeg (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA-tekst",
|
||||
"Image CAPTCHA": "CAPTCHA-foto",
|
||||
"Sign In": "Logi sisse",
|
||||
"Register": "Registreeru",
|
||||
"E-mail": "E-post",
|
||||
@@ -55,48 +57,48 @@
|
||||
"preferences_quality_dash_option_auto": "Automaatne",
|
||||
"preferences_quality_dash_option_best": "Parim",
|
||||
"preferences_quality_dash_option_worst": "Halvim",
|
||||
"preferences_volume_label": "Video helivaljus: ",
|
||||
"preferences_volume_label": "Video helitugevus: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"preferences_related_videos_label": "Näita sarnaseid videoid: ",
|
||||
"preferences_related_videos_label": "Näita sarnaseid videosid: ",
|
||||
"preferences_vr_mode_label": "Interaktiivne 360-kraadine video (vajalik WebGL): ",
|
||||
"preferences_dark_mode_label": "Kujundus: ",
|
||||
"preferences_dark_mode_label": "Teema: ",
|
||||
"dark": "tume",
|
||||
"light": "hele",
|
||||
"preferences_category_subscription": "Tellimuse eelistused",
|
||||
"preferences_category_subscription": "Tellimuse seaded",
|
||||
"preferences_max_results_label": "Avalehel näidatavate videote arv: ",
|
||||
"preferences_sort_label": "Sorteeri: ",
|
||||
"published": "avaldatud",
|
||||
"alphabetically": "tähestikulises järjekorras",
|
||||
"alphabetically - reverse": "vastupidi tähestikulises järjekorras",
|
||||
"channel name": "kanali nimi",
|
||||
"preferences_unseen_only_label": "Näita ainult vaatamata videoid: ",
|
||||
"preferences_unseen_only_label": "Näita ainult vaatamata videosid: ",
|
||||
"Only show latest video from channel: ": "Näita ainult viimast videot: ",
|
||||
"preferences_notifications_only_label": "Näita ainult teavitusi (kui neid on): ",
|
||||
"Enable web notifications": "Luba veebiteavitused",
|
||||
"`x` uploaded a video": "`x` laadis video üles",
|
||||
"`x` is live": "`x` teeb otseülekannet",
|
||||
"preferences_category_data": "Andme-eelistused",
|
||||
"Clear watch history": "Kustuta vaatamisajalugu",
|
||||
"Clear watch history": "Puhasta vaatamisajalugu",
|
||||
"Import/export data": "Impordi/ekspordi andmed",
|
||||
"Change password": "Muuda salasõna",
|
||||
"Watch history": "Vaatamisajalugu",
|
||||
"Delete account": "Kustuta kasutaja",
|
||||
"Save preferences": "Salvesta eelistused",
|
||||
"Token": "Tunnusluba",
|
||||
"Token": "Token",
|
||||
"Import/export": "Imprort/eksport",
|
||||
"unsubscribe": "loobu tellimusest",
|
||||
"Subscriptions": "Tellimused",
|
||||
"search": "otsi",
|
||||
"Source available here.": "Lähtekood on kättesaadaval siin.",
|
||||
"View privacy policy.": "Vaata andmekaitsepõhimõtteid.",
|
||||
"Source available here.": "Allikas on kättesaadaval siin.",
|
||||
"View privacy policy.": "Vaata privaatsuspoliitikat.",
|
||||
"Public": "Avalik",
|
||||
"Private": "Privaatne",
|
||||
"View all playlists": "Vaata kõiki esitusloendeid",
|
||||
"Updated `x` ago": "Uuendas `x` tagasi",
|
||||
"Delete playlist `x`?": "Kustuta esitusloend `x`?",
|
||||
"Delete playlist": "Kustuta esitusloend",
|
||||
"Create playlist": "Koosta esitlusloend",
|
||||
"Create playlist": "Loo esitlusloend",
|
||||
"Title": "Pealkiri",
|
||||
"Playlist privacy": "Esitusloendi privaatsus",
|
||||
"Show more": "Näita rohkem",
|
||||
@@ -115,14 +117,14 @@
|
||||
"Show replies": "Näita vastuseid",
|
||||
"Incorrect password": "Vale salasõna",
|
||||
"Wrong answer": "Vale vastus",
|
||||
"User ID is a required field": "Kasutajatunnus on kohustuslik väli",
|
||||
"User ID is a required field": "Kasutaja ID on kohustuslik väli",
|
||||
"Password is a required field": "Salasõna on kohustuslik väli",
|
||||
"Wrong username or password": "Vale kasutajanimi või salasõna",
|
||||
"Password cannot be longer than 55 characters": "Salasõna ei tohi olla pikem kui 55 tähemärki",
|
||||
"Password cannot be empty": "Salasõna ei tohi olla tühi",
|
||||
"Please log in": "Palun logi sisse",
|
||||
"Please log in": "Palun logige sisse",
|
||||
"channel:`x`": "kanal:`x`",
|
||||
"Deleted or invalid channel": "Kanal on kustutatud või seda ei leidu",
|
||||
"Deleted or invalid channel": "Kanal on kustutatud või seda ei leitud",
|
||||
"This channel does not exist.": "Sellist kanalit pole olemas.",
|
||||
"comments_view_x_replies": "{{count}} vastus",
|
||||
"comments_view_x_replies_plural": "{{count}} vastust",
|
||||
@@ -132,86 +134,86 @@
|
||||
"Not a playlist.": "Tegu pole esitusloendiga.",
|
||||
"Playlist does not exist.": "Seda esitusloendit pole olemas.",
|
||||
"No such user": "Sellist kasutajat pole",
|
||||
"English": "inglise",
|
||||
"English (United Kingdom)": "inglise (Suurbritannia)",
|
||||
"English (United States)": "inglise (USA)",
|
||||
"English (auto-generated)": "inglise (automaatselt koostatud)",
|
||||
"Afrikaans": "afrikaani",
|
||||
"Albanian": "albaania",
|
||||
"Arabic": "araabia",
|
||||
"Armenian": "armeenia",
|
||||
"Bangla": "bengali",
|
||||
"Basque": "baski",
|
||||
"Belarusian": "valgevene",
|
||||
"Bulgarian": "bulgaaria",
|
||||
"Burmese": "birma",
|
||||
"Cantonese (Hong Kong)": "kantoni (Hongkong)",
|
||||
"Chinese (China)": "hiina (Hiina)",
|
||||
"Chinese (Hong Kong)": "hiina (Hongkong)",
|
||||
"Chinese (Simplified)": "hiina (lihtsustatud)",
|
||||
"Chinese (Taiwan)": "hiina (Taiwan)",
|
||||
"Croatian": "horvaadi",
|
||||
"Czech": "tšehhi",
|
||||
"Danish": "taani",
|
||||
"Dutch": "hollandi",
|
||||
"Esperanto": "esperanto",
|
||||
"Estonian": "eesti",
|
||||
"Filipino": "filipiini",
|
||||
"Finnish": "soome",
|
||||
"French": "prantsuse",
|
||||
"French (auto-generated)": "prantsuse (automaatselt koostatud)",
|
||||
"Dutch (auto-generated)": "hollandi (automaatne)",
|
||||
"Galician": "galeegi",
|
||||
"Georgian": "gruusia",
|
||||
"Haitian Creole": "haiti kreooli",
|
||||
"Hausa": "hausa",
|
||||
"Hawaiian": "havaii",
|
||||
"Hebrew": "heebrea",
|
||||
"Hindi": "hindi",
|
||||
"Hungarian": "ungari",
|
||||
"Icelandic": "islandi",
|
||||
"Indonesian": "indoneesia",
|
||||
"Japanese (auto-generated)": "jaapani (automaatselt koostatud)",
|
||||
"Kannada": "kannada",
|
||||
"Kazakh": "kasahhi",
|
||||
"Luxembourgish": "letseburgi",
|
||||
"Macedonian": "makedoonia",
|
||||
"Malay": "malai",
|
||||
"Maltese": "malta",
|
||||
"Maori": "maoori",
|
||||
"Marathi": "marathi",
|
||||
"Mongolian": "mongoli",
|
||||
"Nepali": "nepaali",
|
||||
"Norwegian Bokmål": "norra (Bokmål)",
|
||||
"Persian": "pärsia",
|
||||
"Polish": "poola",
|
||||
"Portuguese": "portugali",
|
||||
"Portuguese (auto-generated)": "portugali (automaatne)",
|
||||
"Portuguese (Brazil)": "portugali (Brasiilia)",
|
||||
"Romanian": "rumeenia",
|
||||
"Russian": "vene",
|
||||
"Russian (auto-generated)": "vene (automaatne)",
|
||||
"Scottish Gaelic": "gaeli",
|
||||
"Serbian": "serbia",
|
||||
"Slovak": "slovaki",
|
||||
"Slovenian": "sloveeni",
|
||||
"Somali": "somaali",
|
||||
"Spanish": "hispaania",
|
||||
"Spanish (auto-generated)": "hispaania (automaatne)",
|
||||
"Spanish (Latin America)": "hispaania (Ladina-Ameerika)",
|
||||
"Spanish (Mexico)": "hispaania (Mehhiko)",
|
||||
"Spanish (Spain)": "hispaania (Hispaania)",
|
||||
"Swahili": "suahiili",
|
||||
"Swedish": "rootsi",
|
||||
"Tajik": "tadžiki",
|
||||
"Tamil": "tamili",
|
||||
"Thai": "tai",
|
||||
"Turkish": "türgi",
|
||||
"Turkish (auto-generated)": "türgi (automaatne)",
|
||||
"Ukrainian": "ukraina",
|
||||
"Uzbek": "usbeki",
|
||||
"Vietnamese": "vietnami",
|
||||
"Vietnamese (auto-generated)": "vietnami (automaatne)",
|
||||
"English": "Inglise",
|
||||
"English (United Kingdom)": "Inglise (Suurbritannia)",
|
||||
"English (United States)": "Inglise (USA)",
|
||||
"English (auto-generated)": "Inglise (automaatselt koostatud)",
|
||||
"Afrikaans": "Afrikaani",
|
||||
"Albanian": "Albaania",
|
||||
"Arabic": "Araabia",
|
||||
"Armenian": "Armeenia",
|
||||
"Bangla": "Bengali",
|
||||
"Basque": "Baski",
|
||||
"Belarusian": "Valgevene",
|
||||
"Bulgarian": "Bulgaaria",
|
||||
"Burmese": "Birma",
|
||||
"Cantonese (Hong Kong)": "Kantoni (Hong Konk)",
|
||||
"Chinese (China)": "Hiina (Hiina)",
|
||||
"Chinese (Hong Kong)": "Hiina (Hong Kong)",
|
||||
"Chinese (Simplified)": "Hiina (lihtsustatud)",
|
||||
"Chinese (Taiwan)": "Hiina (Taiwan)",
|
||||
"Croatian": "Horvaatia",
|
||||
"Czech": "Tšehhi",
|
||||
"Danish": "Taani",
|
||||
"Dutch": "Hollandi",
|
||||
"Esperanto": "Esperanto",
|
||||
"Estonian": "Eesti",
|
||||
"Filipino": "Filipiini",
|
||||
"Finnish": "Soome",
|
||||
"French": "Prantsuse",
|
||||
"French (auto-generated)": "Prantsuse (automaatne)",
|
||||
"Dutch (auto-generated)": "Hollandi (automaatne)",
|
||||
"Galician": "Kaliitsia",
|
||||
"Georgian": "Gruusia",
|
||||
"Haitian Creole": "Haiti kreool",
|
||||
"Hausa": "Hausa",
|
||||
"Hawaiian": "Havaii",
|
||||
"Hebrew": "Heebrea",
|
||||
"Hindi": "Hindi",
|
||||
"Hungarian": "Ungari",
|
||||
"Icelandic": "Islandi",
|
||||
"Indonesian": "Indoneesia",
|
||||
"Japanese (auto-generated)": "Jaapani (automaatne)",
|
||||
"Kannada": "Kannada",
|
||||
"Kazakh": "Kasahhi",
|
||||
"Luxembourgish": "Luksemburgi",
|
||||
"Macedonian": "Makedoonia",
|
||||
"Malay": "Malai",
|
||||
"Maltese": "Malta",
|
||||
"Maori": "Maori",
|
||||
"Marathi": "Marathi",
|
||||
"Mongolian": "Mongoli",
|
||||
"Nepali": "Nepaali",
|
||||
"Norwegian Bokmål": "Norra (Bokmål)",
|
||||
"Persian": "Pärsia",
|
||||
"Polish": "Poola",
|
||||
"Portuguese": "Portugali",
|
||||
"Portuguese (auto-generated)": "Portugali (automaatne)",
|
||||
"Portuguese (Brazil)": "Portugali (Brasiilia)",
|
||||
"Romanian": "Rumeenia",
|
||||
"Russian": "Vene",
|
||||
"Russian (auto-generated)": "Vene (automaatne)",
|
||||
"Scottish Gaelic": "Šoti (Gaeli)",
|
||||
"Serbian": "Serbia",
|
||||
"Slovak": "Slovaki",
|
||||
"Slovenian": "Sloveeni",
|
||||
"Somali": "Somaali",
|
||||
"Spanish": "Hispaania",
|
||||
"Spanish (auto-generated)": "Hispaania (automaatne)",
|
||||
"Spanish (Latin America)": "Hispaania (Ladina-Ameerika)",
|
||||
"Spanish (Mexico)": "Hispaania (Mehhiko)",
|
||||
"Spanish (Spain)": "Hispaania (Hispaania)",
|
||||
"Swahili": "Suahili",
|
||||
"Swedish": "Rootsi",
|
||||
"Tajik": "Tadžiki",
|
||||
"Tamil": "Tamiili",
|
||||
"Thai": "Tai",
|
||||
"Turkish": "Türgi",
|
||||
"Turkish (auto-generated)": "Türgi (automaatne)",
|
||||
"Ukrainian": "Ukraina",
|
||||
"Uzbek": "Usbeki",
|
||||
"Vietnamese": "Vietnami",
|
||||
"Vietnamese (auto-generated)": "Vietnami (automaatne)",
|
||||
"generic_count_years": "{{count}} aasta",
|
||||
"generic_count_years_plural": "{{count}} aastat",
|
||||
"generic_count_months": "{{count}} kuu",
|
||||
@@ -226,15 +228,15 @@
|
||||
"generic_count_minutes_plural": "{{count}} minutit",
|
||||
"Popular": "Populaarne",
|
||||
"Search": "Otsi",
|
||||
"Top": "Parimad",
|
||||
"About": "Saidi teave",
|
||||
"Top": "Top",
|
||||
"About": "Leheküljest",
|
||||
"preferences_locale_label": "Keel: ",
|
||||
"View as playlist": "Vaata esitusloendina",
|
||||
"Movies": "Filmid",
|
||||
"Download as: ": "Laadi alla kui: ",
|
||||
"Download as: ": "Laadi kui: ",
|
||||
"(edited)": "(muudetud)",
|
||||
"`x` marked it with a ❤": "`x` märkis ❤",
|
||||
"Audio mode": "Helirežiim",
|
||||
"Audio mode": "Audiorežiim",
|
||||
"Video mode": "Videorežiim",
|
||||
"search_filters_date_label": "Üleslaadimise kuupäev",
|
||||
"search_filters_date_option_none": "Ükskõik mis kuupäev",
|
||||
@@ -244,10 +246,10 @@
|
||||
"search_filters_date_option_month": "Sel kuul",
|
||||
"search_filters_date_option_year": "Sel aastal",
|
||||
"search_filters_type_label": "Tüüp",
|
||||
"search_filters_type_option_all": "Ükskõik mis tüüpi",
|
||||
"search_filters_type_option_all": "Ükskõik mis tüüp",
|
||||
"search_filters_duration_label": "Kestus",
|
||||
"search_filters_type_option_show": "Näita",
|
||||
"search_filters_duration_option_none": "Ükskõik mis kestusega",
|
||||
"search_filters_duration_option_none": "Ükskõik mis kestus",
|
||||
"search_filters_duration_option_short": "Lühike (alla 4 minuti)",
|
||||
"search_filters_duration_option_medium": "Keskmine (4 - 20 minutit)",
|
||||
"search_filters_duration_option_long": "Pikk (üle 20 minuti)",
|
||||
@@ -256,9 +258,9 @@
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Subtiitrid",
|
||||
"search_filters_features_option_location": "Asukoht",
|
||||
"search_filters_sort_label": "Järjestus",
|
||||
"search_filters_sort_label": "Sorteeri",
|
||||
"search_filters_sort_option_views": "Vaatamiste arv",
|
||||
"next_steps_error_message": "Pärast seda võiksid proovida: ",
|
||||
"next_steps_error_message": "Pärast mida võiksite proovida: ",
|
||||
"videoinfo_started_streaming_x_ago": "Alustas otseülekannet `x` tagasi",
|
||||
"Yes": "Jah",
|
||||
"generic_views_count": "{{count}} vaatamine",
|
||||
@@ -268,48 +270,48 @@
|
||||
"preferences_region_label": "Riik: ",
|
||||
"View YouTube comments": "Vaata YouTube'i kommentaare",
|
||||
"preferences_extend_desc_label": "Ava video kirjeldus automaatselt: ",
|
||||
"German (auto-generated)": "saksa (automaatselt koostatud)",
|
||||
"Italian": "itaalia",
|
||||
"preferences_player_style_label": "Meediaesitaja stiil: ",
|
||||
"German (auto-generated)": "Saksa (automaatne)",
|
||||
"Italian": "Itaalia",
|
||||
"preferences_player_style_label": "Mängija stiil: ",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} lugemata teavitus",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} lugemata teavitust",
|
||||
"View more comments on Reddit": "Vaata teisi kommentaare Redditis",
|
||||
"Only show latest unwatched video from channel: ": "Näita ainult viimast vaatamata videot: ",
|
||||
"tokens_count": "{{count}} tunnusluba",
|
||||
"tokens_count_plural": "{{count}} tunnusluba",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokenit",
|
||||
"Log out": "Logi välja",
|
||||
"Premieres `x`": "Linastub`x`",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Vaata `x` kommentaari",
|
||||
"": "Vaata `x` kommentaare"
|
||||
},
|
||||
"Khmer": "khmeeri",
|
||||
"Bosnian": "bosnia",
|
||||
"Corsican": "korsika",
|
||||
"Javanese": "jaava",
|
||||
"Lithuanian": "leedu",
|
||||
"Khmer": "Khmeeri",
|
||||
"Bosnian": "Bosnia",
|
||||
"Corsican": "Korsika",
|
||||
"Javanese": "Jaava",
|
||||
"Lithuanian": "Leedu",
|
||||
"channel_tab_videos_label": "Videod",
|
||||
"channel_tab_community_label": "Kogukond",
|
||||
"CAPTCHA is a required field": "Robotilõks on kohustuslik väli",
|
||||
"CAPTCHA is a required field": "CAPTCHA on kohustuslik väli",
|
||||
"comments_points_count": "{{count}} punkt",
|
||||
"comments_points_count_plural": "{{count}} punkti",
|
||||
"Chinese": "hiina",
|
||||
"German": "saksa",
|
||||
"Indonesian (auto-generated)": "indoneesia (automaatselt koostatud)",
|
||||
"Italian (auto-generated)": "itaalia (automaatselt koostatud)",
|
||||
"Kyrgyz": "kirgiisi",
|
||||
"Latin": "ladina",
|
||||
"Chinese": "Hiina",
|
||||
"German": "Saksa",
|
||||
"Indonesian (auto-generated)": "Indoneesia (automaatne)",
|
||||
"Italian (auto-generated)": "Itaalia (automaatne)",
|
||||
"Kyrgyz": "Kirkiisi",
|
||||
"Latin": "Ladina",
|
||||
"generic_count_seconds": "{{count}} sekund",
|
||||
"generic_count_seconds_plural": "{{count}} sekundit",
|
||||
"Catalan": "katalaani",
|
||||
"Chinese (Traditional)": "hiina (traditsiooniline)",
|
||||
"Greek": "kreeka",
|
||||
"Kurdish": "kurdi",
|
||||
"Latvian": "läti",
|
||||
"Irish": "iiri",
|
||||
"Korean": "korea",
|
||||
"Japanese": "jaapani",
|
||||
"Korean (auto-generated)": "korea (automaatselt koostatud)",
|
||||
"Catalan": "Katalaani",
|
||||
"Chinese (Traditional)": "Hiina (traditsiooniline)",
|
||||
"Greek": "Kreeka",
|
||||
"Kurdish": "Kurdi",
|
||||
"Latvian": "Läti",
|
||||
"Irish": "Iiri",
|
||||
"Korean": "Korea",
|
||||
"Japanese": "Jaapani",
|
||||
"Korean (auto-generated)": "Korea (automaatne)",
|
||||
"Music": "Muusika",
|
||||
"Playlists": "Esitusloendid",
|
||||
"search_filters_type_option_video": "Video",
|
||||
@@ -323,186 +325,8 @@
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Esitusloend",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"next_steps_error_message_go_to_youtube": "Mine YouTube'i",
|
||||
"next_steps_error_message_refresh": "Laadi uuesti",
|
||||
"next_steps_error_message_go_to_youtube": "Minna YouTube'i",
|
||||
"next_steps_error_message_refresh": "Laadida uuesti",
|
||||
"footer_donate_page": "Anneta",
|
||||
"videoinfo_watch_on_youTube": "Vaata YouTube'is",
|
||||
"Authorize token for `x`?": "Kas volitad tunnusloa kasutamise `x`-le?",
|
||||
"Export data as JSON": "Expordi Invidious andmed JSON-ina",
|
||||
"Import Invidious data": "Impordi Invidious JSON andmed",
|
||||
"preferences_local_label": "Edasta videod vaheserveri kaudu: ",
|
||||
"Music in this video": "Muusika selles videos",
|
||||
"Token manager": "Tunnuslubade haldur",
|
||||
"search_message_use_another_instance": "Võid ka <a href=\"`x`\">otsida teisest serverist</a>.",
|
||||
"Standard YouTube license": "Tavaline Youtube'i litsens",
|
||||
"Song: ": "Lugu: ",
|
||||
"Add to playlist": "Lisa esitlusloendisse",
|
||||
"Add to playlist: ": "Lisa esitlusloendisse: ",
|
||||
"Search for videos": "Otsi videoid",
|
||||
"The Popular feed has been disabled by the administrator.": "Administraator on populaarse voo välja lülitanud.",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"generic_button_rss": "RSS uudisvoog",
|
||||
"Import YouTube watch history (.json)": "Impordi Youtube vaatamiste ajalugu (.json)",
|
||||
"published - reverse": "avaldatud - vastupidine",
|
||||
"preferences_default_home_label": "Vaikimisi koduleht: ",
|
||||
"preferences_feed_menu_label": "Voogude menüü: ",
|
||||
"Login enabled: ": "Sisselogimine lubatud: ",
|
||||
"Registration enabled: ": "Registreerimine lubatud: ",
|
||||
"CAPTCHA enabled: ": "Robotilõks on kasutusel: ",
|
||||
"Blacklisted regions: ": "Mustas nimekirjas piirkonnad: ",
|
||||
"Wilson score: ": "Wilsoni skoor: ",
|
||||
"generic_button_delete": "Kustuta",
|
||||
"generic_button_edit": "Muuda",
|
||||
"generic_button_save": "Salvesta",
|
||||
"generic_button_cancel": "Tühista",
|
||||
"Import YouTube playlist (.csv)": "Impordi Youtube esitlusloend (.csv)",
|
||||
"preferences_category_misc": "Muud seadistused",
|
||||
"preferences_annotations_subscribed_label": "Kas vaikimisi näitame tellitud kanalite sisukokkuvõtteid?: ",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_continue_label": "Vaikimisi mängi järgmine video: ",
|
||||
"View JavaScript license information.": "Vaata JavaScripti litsensiteavet.",
|
||||
"preferences_listen_label": "Kuula vaikimisi: ",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"Erroneous CAPTCHA": "Vigane robotilõks",
|
||||
"Hidden field \"challenge\" is a required field": "Peidetud väli \"väljakutse\" on kohustuslik väli",
|
||||
"Fallback captions: ": "Tagavara subtiitrid: ",
|
||||
"preferences_category_admin": "Administraatori seadistused",
|
||||
"preferences_automatic_instance_redirect_label": "Automaatne serveri ümbersuunamine (varuvariandile redirect.invidious.io): ",
|
||||
"channel name - reverse": "kanali nimi - vastupidine",
|
||||
"An alternative front-end to YouTube": "Alternatiivne Youtube esiliides",
|
||||
"Subscription manager": "Tellimuste haldur",
|
||||
"Redirect homepage to feed: ": "Suuna koduleht voole: ",
|
||||
"Azerbaijani": "aserbaidžaani",
|
||||
"Gujarati": "gudžarati",
|
||||
"generic_channels_count": "{{count}} kanal",
|
||||
"generic_channels_count_plural": "{{count}} kanalit",
|
||||
"preferences_video_loop_label": "Alati korda: ",
|
||||
"preferences_watch_history_label": "Lülita vaatamiste ajalugu sisse: ",
|
||||
"preferences_speed_label": "Vaikimisi kiirus: ",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_captions_label": "Vaikimisi subtiitrid: ",
|
||||
"preferences_annotations_label": "Vaikimisi näita sisukokkuvõtteid: ",
|
||||
"preferences_thin_mode_label": "Napp režiim: ",
|
||||
"Manage subscriptions": "Halda tellimusi",
|
||||
"Manage tokens": "Halda tunnuslube",
|
||||
"preferences_show_nick_label": "Näita üleval hüüdnime ",
|
||||
"revoke": "võta tagasi",
|
||||
"Released under the AGPLv3 on Github.": "Avaldatud GitHubis AGPLv3 litsentsi alusel.",
|
||||
"Trending": "Trendikas",
|
||||
"Unlisted": "Ajajooneväline",
|
||||
"Switch Invidious Instance": "Vaheta Invidiouse Serverit",
|
||||
"Whitelisted regions: ": "Valges nimekirjas piirkonnad: ",
|
||||
"Artist: ": "Esitaja: ",
|
||||
"Could not fetch comments": "Kommentaaride laadimine ei õnnestunud",
|
||||
"Album: ": "Album: ",
|
||||
"Invidious Private Feed for `x`": "Invidiouse privaatne Voog `x`-ile",
|
||||
"Could not pull trending pages.": "Ei saanud alla laadida trendikaid lehti.",
|
||||
"Hidden field \"token\" is a required field": "Peidetud väli \"tunnusluba\" on kohustuslik väli",
|
||||
"Erroneous challenge": "Ekslik väljakutse",
|
||||
"Erroneous token": "Ekslik tunnusluba",
|
||||
"Token is expired, please try again": "Tunnusluba on aegunud, palun proovi uuesti",
|
||||
"Amharic": "amhari",
|
||||
"Cebuano": "sebu",
|
||||
"preferences_autoplay_label": "Automaatesitus: ",
|
||||
"invidious": "Invidious",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"Popular enabled: ": "Populaarsed videod on kasutusel: ",
|
||||
"Top enabled: ": "Ülariba lubatud: ",
|
||||
"Editing playlist `x`": "Esitlusloendi `x` muutmine",
|
||||
"Show annotations": "Näita sisukokkuvõtteid",
|
||||
"Hide annotations": "Peida sisukokkuvõtted",
|
||||
"Could not create mix.": "Ei saanud miksi luua.",
|
||||
"Authorize token?": "Kas volitad tunnusloa kasutamise?",
|
||||
"playlist_button_add_items": "Lisa videoid",
|
||||
"First page": "Esimene leht",
|
||||
"preferences_preload_label": "Eellaadi videoandmed: ",
|
||||
"preferences_category_visual": "Visuaalsed seadistused",
|
||||
"preferences_comments_label": "Vaikimisi kommentaarid: ",
|
||||
"Filipino (auto-generated)": "filipiini (automaatselt koostatud)",
|
||||
"Could not get channel info.": "Kanali info tuvastamine ei õnnestunud.",
|
||||
"Answer": "Vastus",
|
||||
"Report statistics: ": "Teavita statistikast: ",
|
||||
"Hmong": "hmongi",
|
||||
"Igbo": "igbo",
|
||||
"Interlingue": "interlingue",
|
||||
"Lao": "lao",
|
||||
"Malagasy": "malagassi",
|
||||
"Malayalam": "malajalami",
|
||||
"Pashto": "puštu",
|
||||
"Nyanja": "njandža",
|
||||
"Punjabi": "pandžabi",
|
||||
"Samoan": "samoa",
|
||||
"Shona": "šona",
|
||||
"Sindhi": "sindhi",
|
||||
"Sinhala": "singali",
|
||||
"Southern Sotho": "lõunasotho",
|
||||
"Sundanese": "sunda",
|
||||
"Telugu": "telugu",
|
||||
"Urdu": "urdu",
|
||||
"Welsh": "kõmri",
|
||||
"Western Frisian": "läänefriisi",
|
||||
"Xhosa": "koosa",
|
||||
"Yiddish": "jidiši",
|
||||
"Yoruba": "joruba",
|
||||
"Zulu": "suulu",
|
||||
"Fallback comments: ": "Kommentaaride tagavaravariant: ",
|
||||
"Rating: ": "Hinnang: ",
|
||||
"Default": "Vaikimisi",
|
||||
"Download is disabled": "Allalaadimine on keelatud",
|
||||
"YouTube comment permalink": "YouTube'i kommentaari püsilink",
|
||||
"permalink": "püsilink",
|
||||
"Channel Sponsor": "Kanali sponsor",
|
||||
"search_filters_features_label": "Omadused",
|
||||
"search_filters_features_option_c_commons": "Creative Commons litsents",
|
||||
"search_filters_features_option_three_sixty": "360°-video",
|
||||
"search_filters_features_option_vr180": "VR180-video",
|
||||
"search_filters_features_option_three_d": "3D-video",
|
||||
"search_filters_features_option_hdr": "HDR-video",
|
||||
"search_filters_features_option_purchased": "Ostetud",
|
||||
"search_filters_sort_option_relevance": "Olulisus",
|
||||
"search_filters_sort_option_rating": "Hinnang",
|
||||
"search_filters_apply_button": "Rakenda valitud filtrid",
|
||||
"footer_source_code": "Lähtekood",
|
||||
"footer_original_source_code": "Algne lähtekood",
|
||||
"footer_modfied_source_code": "Muudetud lähtekood",
|
||||
"none": "mitte midagi",
|
||||
"videoinfo_youTube_embed_link": "Lõimi",
|
||||
"videoinfo_invidious_embed_link": "Lõimi link",
|
||||
"adminprefs_modified_source_code_url_label": "Link muudetud lähtekoodi hoidlale",
|
||||
"channel_tab_podcasts_label": "Taskuhäälingud",
|
||||
"Engagement: ": "Kaasatus: ",
|
||||
"download_subtitles": "Subtiitrid - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` - koostatud esitusloendid",
|
||||
"user_saved_playlists": "`x` - salvestatud esitusloendid",
|
||||
"Video unavailable": "Video pole saadaval",
|
||||
"preferences_save_player_pos_label": "Salvesta taasesituse asukoht: ",
|
||||
"crash_page_you_found_a_bug": "Tundub, et oled Invidiousest leidnud vea!",
|
||||
"crash_page_before_reporting": "Enne veast teatamist, palun kontrolli, et oleksid:",
|
||||
"crash_page_refresh": "proovinud <a href=\"`x`\">lehte uuesti laadida</a>",
|
||||
"crash_page_switch_instance": "proovinud <a href=\"`x`\">kasutada mõnda muud Invidiouse serverit</a>",
|
||||
"crash_page_read_the_faq": "lugenud <a href=\"`x`\">Korduma kippuvaid küsimusi (KKK)</a>",
|
||||
"crash_page_search_issue": "otsinud <a href=\"`x`\">GitHubist sarnaseid ja juba teaeatud vigu</a>",
|
||||
"crash_page_report_issue": "Kui ükski ülaltoodud võimalustest seda viga ei lahendanud, siis palun <a href=\"`x`\">koosta GitHubis meie veahalduses uus veateade</a> (soovitavalt inglise keeles) ja lisa sinnakogu järgnev tekst (palun ÄRA tõlgi seda teksti):",
|
||||
"error_video_not_in_playlist": "Selles esitusloendis ei leidu soovitud videot. <a href=\"`x`\">Siit pääsed esitusloendi avalehele.</a>",
|
||||
"channel_tab_shorts_label": "Lühivideod",
|
||||
"channel_tab_streams_label": "Otseülekanded",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"channel_tab_releases_label": "Versioonid",
|
||||
"channel_tab_courses_label": "Kursused",
|
||||
"channel_tab_playlists_label": "Esitusloendid",
|
||||
"channel_tab_posts_label": "Postitused",
|
||||
"channel_tab_channels_label": "Kanalid",
|
||||
"toggle_theme": "Vaheta kujundust",
|
||||
"carousel_slide": "Slaid {{current}} / {{total}}",
|
||||
"carousel_skip": "Jäta karussell vahele",
|
||||
"carousel_go_to": "Ava slaid `x`",
|
||||
"timeline_parse_error_placeholder_heading": "Objekti töötlemine ei õnnestu",
|
||||
"timeline_parse_error_placeholder_message": "Selle objekti töötlemisel tekkis Invidiouses viga. Lisateave on alljärgnevas:",
|
||||
"timeline_parse_error_show_technical_details": "Näita tehnilisi üksikasju",
|
||||
"preferences_default_playlist": "Vaikimisi esitusloend: ",
|
||||
"preferences_default_playlist_none": "Ühtegi vaikimisi esitusloendit ei leidu"
|
||||
"videoinfo_watch_on_youTube": "Vaata YouTube'is"
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
"User ID": "Erabiltzaile IDa",
|
||||
"Password": "Pasahitza",
|
||||
"Time (h:mm:ss):": "Denbora (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA testua",
|
||||
"Image CAPTCHA": "CAPTCHA irudia",
|
||||
"Sign In": "Hasi saioa",
|
||||
"Register": "Eman izena",
|
||||
"E-mail": "E-posta",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"generic_views_count": "{{count}} بازدید",
|
||||
"generic_views_count_plural": "{{count}} بازدید",
|
||||
"generic_videos_count": "{{count}} ویدیو",
|
||||
"generic_videos_count_plural": "{{count}} ویدیو",
|
||||
"generic_videos_count": "{{count}} ویدئو",
|
||||
"generic_videos_count_plural": "{{count}} ویدئو",
|
||||
"generic_playlists_count": "{{count}} فهرست پخش",
|
||||
"generic_playlists_count_plural": "{{count}} فهرست پخش",
|
||||
"generic_subscribers_count": "{{count}} دنبالکننده",
|
||||
"generic_subscribers_count_plural": "{{count}} دنبالکننده",
|
||||
"generic_subscribers_count": "{{count}} دنبال کننده",
|
||||
"generic_subscribers_count_plural": "{{count}} دنبال کننده",
|
||||
"generic_subscriptions_count": "{{count}} اشتراک",
|
||||
"generic_subscriptions_count_plural": "{{count}} اشتراک",
|
||||
"LIVE": "زنده",
|
||||
@@ -24,21 +24,21 @@
|
||||
"Clear watch history?": "پاک کردن تاریخچه نمایش؟",
|
||||
"New password": "گذرواژه تازه",
|
||||
"New passwords must match": "گذارواژه های تازه باید باهم همخوانی داشته باشند",
|
||||
"Authorize token?": "اجازه دادن به توکن؟",
|
||||
"Authorize token for `x`?": "اجازه دادن به توکن برای `x`؟",
|
||||
"Yes": "آری",
|
||||
"No": "نه",
|
||||
"Authorize token?": "توکن دسترسی؟",
|
||||
"Authorize token for `x`?": "توکن دسترسی برای `x`؟",
|
||||
"Yes": "بله",
|
||||
"No": "خیر",
|
||||
"Import and Export Data": "درونبرد و برونبرد داده",
|
||||
"Import": "درونبرد",
|
||||
"Import Invidious data": "درونبرد داده JSON اینویدیوس",
|
||||
"Import YouTube subscriptions": "درونبرد پروندهٔ CSV یا OPML اشتراکهای یوتیوب",
|
||||
"Import Invidious data": "وارد کردن داده JSON اینویدیوس",
|
||||
"Import YouTube subscriptions": "وارد کردن فایل CSV یا OPML سابسکرایب های یوتیوب",
|
||||
"Import FreeTube subscriptions (.db)": "درونبرد اشتراکهای فریتیوب (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "درونبرد اشتراکهای نیوپایپ (.json)",
|
||||
"Import NewPipe data (.zip)": "درونبرد داده نیوپایپ (.zip)",
|
||||
"Export": "برونبرد",
|
||||
"Export subscriptions as OPML": "برونبرد اشتراکها در قالب OPML",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "برونبرد اشتراکها در قالب OPML (برای نیوپایپ و فریتیوب)",
|
||||
"Export data as JSON": "برونبرد دادهٔ اینویدیوس بهعنوان JSON",
|
||||
"Export data as JSON": "گرفتن(خارج کردن) اطلاعات اینویدیوس با فرمت JSON",
|
||||
"Delete account?": "حذف حساب کاربری؟",
|
||||
"History": "تاریخچه",
|
||||
"An alternative front-end to YouTube": "یک پیشانه جایگزین برای یوتیوب",
|
||||
@@ -49,13 +49,15 @@
|
||||
"User ID": "شناسه کاربری",
|
||||
"Password": "گذرواژه",
|
||||
"Time (h:mm:ss):": "زمان (h:mm:ss):",
|
||||
"Text CAPTCHA": "کپچای متنی",
|
||||
"Image CAPTCHA": "کپچای تصویری",
|
||||
"Sign In": "ورود",
|
||||
"Register": "ثبت نام",
|
||||
"E-mail": "ایمیل",
|
||||
"Preferences": "ترجیحات",
|
||||
"preferences_category_player": "ترجیحات نمایشدهنده",
|
||||
"preferences_video_loop_label": "همیشه بازپخش کن: ",
|
||||
"preferences_autoplay_label": "پخش خودکار: ",
|
||||
"preferences_video_loop_label": "همواره ویدئو را بازپخش کن ",
|
||||
"preferences_autoplay_label": "نمایش خودکار: ",
|
||||
"preferences_continue_label": "پخش بعدی به طور پیشفرض: ",
|
||||
"preferences_continue_autoplay_label": "پخش خودکار ویدیو بعدی: ",
|
||||
"preferences_listen_label": "گوش کردن به طور پیشفرض: ",
|
||||
@@ -66,14 +68,14 @@
|
||||
"preferences_comments_label": "نظرات پیشفرض: ",
|
||||
"youtube": "یوتیوب",
|
||||
"reddit": "ردیت",
|
||||
"preferences_captions_label": "زیرنویسهای پیشفرض: ",
|
||||
"Fallback captions: ": "عقبگرد زیرنویسها: ",
|
||||
"preferences_related_videos_label": "نمایش ویدیوهای مرتبط: ",
|
||||
"preferences_annotations_label": "نمایش حاشیهنویسیها بهطور پیشفرض: ",
|
||||
"preferences_extend_desc_label": "گسترش خودکار توضیحات ویدیو: ",
|
||||
"preferences_vr_mode_label": "ویدیوهای ۳۶۰ درجهٔ تعاملی (نیازمند WebGL): ",
|
||||
"preferences_captions_label": "زیرنویس های پیشفرض: ",
|
||||
"Fallback captions: ": "عقب گرد زیرنویس ها: ",
|
||||
"preferences_related_videos_label": "نمایش ویدیو های مرتبط: ",
|
||||
"preferences_annotations_label": "نمایش حاشیه نویسی ها به طور پیشفرض: ",
|
||||
"preferences_extend_desc_label": "گسترش خودکار توضیحات ویدئو: ",
|
||||
"preferences_vr_mode_label": "ویدئوها ۳۶۰ درجه تعاملی(نیازمند WebGL): ",
|
||||
"preferences_category_visual": "ترجیحات بصری",
|
||||
"preferences_player_style_label": "حالت پخشکننده: ",
|
||||
"preferences_player_style_label": "حالت پخش کننده: ",
|
||||
"Dark mode: ": "حالت تاریک: ",
|
||||
"preferences_dark_mode_label": "تم: ",
|
||||
"dark": "تاریک",
|
||||
@@ -82,7 +84,7 @@
|
||||
"preferences_category_misc": "ترجیحات متفرقه",
|
||||
"preferences_automatic_instance_redirect_label": "هدایت خودکار نمونه (انتقال به redirect.invidious.io): ",
|
||||
"preferences_category_subscription": "ترجیحات اشتراک",
|
||||
"preferences_annotations_subscribed_label": "نمایش حاشیهنویسیها بهطور پیشفرض برای کانالهای مشترکشده: ",
|
||||
"preferences_annotations_subscribed_label": "نمایش حاشیه نویسی ها به طور پیشفرض برای کانال های مشترک شده: ",
|
||||
"Redirect homepage to feed: ": "تغییر مسیر صفحه خانه به خوراک: ",
|
||||
"preferences_max_results_label": "تعداد ویدیو های نمایش داده شده در خوراک: ",
|
||||
"preferences_sort_label": "مرتب سازی ویدیو ها بر اساس: ",
|
||||
@@ -381,21 +383,21 @@
|
||||
"next_steps_error_message_refresh": "تازهسازی",
|
||||
"next_steps_error_message_go_to_youtube": "رفتن به یوتیوب",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_dash": "DASH (کیفیت سازگارشونده)",
|
||||
"preferences_quality_option_dash": "DASH (کیفیت تطبیفی)",
|
||||
"preferences_quality_option_medium": "میانه",
|
||||
"preferences_quality_option_small": "پایین",
|
||||
"preferences_quality_dash_option_auto": "خودکار",
|
||||
"preferences_quality_dash_option_best": "بهترین",
|
||||
"preferences_quality_dash_option_worst": "بدترین",
|
||||
"preferences_quality_dash_option_4320p": "۴۳۲۰p",
|
||||
"preferences_quality_dash_option_2160p": "۲۱۶۰p",
|
||||
"preferences_quality_dash_option_1440p": "۱۴۴۰p",
|
||||
"preferences_quality_dash_option_1080p": "۱۰۸۰p",
|
||||
"preferences_quality_dash_option_720p": "۷۲۰p",
|
||||
"preferences_quality_dash_option_480p": "۴۸۰p",
|
||||
"preferences_quality_dash_option_360p": "۳۶۰p",
|
||||
"preferences_quality_dash_option_240p": "۲۴۰p",
|
||||
"preferences_quality_dash_option_144p": "۱۴۴p",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "اینویدیوس",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"footer_donate_page": "کمک مالی",
|
||||
@@ -474,8 +476,8 @@
|
||||
"generic_button_rss": "خوراک RSS",
|
||||
"crash_page_read_the_faq": "که <a href=\"`x`\">سوالات بیشتر پرسیده شده (FAQ)</a> را خواندهاید",
|
||||
"generic_button_delete": "حذف",
|
||||
"Import YouTube playlist (.csv)": "درونبرد فهرستپخش YouTube (.csv)",
|
||||
"Import YouTube watch history (.json)": "درونبرد تاریخچهٔ تماشای یوتیوب (.json)",
|
||||
"Import YouTube playlist (.csv)": "واردکردن فهرستپخش YouTube (.csv)",
|
||||
"Import YouTube watch history (.json)": "وارد کردن فهرست پخش YouTube (.json)",
|
||||
"crash_page_you_found_a_bug": "به نظر میرسد که ایرادی در Invidious پیدا کردهاید!",
|
||||
"channel_tab_podcasts_label": "پادکستها",
|
||||
"channel_tab_streams_label": "پخش زندهها",
|
||||
@@ -483,10 +485,10 @@
|
||||
"channel_tab_playlists_label": "فهرستهای پخش",
|
||||
"channel_tab_channels_label": "کانالها",
|
||||
"error_video_not_in_playlist": "ویدیوی درخواستی معلق به این فهرست پخش نیست. <a href=\"`x`\">کلیک کنید تا به صفحهٔ اصلی فهرست پخش بروید.</a>",
|
||||
"Add to playlist": "افزودن به فهرست پخش",
|
||||
"Add to playlist": "به لیست پخش افزوده شود",
|
||||
"Answer": "پاسخ",
|
||||
"Search for videos": "جستوجو برای ویدیوها",
|
||||
"Add to playlist: ": "افزودن به فهرست پخش ",
|
||||
"Search for videos": "جست و جو برای ویدیوها",
|
||||
"Add to playlist: ": "افزودن به لیست پخش ",
|
||||
"The Popular feed has been disabled by the administrator.": "بخش ویدیوهای پرطرفدار توسط مدیر غیرفعال شده است.",
|
||||
"carousel_slide": "اسلاید {{current}} از {{total}}",
|
||||
"carousel_skip": "رد شدن از گرداننده",
|
||||
@@ -495,11 +497,5 @@
|
||||
"crash_page_report_issue": "اگر هیچ یک از روش های بالا کمکی نکردند لطفا <a href=\"`x`\"> (ترجیحا به انگلیسی) یک سوال جدید در گیت هاب بپرسید و </a> طوری که سوالتون شامل متن زیر باشه:",
|
||||
"channel_tab_releases_label": "آثار",
|
||||
"toggle_theme": "تغییر وضعیت تم",
|
||||
"preferences_preload_label": "پیش بار کردن دادههای ویدیو: ",
|
||||
"First page": "نخستین صفحه",
|
||||
"Filipino (auto-generated)": "فیلیپنی (تولید خودکار)",
|
||||
"channel_tab_posts_label": "فرستهها",
|
||||
"timeline_parse_error_placeholder_heading": "ناتوانی در تجزیهٔ مورد",
|
||||
"timeline_parse_error_placeholder_message": "اینویدیوس هنگام کوشش برای تجزیهٔ این مورد به خطایی برخورد. برای اطلاعات بیشتر زیر را ببینید:",
|
||||
"timeline_parse_error_show_technical_details": "نمایش جزئیات فنی"
|
||||
"preferences_preload_label": "پیش بار کردن دادههای ویدیو: "
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Käyttäjätunnus",
|
||||
"Password": "Salasana",
|
||||
"Time (h:mm:ss):": "Aika (h:mm:ss):",
|
||||
"Text CAPTCHA": "Teksti-CAPTCHA",
|
||||
"Image CAPTCHA": "Kuva-CAPTCHA",
|
||||
"Sign In": "Kirjaudu sisään",
|
||||
"Register": "Rekisteröidy",
|
||||
"E-mail": "Sähköposti",
|
||||
@@ -495,7 +497,5 @@
|
||||
"The Popular feed has been disabled by the administrator.": "Järjestelmänvalvoja on poistanut Suositut-syötteen.",
|
||||
"Import YouTube watch history (.json)": "Tuo Youtube-katseluhistoria (.json)",
|
||||
"toggle_theme": "Vaihda teemaa",
|
||||
"preferences_preload_label": "Esilataa video data. ",
|
||||
"timeline_parse_error_show_technical_details": "Näytä tekniset yksityiskohdat",
|
||||
"First page": "Ensimmäinen sivu"
|
||||
"preferences_preload_label": "Esilataa video data. "
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
"User ID": "Identifiant utilisateur",
|
||||
"Password": "Mot de passe",
|
||||
"Time (h:mm:ss):": "Heure (h:mm:ss) :",
|
||||
"Text CAPTCHA": "CAPTCHA textuel",
|
||||
"Image CAPTCHA": "CAPTCHA pictural",
|
||||
"Sign In": "S'identifier",
|
||||
"Register": "S'inscrire",
|
||||
"E-mail": "Courriel",
|
||||
@@ -513,9 +515,5 @@
|
||||
"carousel_go_to": "Aller à la diapositive `x`",
|
||||
"toggle_theme": "Changer le Thème",
|
||||
"Filipino (auto-generated)": "Philippines (automatiquement générer)",
|
||||
"preferences_preload_label": "Précharger les données de la vidéo : ",
|
||||
"First page": "Première page",
|
||||
"channel_tab_courses_label": "Cours",
|
||||
"channel_tab_posts_label": "Messages",
|
||||
"timeline_parse_error_show_technical_details": "Afficher les détails techniques"
|
||||
"preferences_preload_label": "Précharger les données de la vidéo : "
|
||||
}
|
||||
|
||||
506
locales/gsw.json
506
locales/gsw.json
@@ -1,506 +0,0 @@
|
||||
{
|
||||
"Add to playlist": "Enere Widergabelischte hinzuefüege",
|
||||
"Add to playlist: ": "Enere Widergabelischte hinzuefüege: ",
|
||||
"Answer": "Antwort",
|
||||
"Search for videos": "Nach Videos sueche",
|
||||
"The Popular feed has been disabled by the administrator.": "De Feed für beliebti Inhält isch vom Administrator deaktiviert worde.",
|
||||
"generic_channels_count": "{{count}} Kanal",
|
||||
"generic_channels_count_plural": "{{count}} Kanäl",
|
||||
"generic_views_count": "{{count}} Uufruef",
|
||||
"generic_views_count_plural": "{{count}} Uufrüef",
|
||||
"generic_videos_count": "{{count}} Video",
|
||||
"generic_videos_count_plural": "{{count}} Videos",
|
||||
"generic_playlists_count": "{{count}} Widergabelischte",
|
||||
"generic_playlists_count_plural": "{{count}} Widergabelischtene",
|
||||
"generic_subscribers_count": "{{count}} Abonnent",
|
||||
"generic_subscribers_count_plural": "{{count}} Abonnente",
|
||||
"generic_subscriptions_count": "{{count}} Abo",
|
||||
"generic_subscriptions_count_plural": "{{count}} Abos",
|
||||
"generic_button_delete": "Lösche",
|
||||
"generic_button_edit": "Bearbeite",
|
||||
"generic_button_save": "Speichere",
|
||||
"generic_button_cancel": "Abbreche",
|
||||
"generic_button_rss": "RSS",
|
||||
"LIVE": "LIVE",
|
||||
"Shared `x` ago": "Vor `x` teilt",
|
||||
"Unsubscribe": "Abo beende",
|
||||
"Subscribe": "Abonniere",
|
||||
"View channel on YouTube": "Kanal uf YouTube aazeige",
|
||||
"View playlist on YouTube": "Widergabelischte uf YouTube aazeige",
|
||||
"newest": "neusti",
|
||||
"oldest": "ältisti",
|
||||
"popular": "beliebtisti",
|
||||
"last": "neusti",
|
||||
"Next page": "Nächsti Siite",
|
||||
"Previous page": "Vorherigi Siite",
|
||||
"First page": "Ersti Siite",
|
||||
"Clear watch history?": "Widergabeverlauf lösche?",
|
||||
"New password": "Neus Passwort",
|
||||
"New passwords must match": "Neui Passwörter müend übereinstimme",
|
||||
"Authorize token?": "Token autorisiere?",
|
||||
"Authorize token for `x`?": "Token für `x` autorisiere?",
|
||||
"Yes": "Ja",
|
||||
"No": "Nei",
|
||||
"Import and Export Data": "Date importiere und exportiere",
|
||||
"Import": "Importiere",
|
||||
"Import Invidious data": "Invidious-JSON-Date importiere",
|
||||
"Import YouTube subscriptions": "YouTube-CSV/OPML-Abonnements importiere",
|
||||
"Import YouTube playlist (.csv)": "YouTube-Widergabelischte importiere (.csv)",
|
||||
"Import YouTube watch history (.json)": "YouTube-Widergabeverlauf importiere (.json)",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube Abonnements importiere (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe Abonnements importiere (.json)",
|
||||
"Import NewPipe data (.zip)": "NewPipe Date importiere (.zip)",
|
||||
"Export": "Exportiere",
|
||||
"Export subscriptions as OPML": "Abonnements als OPML exportiere",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Abonnements als OPML exportiere (für NewPipe & FreeTube)",
|
||||
"Export data as JSON": "Invidious-Date als JSON exportiere",
|
||||
"Delete account?": "Konto lösche?",
|
||||
"History": "Verlauf",
|
||||
"An alternative front-end to YouTube": "En alternativi Oberflächi für YouTube",
|
||||
"JavaScript license information": "JavaScript Lizenzinformatione",
|
||||
"source": "Quelle",
|
||||
"Log in": "Aamelde",
|
||||
"Log in/register": "Aamelde/registriere",
|
||||
"User ID": "Benutzer-ID",
|
||||
"Password": "Passwort",
|
||||
"Time (h:mm:ss):": "Ziit (h:mm:ss):",
|
||||
"Sign In": "Aamelde",
|
||||
"Register": "Registriere",
|
||||
"E-mail": "E-Mail",
|
||||
"Preferences": "Iistellige",
|
||||
"preferences_category_player": "Widergabeiistellige",
|
||||
"preferences_video_loop_label": "Immer widerhole: ",
|
||||
"preferences_preload_label": "Videodate vorlade: ",
|
||||
"preferences_autoplay_label": "Automatisch abspiele: ",
|
||||
"preferences_continue_label": "Immer automatisch nächsts Video abspiele: ",
|
||||
"preferences_continue_autoplay_label": "Nächsts Video automatisch abspiele: ",
|
||||
"preferences_listen_label": "Nur Ton als Standard: ",
|
||||
"preferences_local_label": "Videos dur Proxy leite: ",
|
||||
"preferences_watch_history_label": "Widergabeverlauf aktiviere: ",
|
||||
"preferences_speed_label": "Standardgschwindigkeit: ",
|
||||
"preferences_quality_label": "Bevorzugti Videoqualität: ",
|
||||
"preferences_quality_option_dash": "DASH (adaptivi Qualität)",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
"preferences_quality_option_medium": "Mittel",
|
||||
"preferences_quality_option_small": "Niedrig",
|
||||
"preferences_quality_dash_label": "Bevorzugti DASH-Videoqualität: ",
|
||||
"preferences_quality_dash_option_auto": "Auto",
|
||||
"preferences_quality_dash_option_best": "Höchsti",
|
||||
"preferences_quality_dash_option_worst": "Niedrigsti",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_1080p": "1080p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
"preferences_quality_dash_option_480p": "480p",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_volume_label": "Widergabeluutstärchi: ",
|
||||
"preferences_comments_label": "Standardkommentär: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"invidious": "Invidious",
|
||||
"preferences_captions_label": "Standarduntertitel: ",
|
||||
"Fallback captions: ": "Ersatzuntertitel: ",
|
||||
"preferences_related_videos_label": "Ähnlichi Videos aazeige: ",
|
||||
"preferences_annotations_label": "Aamerkige standardmässig aazeige: ",
|
||||
"preferences_extend_desc_label": "Videobeschriibig automatisch erwiitere: ",
|
||||
"preferences_vr_mode_label": "Interaktivi 360-Grad-Videos (bruucht WebGL): ",
|
||||
"preferences_category_visual": "Aazeigeiistellige",
|
||||
"preferences_region_label": "Land vo de Inhält: ",
|
||||
"preferences_player_style_label": "Player-Stil: ",
|
||||
"Dark mode: ": "Nachtmodus: ",
|
||||
"preferences_dark_mode_label": "Modus: ",
|
||||
"dark": "Nachtmodus",
|
||||
"light": "hell",
|
||||
"preferences_thin_mode_label": "Schlanke Modus: ",
|
||||
"preferences_category_misc": "Suschtigi Iistellige",
|
||||
"preferences_automatic_instance_redirect_label": "Automatischi Instanzwiiterleitig (über redirect.invidious.io): ",
|
||||
"preferences_category_subscription": "Abonnementiistellige",
|
||||
"preferences_annotations_subscribed_label": "Aamerkige für abonnierti Kanäl standardmässig aazeige? ",
|
||||
"Redirect homepage to feed: ": "Startsiite zu Feed umleite: ",
|
||||
"preferences_max_results_label": "Aazahl vo Videos wo im Feed aazeigt werded: ",
|
||||
"preferences_sort_label": "Videos sortiere nach: ",
|
||||
"published": "veröffentlicht",
|
||||
"published - reverse": "veröffentlicht - invertiert",
|
||||
"alphabetically": "alphabetisch",
|
||||
"alphabetically - reverse": "alphabetisch - invertiert",
|
||||
"channel name": "Kanalname",
|
||||
"channel name - reverse": "Kanalname - invertiert",
|
||||
"Only show latest video from channel: ": "Nur neusti Videos vom Kanal aazeige: ",
|
||||
"Only show latest unwatched video from channel: ": "Neu neusti ungseheni Videos vom Kanal aazeige: ",
|
||||
"preferences_unseen_only_label": "Nur ungseheni aazeige: ",
|
||||
"preferences_notifications_only_label": "Nur Benachrichtigunge aazeige (wenns welchi git): ",
|
||||
"Enable web notifications": "Webbenachrichtigunge aktiviere",
|
||||
"`x` uploaded a video": "`x` het es Video ufeglade",
|
||||
"`x` is live": "`x` isch live",
|
||||
"preferences_category_data": "Dateiistellige",
|
||||
"Clear watch history": "Verlauf lösche",
|
||||
"Import/export data": "Date importiere/exportiere",
|
||||
"Change password": "Passwort ändere",
|
||||
"Manage subscriptions": "Abonnements verwalte",
|
||||
"Manage tokens": "Tokens verwalte",
|
||||
"Watch history": "Widergabeverlauf",
|
||||
"Delete account": "Account lösche",
|
||||
"preferences_category_admin": "Administrator-Iistellige",
|
||||
"preferences_default_home_label": "Standard-Startsiite: ",
|
||||
"preferences_feed_menu_label": "Feed-Menü: ",
|
||||
"preferences_show_nick_label": "Nutzernäme obe aazeige: ",
|
||||
"Popular enabled: ": "„Beliebt“-Siite aktiviert: ",
|
||||
"Top enabled: ": "Top aktiviert? ",
|
||||
"CAPTCHA enabled: ": "CAPTCHA aktiviert? ",
|
||||
"Login enabled: ": "Aameldig aktiviert: ",
|
||||
"Registration enabled: ": "Registrierig aktiviert: ",
|
||||
"Report statistics: ": "Statistike brichte: ",
|
||||
"Save preferences": "Iistellige speichere",
|
||||
"Subscription manager": "Abonnementsverwaltig",
|
||||
"Token manager": "Tokenverwaltig",
|
||||
"Token": "Token",
|
||||
"tokens_count": "{{count}} Token",
|
||||
"tokens_count_plural": "{{count}} Tokens",
|
||||
"Import/export": "Importiere/Exportiere",
|
||||
"unsubscribe": "abbstelle",
|
||||
"revoke": "widerrüefe",
|
||||
"Subscriptions": "Abonnements",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} ungsehni Benachrichtigung",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} ungsehni Benachrichtigunge",
|
||||
"search": "Sueche",
|
||||
"Log out": "Abmelde",
|
||||
"Released under the AGPLv3 on Github.": "Uf GitHub under de AGPLv3 Lizenz veröffentlicht.",
|
||||
"Source available here.": "Quellcode da verfüegbar.",
|
||||
"View JavaScript license information.": "JavaScript-Lizenzinformatione aazeige.",
|
||||
"View privacy policy.": "Dateschutzerchlärig iigseh.",
|
||||
"Trending": "Aagseit",
|
||||
"Public": "Öffentlich",
|
||||
"Unlisted": "Nöd glischtet",
|
||||
"Private": "Privat",
|
||||
"View all playlists": "Alli Widergabelischtene aazeige",
|
||||
"Updated `x` ago": "Aktualisiert vor `x`",
|
||||
"Delete playlist `x`?": "Widergabelischte `x` lösche?",
|
||||
"Delete playlist": "Widergabelischte lösche",
|
||||
"Create playlist": "Widergabelischte erstelle",
|
||||
"Title": "Titel",
|
||||
"Playlist privacy": "Widergabelischte-Privatsphäri",
|
||||
"Editing playlist `x`": "Widergabelischte `x` bearbeite",
|
||||
"playlist_button_add_items": "Videos hinzuefüege",
|
||||
"Show more": "Meh aazeige",
|
||||
"Show less": "Weniger aazeige",
|
||||
"Watch on YouTube": "Video uf YouTube aaluege",
|
||||
"Switch Invidious Instance": "Invidious Instanz wechsle",
|
||||
"search_message_no_results": "Kei Ergebnis gfunde.",
|
||||
"search_message_change_filters_or_query": "Versuech, dini Suechaafrag z erwiitere und/oder d Filter z ändere.",
|
||||
"search_message_use_another_instance": "Du chasch au <a href=\"`x`\">uf ere andere Instanz sueche</a>.",
|
||||
"Hide annotations": "Aamerkige uusblende",
|
||||
"Show annotations": "Aamerkige aazeige",
|
||||
"Genre: ": "Genre: ",
|
||||
"License: ": "Lizenz: ",
|
||||
"Standard YouTube license": "Standard YouTube-Lizenz",
|
||||
"Family friendly? ": "Familiefründlich? ",
|
||||
"Wilson score: ": "Wilson-Score: ",
|
||||
"Engagement: ": "Engagement: ",
|
||||
"Whitelisted regions: ": "Erlaubti Regione: ",
|
||||
"Blacklisted regions: ": "Unerlaubti Regione: ",
|
||||
"Music in this video": "Musig i dem Video",
|
||||
"Artist: ": "Künschtler: ",
|
||||
"Song: ": "Musig: ",
|
||||
"Album: ": "Album: ",
|
||||
"Shared `x`": "Teilt `x`",
|
||||
"Premieres in `x`": "Premiere i `x`",
|
||||
"Premieres `x`": "Premiere `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Hallo! Anschinend hesch du JavaScript deaktiviert. Klick da, zum Kommentär aazzeige, beacht, dass es chli länger duure cha, zum sie z lade.",
|
||||
"View YouTube comments": "YouTube Kommentär aazeige",
|
||||
"View more comments on Reddit": "Meh Kommentär uf Reddit aazeige",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` Kommentar aazeige",
|
||||
"": "`x` Kommentär aazeige"
|
||||
},
|
||||
"View Reddit comments": "Reddit-Kommentär aazeige",
|
||||
"Hide replies": "Antworte verstecke",
|
||||
"Show replies": "Antworte aazeige",
|
||||
"Incorrect password": "Falschs Passwort",
|
||||
"Wrong answer": "Ungültigi Antwort",
|
||||
"Erroneous CAPTCHA": "Ungültigs CAPTCHA",
|
||||
"CAPTCHA is a required field": "CAPTCHA isch en erforderlichi Iigab",
|
||||
"User ID is a required field": "Benutzer ID isch en erforderlichi Iigab",
|
||||
"Password is a required field": "Passwort isch en erforderlichi Iigab",
|
||||
"Wrong username or password": "Ungültige Benutzername oder Passwort",
|
||||
"Password cannot be empty": "Passwort derf nöd leer sii",
|
||||
"Password cannot be longer than 55 characters": "Passwort derf nöd länger als 55 Zeiche sii",
|
||||
"Please log in": "Bitte aamelde",
|
||||
"Invidious Private Feed for `x`": "Invidious Persönliche Feed für `x`",
|
||||
"channel:`x`": "Kanal:`x`",
|
||||
"Deleted or invalid channel": "Glöschte oder ungültige Kanal",
|
||||
"This channel does not exist.": "De Kanal existiert nöd.",
|
||||
"Could not get channel info.": "Kanalinformatione hend nöd chönne glade werde.",
|
||||
"Could not fetch comments": "Kommentär hend nöd chönne glade werde",
|
||||
"comments_view_x_replies": "{{count}} Antwort aazeige",
|
||||
"comments_view_x_replies_plural": "{{count}} Antworte aazeige",
|
||||
"`x` ago": "vor `x`",
|
||||
"Load more": "Meh lade",
|
||||
"comments_points_count": "{{count}} Punkt",
|
||||
"comments_points_count_plural": "{{count}} Pünkt",
|
||||
"Could not create mix.": "Mix het nöd chönne erstellt werde.",
|
||||
"Empty playlist": "Widergabelischte isch leer",
|
||||
"Not a playlist.": "Ungültigi Widergabelischte.",
|
||||
"Playlist does not exist.": "Widergabelischte existiert nöd.",
|
||||
"Could not pull trending pages.": "Beliebt-Siitene hend nöd chönne glade werde.",
|
||||
"Hidden field \"challenge\" is a required field": "Versteckts Feld „challenge“ isch en erforderlichi Iigab",
|
||||
"Hidden field \"token\" is a required field": "Versteckts Feld „token“ isch en erforderlichi Iigab",
|
||||
"Erroneous challenge": "Ungültige Test",
|
||||
"Erroneous token": "Ungültige Token",
|
||||
"No such user": "Ungültige Benutzer",
|
||||
"Token is expired, please try again": "Token isch abgloffe, bitte nomal versueche",
|
||||
"generic_count_years": "{{count}} Jahr",
|
||||
"generic_count_years_plural": "{{count}} Jahr",
|
||||
"generic_count_months": "{{count}} Monet",
|
||||
"generic_count_months_plural": "{{count}} Mönet",
|
||||
"generic_count_weeks": "{{count}} Wuche",
|
||||
"generic_count_weeks_plural": "{{count}} Wuche",
|
||||
"generic_count_days": "{{count}} Tag",
|
||||
"generic_count_days_plural": "{{count}} Täg",
|
||||
"generic_count_hours": "{{count}} Stund",
|
||||
"generic_count_hours_plural": "{{count}} Stunde",
|
||||
"generic_count_minutes": "{{count}} Minute",
|
||||
"generic_count_minutes_plural": "{{count}} Minute",
|
||||
"generic_count_seconds": "{{count}} Sekunde",
|
||||
"generic_count_seconds_plural": "{{count}} Sekunde",
|
||||
"Fallback comments: ": "Alternativi Kommentär: ",
|
||||
"Popular": "Populär",
|
||||
"Search": "Sueche",
|
||||
"Top": "Top",
|
||||
"About": "Über",
|
||||
"Rating: ": "Bewertig: ",
|
||||
"preferences_locale_label": "Spraach: ",
|
||||
"View as playlist": "Als Widergabelischte aazeige",
|
||||
"Default": "Standard",
|
||||
"Music": "Musig",
|
||||
"Gaming": "Videospiel",
|
||||
"News": "Neuigkeite",
|
||||
"Movies": "Film",
|
||||
"Download": "Abelade",
|
||||
"Download as: ": "Abelade als: ",
|
||||
"Download is disabled": "Abelade isch deaktiviert",
|
||||
"%A %B %-d, %Y": "%A %-d %B %Y",
|
||||
"(edited)": "(bearbeitet)",
|
||||
"YouTube comment permalink": "YouTube-Kommentar Permalink",
|
||||
"permalink": "Permalink",
|
||||
"`x` marked it with a ❤": "`x` hets mitme ❤ markiert",
|
||||
"Channel Sponsor": "Kanalsponsor",
|
||||
"Audio mode": "Audiomodus",
|
||||
"Video mode": "Videomodus",
|
||||
"Playlists": "Widergabelischtene",
|
||||
"search_filters_title": "Filtere",
|
||||
"search_filters_date_label": "Upload-Datum",
|
||||
"search_filters_date_option_none": "Bliebigs Datum",
|
||||
"search_filters_date_option_hour": "Letschti Stund",
|
||||
"search_filters_date_option_today": "Hüt",
|
||||
"search_filters_date_option_week": "Die Wuche",
|
||||
"search_filters_date_option_month": "De Monet",
|
||||
"search_filters_date_option_year": "Das Jahr",
|
||||
"search_filters_type_label": "Inhaltstyp",
|
||||
"search_filters_type_option_all": "Bliebige Typ",
|
||||
"search_filters_type_option_video": "Video",
|
||||
"search_filters_type_option_channel": "Kanal",
|
||||
"search_filters_type_option_playlist": "Widergabelischte",
|
||||
"search_filters_type_option_movie": "Film",
|
||||
"search_filters_type_option_show": "Aazeige",
|
||||
"search_filters_duration_label": "Duur",
|
||||
"search_filters_duration_option_none": "Bliebigi Längi",
|
||||
"search_filters_duration_option_short": "Churz (< 4 Minute)",
|
||||
"search_filters_duration_option_medium": "Mittel (4 - 20 Minute)",
|
||||
"search_filters_duration_option_long": "Lang (> 20 Minute)",
|
||||
"search_filters_features_label": "Eigeschafte",
|
||||
"search_filters_features_option_live": "Live",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Untertitel/CC",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"search_filters_features_option_location": "Standort",
|
||||
"search_filters_features_option_purchased": "Kauft",
|
||||
"search_filters_sort_label": "Sortiere nach",
|
||||
"search_filters_sort_option_relevance": "Relevanz",
|
||||
"search_filters_sort_option_rating": "Bewertig",
|
||||
"search_filters_sort_option_date": "Ueladedatum",
|
||||
"search_filters_sort_option_views": "Uufrüef",
|
||||
"search_filters_apply_button": "Uusgwählti Filter aawende",
|
||||
"Current version: ": "Aktuelli Version: ",
|
||||
"next_steps_error_message": "Nachher das versueche: ",
|
||||
"next_steps_error_message_refresh": "Aktualisiere",
|
||||
"next_steps_error_message_go_to_youtube": "Zu YouTube gah",
|
||||
"footer_donate_page": "Spende",
|
||||
"footer_documentation": "Dokumentation",
|
||||
"footer_source_code": "Quellcode",
|
||||
"footer_original_source_code": "Original Quellcode",
|
||||
"footer_modfied_source_code": "Modifizierte Quellcode",
|
||||
"adminprefs_modified_source_code_url_label": "URL zum Repository vom modifizierte Quellcode",
|
||||
"none": "kei",
|
||||
"videoinfo_started_streaming_x_ago": "Stream het vor `x` aagfange",
|
||||
"videoinfo_watch_on_youTube": "Uf YouTube aaluege",
|
||||
"videoinfo_youTube_embed_link": "Iibettet",
|
||||
"videoinfo_invidious_embed_link": "Link zum Iibette",
|
||||
"download_subtitles": "Untertitel - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` Widergabelischtene erstellt",
|
||||
"user_saved_playlists": "`x` Widergabelischtene gspeicheret",
|
||||
"Video unavailable": "Video nöd verfüegbar",
|
||||
"preferences_save_player_pos_label": "Widergabeposition speichere: ",
|
||||
"crash_page_you_found_a_bug": "Anschinend hesch du en Fehler in Invidious gfunde!",
|
||||
"crash_page_before_reporting": "Bevor du en Bug meldsch, stell sicher, dass du:",
|
||||
"crash_page_refresh": "Versuecht hesch, <a href=\"`x`\">d Siite neu z lade</a>",
|
||||
"crash_page_switch_instance": "En <a href=\"`x`\">anderi Instanz</a> versuecht hesch",
|
||||
"crash_page_read_the_faq": "S <a href=\"`x`\">FAQ</a> glese hesch",
|
||||
"crash_page_search_issue": "Nach <a href=\"`x`\">scho gmeldete Bugs uf GitHub</a> gsuecht hesch",
|
||||
"crash_page_report_issue": "Wenn all das nöd ghulfe het, <a href=\"`x`\">öffne bitte es neus Problem (issue) uf GitHub</a> (vorzugswiis uf Englisch) und füeg de folgendi Text i dini Nachricht ii (bitte übersetz de Text NÖD):",
|
||||
"error_video_not_in_playlist": "S agforderete Video existiert nöd i dere Widergabelischte. <a href=\"`x`\">Klick da, zum zur Startsiite vo de Widergabelischte z cho.</a>",
|
||||
"channel_tab_videos_label": "Videos",
|
||||
"channel_tab_shorts_label": "Shorts",
|
||||
"channel_tab_streams_label": "Livestreams",
|
||||
"channel_tab_podcasts_label": "Podcasts",
|
||||
"channel_tab_releases_label": "Veröffentlichige",
|
||||
"channel_tab_courses_label": "Kürs",
|
||||
"channel_tab_playlists_label": "Widergabelischtene",
|
||||
"channel_tab_community_label": "Community",
|
||||
"channel_tab_posts_label": "Biiträg",
|
||||
"channel_tab_channels_label": "Kanäl",
|
||||
"toggle_theme": "Thema wechsle",
|
||||
"carousel_slide": "Siite {{current}} vo {{total}}",
|
||||
"carousel_skip": "Galerie überspringe",
|
||||
"carousel_go_to": "Zu Element `x` springe",
|
||||
"timeline_parse_error_placeholder_heading": "Element cha nöd parsed werde",
|
||||
"timeline_parse_error_placeholder_message": "Invidious isch bim Parse vo dem Element uf en Fehler gstosse. Für wiiteri Information lueg da une:",
|
||||
"timeline_parse_error_show_technical_details": "Technischi Details aazeige",
|
||||
"English": "Englisch",
|
||||
"English (United Kingdom)": "Englisch (Vereinigts Königriich)",
|
||||
"English (United States)": "Englisch (Vereinigti Staate)",
|
||||
"English (auto-generated)": "Englisch (automatisch generiert)",
|
||||
"Afrikaans": "Afrikaans",
|
||||
"Albanian": "Albanisch",
|
||||
"Amharic": "Amharisch",
|
||||
"Arabic": "Arabisch",
|
||||
"Armenian": "Armenisch",
|
||||
"Azerbaijani": "Aserbaidschanisch",
|
||||
"Bangla": "Bengalisch",
|
||||
"Basque": "Baskisch",
|
||||
"Belarusian": "Wiissrussisch",
|
||||
"Bosnian": "Bosnisch",
|
||||
"Bulgarian": "Bulgarisch",
|
||||
"Burmese": "Burmesisch",
|
||||
"Cantonese (Hong Kong)": "Kantonesisch (Hong Kong)",
|
||||
"Catalan": "Katalanisch",
|
||||
"Cebuano": "Cebuano",
|
||||
"Chinese": "Chinesisch",
|
||||
"Chinese (China)": "Chinesisch (China)",
|
||||
"Chinese (Hong Kong)": "Chinesisch (Hong Kong)",
|
||||
"Chinese (Simplified)": "Chinesisch (vereifacht)",
|
||||
"Chinese (Taiwan)": "Chinesisch (Taiwan)",
|
||||
"Chinese (Traditional)": "Chinesisch (traditionell)",
|
||||
"Corsican": "Korsisch",
|
||||
"Croatian": "Kroatisch",
|
||||
"Czech": "Tschechisch",
|
||||
"Danish": "Dänisch",
|
||||
"Dutch": "Niederländisch",
|
||||
"Dutch (auto-generated)": "Niederländisch (automatisch generiert)",
|
||||
"Esperanto": "Esperanto",
|
||||
"Estonian": "Estnisch",
|
||||
"Filipino": "Philippinisch",
|
||||
"Filipino (auto-generated)": "Philippinisch (automatisch generiert)",
|
||||
"Finnish": "Finnisch",
|
||||
"French": "Französisch",
|
||||
"French (auto-generated)": "Französisch (automatisch generiert)",
|
||||
"Galician": "Galizisch",
|
||||
"Georgian": "Gerogisch",
|
||||
"German": "Dütsch",
|
||||
"German (auto-generated)": "Dütsch (automatisch generiert)",
|
||||
"Greek": "Griechisch",
|
||||
"Gujarati": "Gujarati",
|
||||
"Haitian Creole": "Haitianischs Kreolisch",
|
||||
"Hausa": "Hausa",
|
||||
"Hawaiian": "Hawaiianisch",
|
||||
"Hebrew": "Hebräisch",
|
||||
"Hindi": "Hindi",
|
||||
"Hmong": "Hmong",
|
||||
"Hungarian": "Ungarisch",
|
||||
"Icelandic": "Isländisch",
|
||||
"Igbo": "Igbo",
|
||||
"Indonesian": "Indonesisch",
|
||||
"Indonesian (auto-generated)": "Indonesisch (automatisch generiert)",
|
||||
"Interlingue": "Interlingue",
|
||||
"Irish": "Irisch",
|
||||
"Italian": "Italienisch",
|
||||
"Italian (auto-generated)": "Italienisch (automatisch generiert)",
|
||||
"Japanese": "Japanisch",
|
||||
"Japanese (auto-generated)": "Japanisch (automatisch generiert)",
|
||||
"Javanese": "Javanisch",
|
||||
"Kannada": "Kannada",
|
||||
"Kazakh": "Kasachisch",
|
||||
"Khmer": "Khmer",
|
||||
"Korean": "Koreanisch",
|
||||
"Korean (auto-generated)": "Koreanisch (automatisch generiert)",
|
||||
"Kurdish": "Kurdisch",
|
||||
"Kyrgyz": "Kirgisisch",
|
||||
"Lao": "Laotisch",
|
||||
"Latin": "Latinisch",
|
||||
"Latvian": "Lettisch",
|
||||
"Lithuanian": "Litauisch",
|
||||
"Luxembourgish": "Luxeburgisch",
|
||||
"Macedonian": "Mazedonisch",
|
||||
"Malagasy": "Madagassisch",
|
||||
"Malay": "Malaiisch",
|
||||
"Malayalam": "Malayalam",
|
||||
"Maltese": "Maltesisch",
|
||||
"Maori": "Maori",
|
||||
"Marathi": "Marathi",
|
||||
"Mongolian": "Mongolisch",
|
||||
"Nepali": "Nepalesisch",
|
||||
"Norwegian Bokmål": "Norwegisch",
|
||||
"Nyanja": "Nyanja",
|
||||
"Pashto": "Paschtunisch",
|
||||
"Persian": "Persisch",
|
||||
"Polish": "Polnisch",
|
||||
"Portuguese": "Portugiesisch",
|
||||
"Portuguese (auto-generated)": "Portugiesisch (automatisch generiert)",
|
||||
"Portuguese (Brazil)": "Portugiesisch (Brasilie)",
|
||||
"Punjabi": "Pandschabi",
|
||||
"Romanian": "Rumänisch",
|
||||
"Russian": "Russisch",
|
||||
"Russian (auto-generated)": "Russisch (automatisch generiert)",
|
||||
"Samoan": "Samoanisch",
|
||||
"Scottish Gaelic": "Schottischs Gällisch",
|
||||
"Serbian": "Serbisch",
|
||||
"Shona": "Schona",
|
||||
"Sindhi": "Sindhi",
|
||||
"Sinhala": "Singhalesisch",
|
||||
"Slovak": "Slowakisch",
|
||||
"Slovenian": "Slowenisch",
|
||||
"Somali": "Somali",
|
||||
"Southern Sotho": "Südlichs Sotho",
|
||||
"Spanish": "Spanisch",
|
||||
"Spanish (auto-generated)": "Spanisch (automatisch generiert)",
|
||||
"Spanish (Latin America)": "Spanisch (Latinamerika)",
|
||||
"Spanish (Mexico)": "Spanisch (Mexiko)",
|
||||
"Spanish (Spain)": "Spanisch (Spanie)",
|
||||
"Sundanese": "Sundanesisch",
|
||||
"Swahili": "Suaheli",
|
||||
"Swedish": "Schwedisch",
|
||||
"Tajik": "Tadschikisch",
|
||||
"Tamil": "Tamilisch",
|
||||
"Telugu": "Telugu",
|
||||
"Thai": "Thailändisch",
|
||||
"Turkish": "Türkisch",
|
||||
"Turkish (auto-generated)": "Türkisch (automatisch generiert)",
|
||||
"Ukrainian": "Ukrainisch",
|
||||
"Urdu": "Urdu",
|
||||
"Uzbek": "Usbekisch",
|
||||
"Vietnamese": "Vietnamesisch",
|
||||
"Vietnamese (auto-generated)": "Vietnamesisch (automatisch generiert)",
|
||||
"Welsh": "Walisisch",
|
||||
"Western Frisian": "Weschtfriesisch",
|
||||
"Xhosa": "Xhosa",
|
||||
"Yiddish": "Jiddisch",
|
||||
"Yoruba": "Joruba",
|
||||
"Zulu": "Zulu"
|
||||
}
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "שם משתמש",
|
||||
"Password": "סיסמה",
|
||||
"Time (h:mm:ss):": "זמן (h:mm:ss):",
|
||||
"Text CAPTCHA": "Text CAPTCHA",
|
||||
"Image CAPTCHA": "Image CAPTCHA",
|
||||
"Sign In": "התחברות",
|
||||
"Register": "הרשמה",
|
||||
"E-mail": "דוא״ל",
|
||||
|
||||
@@ -80,6 +80,8 @@
|
||||
"Register": "पंजीकृत करें",
|
||||
"E-mail": "ईमेल",
|
||||
"Time (h:mm:ss):": "समय (घं:मिमि:सेसे):",
|
||||
"Text CAPTCHA": "टेक्स्ट CAPTCHA",
|
||||
"Image CAPTCHA": "चित्र CAPTCHA",
|
||||
"Sign In": "साइन इन करें",
|
||||
"Preferences": "प्राथमिकताएँ",
|
||||
"preferences_category_player": "प्लेयर की प्राथमिकताएँ",
|
||||
@@ -197,7 +199,7 @@
|
||||
"Switch Invidious Instance": "Invidious उदाहरण बदलें",
|
||||
"search_message_no_results": "कोई परिणाम नहीं मिला।",
|
||||
"search_message_change_filters_or_query": "अपने खोज क्वेरी को और चौड़ा करें और/या फ़िल्टर बदलें।",
|
||||
"search_message_use_another_instance": "आप <a href=\"`x`\">दूसरे उदाहरण पर भी खोज सकते हैं</a>।",
|
||||
"search_message_use_another_instance": " आप <a href=\"`x`\">दूसरे उदाहरण पर भी खोज सकते हैं</a>।",
|
||||
"Hide annotations": "टिप्पणियाँ छिपाएँ",
|
||||
"Show annotations": "टिप्पणियाँ दिखाएँ",
|
||||
"Genre: ": "श्रेणी: ",
|
||||
@@ -432,7 +434,7 @@
|
||||
"search_filters_features_option_location": "जगह",
|
||||
"search_filters_features_option_purchased": "खरीदा गया",
|
||||
"search_filters_sort_label": "इस क्रम से लगाएँ",
|
||||
"search_filters_sort_option_date": "अपलोड की तारीख",
|
||||
"search_filters_sort_option_date": "अपलोड की ताऱीख",
|
||||
"search_filters_sort_option_views": "देखे जाने की संख्या",
|
||||
"search_filters_apply_button": "चयनित फ़िल्टर लागू करें",
|
||||
"footer_documentation": "प्रलेख",
|
||||
@@ -474,7 +476,7 @@
|
||||
"generic_button_cancel": "रद्द करें",
|
||||
"generic_button_rss": "आरएसएस",
|
||||
"generic_button_edit": "संपादित करें",
|
||||
"generic_button_delete": "हटाएँ",
|
||||
"generic_button_delete": "हटाएं",
|
||||
"playlist_button_add_items": "वीडियो जोड़ें",
|
||||
"Song: ": "गाना: ",
|
||||
"channel_tab_podcasts_label": "पाॅडकास्ट",
|
||||
@@ -494,13 +496,5 @@
|
||||
"carousel_skip": "कैरोसेल छोड़ें",
|
||||
"Add to playlist: ": "प्लेलिस्ट में जोड़ें: ",
|
||||
"Search for videos": "वीडियो खोजें",
|
||||
"carousel_go_to": "स्लाइड `x` पर जाएँ",
|
||||
"First page": "पहला पृष्ठ",
|
||||
"preferences_preload_label": "वीडियो डेटा प्रीलोड करें: ",
|
||||
"Filipino (auto-generated)": "फ़िलिपीनो (अपने-आप जनरेट हुआ)",
|
||||
"channel_tab_courses_label": "कोर्स",
|
||||
"channel_tab_posts_label": "पोस्ट",
|
||||
"timeline_parse_error_placeholder_heading": "आयटम को पार्स नहीं किया जा सका",
|
||||
"timeline_parse_error_placeholder_message": "इस आयटम को पार्स करते समय Invidious को एक त्रुटि आई। अधिक जानकारी के लिए नीचे देखें:",
|
||||
"timeline_parse_error_show_technical_details": "तकनीकी जानकारी दिखाएँ"
|
||||
"carousel_go_to": "स्लाइड `x` पर जाएँ"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Korisnički ID",
|
||||
"Password": "Lozinka",
|
||||
"Time (h:mm:ss):": "Vrijeme (h:mm:ss):",
|
||||
"Text CAPTCHA": "Tekstualni CAPTCHA",
|
||||
"Image CAPTCHA": "Slikovni CAPTCHA",
|
||||
"Sign In": "Prijavi se",
|
||||
"Register": "Registriraj se",
|
||||
"E-mail": "E-mail adresa",
|
||||
@@ -513,11 +515,5 @@
|
||||
"carousel_go_to": "Idi na kadar `x`",
|
||||
"carousel_skip": "Preskoči vrtuljak",
|
||||
"Filipino (auto-generated)": "Filipinski (automatski generirano)",
|
||||
"preferences_preload_label": "Unaprijed učitaj podatke videa: ",
|
||||
"channel_tab_posts_label": "Objave",
|
||||
"timeline_parse_error_placeholder_heading": "Nije moguće obraditi stavku",
|
||||
"timeline_parse_error_placeholder_message": "Invidious je naišao na grešku prilikom obrade ove stavke. Za više informacija pogledajte niže dolje:",
|
||||
"timeline_parse_error_show_technical_details": "Prikaži tehničke detalje",
|
||||
"First page": "Prva stranica",
|
||||
"channel_tab_courses_label": "Tečajevi"
|
||||
"preferences_preload_label": "Unaprijed učitaj podatke videa: "
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
"User ID": "Felhasználói azonosító",
|
||||
"Password": "Jelszó",
|
||||
"Time (h:mm:ss):": "A pontos idő (ó:pp:mm):",
|
||||
"Text CAPTCHA": "Szöveges CAPTCHA kérése",
|
||||
"Image CAPTCHA": "Kép CAPTCHA kérése",
|
||||
"Sign In": "Bejelentkezés",
|
||||
"Register": "Regisztrálás",
|
||||
"E-mail": "E-mail-cím",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"oldest": "plus ancian",
|
||||
"published": "data de publication",
|
||||
"invidious": "Invidious",
|
||||
"Image CAPTCHA": "Imagine CAPTCHA",
|
||||
"newest": "plus nove",
|
||||
"generic_button_save": "Salveguardar",
|
||||
"Dark mode: ": "Modo obscur: ",
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"User ID": "ID Pengguna",
|
||||
"Password": "Kata Sandi",
|
||||
"Time (h:mm:ss):": "Waktu (j:mm:dd):",
|
||||
"Text CAPTCHA": "Teks CAPTCHA",
|
||||
"Image CAPTCHA": "Gambar CAPTCHA",
|
||||
"Sign In": "Masuk",
|
||||
"Register": "Daftar",
|
||||
"E-mail": "Surel",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"LIVE": "BEINT",
|
||||
"Shared `x` ago": "Deilt fyrir `x` síðan",
|
||||
"Unsubscribe": "Afskrá",
|
||||
"Subscribe": "Setja í áskrift",
|
||||
"Subscribe": "Áskrifa",
|
||||
"View channel on YouTube": "Skoða rás á YouTube",
|
||||
"View playlist on YouTube": "Skoða spilunarlista á YouTube",
|
||||
"newest": "nýjasta",
|
||||
@@ -14,8 +14,8 @@
|
||||
"Clear watch history?": "Hreinsa áhorfsferil?",
|
||||
"New password": "Nýtt lykilorð",
|
||||
"New passwords must match": "Nýtt lykilorð verður að passa",
|
||||
"Authorize token?": "Auðkenna teikn?",
|
||||
"Authorize token for `x`?": "Auðkenna teikn fyrir `x`?",
|
||||
"Authorize token?": "Leyfa teikn?",
|
||||
"Authorize token for `x`?": "Leyfa teikn fyrir `x`?",
|
||||
"Yes": "Já",
|
||||
"No": "Nei",
|
||||
"Import and Export Data": "Inn- og útflutningur gagna",
|
||||
@@ -36,15 +36,17 @@
|
||||
"source": "uppruni",
|
||||
"Log in": "Skrá inn",
|
||||
"Log in/register": "Innskráning/nýskráning",
|
||||
"User ID": "Auðkenni notanda",
|
||||
"User ID": "Notandakenni",
|
||||
"Password": "Lykilorð",
|
||||
"Time (h:mm:ss):": "Tími (h:mm: ss):",
|
||||
"Text CAPTCHA": "Texta CAPTCHA",
|
||||
"Image CAPTCHA": "Mynd CAPTCHA",
|
||||
"Sign In": "Skrá inn",
|
||||
"Register": "Nýskrá",
|
||||
"E-mail": "Tölvupóstur",
|
||||
"Preferences": "Kjörstillingar",
|
||||
"preferences_category_player": "Kjörstillingar spilara",
|
||||
"preferences_video_loop_label": "Alltaf endurtaka: ",
|
||||
"preferences_video_loop_label": "Alltaf lykkja: ",
|
||||
"preferences_autoplay_label": "Sjálfvirk spilun: ",
|
||||
"preferences_continue_label": "Spila næst sjálfgefið: ",
|
||||
"preferences_continue_autoplay_label": "Spila næsta myndskeið sjálfkrafa: ",
|
||||
@@ -83,7 +85,7 @@
|
||||
"preferences_unseen_only_label": "Sýna aðeins óséð: ",
|
||||
"preferences_notifications_only_label": "Sýna aðeins tilkynningar (ef einhverjar eru): ",
|
||||
"Enable web notifications": "Virkja veftilkynningar",
|
||||
"`x` uploaded a video": "`x` sendi inn myndskeið",
|
||||
"`x` uploaded a video": "`x` hlóð upp myndband",
|
||||
"`x` is live": "`x` er í beinni",
|
||||
"preferences_category_data": "Gagnastillingar",
|
||||
"Clear watch history": "Hreinsa áhorfsferil",
|
||||
@@ -102,8 +104,8 @@
|
||||
"Registration enabled: ": "Nýskráning virkjuð? ",
|
||||
"Report statistics: ": "Skrá tölfræði? ",
|
||||
"Save preferences": "Vista stillingar",
|
||||
"Subscription manager": "Áskriftastýring",
|
||||
"Token manager": "Teiknastýring",
|
||||
"Subscription manager": "Áskriftarstjóri",
|
||||
"Token manager": "Teiknastjórnun",
|
||||
"Token": "Teikn",
|
||||
"Import/export": "Flytja inn/út",
|
||||
"unsubscribe": "afskrá",
|
||||
@@ -231,7 +233,7 @@
|
||||
"Korean": "Kóreska",
|
||||
"Kurdish": "Kúrdíska",
|
||||
"Kyrgyz": "Kirgisíska",
|
||||
"Lao": "Laóska",
|
||||
"Lao": "Laó",
|
||||
"Latin": "Latína",
|
||||
"Latvian": "Lettneska",
|
||||
"Lithuanian": "Litháíska",
|
||||
@@ -293,18 +295,18 @@
|
||||
"View as playlist": "Skoða sem spilunarlista",
|
||||
"Default": "Sjálfgefið",
|
||||
"Music": "Tónlist",
|
||||
"Gaming": "Spilun leikja",
|
||||
"Gaming": "Tólvuleikja",
|
||||
"News": "Fréttir",
|
||||
"Movies": "Kvikmyndir",
|
||||
"Download": "Niðurhal",
|
||||
"Download as: ": "Sækja sem: ",
|
||||
"Download as: ": "Niðurhala sem: ",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"(edited)": "(breytt)",
|
||||
"YouTube comment permalink": "Varanlegur tengill á YouTube-ummæli",
|
||||
"YouTube comment permalink": "YouTube ummæli varanlegur tengill",
|
||||
"permalink": "Varanlegur tengill",
|
||||
"`x` marked it with a ❤": "`x` merkti það með ❤",
|
||||
"Audio mode": "Hljóðhamur",
|
||||
"Video mode": "Myndhamur",
|
||||
"Audio mode": "Hljóð ham",
|
||||
"Video mode": "Myndband ham",
|
||||
"channel_tab_videos_label": "Myndskeið",
|
||||
"Playlists": "Spilunarlistar",
|
||||
"channel_tab_community_label": "Samfélag",
|
||||
@@ -386,7 +388,7 @@
|
||||
"crash_page_before_reporting": "Áður en þú tilkynnir villu, gakktu úr skugga um að þú hafir:",
|
||||
"crash_page_switch_instance": "reynt að <a href=\"`x`\">nota annað tilvik</a>",
|
||||
"crash_page_report_issue": "Ef ekkert af ofantöldu hjálpaði, ættirðu að <a href=\"`x`\">opna nýja verkbeiðni (issue) á GitHub</a> (helst á ensku) og láta fylgja eftirfarandi texta í skilaboðunum þínum (alls EKKI þýða þennan texta):",
|
||||
"channel_tab_shorts_label": "Símamyndir",
|
||||
"channel_tab_shorts_label": "Stuttmyndir",
|
||||
"carousel_slide": "Skyggna {{current}} af {{total}}",
|
||||
"carousel_go_to": "Fara á skyggnu `x`",
|
||||
"channel_tab_streams_label": "Bein streymi",
|
||||
@@ -399,8 +401,8 @@
|
||||
"English (United Kingdom)": "Enska (Bretland)",
|
||||
"English (United States)": "Enska (Bandarísk)",
|
||||
"Vietnamese (auto-generated)": "Víetnamska (sjálfvirkt útbúið)",
|
||||
"generic_count_months": "{{count}} mánuði",
|
||||
"generic_count_months_plural": "{{count}} mánuðum",
|
||||
"generic_count_months": "{{count}} mánuður",
|
||||
"generic_count_months_plural": "{{count}} mánuðir",
|
||||
"search_filters_sort_option_rating": "Einkunn",
|
||||
"videoinfo_youTube_embed_link": "Ívefja",
|
||||
"error_video_not_in_playlist": "Umbeðið myndskeið fyrirfinnst ekki í þessum spilunarlista. <a href=\"`x`\">Smelltu hér til að fara á heimasíðu spilunarlistans.</a>",
|
||||
@@ -427,11 +429,11 @@
|
||||
"Spanish (auto-generated)": "Spænska (sjálfvirkt útbúið)",
|
||||
"Spanish (Mexico)": "Spænska (Mexíkó)",
|
||||
"generic_count_hours": "{{count}} klukkustund",
|
||||
"generic_count_hours_plural": "{{count}} klukkustundum",
|
||||
"generic_count_years": "{{count}} ári",
|
||||
"generic_count_years_plural": "{{count}} árum",
|
||||
"generic_count_weeks": "{{count}} viku",
|
||||
"generic_count_weeks_plural": "{{count}} vikum",
|
||||
"generic_count_hours_plural": "{{count}} klukkustundir",
|
||||
"generic_count_years": "{{count}} ár",
|
||||
"generic_count_years_plural": "{{count}} ár",
|
||||
"generic_count_weeks": "{{count}} vika",
|
||||
"generic_count_weeks_plural": "{{count}} vikur",
|
||||
"search_filters_date_option_none": "Hvaða dagsetning sem er",
|
||||
"Channel Sponsor": "Styrktaraðili rásar",
|
||||
"search_filters_date_option_week": "Í þessari viku",
|
||||
@@ -474,8 +476,8 @@
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"invidious": "Invidious",
|
||||
"Korean (auto-generated)": "Kóreska (sjálfvirkt útbúið)",
|
||||
"generic_count_days": "{{count}} degi",
|
||||
"generic_count_days_plural": "{{count}} dögum",
|
||||
"generic_count_days": "{{count}} dagur",
|
||||
"generic_count_days_plural": "{{count}} dagar",
|
||||
"search_filters_date_option_today": "Í dag",
|
||||
"search_filters_type_label": "Tegund",
|
||||
"search_filters_type_option_all": "Hvaða tegund sem er",
|
||||
@@ -496,11 +498,5 @@
|
||||
"Import YouTube playlist (.csv)": "Flytja inn YouTube spilunarlista (.csv)",
|
||||
"preferences_quality_option_dash": "DASH (aðlaganleg gæði)",
|
||||
"preferences_preload_label": "Forhlaða gögnum myndskeiðs: ",
|
||||
"Filipino (auto-generated)": "Filippínska (sjálfvirkt útbúin)",
|
||||
"channel_tab_posts_label": "Færslur",
|
||||
"First page": "Fyrsta síða",
|
||||
"channel_tab_courses_label": "Kennsluefni",
|
||||
"timeline_parse_error_placeholder_heading": "Tekst ekki að meðhöndla þetta atriði",
|
||||
"timeline_parse_error_placeholder_message": "Invidious rakst á villu við að reyna að meðhöndla þetta atriði. Skoðaðu nánari upplýsingar hér fyrir neðan:",
|
||||
"timeline_parse_error_show_technical_details": "Sýna nánari tæknilegar upplýsingar"
|
||||
"Filipino (auto-generated)": "Filippínska (sjálfvirkt útbúin)"
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
"User ID": "ID utente",
|
||||
"Password": "Password",
|
||||
"Time (h:mm:ss):": "Orario (h:mm:ss):",
|
||||
"Text CAPTCHA": "Testo del CAPTCHA",
|
||||
"Image CAPTCHA": "Immagine CAPTCHA",
|
||||
"Sign In": "Accedi",
|
||||
"Register": "Registrati",
|
||||
"E-mail": "E-mail",
|
||||
@@ -127,7 +129,7 @@
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} notifica non visualizzata",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} notifiche non visualizzate",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} notifiche non visualizzate",
|
||||
"search": "cerca",
|
||||
"search": "Cerca",
|
||||
"Log out": "Esci",
|
||||
"Source available here.": "Codice sorgente.",
|
||||
"View JavaScript license information.": "Guarda le informazioni di licenza del codice JavaScript.",
|
||||
@@ -513,11 +515,5 @@
|
||||
"carousel_skip": "Salta la galleria",
|
||||
"carousel_go_to": "Vai al fotogramma `x`",
|
||||
"preferences_preload_label": "Precarica dati video: ",
|
||||
"Filipino (auto-generated)": "Filippino (generati automaticamente)",
|
||||
"First page": "Prima pagina",
|
||||
"channel_tab_courses_label": "Corsi",
|
||||
"channel_tab_posts_label": "Post",
|
||||
"timeline_parse_error_show_technical_details": "Mostra i dettagli tecnici",
|
||||
"timeline_parse_error_placeholder_message": "Invidious ha riscontrato un errore tentando di leggere questo elemento. Per altre informazioni vedi di seguito:",
|
||||
"timeline_parse_error_placeholder_heading": "Lettura elemento non riuscita"
|
||||
"Filipino (auto-generated)": "Filippino (generati automaticamente)"
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"No": "いいえ",
|
||||
"Import and Export Data": "データのインポートとエクスポート",
|
||||
"Import": "インポート",
|
||||
"Import Invidious data": "Invidious JSON データをインポート",
|
||||
"Import Invidious data": "Invidious JSONデータをインポート",
|
||||
"Import YouTube subscriptions": "YouTube/OPML 登録チャンネルをインポート",
|
||||
"Import FreeTube subscriptions (.db)": "FreeTube 登録チャンネルをインポート (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "NewPipe 登録チャンネルをインポート (.json)",
|
||||
@@ -44,6 +44,8 @@
|
||||
"User ID": "ユーザー ID",
|
||||
"Password": "パスワード",
|
||||
"Time (h:mm:ss):": "時間 (時:分分:秒秒):",
|
||||
"Text CAPTCHA": "テキスト CAPTCHA",
|
||||
"Image CAPTCHA": "画像 CAPTCHA",
|
||||
"Sign In": "サインイン",
|
||||
"Register": "登録",
|
||||
"E-mail": "メールアドレス",
|
||||
@@ -66,7 +68,7 @@
|
||||
"preferences_related_videos_label": "関連動画を表示: ",
|
||||
"preferences_annotations_label": "最初からアノテーションを表示: ",
|
||||
"preferences_extend_desc_label": "動画の説明文を自動的に拡張: ",
|
||||
"preferences_vr_mode_label": "対話的な 360° 動画 (WebGL が必要): ",
|
||||
"preferences_vr_mode_label": "対話的な360°動画 (WebGLが必要): ",
|
||||
"preferences_category_visual": "外観設定",
|
||||
"preferences_player_style_label": "プレイヤーのスタイル: ",
|
||||
"Dark mode: ": "ダークモード: ",
|
||||
@@ -75,7 +77,7 @@
|
||||
"light": "ライト",
|
||||
"preferences_thin_mode_label": "最小モード: ",
|
||||
"preferences_category_misc": "ほかの設定",
|
||||
"preferences_automatic_instance_redirect_label": "インスタンスの自動転送 (redirect.invidious.io にフォールバック): ",
|
||||
"preferences_automatic_instance_redirect_label": "インスタンスの自動転送 (redirect.invidious.ioにフォールバック): ",
|
||||
"preferences_category_subscription": "登録チャンネル設定",
|
||||
"preferences_annotations_subscribed_label": "最初から登録チャンネルのアノテーションを表示 ",
|
||||
"Redirect homepage to feed: ": "ホームからフィードにリダイレクト: ",
|
||||
@@ -123,7 +125,7 @@
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}}件の未読通知",
|
||||
"search": "検索",
|
||||
"Log out": "ログアウト",
|
||||
"Released under the AGPLv3 on Github.": "GitHub 上で AGPLv3 の元で公開",
|
||||
"Released under the AGPLv3 on Github.": "GitHub上でAGPLv3の元で公開",
|
||||
"Source available here.": "ソースはここで閲覧可能です。",
|
||||
"View JavaScript license information.": "JavaScriptライセンス情報",
|
||||
"View privacy policy.": "個人情報保護方針",
|
||||
@@ -141,8 +143,8 @@
|
||||
"Editing playlist `x`": "再生リスト `x` を編集中",
|
||||
"Show more": "もっと見る",
|
||||
"Show less": "表示を少なく",
|
||||
"Watch on YouTube": "YouTube で視聴",
|
||||
"Switch Invidious Instance": "Invidious インスタンスの変更",
|
||||
"Watch on YouTube": "YouTubeで視聴",
|
||||
"Switch Invidious Instance": "Invidiousインスタンスの変更",
|
||||
"Hide annotations": "アノテーションを隠す",
|
||||
"Show annotations": "アノテーションを表示",
|
||||
"Genre: ": "ジャンル: ",
|
||||
@@ -328,7 +330,7 @@
|
||||
"(edited)": "(編集済み)",
|
||||
"YouTube comment permalink": "YouTube コメントのパーマリンク",
|
||||
"permalink": "パーマリンク",
|
||||
"`x` marked it with a ❤": "`x` が ❤ を送りました",
|
||||
"`x` marked it with a ❤": "`x` が❤を送りました",
|
||||
"Audio mode": "音声モード",
|
||||
"Video mode": "動画モード",
|
||||
"channel_tab_videos_label": "動画",
|
||||
@@ -341,7 +343,7 @@
|
||||
"search_filters_type_label": "種類",
|
||||
"search_filters_duration_label": "再生時間",
|
||||
"search_filters_features_label": "特徴",
|
||||
"search_filters_sort_label": "並べ替え",
|
||||
"search_filters_sort_label": "順番",
|
||||
"search_filters_date_option_hour": "1時間以内",
|
||||
"search_filters_date_option_today": "今日",
|
||||
"search_filters_date_option_week": "今週",
|
||||
@@ -363,13 +365,13 @@
|
||||
"Current version: ": "現在のバージョン: ",
|
||||
"next_steps_error_message": "以下をお試しください: ",
|
||||
"next_steps_error_message_refresh": "再読み込み",
|
||||
"next_steps_error_message_go_to_youtube": "YouTube を開く",
|
||||
"next_steps_error_message_go_to_youtube": "YouTubeを開く",
|
||||
"search_filters_duration_option_short": "4分未満",
|
||||
"footer_documentation": "説明書",
|
||||
"footer_source_code": "ソースコード",
|
||||
"footer_original_source_code": "元のソースコード",
|
||||
"footer_modfied_source_code": "改変し使用中",
|
||||
"adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリの URL",
|
||||
"footer_modfied_source_code": "改変して使用",
|
||||
"adminprefs_modified_source_code_url_label": "改変されたソースコードのレポジトリのURL",
|
||||
"search_filters_duration_option_long": "20分以上",
|
||||
"preferences_region_label": "地域: ",
|
||||
"footer_donate_page": "寄付する",
|
||||
@@ -397,7 +399,7 @@
|
||||
"preferences_quality_dash_option_worst": "最低",
|
||||
"preferences_quality_dash_option_best": "最高",
|
||||
"videoinfo_started_streaming_x_ago": "`x`前に配信を開始",
|
||||
"videoinfo_watch_on_youTube": "YouTube で視聴",
|
||||
"videoinfo_watch_on_youTube": "YouTubeで視聴",
|
||||
"user_created_playlists": "`x`個の作成した再生リスト",
|
||||
"Video unavailable": "動画は利用できません",
|
||||
"Chinese": "中国語",
|
||||
@@ -444,7 +446,7 @@
|
||||
"search_filters_duration_option_medium": "4 ~ 20分",
|
||||
"preferences_save_player_pos_label": "再生位置を保存: ",
|
||||
"crash_page_before_reporting": "バグを報告する前に、次のことを確認してください。",
|
||||
"crash_page_report_issue": "上記が助けにならない場合、<a href=\"`x`\">GitHub</a> に新しい issue を作成し (できれば英語で) 、メッセージに次のテキストを含めてください (テキストは翻訳しない) 。",
|
||||
"crash_page_report_issue": "上記が助けにならないなら、<a href=\"`x`\">GitHub</a> に新しい issue を作成し(英語が好ましい)、メッセージに次のテキストを含めてください(テキストは翻訳しない)。",
|
||||
"crash_page_search_issue": "<a href=\"`x`\">GitHub の既存の問題 (issue)</a> を検索",
|
||||
"channel_tab_streams_label": "ライブ",
|
||||
"channel_tab_playlists_label": "再生リスト",
|
||||
@@ -479,13 +481,5 @@
|
||||
"carousel_skip": "画像のスライド表示をスキップ",
|
||||
"toggle_theme": "テーマの切り替え",
|
||||
"preferences_preload_label": "動画データを事前に読み込む: ",
|
||||
"Filipino (auto-generated)": "フィリピノ語 (自動生成)",
|
||||
"First page": "最初のページ",
|
||||
"channel_tab_posts_label": "投稿",
|
||||
"channel_tab_courses_label": "コース",
|
||||
"timeline_parse_error_placeholder_message": "Invidious によるこの項目の解析中にエラーが発生。詳細は以下:",
|
||||
"timeline_parse_error_placeholder_heading": "この項目を解析できません",
|
||||
"timeline_parse_error_show_technical_details": "技術的詳細を表示",
|
||||
"preferences_default_playlist": "デフォルトのプレイリスト: ",
|
||||
"preferences_default_playlist_none": "デフォルトのプレイリストは設定されていません"
|
||||
"Filipino (auto-generated)": "フィリピノ語 (自動生成)"
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
"Register": "회원가입",
|
||||
"Sign In": "로그인",
|
||||
"preferences_category_misc": "기타 설정",
|
||||
"Image CAPTCHA": "이미지 캡차",
|
||||
"Text CAPTCHA": "텍스트 캡차",
|
||||
"Time (h:mm:ss):": "시각 (h:mm:ss):",
|
||||
"Password": "비밀번호",
|
||||
"User ID": "사용자 ID",
|
||||
@@ -417,7 +419,7 @@
|
||||
"Portuguese (Brazil)": "포르투갈어 (브라질)",
|
||||
"search_message_no_results": "결과가 없습니다.",
|
||||
"search_message_change_filters_or_query": "필터를 변경하시거나 검색어를 넓게 시도해보세요.",
|
||||
"search_message_use_another_instance": "<a href=\"`x`\">다른 인스턴스에서 검색</a>할 수도 있습니다.",
|
||||
"search_message_use_another_instance": " <a href=\"`x`\">다른 인스턴스에서 검색</a>할 수도 있습니다.",
|
||||
"English (United States)": "영어 (미국)",
|
||||
"Chinese": "중국어",
|
||||
"Chinese (China)": "중국어 (중국)",
|
||||
@@ -478,9 +480,5 @@
|
||||
"Search for videos": "비디오 검색",
|
||||
"toggle_theme": "테마 전환",
|
||||
"carousel_slide": "{{total}}의 슬라이드 {{current}}",
|
||||
"preferences_preload_label": "비디오 데이터 사전 로드: ",
|
||||
"First page": "첫 페이지",
|
||||
"Filipino (auto-generated)": "Filipino (auto-generated)",
|
||||
"channel_tab_posts_label": "게시글",
|
||||
"channel_tab_courses_label": "코스"
|
||||
"preferences_preload_label": "비디오 데이터 사전 로드: "
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"JavaScript license information": "Informaziòn su la licensa JavaScript",
|
||||
"source": "font",
|
||||
"Log in": "Và dent",
|
||||
"Text CAPTCHA": "Tèst del CAPTCHA",
|
||||
"Image CAPTCHA": "Imàgen del CAPTCHA",
|
||||
"Sign In": "Ven denter",
|
||||
"Register": "Registres",
|
||||
"E-mail": "E-mail",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Naudotojo ID",
|
||||
"Password": "Slaptažodis",
|
||||
"Time (h:mm:ss):": "Laikas (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA tekstas",
|
||||
"Image CAPTCHA": "CAPTCHA paveikslėlis",
|
||||
"Sign In": "Prisijungti",
|
||||
"Register": "Registruotis",
|
||||
"E-mail": "El. paštas",
|
||||
|
||||
143
locales/lv.json
143
locales/lv.json
@@ -1,143 +0,0 @@
|
||||
{
|
||||
"generic_channels_count_0": "{{count}} kanāli",
|
||||
"generic_channels_count_1": "{{count}} kanāls",
|
||||
"generic_channels_count_2": "{{count}} kanāli",
|
||||
"Add to playlist": "Pievienot atskaņošanas sarakstam",
|
||||
"Answer": "Atbildēt",
|
||||
"generic_subscribers_count_0": "{{count}} abonenti",
|
||||
"generic_subscribers_count_1": "{{count}} abonents",
|
||||
"generic_subscribers_count_2": "{{count}} abonenti",
|
||||
"generic_button_delete": "Dzēst",
|
||||
"generic_button_edit": "Rediģēt",
|
||||
"generic_button_save": "Saglabāt",
|
||||
"generic_button_cancel": "Atcelt",
|
||||
"generic_button_rss": "RSS",
|
||||
"Unsubscribe": "Pārtraukt abonementu",
|
||||
"View playlist on YouTube": "Skatīt atskaņošanas sarakstu YouTube vietnē",
|
||||
"New password": "Jaunā parole",
|
||||
"Yes": "Jā",
|
||||
"No": "Nē",
|
||||
"Import and Export Data": "Ievietot un izgūt datus",
|
||||
"Import": "Ievietot",
|
||||
"Import Invidious data": "Ievietot Invidious JSON datus",
|
||||
"Delete account?": "Vai dzēst kontu?",
|
||||
"History": "Vēsture",
|
||||
"User ID": "Lietotāja ID",
|
||||
"Password": "Parole",
|
||||
"Import YouTube subscriptions": "Ievietot YouTube CSV vai OPML abonementus",
|
||||
"E-mail": "E-pasts",
|
||||
"Preferences": "Iestatījumi",
|
||||
"preferences_category_player": "Atskaņotāja iestatījumi",
|
||||
"preferences_quality_option_hd720": "HD - 720p",
|
||||
"preferences_quality_option_medium": "Vidēja",
|
||||
"preferences_quality_dash_option_worst": "Vissliktākā",
|
||||
"preferences_quality_dash_option_2160p": "2160p (4K)",
|
||||
"preferences_quality_dash_option_1080p": "1080p (Full HD)",
|
||||
"preferences_quality_dash_option_720p": "720p (HD)",
|
||||
"preferences_quality_dash_option_1440p": "1440p (2.5K, QHD)",
|
||||
"preferences_quality_dash_option_480p": "480p (SD)",
|
||||
"preferences_quality_dash_option_360p": "360p",
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"preferences_quality_dash_option_144p": "144p",
|
||||
"preferences_volume_label": "Atskaņošanas skaļums: ",
|
||||
"reddit": "Reddit",
|
||||
"invidious": "Invidious",
|
||||
"Bangla": "Bengāļu",
|
||||
"Basque": "Basku",
|
||||
"Cebuano": "Sebuāņu",
|
||||
"Chinese (Traditional)": "Ķīniešu (tradicionālā)",
|
||||
"Corsican": "Korsikāņu",
|
||||
"Croatian": "Horvātu",
|
||||
"Galician": "Galisiešu",
|
||||
"Georgian": "Gruzīnu",
|
||||
"Gujarati": "Gudžaratu",
|
||||
"German": "Vācu",
|
||||
"Greek": "Grieķu",
|
||||
"Haitian Creole": "Haitiešu",
|
||||
"Hausa": "Hausu",
|
||||
"Hawaiian": "Havajiešu",
|
||||
"Export data as JSON": "Izgūt Invidious datus JSON formātā",
|
||||
"preferences_quality_dash_option_4320p": "4320p (8K)",
|
||||
"Time (h:mm:ss):": "Laiks (h:mm:ss):",
|
||||
"Chinese (Simplified)": "Ķīniešu (vienkāršotā)",
|
||||
"preferences_quality_dash_option_best": "Vislabākā",
|
||||
"preferences_quality_option_small": "Zema",
|
||||
"youtube": "YouTube",
|
||||
"Add to playlist: ": "Pievienot atskaņošanas sarakstam: ",
|
||||
"Subscribe": "Abonēt",
|
||||
"View channel on YouTube": "Skatīt kanālu YouTube vietnē",
|
||||
"LIVE": "TIEŠRAIDE",
|
||||
"Export": "Izgūt",
|
||||
"preferences_dark_mode_label": "Motīvs: ",
|
||||
"published": "Publicēšanas datuma",
|
||||
"preferences_sort_label": "Kārtot video pēc: ",
|
||||
"search_filters_sort_label": "Kārtot pēc",
|
||||
"search_filters_sort_option_date": "Augšupielādes datuma",
|
||||
"search_filters_sort_option_views": "Skatījumu skaita",
|
||||
"published - reverse": "Publicēšanas datuma apgrieztā secībā",
|
||||
"generic_views_count_0": "{{count}} skatījumi",
|
||||
"generic_views_count_1": "{{count}} skatījums",
|
||||
"generic_views_count_2": "{{count}} skatījumi",
|
||||
"generic_videos_count_0": "{{count}} video",
|
||||
"generic_videos_count_1": "{{count}} video",
|
||||
"generic_videos_count_2": "{{count}} video",
|
||||
"generic_playlists_count_0": "{{count}} atskaņošanas saraksti",
|
||||
"generic_playlists_count_1": "{{count}} atskaņošanas saraksts",
|
||||
"generic_playlists_count_2": "{{count}} atskaņošanas saraksti",
|
||||
"generic_subscriptions_count_0": "{{count}} abonementi",
|
||||
"generic_subscriptions_count_1": "{{count}} abonements",
|
||||
"generic_subscriptions_count_2": "{{count}} abonementi",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} jauni paziņojumi",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} jauns paziņojums",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} jauni paziņojumi",
|
||||
"comments_view_x_replies_0": "Skatīt {{count}} atbildes",
|
||||
"comments_view_x_replies_1": "Skatīt {{count}} atbildi",
|
||||
"comments_view_x_replies_2": "Skatīt {{count}} atbildes",
|
||||
"generic_count_years_0": "{{count}} gadi",
|
||||
"generic_count_years_1": "{{count}} gads",
|
||||
"generic_count_years_2": "{{count}} gadi",
|
||||
"generic_count_months_0": "{{count}} mēneši",
|
||||
"generic_count_months_1": "{{count}} mēnesis",
|
||||
"generic_count_months_2": "{{count}} mēneši",
|
||||
"generic_count_weeks_0": "{{count}} nedēļas",
|
||||
"generic_count_weeks_1": "{{count}} nedēļa",
|
||||
"generic_count_weeks_2": "{{count}} nedēļas",
|
||||
"generic_count_days_0": "{{count}} dienas",
|
||||
"generic_count_days_1": "{{count}} diena",
|
||||
"generic_count_days_2": "{{count}} dienas",
|
||||
"generic_count_hours_0": "{{count}} stundas",
|
||||
"generic_count_hours_1": "{{count}} stunda",
|
||||
"generic_count_hours_2": "{{count}} stundas",
|
||||
"generic_count_minutes_0": "{{count}} minūtes",
|
||||
"generic_count_minutes_1": "{{count}} minūte",
|
||||
"generic_count_minutes_2": "{{count}} minūtes",
|
||||
"generic_count_seconds_0": "{{count}} sekundes",
|
||||
"generic_count_seconds_1": "{{count}} sekunde",
|
||||
"generic_count_seconds_2": "{{count}} sekundes",
|
||||
"Import YouTube playlist (.csv)": "Ievietot YouTube atskaņošanas sarakstu (.csv)",
|
||||
"Import YouTube watch history (.json)": "Ievietot YouTube skatīto video vēsturi (.json)",
|
||||
"Import FreeTube subscriptions (.db)": "Ievietot FreeTube abonementus (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Ievietot NewPipe abonementus (.json)",
|
||||
"Import NewPipe data (.zip)": "Ievietot NewPipe datus (.zip)",
|
||||
"Export subscriptions as OPML": "Izgūt abonementus OPML formātā",
|
||||
"Export subscriptions as OPML (for NewPipe & FreeTube)": "Izgūt abonementus OPML formātā (der NewPipe un FreeTube lietotnēm)",
|
||||
"preferences_max_results_label": "Video skaits plūsmā: ",
|
||||
"channel name": "kanāla nosaukuma",
|
||||
"channel name - reverse": "kanāla nosaukuma apgrieztā secībā",
|
||||
"preferences_unseen_only_label": "Rādīt tikai neskatītos video: ",
|
||||
"Enable web notifications": "Iespējot paziņojumus pārlūkā",
|
||||
"`x` uploaded a video": "`x` augšupielādēja video",
|
||||
"Watch history": "Skatīto video vēsture",
|
||||
"Delete account": "Dzēst kontu",
|
||||
"Save preferences": "Saglabāt iestatījumus",
|
||||
"Import/export": "Ievietot/Izgūt",
|
||||
"Released under the AGPLv3 on Github.": "Izvietots GitHub saskaņā ar AGPLv3 licenci.",
|
||||
"Source available here.": "Pirmkods pieejams šeit.",
|
||||
"View JavaScript license information.": "Skatīt JavaScript licences informāciju.",
|
||||
"Public": "Publisks",
|
||||
"Private": "Privāts",
|
||||
"View all playlists": "Skatīt visus atskaņošanas sarakstus",
|
||||
"Delete playlist `x`?": "Vai tiešām dzēst `x` atskaņošanas sarakstu?",
|
||||
"Delete playlist": "Dzēst atskaņošanas sarakstu",
|
||||
"Create playlist": "Izveidot atskaņošanas sarakstu"
|
||||
}
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Bruker-ID",
|
||||
"Password": "Passord",
|
||||
"Time (h:mm:ss):": "Tid (h:mm:ss):",
|
||||
"Text CAPTCHA": "Tekst-CAPTCHA",
|
||||
"Image CAPTCHA": "Bilde-CAPTCHA",
|
||||
"Sign In": "Innlogging",
|
||||
"Register": "Registrer",
|
||||
"E-mail": "E-post",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Gebruikers-id",
|
||||
"Password": "Wachtwoord",
|
||||
"Time (h:mm:ss):": "Tijd (h:mm:ss):",
|
||||
"Text CAPTCHA": "Tekst-CAPTCHA",
|
||||
"Image CAPTCHA": "Afbeelding-CAPTCHA",
|
||||
"Sign In": "Inloggen",
|
||||
"Register": "Registreren",
|
||||
"E-mail": "E-mailadres",
|
||||
@@ -496,11 +498,5 @@
|
||||
"carousel_skip": "Carousel overslaan",
|
||||
"toggle_theme": "Thema omschakelen",
|
||||
"preferences_preload_label": "Videogegevens vooraf laden: ",
|
||||
"Filipino (auto-generated)": "Filipijns (automatisch gegenereerd)",
|
||||
"channel_tab_courses_label": "Cursussen",
|
||||
"First page": "Eerste pagina",
|
||||
"channel_tab_posts_label": "Gepost",
|
||||
"timeline_parse_error_placeholder_heading": "Kan item niet parsen",
|
||||
"timeline_parse_error_placeholder_message": "Invidious kwam een fout tegen bij het proberen te parsen van dit item. Voor meer informatie, kijk hieronder:",
|
||||
"timeline_parse_error_show_technical_details": "Technische details weergeven"
|
||||
"Filipino (auto-generated)": "Filipijns (automatisch gegenereerd)"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ID użytkownika",
|
||||
"Password": "Hasło",
|
||||
"Time (h:mm:ss):": "Godzina (h:mm:ss):",
|
||||
"Text CAPTCHA": "Tekst CAPTCHA",
|
||||
"Image CAPTCHA": "Obraz CAPTCHA",
|
||||
"Sign In": "Zaloguj się",
|
||||
"Register": "Zarejestruj się",
|
||||
"E-mail": "E-mail",
|
||||
@@ -76,7 +78,7 @@
|
||||
"Redirect homepage to feed: ": "Przekieruj stronę główną do subskrybcji: ",
|
||||
"preferences_max_results_label": "Liczba filmów widoczna na stronie subskrybcji: ",
|
||||
"preferences_sort_label": "Sortuj filmy: ",
|
||||
"published": "opublikowano",
|
||||
"published": "po czasie publikacji",
|
||||
"published - reverse": "po czasie publikacji od najstarszych",
|
||||
"alphabetically": "alfabetycznie",
|
||||
"alphabetically - reverse": "alfabetycznie od tyłu",
|
||||
@@ -513,13 +515,5 @@
|
||||
"carousel_skip": "Pomiń karuzelę",
|
||||
"carousel_go_to": "Przejdź do slajdu `x`",
|
||||
"preferences_preload_label": "Wstępne ładowanie danych wideo: ",
|
||||
"Filipino (auto-generated)": "filipiński (wygenerowany automatycznie)",
|
||||
"First page": "Pierwsza strona",
|
||||
"channel_tab_posts_label": "Posty",
|
||||
"channel_tab_courses_label": "Kursy",
|
||||
"timeline_parse_error_placeholder_message": "Invidious napotkał błąd podczas próby parsowania tego elementu. Aby uzyskać więcej informacji, zobacz poniżej:",
|
||||
"timeline_parse_error_placeholder_heading": "Nie można przeanalizować elementu",
|
||||
"timeline_parse_error_show_technical_details": "Pokaż szczegóły techniczne",
|
||||
"preferences_default_playlist_none": "Brak domyślnej playlisty",
|
||||
"preferences_default_playlist": "Domyślna playlista: "
|
||||
"Filipino (auto-generated)": "filipiński (wygenerowany automatycznie)"
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"Authorize token for `x`?": "Autorizar token para `x`?",
|
||||
"Yes": "Sim",
|
||||
"No": "Não",
|
||||
"Import and Export Data": "Importar e exportar dados",
|
||||
"Import and Export Data": "Importar/exportar dados",
|
||||
"Import": "Importar",
|
||||
"Import Invidious data": "Importar dados JSON do Invidious",
|
||||
"Import YouTube subscriptions": "Importar inscrições no formato CSV ou OPML do YouTube",
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Usuário",
|
||||
"Password": "Senha",
|
||||
"Time (h:mm:ss):": "Hora (h:mm:ss):",
|
||||
"Text CAPTCHA": "Mudar para um desafio de texto",
|
||||
"Image CAPTCHA": "Mudar para um desafio visual",
|
||||
"Sign In": "Fazer login",
|
||||
"Register": "Criar conta",
|
||||
"E-mail": "E-mail",
|
||||
@@ -482,7 +484,7 @@
|
||||
"channel_tab_channels_label": "Canais",
|
||||
"channel_tab_playlists_label": "Playlists",
|
||||
"channel_tab_shorts_label": "Shorts",
|
||||
"channel_tab_streams_label": "Transmissões ao vivo",
|
||||
"channel_tab_streams_label": "Transmissão ao vivo",
|
||||
"Music in this video": "Música neste vídeo",
|
||||
"Artist: ": "Artista: ",
|
||||
"Album: ": "Álbum: ",
|
||||
@@ -513,11 +515,5 @@
|
||||
"carousel_skip": "Ignorar carrossel",
|
||||
"carousel_go_to": "Ir ao slide `x`",
|
||||
"preferences_preload_label": "Pré-carregar dados do vídeo: ",
|
||||
"Filipino (auto-generated)": "Filipino (gerado automaticamente)",
|
||||
"channel_tab_posts_label": "Postagens",
|
||||
"First page": "Primeira página",
|
||||
"channel_tab_courses_label": "Cursos",
|
||||
"timeline_parse_error_show_technical_details": "Mostrar detalhes técnicos",
|
||||
"timeline_parse_error_placeholder_message": "O Invidious encontrou um problema ao processar este item. Para mais informações, veja abaixo:",
|
||||
"timeline_parse_error_placeholder_heading": "Incapaz de processar item"
|
||||
"Filipino (auto-generated)": "Filipino (gerado automaticamente)"
|
||||
}
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
{
|
||||
"LIVE": "Direto",
|
||||
"LIVE": "Em direto",
|
||||
"Shared `x` ago": "Partilhado `x` atrás",
|
||||
"Unsubscribe": "Anular subscrição",
|
||||
"Subscribe": "Subscrever",
|
||||
"View channel on YouTube": "Ver canal no YouTube",
|
||||
"View playlist on YouTube": "Ver lista de reprodução no YouTube",
|
||||
"newest": "recentes",
|
||||
"oldest": "antigos",
|
||||
"popular": "populares",
|
||||
"newest": "mais recentes",
|
||||
"oldest": "mais antigos",
|
||||
"popular": "popular",
|
||||
"last": "últimos",
|
||||
"Next page": "Página seguinte",
|
||||
"Next page": "Próxima página",
|
||||
"Previous page": "Página anterior",
|
||||
"Clear watch history?": "Limpar histórico de reprodução?",
|
||||
"New password": "Nova palavra-passe",
|
||||
"New passwords must match": "As novas palavras-passe devem ser iguais",
|
||||
"Authorize token?": "Autorizar 'token'?",
|
||||
"Authorize token for `x`?": "Autorizar 'token' para `x`?",
|
||||
"New password": "Nova palavra-chave",
|
||||
"New passwords must match": "As novas palavra-chaves devem corresponder",
|
||||
"Authorize token?": "Autorizar token?",
|
||||
"Authorize token for `x`?": "Autorizar token para `x`?",
|
||||
"Yes": "Sim",
|
||||
"No": "Não",
|
||||
"Import and Export Data": "Importar e exportar dados",
|
||||
"Import": "Importar",
|
||||
"Import Invidious data": "Importar dados JSON do Invidious",
|
||||
"Import YouTube subscriptions": "Importar via YouTube csv ou subscrição OPML",
|
||||
"Import YouTube subscriptions": "Importar subscrições do YouTube/OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Importar subscrições do FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Importar subscrições do NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Importar dados do NewPipe (.zip)",
|
||||
@@ -32,36 +32,38 @@
|
||||
"Delete account?": "Eliminar conta?",
|
||||
"History": "Histórico",
|
||||
"An alternative front-end to YouTube": "Uma interface alternativa ao YouTube",
|
||||
"JavaScript license information": "Informação da licença JavaScript",
|
||||
"source": "fonte",
|
||||
"JavaScript license information": "Informação de licença do JavaScript",
|
||||
"source": "código-fonte",
|
||||
"Log in": "Iniciar sessão",
|
||||
"Log in/register": "Iniciar sessão/registar",
|
||||
"User ID": "Utilizador",
|
||||
"Password": "Palavra-passe",
|
||||
"Password": "Palavra-chave",
|
||||
"Time (h:mm:ss):": "Tempo (h:mm:ss):",
|
||||
"Sign In": "Entrar",
|
||||
"Text CAPTCHA": "Texto CAPTCHA",
|
||||
"Image CAPTCHA": "Imagem CAPTCHA",
|
||||
"Sign In": "Iniciar sessão",
|
||||
"Register": "Registar",
|
||||
"E-mail": "E-mail",
|
||||
"Preferences": "Preferências",
|
||||
"preferences_category_player": "Preferências do reprodutor",
|
||||
"preferences_video_loop_label": "Repetir sempre: ",
|
||||
"preferences_autoplay_label": "Reprodução automática: ",
|
||||
"preferences_continue_label": "Reproduzir sempre o seguinte: ",
|
||||
"preferences_continue_label": "Reproduzir sempre o próximo: ",
|
||||
"preferences_continue_autoplay_label": "Reproduzir próximo vídeo automaticamente: ",
|
||||
"preferences_listen_label": "Apenas áudio: ",
|
||||
"preferences_local_label": "Usar proxy nos vídeos: ",
|
||||
"preferences_speed_label": "Velocidade preferida: ",
|
||||
"preferences_quality_label": "Qualidade de vídeo preferida: ",
|
||||
"preferences_volume_label": "Volume de reprodução: ",
|
||||
"preferences_comments_label": "Comentários padrão: ",
|
||||
"preferences_volume_label": "Volume da reprodução: ",
|
||||
"preferences_comments_label": "Preferência dos comentários: ",
|
||||
"youtube": "YouTube",
|
||||
"reddit": "Reddit",
|
||||
"preferences_captions_label": "Legendas padrão: ",
|
||||
"preferences_captions_label": "Legendas predefinidas: ",
|
||||
"Fallback captions: ": "Legendas alternativas: ",
|
||||
"preferences_related_videos_label": "Mostrar vídeos relacionados: ",
|
||||
"preferences_annotations_label": "Mostrar anotações sempre: ",
|
||||
"preferences_extend_desc_label": "Expandir automaticamente a descrição do vídeo: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus (requer WebGL): ",
|
||||
"preferences_extend_desc_label": "Estender automaticamente a descrição do vídeo: ",
|
||||
"preferences_vr_mode_label": "Vídeos interativos de 360 graus (necessita de WebGL): ",
|
||||
"preferences_category_visual": "Preferências visuais",
|
||||
"preferences_player_style_label": "Estilo do reprodutor: ",
|
||||
"Dark mode: ": "Modo escuro: ",
|
||||
@@ -72,9 +74,9 @@
|
||||
"preferences_category_misc": "Preferências diversas",
|
||||
"preferences_automatic_instance_redirect_label": "Redirecionamento de instância automática (solução de último recurso para redirect.invidious.io): ",
|
||||
"preferences_category_subscription": "Preferências de subscrições",
|
||||
"preferences_annotations_subscribed_label": "Mostrar sempre anotações nos canais subscritos: ",
|
||||
"preferences_annotations_subscribed_label": "Mostrar sempre anotações aos canais subscritos: ",
|
||||
"Redirect homepage to feed: ": "Redirecionar página inicial para subscrições: ",
|
||||
"preferences_max_results_label": "Número de vídeos nas subscrições: ",
|
||||
"preferences_max_results_label": "Quantidade de vídeos nas subscrições: ",
|
||||
"preferences_sort_label": "Ordenar vídeos por: ",
|
||||
"published": "publicado",
|
||||
"published - reverse": "publicado - inverso",
|
||||
@@ -86,19 +88,19 @@
|
||||
"Only show latest unwatched video from channel: ": "Mostrar apenas vídeos mais recentes não visualizados do canal: ",
|
||||
"preferences_unseen_only_label": "Mostrar apenas vídeos não visualizados: ",
|
||||
"preferences_notifications_only_label": "Mostrar apenas notificações (se existirem): ",
|
||||
"Enable web notifications": "Ativar notificações web",
|
||||
"`x` uploaded a video": "`x` publicou um vídeo",
|
||||
"Enable web notifications": "Ativar notificações pela web",
|
||||
"`x` uploaded a video": "`x` publicou um novo vídeo",
|
||||
"`x` is live": "`x` está em direto",
|
||||
"preferences_category_data": "Preferências de dados",
|
||||
"Clear watch history": "Limpar histórico de reprodução",
|
||||
"Import/export data": "Importar/exportar dados",
|
||||
"Change password": "Alterar palavra-passe",
|
||||
"Manage subscriptions": "Gerir subscrições",
|
||||
"Import/export data": "Importar / exportar dados",
|
||||
"Change password": "Alterar palavra-chave",
|
||||
"Manage subscriptions": "Gerir as subscrições",
|
||||
"Manage tokens": "Gerir tokens",
|
||||
"Watch history": "Histórico de reprodução",
|
||||
"Delete account": "Eliminar conta",
|
||||
"preferences_category_admin": "Preferências de administrador",
|
||||
"preferences_default_home_label": "Página inicial padrão: ",
|
||||
"preferences_default_home_label": "Página inicial predefinida: ",
|
||||
"preferences_feed_menu_label": "Menu de subscrições: ",
|
||||
"preferences_show_nick_label": "Mostrar nome de utilizador em cima: ",
|
||||
"Top enabled: ": "Destaques ativados: ",
|
||||
@@ -107,29 +109,28 @@
|
||||
"Registration enabled: ": "Registar ativado: ",
|
||||
"Report statistics: ": "Relatório de estatísticas: ",
|
||||
"Save preferences": "Guardar preferências",
|
||||
"Subscription manager": "Gestor de subscrições",
|
||||
"Token manager": "Gestor de tokens",
|
||||
"Subscription manager": "Gerir subscrições",
|
||||
"Token manager": "Gerir tokens",
|
||||
"Token": "Token",
|
||||
"tokens_count_0": "{{count}} token",
|
||||
"tokens_count_1": "{{count}} tokens",
|
||||
"tokens_count_2": "{{count}} tokens",
|
||||
"Import/export": "Importar/exportar",
|
||||
"tokens_count": "{{count}} token",
|
||||
"tokens_count_plural": "{{count}} tokens",
|
||||
"Import/export": "Importar / exportar",
|
||||
"unsubscribe": "anular subscrição",
|
||||
"revoke": "revogar",
|
||||
"Subscriptions": "Subscrições",
|
||||
"search": "pesquisar",
|
||||
"Log out": "Terminar sessão",
|
||||
"Released under the AGPLv3 on Github.": "Disponibilizada sob a AGPLv3 no GitHub.",
|
||||
"Released under the AGPLv3 on Github.": "Lançado sob a AGPLv3 no GitHub.",
|
||||
"Source available here.": "Código-fonte disponível aqui.",
|
||||
"View JavaScript license information.": "Ver informações da licença JavaScript.",
|
||||
"View privacy policy.": "Ver política de privacidade.",
|
||||
"View JavaScript license information.": "Ver informações da licença do JavaScript.",
|
||||
"View privacy policy.": "Ver a política de privacidade.",
|
||||
"Trending": "Tendências",
|
||||
"Public": "Público",
|
||||
"Unlisted": "Não listado",
|
||||
"Private": "Privado",
|
||||
"View all playlists": "Ver todas as listas de reprodução",
|
||||
"Updated `x` ago": "Atualizado há `x`",
|
||||
"Delete playlist `x`?": "Eliminar lista de reprodução `x`?",
|
||||
"Updated `x` ago": "Atualizado `x` atrás",
|
||||
"Delete playlist `x`?": "Eliminar a lista de reprodução `x`?",
|
||||
"Delete playlist": "Eliminar lista de reprodução",
|
||||
"Create playlist": "Criar lista de reprodução",
|
||||
"Title": "Título",
|
||||
@@ -138,7 +139,7 @@
|
||||
"Show more": "Mostrar mais",
|
||||
"Show less": "Mostrar menos",
|
||||
"Watch on YouTube": "Ver no YouTube",
|
||||
"Switch Invidious Instance": "Alterar instância Invidious",
|
||||
"Switch Invidious Instance": "Mudar a instância do Invidious",
|
||||
"Hide annotations": "Ocultar anotações",
|
||||
"Show annotations": "Mostrar anotações",
|
||||
"Genre: ": "Género: ",
|
||||
@@ -149,27 +150,27 @@
|
||||
"Whitelisted regions: ": "Regiões permitidas: ",
|
||||
"Blacklisted regions: ": "Regiões bloqueadas: ",
|
||||
"Shared `x`": "Partilhado `x`",
|
||||
"Premieres in `x`": "Estreia a `x`",
|
||||
"Premieres `x`": "Estreia `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Olá! Parece que o JavaScript está desativado. Clique aqui para ver os comentários, mas tenha e conta que podem levar mais tempo para carregar.",
|
||||
"Premieres in `x`": "Estreias em `x`",
|
||||
"Premieres `x`": "Estreias `x`",
|
||||
"Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.": "Olá! Parece que o JavaScript está desativado. Clique aqui para ver os comentários, entretanto eles podem levar mais tempo para carregar.",
|
||||
"View YouTube comments": "Ver comentários do YouTube",
|
||||
"View more comments on Reddit": "Ver mais comentários no Reddit",
|
||||
"View `x` comments": {
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentário",
|
||||
"([^.,0-9]|^)1([^.,0-9]|$)": "Ver `x` comentários",
|
||||
"": "Ver `x` comentários"
|
||||
},
|
||||
"View Reddit comments": "Ver comentários do Reddit",
|
||||
"Hide replies": "Ocultar respostas",
|
||||
"Show replies": "Mostrar respostas",
|
||||
"Incorrect password": "Palavra-passe incorreta",
|
||||
"Incorrect password": "Palavra-chave incorreta",
|
||||
"Wrong answer": "Resposta errada",
|
||||
"Erroneous CAPTCHA": "CAPTCHA inválido",
|
||||
"CAPTCHA is a required field": "CAPTCHA é um campo obrigatório",
|
||||
"User ID is a required field": "O nome de utilizador é um campo obrigatório",
|
||||
"Password is a required field": "Palavra-passe é um campo obrigatório",
|
||||
"Wrong username or password": "Nome de utilizador ou palavra-passe incorreta",
|
||||
"Password cannot be empty": "A palavra-passe não pode estar vazia",
|
||||
"Password cannot be longer than 55 characters": "A palavra-passe não pode ter mais do que 55 caracteres",
|
||||
"Password is a required field": "Palavra-chave é um campo obrigatório",
|
||||
"Wrong username or password": "Nome de utilizador ou palavra-chave incorreto",
|
||||
"Password cannot be empty": "A palavra-chave não pode estar vazia",
|
||||
"Password cannot be longer than 55 characters": "A palavra-chave não pode ser superior a 55 caracteres",
|
||||
"Please log in": "Por favor, inicie sessão",
|
||||
"Invidious Private Feed for `x`": "Feed Privado do Invidious para `x`",
|
||||
"channel:`x`": "canal:`x`",
|
||||
@@ -179,20 +180,20 @@
|
||||
"Could not fetch comments": "Não foi possível obter os comentários",
|
||||
"`x` ago": "`x` atrás",
|
||||
"Load more": "Carregar mais",
|
||||
"Could not create mix.": "Não foi possível criar o mix.",
|
||||
"Could not create mix.": "Não foi possível criar a mistura.",
|
||||
"Empty playlist": "Lista de reprodução vazia",
|
||||
"Not a playlist.": "Não é uma lista de reprodução.",
|
||||
"Playlist does not exist.": "A lista de reprodução não existe.",
|
||||
"Could not pull trending pages.": "Não foi possível obter a página de tendências.",
|
||||
"Could not pull trending pages.": "Não foi possível obter as páginas de tendências.",
|
||||
"Hidden field \"challenge\" is a required field": "O campo oculto \"desafio\" é obrigatório",
|
||||
"Hidden field \"token\" is a required field": "O campo oculto \"token\" é um campo obrigatório",
|
||||
"Erroneous challenge": "Desafio inválido",
|
||||
"Erroneous token": "Token inválido",
|
||||
"No such user": "Utilizador inválido",
|
||||
"Token is expired, please try again": "Token caducado, tente novamente",
|
||||
"Token is expired, please try again": "Token expirou, tente novamente",
|
||||
"English": "Inglês",
|
||||
"English (auto-generated)": "Inglês (auto-gerado)",
|
||||
"Afrikaans": "Africânder",
|
||||
"Afrikaans": "Africano",
|
||||
"Albanian": "Albanês",
|
||||
"Amharic": "Amárico",
|
||||
"Arabic": "Árabe",
|
||||
@@ -208,7 +209,7 @@
|
||||
"Cebuano": "Cebuano",
|
||||
"Chinese (Simplified)": "Chinês (simplificado)",
|
||||
"Chinese (Traditional)": "Chinês (tradicional)",
|
||||
"Corsican": "Córsego",
|
||||
"Corsican": "Corso",
|
||||
"Croatian": "Croata",
|
||||
"Czech": "Checo",
|
||||
"Danish": "Dinamarquês",
|
||||
@@ -251,7 +252,7 @@
|
||||
"Macedonian": "Macedónio",
|
||||
"Malagasy": "Malgaxe",
|
||||
"Malay": "Malaio",
|
||||
"Malayalam": "Malaialaio",
|
||||
"Malayalam": "Malaiala",
|
||||
"Maltese": "Maltês",
|
||||
"Maori": "Maori",
|
||||
"Marathi": "Marathi",
|
||||
@@ -296,37 +297,30 @@
|
||||
"Yiddish": "Iídiche",
|
||||
"Yoruba": "Ioruba",
|
||||
"Zulu": "Zulu",
|
||||
"generic_count_years_0": "{{count}} ano",
|
||||
"generic_count_years_1": "{{count}} anos",
|
||||
"generic_count_years_2": "{{count}} anos",
|
||||
"generic_count_months_0": "{{count}} mês",
|
||||
"generic_count_months_1": "{{count}} meses",
|
||||
"generic_count_months_2": "{{count}} meses",
|
||||
"generic_count_weeks_0": "{{count}} semana",
|
||||
"generic_count_weeks_1": "{{count}} semanas",
|
||||
"generic_count_weeks_2": "{{count}} semanas",
|
||||
"generic_count_days_0": "{{count}} dia",
|
||||
"generic_count_days_1": "{{count}} dias",
|
||||
"generic_count_days_2": "{{count}} dias",
|
||||
"generic_count_hours_0": "{{count}} hora",
|
||||
"generic_count_hours_1": "{{count}} horas",
|
||||
"generic_count_hours_2": "{{count}} horas",
|
||||
"generic_count_minutes_0": "{{count}} minuto",
|
||||
"generic_count_minutes_1": "{{count}} minutos",
|
||||
"generic_count_minutes_2": "{{count}} minutos",
|
||||
"generic_count_seconds_0": "{{count}} segundo",
|
||||
"generic_count_seconds_1": "{{count}} segundos",
|
||||
"generic_count_seconds_2": "{{count}} segundos",
|
||||
"Fallback comments: ": "Alternativa para comentários: ",
|
||||
"generic_count_years": "{{count}} ano",
|
||||
"generic_count_years_plural": "{{count}} anos",
|
||||
"generic_count_months": "{{count}} mês",
|
||||
"generic_count_months_plural": "{{count}} meses",
|
||||
"generic_count_weeks": "{{count}} seman",
|
||||
"generic_count_weeks_plural": "{{count}} semanas",
|
||||
"generic_count_days": "{{count}} dia",
|
||||
"generic_count_days_plural": "{{count}} dias",
|
||||
"generic_count_hours": "{{count}} hora",
|
||||
"generic_count_hours_plural": "{{count}} horas",
|
||||
"generic_count_minutes": "{{count}} minuto",
|
||||
"generic_count_minutes_plural": "{{count}} minutos",
|
||||
"generic_count_seconds": "{{count}} segundo",
|
||||
"generic_count_seconds_plural": "{{count}} segundos",
|
||||
"Fallback comments: ": "Comentários alternativos: ",
|
||||
"Popular": "Popular",
|
||||
"Search": "Pesquisar",
|
||||
"Top": "Destaques",
|
||||
"About": "Acerca",
|
||||
"About": "Sobre",
|
||||
"Rating: ": "Avaliação: ",
|
||||
"preferences_locale_label": "Idioma: ",
|
||||
"View as playlist": "Ver como lista de reprodução",
|
||||
"Default": "Padrão",
|
||||
"Music": "Músicas",
|
||||
"Default": "Predefinido",
|
||||
"Music": "Música",
|
||||
"Gaming": "Jogos",
|
||||
"News": "Notícias",
|
||||
"Movies": "Filmes",
|
||||
@@ -334,9 +328,9 @@
|
||||
"Download as: ": "Descarregar como: ",
|
||||
"%A %B %-d, %Y": "%A %B %-d, %Y",
|
||||
"(edited)": "(editado)",
|
||||
"YouTube comment permalink": "Ligação permanente do comentário no YouTube",
|
||||
"permalink": "ligação permanente",
|
||||
"`x` marked it with a ❤": "`x` foi marcado com um ❤",
|
||||
"YouTube comment permalink": "Hiperligação permanente do comentário no YouTube",
|
||||
"permalink": "hiperligação permanente",
|
||||
"`x` marked it with a ❤": "`x` foi marcado como ❤",
|
||||
"Audio mode": "Modo de áudio",
|
||||
"Video mode": "Modo de vídeo",
|
||||
"channel_tab_videos_label": "Vídeos",
|
||||
@@ -344,7 +338,7 @@
|
||||
"channel_tab_community_label": "Comunidade",
|
||||
"search_filters_sort_option_relevance": "Relevância",
|
||||
"search_filters_sort_option_rating": "Avaliação",
|
||||
"search_filters_sort_option_date": "Data de carregamento",
|
||||
"search_filters_sort_option_date": "Data de envio",
|
||||
"search_filters_sort_option_views": "Visualizações",
|
||||
"search_filters_type_label": "Tipo",
|
||||
"search_filters_duration_label": "Duração",
|
||||
@@ -359,44 +353,38 @@
|
||||
"search_filters_type_option_channel": "Canal",
|
||||
"search_filters_type_option_playlist": "Lista de reprodução",
|
||||
"search_filters_type_option_movie": "Filme",
|
||||
"search_filters_type_option_show": "Séries",
|
||||
"search_filters_type_option_show": "Espetáculo",
|
||||
"search_filters_features_option_hd": "HD",
|
||||
"search_filters_features_option_subtitles": "Legendas",
|
||||
"search_filters_features_option_c_commons": "Creative Commons",
|
||||
"search_filters_features_option_three_d": "3D",
|
||||
"search_filters_features_option_live": "Direto",
|
||||
"search_filters_features_option_live": "Em direto",
|
||||
"search_filters_features_option_four_k": "4K",
|
||||
"search_filters_features_option_location": "Localização",
|
||||
"search_filters_features_option_hdr": "HDR",
|
||||
"Current version: ": "Versão atual: ",
|
||||
"next_steps_error_message": "Pode tentar as seguintes opções: ",
|
||||
"next_steps_error_message_refresh": "Recarregar",
|
||||
"next_steps_error_message_go_to_youtube": "Ir para o YouTube",
|
||||
"next_steps_error_message_refresh": "Atualizar",
|
||||
"next_steps_error_message_go_to_youtube": "Ir ao YouTube",
|
||||
"search_filters_title": "Filtro",
|
||||
"generic_videos_count_0": "{{count}} vídeo",
|
||||
"generic_videos_count_1": "{{count}} vídeos",
|
||||
"generic_videos_count_2": "{{count}} vídeos",
|
||||
"generic_playlists_count_0": "{{count}} lista de reprodução",
|
||||
"generic_playlists_count_1": "{{count}} listas de reprodução",
|
||||
"generic_playlists_count_2": "{{count}} listas de reprodução",
|
||||
"generic_subscriptions_count_0": "{{count}} subscrição",
|
||||
"generic_subscriptions_count_1": "{{count}} subscrições",
|
||||
"generic_subscriptions_count_2": "{{count}} subscrições",
|
||||
"generic_views_count_0": "{{count}} visualização",
|
||||
"generic_views_count_1": "{{count}} visualizações",
|
||||
"generic_views_count_2": "{{count}} visualizações",
|
||||
"generic_subscribers_count_0": "{{count}} subscritor",
|
||||
"generic_subscribers_count_1": "{{count}} subscritores",
|
||||
"generic_subscribers_count_2": "{{count}} subscritores",
|
||||
"generic_videos_count": "{{count}} vídeo",
|
||||
"generic_videos_count_plural": "{{count}} vídeos",
|
||||
"generic_playlists_count": "{{count}} lista de reprodução",
|
||||
"generic_playlists_count_plural": "{{count}} listas de reprodução",
|
||||
"generic_subscriptions_count": "{{count}} inscrição",
|
||||
"generic_subscriptions_count_plural": "{{count}} inscrições",
|
||||
"generic_views_count": "{{count}} visualização",
|
||||
"generic_views_count_plural": "{{count}} visualizações",
|
||||
"generic_subscribers_count": "{{count}} inscrito",
|
||||
"generic_subscribers_count_plural": "{{count}} inscritos",
|
||||
"preferences_quality_dash_option_4320p": "4320p",
|
||||
"preferences_quality_dash_label": "Qualidade de vídeo DASH preferida: ",
|
||||
"preferences_quality_dash_option_2160p": "2160p",
|
||||
"subscriptions_unseen_notifs_count_0": "{{count}} notificação não vista",
|
||||
"subscriptions_unseen_notifs_count_1": "{{count}} notificações não vistas",
|
||||
"subscriptions_unseen_notifs_count_2": "{{count}} notificações não vistas",
|
||||
"subscriptions_unseen_notifs_count": "{{count}} notificação não vista",
|
||||
"subscriptions_unseen_notifs_count_plural": "{{count}} notificações não vistas",
|
||||
"Popular enabled: ": "Página \"popular\" ativada: ",
|
||||
"search_message_no_results": "Nenhum resultado encontrado.",
|
||||
"preferences_quality_dash_option_auto": "Automática",
|
||||
"preferences_quality_dash_option_auto": "Automático",
|
||||
"preferences_region_label": "País do conteúdo: ",
|
||||
"preferences_quality_dash_option_1440p": "1440p",
|
||||
"preferences_quality_dash_option_720p": "720p",
|
||||
@@ -415,12 +403,10 @@
|
||||
"preferences_quality_dash_option_240p": "240p",
|
||||
"Video unavailable": "Vídeo não disponível",
|
||||
"Russian (auto-generated)": "Russo (gerado automaticamente)",
|
||||
"comments_view_x_replies_0": "Ver {{count}} resposta",
|
||||
"comments_view_x_replies_1": "Ver {{count}} respostas",
|
||||
"comments_view_x_replies_2": "Ver {{count}} respostas",
|
||||
"comments_points_count_0": "{{count}} ponto",
|
||||
"comments_points_count_1": "{{count}} pontos",
|
||||
"comments_points_count_2": "{{count}} pontos",
|
||||
"comments_view_x_replies": "Ver {{count}} resposta",
|
||||
"comments_view_x_replies_plural": "Ver {{count}} respostas",
|
||||
"comments_points_count": "{{count}} ponto",
|
||||
"comments_points_count_plural": "{{count}} pontos",
|
||||
"English (United Kingdom)": "Inglês (Reino Unido)",
|
||||
"Chinese (Hong Kong)": "Chinês (Hong Kong)",
|
||||
"Chinese (Taiwan)": "Chinês (Taiwan)",
|
||||
@@ -446,13 +432,13 @@
|
||||
"videoinfo_watch_on_youTube": "Ver no YouTube",
|
||||
"videoinfo_youTube_embed_link": "Incorporar",
|
||||
"adminprefs_modified_source_code_url_label": "URL do repositório do código-fonte alterado",
|
||||
"videoinfo_invidious_embed_link": "Incorporar ligação",
|
||||
"videoinfo_invidious_embed_link": "Incorporar hiperligação",
|
||||
"none": "nenhum",
|
||||
"videoinfo_started_streaming_x_ago": "Iniciou a transmissão há `x`",
|
||||
"download_subtitles": "Legendas - `x` (.vtt)",
|
||||
"user_created_playlists": "`x` listas de reprodução criadas",
|
||||
"user_saved_playlists": "`x` listas de reprodução guardadas",
|
||||
"preferences_save_player_pos_label": "Guardar posição de reprodução: ",
|
||||
"preferences_save_player_pos_label": "Guardar a posição de reprodução atual do vídeo: ",
|
||||
"Turkish (auto-generated)": "Turco (gerado automaticamente)",
|
||||
"Cantonese (Hong Kong)": "Cantonês (Hong Kong)",
|
||||
"Chinese (China)": "Chinês (China)",
|
||||
@@ -469,55 +455,21 @@
|
||||
"search_filters_date_option_none": "Qualquer data",
|
||||
"search_filters_features_option_three_sixty": "360°",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_message_use_another_instance": "Também pode <a href=\"`x`\">pesquisar noutra instância</a>.",
|
||||
"search_message_use_another_instance": " Também pode <a href=\"`x`\">pesquisar noutra instância</a>.",
|
||||
"crash_page_you_found_a_bug": "Parece que encontrou um erro no Invidious!",
|
||||
"crash_page_before_reporting": "Antes de reportar um erro, verifique se:",
|
||||
"crash_page_read_the_faq": "leu as <a href=\"`x`\">Perguntas frequentes (FAQ)</a>",
|
||||
"crash_page_read_the_faq": "leia as <a href=\"`x`\">Perguntas frequentes (FAQ)</a>",
|
||||
"crash_page_search_issue": "procurou se <a href=\"`x`\">o erro já foi reportado no GitHub</a>",
|
||||
"crash_page_report_issue": "Se nenhuma opção acima ajudou, por favor <a href=\"`x`\">abra um novo problema no Github</a> (preferencialmente em inglês) e inclua o seguinte texto (NÃO o traduza):",
|
||||
"crash_page_report_issue": "Se nenhuma opção acima ajudou, por favor <a href=\"`x`\">abra um novo problema no Github</a> (preferencialmente em inglês) e inclua o seguinte texto tal qual (NÃO o traduza):",
|
||||
"search_message_change_filters_or_query": "Tente alargar os termos genéricos da pesquisa e/ou alterar os filtros.",
|
||||
"crash_page_refresh": "tentou <a href=\"`x`\">recarregar a página</a>",
|
||||
"crash_page_switch_instance": "tentou <a href=\"`x`\">usar outra instância</a>",
|
||||
"error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. <a href=\"`x`\">Clique aqui para voltar à página inicial da lista de reprodução.</a>",
|
||||
"error_video_not_in_playlist": "O vídeo pedido não existe nesta lista de reprodução. <a href=\"`x`\">Clique aqui para a página inicial da lista de reprodução.</a>",
|
||||
"Artist: ": "Artista: ",
|
||||
"Album: ": "Álbum: ",
|
||||
"channel_tab_streams_label": "Emissões em direto",
|
||||
"channel_tab_streams_label": "Diretos",
|
||||
"channel_tab_playlists_label": "Listas de reprodução",
|
||||
"channel_tab_channels_label": "Canais",
|
||||
"Music in this video": "Música neste vídeo",
|
||||
"channel_tab_shorts_label": "Curtos",
|
||||
"generic_button_delete": "Eliminar",
|
||||
"generic_button_edit": "Editar",
|
||||
"generic_button_save": "Guardar",
|
||||
"generic_button_cancel": "Cancelar",
|
||||
"Import YouTube playlist (.csv)": "Importar lista de reprodução do YouTube (.csv)",
|
||||
"Song: ": "Canção: ",
|
||||
"Answer": "Responder",
|
||||
"The Popular feed has been disabled by the administrator.": "O feed Popular foi desativado por um administrador.",
|
||||
"Channel Sponsor": "Patrocinador do canal",
|
||||
"Download is disabled": "A descarga está desativada",
|
||||
"Add to playlist": "Adicionar à lista de reprodução",
|
||||
"Add to playlist: ": "Adicionar à lista de reprodução: ",
|
||||
"Search for videos": "Procurar vídeos",
|
||||
"generic_channels_count_0": "{{count}} canal",
|
||||
"generic_channels_count_1": "{{count}} canais",
|
||||
"generic_channels_count_2": "{{count}} canais",
|
||||
"generic_button_rss": "RSS",
|
||||
"Import YouTube watch history (.json)": "Importar histórico de reprodução do YouTube (.json)",
|
||||
"preferences_preload_label": "Pré-carregamento dos dados: ",
|
||||
"playlist_button_add_items": "Adicionar vídeos",
|
||||
"channel_tab_podcasts_label": "Podcasts",
|
||||
"channel_tab_releases_label": "Lançamentos",
|
||||
"carousel_slide": "Diapositivo {{current}} de{{total}}",
|
||||
"carousel_skip": "Ignorar carrossel",
|
||||
"carousel_go_to": "Ir para o diapositivo`x`",
|
||||
"First page": "Primeira página",
|
||||
"Standard YouTube license": "Licença padrão do YouTube",
|
||||
"Filipino (auto-generated)": "Filipino (gerado automaticamente)",
|
||||
"channel_tab_courses_label": "Cursos",
|
||||
"channel_tab_posts_label": "Publicações",
|
||||
"toggle_theme": "Trocar tema",
|
||||
"timeline_parse_error_placeholder_heading": "Incapaz de processar o elemento",
|
||||
"timeline_parse_error_placeholder_message": "O Invidious encontrou um problema ao processar este elemento. Para mais informações, veja abaixo:",
|
||||
"timeline_parse_error_show_technical_details": "Mostrar detalhes técnicos"
|
||||
"channel_tab_shorts_label": "Curtos"
|
||||
}
|
||||
|
||||
@@ -236,6 +236,8 @@
|
||||
"Preferences": "Preferências",
|
||||
"E-mail": "E-mail",
|
||||
"Register": "Registar",
|
||||
"Image CAPTCHA": "Imagem CAPTCHA",
|
||||
"Text CAPTCHA": "Texto CAPTCHA",
|
||||
"Time (h:mm:ss):": "Tempo (h:mm:ss):",
|
||||
"Password": "Palavra-passe",
|
||||
"User ID": "Utilizador",
|
||||
@@ -513,8 +515,5 @@
|
||||
"carousel_go_to": "Ir para o diapositivo`x`",
|
||||
"The Popular feed has been disabled by the administrator.": "O feed Popular foi desativado por um administrador.",
|
||||
"preferences_preload_label": "Pré-carregamento dos dados: ",
|
||||
"Filipino (auto-generated)": "Filipino (gerado automaticamente)",
|
||||
"First page": "Primeira página",
|
||||
"channel_tab_courses_label": "Cursos",
|
||||
"channel_tab_posts_label": "Publicações"
|
||||
"Filipino (auto-generated)": "Filipino (gerado automaticamente)"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ID Utilizator",
|
||||
"Password": "Parolă",
|
||||
"Time (h:mm:ss):": "Ora (h:mm:ss) :",
|
||||
"Text CAPTCHA": "Text CAPTCHA",
|
||||
"Image CAPTCHA": "Imagine CAPTCHA",
|
||||
"Sign In": "Conectați-vă",
|
||||
"Register": "Înregistrați-vă",
|
||||
"E-mail": "E-mail",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"Import and Export Data": "Импорт и экспорт данных",
|
||||
"Import": "Импорт",
|
||||
"Import Invidious data": "Импортировать JSON с данными Invidious",
|
||||
"Import YouTube subscriptions": "Импортировать подписки из YouTube через файлы CSV или OPML",
|
||||
"Import YouTube subscriptions": "Импортировать подписки из CSV или OPML",
|
||||
"Import FreeTube subscriptions (.db)": "Импортировать подписки из FreeTube (.db)",
|
||||
"Import NewPipe subscriptions (.json)": "Импортировать подписки из NewPipe (.json)",
|
||||
"Import NewPipe data (.zip)": "Импортировать данные из NewPipe (.zip)",
|
||||
@@ -40,6 +40,8 @@
|
||||
"User ID": "ИД пользователя",
|
||||
"Password": "Пароль",
|
||||
"Time (h:mm:ss):": "Время (ч:мм:сс):",
|
||||
"Text CAPTCHA": "Текстовая капча (англ.)",
|
||||
"Image CAPTCHA": "Капча-картинка",
|
||||
"Sign In": "Войти",
|
||||
"Register": "Регистрация",
|
||||
"E-mail": "Эл. почта",
|
||||
@@ -473,7 +475,7 @@
|
||||
"search_filters_date_option_none": "Любая дата",
|
||||
"search_filters_date_label": "Дата загрузки",
|
||||
"search_message_no_results": "Ничего не найдено.",
|
||||
"search_message_use_another_instance": "Дополнительно вы можете <a href=\"`x`\">поискать на других зеркалах</a>.",
|
||||
"search_message_use_another_instance": " Дополнительно вы можете <a href=\"`x`\">поискать на других зеркалах</a>.",
|
||||
"search_filters_features_option_vr180": "VR180",
|
||||
"search_message_change_filters_or_query": "Попробуйте расширить поисковый запрос и/или изменить фильтры.",
|
||||
"search_filters_duration_option_medium": "Средние (4 - 20 минут)",
|
||||
@@ -509,17 +511,9 @@
|
||||
"Answer": "Ответить",
|
||||
"Search for videos": "Поиск видео",
|
||||
"The Popular feed has been disabled by the administrator.": "Лента популярного была отключена администратором.",
|
||||
"toggle_theme": "Переключить тему оформления",
|
||||
"carousel_slide": "Слайд {{current}} из {{total}}",
|
||||
"toggle_theme": "Переключатель тем",
|
||||
"carousel_slide": "Пролистано {{current}} из {{total}}",
|
||||
"carousel_skip": "Пропустить всё",
|
||||
"carousel_go_to": "Перейти на слайд `x`",
|
||||
"preferences_preload_label": "Предзагрузка видеоданных: ",
|
||||
"channel_tab_courses_label": "Курсы",
|
||||
"channel_tab_posts_label": "Записи",
|
||||
"timeline_parse_error_placeholder_message": "Invidious столкнулся с ошибкой, пытаясь разобрать с этот элемент. Подробнее смотрите ниже:",
|
||||
"timeline_parse_error_placeholder_heading": "Невозможно разобрать элемент",
|
||||
"timeline_parse_error_show_technical_details": "Показать технические подробности",
|
||||
"Filipino (auto-generated)": "Филиппинский (автоматически сгенерировано)",
|
||||
"preferences_default_playlist": "Плейлист по умолчанию: ",
|
||||
"preferences_default_playlist_none": "Плейлист по умолчанию не указан"
|
||||
"carousel_go_to": "Перейти к странице `x`",
|
||||
"preferences_preload_label": "Предзагрузка видеоданных: "
|
||||
}
|
||||
|
||||
@@ -82,6 +82,8 @@
|
||||
"Export subscriptions as OPML": "දායකත්වයන් OPML ලෙස අපනයනය කරන්න",
|
||||
"JavaScript license information": "JavaScript බලපත්ර තොරතුරු",
|
||||
"User ID": "පරිශීලක කේතය",
|
||||
"Text CAPTCHA": "CAPTCHA පෙල",
|
||||
"Image CAPTCHA": "CAPTCHA රූපය",
|
||||
"E-mail": "විද්යුත් තැපෑල",
|
||||
"preferences_quality_label": "කැමති වීඩියෝ ගුණත්වය: ",
|
||||
"preferences_quality_option_hd720": "HD720",
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
"User ID": "ID používateľa",
|
||||
"Password": "Heslo",
|
||||
"Time (h:mm:ss):": "Čas (h:mm:ss):",
|
||||
"Text CAPTCHA": "Textové CAPTCHA",
|
||||
"Image CAPTCHA": "Obrázkové CAPTCHA",
|
||||
"Sign In": "Prihlásiť sa",
|
||||
"Register": "Registrovať",
|
||||
"E-mail": "E-mail",
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
"User ID": "ID uporabnika",
|
||||
"Password": "Geslo",
|
||||
"Time (h:mm:ss):": "Čas (h:mm:ss):",
|
||||
"Text CAPTCHA": "Besedilo CAPTCHA",
|
||||
"source": "izvorna koda",
|
||||
"Image CAPTCHA": "Slika CAPTCHA",
|
||||
"Sign In": "Prijavi se",
|
||||
"Register": "Registriraj se",
|
||||
"E-mail": "E-pošta",
|
||||
@@ -530,11 +532,5 @@
|
||||
"carousel_slide": "Diapozitiv {{current}} od {{total}}",
|
||||
"carousel_skip": "Preskoči galerijo",
|
||||
"carousel_go_to": "Pojdi na diapozitiv `x`",
|
||||
"preferences_preload_label": "Predhodno naloži video podatke: ",
|
||||
"First page": "Prva stran",
|
||||
"channel_tab_courses_label": "Tečaji",
|
||||
"channel_tab_posts_label": "Objave",
|
||||
"timeline_parse_error_placeholder_heading": "Elementa ni mogoče razčleniti",
|
||||
"timeline_parse_error_placeholder_message": "Invidious je naletel na napako pri poskusu razčlenitve tega elementa. Za več informacij glej spodaj:",
|
||||
"timeline_parse_error_show_technical_details": "Pokaži tehnične podrobnosti"
|
||||
"preferences_preload_label": "Predhodno naloži video podatke: "
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
"User ID": "ID Përdoruesi",
|
||||
"Password": "Fjalëkalim",
|
||||
"Time (h:mm:ss):": "Kohë (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA Tekst",
|
||||
"Image CAPTCHA": "CAPTCHA Figurë",
|
||||
"Sign In": "Hyni",
|
||||
"Register": "Regjistrohuni",
|
||||
"E-mail": "Email",
|
||||
@@ -492,9 +494,5 @@
|
||||
"carousel_slide": "Diapozitiv {{current}} nga {{total}}",
|
||||
"carousel_go_to": "Kalo te diapozitivi `x`",
|
||||
"Filipino (auto-generated)": "Filipineze (të prodhuara automatikisht)",
|
||||
"preferences_preload_label": "Parangarko të dhëna videoje: ",
|
||||
"toggle_theme": "Ndërroni Temë",
|
||||
"channel_tab_courses_label": "Kurse",
|
||||
"channel_tab_posts_label": "Postime",
|
||||
"First page": "Faqja e parë"
|
||||
"preferences_preload_label": "Parangarko të dhëna videoje: "
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ID korisnika",
|
||||
"Password": "Lozinka",
|
||||
"Time (h:mm:ss):": "Vreme (č:mm:ss):",
|
||||
"Text CAPTCHA": "Tekst CAPTCHA",
|
||||
"Image CAPTCHA": "Slika CAPTCHA",
|
||||
"Sign In": "Prijava",
|
||||
"Register": "Registracija",
|
||||
"E-mail": "Imejl",
|
||||
@@ -511,13 +513,7 @@
|
||||
"Answer": "Odgovor",
|
||||
"Search for videos": "Pretražite video snimke",
|
||||
"carousel_skip": "Preskoči karusel",
|
||||
"toggle_theme": "Podesi temu",
|
||||
"toggle_theme": "Подеси тему",
|
||||
"preferences_preload_label": "Unapred učitaj podatke o video snimku: ",
|
||||
"Filipino (auto-generated)": "Filipinski (automatski generisano)",
|
||||
"channel_tab_posts_label": "Objave",
|
||||
"First page": "Prva stranica",
|
||||
"channel_tab_courses_label": "Kursevi",
|
||||
"timeline_parse_error_placeholder_heading": "Nije moguće raščlaniti predmet",
|
||||
"timeline_parse_error_show_technical_details": "Prikaži tehničke detalje",
|
||||
"timeline_parse_error_placeholder_message": "Invidious je naišao na grešku prilikom pokušaja raščlanjivanja ovog predmeta. Za više informacija pogledajte ispod:"
|
||||
"Filipino (auto-generated)": "Filipinski (automatski generisano)"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ID корисника",
|
||||
"Password": "Лозинка",
|
||||
"Time (h:mm:ss):": "Време (ч:мм:сс):",
|
||||
"Text CAPTCHA": "Текст CAPTCHA",
|
||||
"Image CAPTCHA": "Слика CAPTCHA",
|
||||
"Sign In": "Пријава",
|
||||
"Register": "Регистрација",
|
||||
"E-mail": "Имејл",
|
||||
@@ -513,11 +515,5 @@
|
||||
"The Popular feed has been disabled by the administrator.": "Администратор је онемогућио фид „Популарно“.",
|
||||
"carousel_slide": "Слајд {{current}} од {{total}}",
|
||||
"preferences_preload_label": "Унапред учитај податке о видео снимку: ",
|
||||
"Filipino (auto-generated)": "Филипински (аутоматски генерисано)",
|
||||
"channel_tab_courses_label": "Курсеви",
|
||||
"First page": "Прва страница",
|
||||
"channel_tab_posts_label": "Објаве",
|
||||
"timeline_parse_error_show_technical_details": "Прикажи техничке детаље",
|
||||
"timeline_parse_error_placeholder_heading": "Није могуће рашчланити предмет",
|
||||
"timeline_parse_error_placeholder_message": "Invidious је наишао на грешку приликом покушаја рашчлањивања овог предмета. За више информација погледајте испод:"
|
||||
"Filipino (auto-generated)": "Филипински (аутоматски генерисано)"
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Användar-ID",
|
||||
"Password": "Lösenord",
|
||||
"Time (h:mm:ss):": "Tid (h:mm:ss):",
|
||||
"Text CAPTCHA": "Text-CAPTCHA",
|
||||
"Image CAPTCHA": "Bild-CAPTCHA",
|
||||
"Sign In": "Inloggning",
|
||||
"Register": "Registrera",
|
||||
"E-mail": "E-post",
|
||||
@@ -496,8 +498,5 @@
|
||||
"carousel_skip": "Hoppa över karusellen",
|
||||
"carousel_go_to": "Gå till bildspel `x`",
|
||||
"preferences_preload_label": "Förladda video data: ",
|
||||
"Filipino (auto-generated)": "Filippinska (auto-genererad)",
|
||||
"First page": "Första sidan",
|
||||
"channel_tab_courses_label": "Kurser",
|
||||
"channel_tab_posts_label": "Inlägg"
|
||||
"Filipino (auto-generated)": "Filippinska (auto-genererad)"
|
||||
}
|
||||
|
||||
@@ -282,6 +282,8 @@
|
||||
"Import": "இறக்குமதி",
|
||||
"Import NewPipe subscriptions (.json)": "நியூபிப்பிப் சந்தாக்களை இறக்குமதி செய்யுங்கள் (.json)",
|
||||
"Export": "ஏற்றுமதி",
|
||||
"Text CAPTCHA": "உரை கேப்ட்சா",
|
||||
"Image CAPTCHA": "பட கேப்ட்சா",
|
||||
"preferences_category_player": "பிளேயர் விருப்பத்தேர்வுகள்",
|
||||
"preferences_video_loop_label": "எப்போதும் லூப்: ",
|
||||
"preferences_continue_autoplay_label": "தன்னியக்க அடுத்த வீடியோ: ",
|
||||
@@ -496,11 +498,5 @@
|
||||
"channel_tab_channels_label": "சேனல்கள்",
|
||||
"toggle_theme": "கருப்பொருளை மாற்றவும்",
|
||||
"carousel_slide": "{{total}} இன் ச்லைடு {{current}}",
|
||||
"carousel_skip": "கொணர்வி தவிர்க்கவும்",
|
||||
"First page": "முதல் பக்கம்",
|
||||
"channel_tab_courses_label": "படிப்புகள்",
|
||||
"channel_tab_posts_label": "இடுகைகள்",
|
||||
"timeline_parse_error_placeholder_heading": "உருப்படியை அலச முடியவில்லை",
|
||||
"timeline_parse_error_placeholder_message": "இந்த உருப்படியை அலச முயற்சிக்கும் போது ஒரு பிழையை அடக்கமடைந்தது. மேலும் தகவலுக்கு கீழே காண்க:",
|
||||
"timeline_parse_error_show_technical_details": "தொழில்நுட்ப விவரங்களைக் காட்டு"
|
||||
"carousel_skip": "கொணர்வி தவிர்க்கவும்"
|
||||
}
|
||||
|
||||
@@ -1,26 +1,7 @@
|
||||
{
|
||||
"Add to playlist": "Pleýer Sanawa goş",
|
||||
"Add to playlist": "Aýdym sanawyna goş",
|
||||
"Add to playlist: ": "Pleýliste goş: ",
|
||||
"Answer": "Jogap",
|
||||
"Search for videos": "Wideo gözläň",
|
||||
"The Popular feed has been disabled by the administrator.": "Trende bolan administrator tarapyndan ýapyldy.",
|
||||
"generic_views_count": "{{count}} gezek görülen",
|
||||
"generic_views_count_plural": "{{count}} görülen",
|
||||
"generic_button_delete": "Öçür",
|
||||
"generic_button_save": "Ýatda sakla",
|
||||
"generic_button_cancel": "Goýbolsun",
|
||||
"generic_button_rss": "RSS",
|
||||
"LIVE": "Efif",
|
||||
"generic_playlists_count": "{{count}} Oýnaw sanawy",
|
||||
"generic_playlists_count_plural": "{{count}} Oýnaw sanawlary",
|
||||
"generic_subscribers_count": "{{count}} abuna",
|
||||
"generic_subscribers_count_plural": "{{count}} abunaçalar",
|
||||
"generic_subscriptions_count": "{{count}} abuna",
|
||||
"generic_subscriptions_count_plural": "{{count}} abunalar",
|
||||
"generic_button_edit": "Üýtget",
|
||||
"generic_videos_count": "{{count}} widýo",
|
||||
"generic_videos_count_plural": "{{count}} widýolar",
|
||||
"Shared `x` ago": "`x` öň paýlaşyldy",
|
||||
"generic_channels_count": "{{count}} kanal",
|
||||
"generic_channels_count_plural": "{{count}} kanallar"
|
||||
"The Popular feed has been disabled by the administrator.": "Trende bolan administrator tarapyndan ýapyldy."
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "Kullanıcı Kimliği",
|
||||
"Password": "Parola",
|
||||
"Time (h:mm:ss):": "Zaman (h:mm:ss):",
|
||||
"Text CAPTCHA": "Metin CAPTCHA",
|
||||
"Image CAPTCHA": "Resim CAPTCHA",
|
||||
"Sign In": "Oturum Aç",
|
||||
"Register": "Kayıt Ol",
|
||||
"E-mail": "E-Posta",
|
||||
@@ -495,12 +497,5 @@
|
||||
"carousel_skip": "Kayar menüyü atla",
|
||||
"carousel_go_to": "`x` sunumuna git",
|
||||
"The Popular feed has been disabled by the administrator.": "Popüler akışı yönetici tarafından devre dışı bırakıldı.",
|
||||
"preferences_preload_label": "Video verilerini önceden yükle: ",
|
||||
"First page": "İlk sayfa",
|
||||
"Filipino (auto-generated)": "Filipince (oto-oluşturuldu)",
|
||||
"channel_tab_courses_label": "Kurslar",
|
||||
"channel_tab_posts_label": "Yazılar",
|
||||
"timeline_parse_error_placeholder_heading": "Öge ayrıştıramıyor",
|
||||
"timeline_parse_error_placeholder_message": "Invidious, bu ögeyi ayrıştırmaya çalışırken bir hatayla karşılaştı. Daha fazla bilgi için aşağıya bakın:",
|
||||
"timeline_parse_error_show_technical_details": "Teknik ayrıntıları göster"
|
||||
"preferences_preload_label": "Video verilerini önceden yükle: "
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
"User ID": "ID користувача",
|
||||
"Password": "Пароль",
|
||||
"Time (h:mm:ss):": "Час (г:хх:сс):",
|
||||
"Text CAPTCHA": "Текст CAPTCHA",
|
||||
"Image CAPTCHA": "Зображення CAPTCHA",
|
||||
"Sign In": "Увійти",
|
||||
"Register": "Зареєструватися",
|
||||
"E-mail": "Електронна пошта",
|
||||
@@ -513,11 +515,5 @@
|
||||
"carousel_skip": "Пропустити карусель",
|
||||
"carousel_go_to": "Перейти до слайда `x`",
|
||||
"preferences_preload_label": "Попереднє завантаження відеоданих: ",
|
||||
"Filipino (auto-generated)": "Філіппінська (згенеровано автоматично)",
|
||||
"First page": "Перша сторінка",
|
||||
"channel_tab_courses_label": "Курси",
|
||||
"channel_tab_posts_label": "Дописи",
|
||||
"timeline_parse_error_placeholder_heading": "Неможливо розібрати елемент",
|
||||
"timeline_parse_error_show_technical_details": "Показати технічні подробиці",
|
||||
"timeline_parse_error_placeholder_message": "Invidious зіткнувся з помилкою під час спроби розібрати цей елемент. Докладнішу інформацію читайте нижче:"
|
||||
"Filipino (auto-generated)": "Філіппінська (згенеровано автоматично)"
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
"User ID": "Mã nhận dạng người dùng",
|
||||
"Password": "Mật khẩu",
|
||||
"Time (h:mm:ss):": "Thời gian (h:mm:ss):",
|
||||
"Text CAPTCHA": "CAPTCHA dạng chữ",
|
||||
"Image CAPTCHA": "CAPTCHA dạng ảnh",
|
||||
"Sign In": "Đăng nhập",
|
||||
"Register": "Đăng ký",
|
||||
"E-mail": "E-mail",
|
||||
@@ -312,11 +314,11 @@
|
||||
"search_filters_duration_label": "Thời lượng",
|
||||
"search_filters_features_label": "Đặc điểm",
|
||||
"search_filters_sort_label": "Sắp xếp theo",
|
||||
"search_filters_date_option_hour": "Một giờ trước",
|
||||
"search_filters_date_option_hour": "Một giờ qua",
|
||||
"search_filters_date_option_today": "Hôm nay",
|
||||
"search_filters_date_option_week": "Tuần này",
|
||||
"search_filters_date_option_month": "Tháng này",
|
||||
"search_filters_date_option_year": "Năm nay",
|
||||
"search_filters_date_option_year": "Năm này",
|
||||
"search_filters_type_option_video": "video",
|
||||
"search_filters_type_option_channel": "Kênh",
|
||||
"search_filters_type_option_playlist": "Danh sách phát",
|
||||
@@ -477,8 +479,5 @@
|
||||
"carousel_skip": "Bỏ qua Carousel",
|
||||
"carousel_go_to": "Đi tới trang `x`",
|
||||
"Search for videos": "Tìm kiếm video",
|
||||
"The Popular feed has been disabled by the administrator.": "Bảng tin phổ biến đã bị tắt bởi ban quản lý.",
|
||||
"preferences_preload_label": "Tải trước dữ liệu video: ",
|
||||
"Filipino (auto-generated)": "Tiếng Philippines (tự động tạo)",
|
||||
"First page": "Trang đầu"
|
||||
"The Popular feed has been disabled by the administrator.": "Bảng tin phổ biến đã bị tắt bởi ban quản lý."
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"User ID": "用户 ID",
|
||||
"Password": "密码",
|
||||
"Time (h:mm:ss):": "时间 (h:mm:ss):",
|
||||
"Text CAPTCHA": "文本验证码",
|
||||
"Image CAPTCHA": "图片验证码",
|
||||
"Sign In": "登录",
|
||||
"Register": "注册",
|
||||
"E-mail": "E-mail",
|
||||
@@ -418,7 +420,7 @@
|
||||
"Chinese": "中文",
|
||||
"Chinese (China)": "中文 (中国)",
|
||||
"Chinese (Hong Kong)": "中文 (中国香港)",
|
||||
"Chinese (Taiwan)": "中文 (台湾)",
|
||||
"Chinese (Taiwan)": "中文 (中国台湾)",
|
||||
"German (auto-generated)": "德语 (自动生成)",
|
||||
"Indonesian (auto-generated)": "印尼语 (自动生成)",
|
||||
"Interlingue": "国际语",
|
||||
@@ -479,13 +481,5 @@
|
||||
"carousel_skip": "跳过图集",
|
||||
"carousel_go_to": "转到图 `x`",
|
||||
"preferences_preload_label": "预加载视频数据: ",
|
||||
"Filipino (auto-generated)": "菲律宾语 (自动生成)",
|
||||
"channel_tab_posts_label": "帖子",
|
||||
"First page": "第一页",
|
||||
"channel_tab_courses_label": "课程",
|
||||
"timeline_parse_error_show_technical_details": "显示技术细节",
|
||||
"timeline_parse_error_placeholder_heading": "无法解析项目",
|
||||
"timeline_parse_error_placeholder_message": "Invidious 在尝试解析此项目时遇到一个错误。更多信息请见下方:",
|
||||
"preferences_default_playlist": "默认播放列表: ",
|
||||
"preferences_default_playlist_none": "尚无默认播放列表"
|
||||
"Filipino (auto-generated)": "菲律宾语 (自动生成)"
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
"User ID": "使用者 ID",
|
||||
"Password": "密碼",
|
||||
"Time (h:mm:ss):": "時間 (h:mm:ss):",
|
||||
"Text CAPTCHA": "文字 CAPTCHA",
|
||||
"Image CAPTCHA": "圖片 CAPTCHA",
|
||||
"Sign In": "登入",
|
||||
"Register": "註冊",
|
||||
"E-mail": "電子郵件",
|
||||
@@ -479,13 +481,5 @@
|
||||
"carousel_go_to": "跳到投影片 `x`",
|
||||
"The Popular feed has been disabled by the administrator.": "熱門 feed 已被管理員停用。",
|
||||
"preferences_preload_label": "預先載入影片資訊 ",
|
||||
"Filipino (auto-generated)": "菲律賓語(自動產生)",
|
||||
"channel_tab_courses_label": "課程",
|
||||
"First page": "第一頁",
|
||||
"channel_tab_posts_label": "貼文",
|
||||
"timeline_parse_error_show_technical_details": "顯示技術細節",
|
||||
"timeline_parse_error_placeholder_heading": "無法解析項目",
|
||||
"timeline_parse_error_placeholder_message": "Invidious 在嘗試解析此項目時遇到錯誤。要取得更多資訊,請見下方:",
|
||||
"preferences_default_playlist": "預設播放清單: ",
|
||||
"preferences_default_playlist_none": "未設定預設播放清單"
|
||||
"Filipino (auto-generated)": "菲律賓語(自動產生)"
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# This file automatically generates Crystal strings of rows within an HTML Javascript licenses table
|
||||
#
|
||||
# These strings will then be placed within a `<%= %>` statement in licenses.ecr at compile time which
|
||||
# will be interpolated at run-time. This interpolation is only for the translation of the "source" string
|
||||
# so maybe we can just switch to a non-translated string to simplify the logic here.
|
||||
#
|
||||
# The Javascript Web Labels table defined at https://www.gnu.org/software/librejs/free-your-javascript.html#step3
|
||||
# for example just reiterates the name of the source file rather than use a "source" string.
|
||||
all_javascript_files = Dir.glob("assets/**/*.js")
|
||||
|
||||
videojs_js = [] of String
|
||||
invidious_js = [] of String
|
||||
|
||||
all_javascript_files.each do |js_path|
|
||||
if js_path.starts_with?("assets/videojs/")
|
||||
videojs_js << js_path[7..]
|
||||
else
|
||||
invidious_js << js_path[7..]
|
||||
end
|
||||
end
|
||||
|
||||
def create_licence_tr(path, file_name, licence_name, licence_link, source_location)
|
||||
tr = <<-HTML
|
||||
"<tr>
|
||||
<td><a href=\\"/#{path}\\">#{file_name}</a></td>
|
||||
<td><a href=\\"#{licence_link}\\">#{licence_name}</a></td>
|
||||
<td><a href=\\"#{source_location}\\">\#{translate(locale, "source")}</a></td>
|
||||
</tr>"
|
||||
HTML
|
||||
|
||||
# New lines are removed as to allow for using String.join and StringLiteral.split
|
||||
# to get a clean list of each table row.
|
||||
tr.gsub('\n', "")
|
||||
end
|
||||
|
||||
# TODO Use videojs-dependencies.yml to generate license info for videojs javascript
|
||||
jslicence_table_rows = [] of String
|
||||
|
||||
invidious_js.each do |path|
|
||||
file_name = path.split('/')[-1]
|
||||
|
||||
# A couple non Invidious JS files are also shipped alongside Invidious due to various reasons
|
||||
next if {
|
||||
"sse.js", "silvermine-videojs-quality-selector.min.js", "videojs-youtube-annotations.min.js",
|
||||
}.includes?(file_name)
|
||||
|
||||
jslicence_table_rows << create_licence_tr(
|
||||
path: path,
|
||||
file_name: file_name,
|
||||
licence_name: "AGPL-3.0",
|
||||
licence_link: "https://www.gnu.org/licenses/agpl-3.0.html",
|
||||
source_location: path
|
||||
)
|
||||
end
|
||||
|
||||
puts jslicence_table_rows.join("\n")
|
||||
@@ -18,7 +18,7 @@ shards:
|
||||
|
||||
exception_page:
|
||||
git: https://github.com/crystal-loot/exception_page.git
|
||||
version: 0.4.1
|
||||
version: 0.2.2
|
||||
|
||||
http_proxy:
|
||||
git: https://github.com/mamantoha/http_proxy.git
|
||||
@@ -26,7 +26,11 @@ shards:
|
||||
|
||||
kemal:
|
||||
git: https://github.com/kemalcr/kemal.git
|
||||
version: 1.6.0
|
||||
version: 1.1.2
|
||||
|
||||
kilt:
|
||||
git: https://github.com/jeromegn/kilt.git
|
||||
version: 0.6.1
|
||||
|
||||
pg:
|
||||
git: https://github.com/will/crystal-pg.git
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: invidious
|
||||
version: 2.20250913.0
|
||||
version: 2.20250314.0-dev
|
||||
|
||||
authors:
|
||||
- Invidious team <contact@invidious.io>
|
||||
@@ -17,7 +17,10 @@ dependencies:
|
||||
version: ~> 0.21.0
|
||||
kemal:
|
||||
github: kemalcr/kemal
|
||||
version: ~> 1.6.0
|
||||
version: ~> 1.1.2
|
||||
kilt:
|
||||
github: jeromegn/kilt
|
||||
version: ~> 0.6.1
|
||||
protodec:
|
||||
github: iv-org/protodec
|
||||
version: ~> 0.1.5
|
||||
|
||||
112
spec/helpers/networking/connection_pool_spec.cr
Normal file
112
spec/helpers/networking/connection_pool_spec.cr
Normal file
@@ -0,0 +1,112 @@
|
||||
# Due to the way that specs are handled this file cannot be run
|
||||
# together with everything else without causing a compile time error
|
||||
#
|
||||
# TODO: Allow running different isolated spec through make
|
||||
#
|
||||
# For now run this with `crystal spec -p spec/helpers/networking/connection_pool_spec.cr -Drunning_by_self`
|
||||
{% skip_file unless flag?(:running_by_self) %}
|
||||
|
||||
# Based on https://github.com/jgaskins/http_client/blob/958cf56064c0d31264a117467022b90397eb65d7/spec/http_client_spec.cr
|
||||
require "wait_group"
|
||||
require "uri"
|
||||
require "http"
|
||||
require "http/server"
|
||||
require "http_proxy"
|
||||
|
||||
require "db"
|
||||
require "pg"
|
||||
require "spectator"
|
||||
|
||||
require "../../load_config_helper"
|
||||
require "../../../src/invidious/helpers/crystal_class_overrides"
|
||||
require "../../../src/invidious/connection/*"
|
||||
|
||||
TEST_SERVER_URL = URI.parse("http://localhost:12345")
|
||||
|
||||
server = HTTP::Server.new do |context|
|
||||
request = context.request
|
||||
response = context.response
|
||||
|
||||
case {request.method, request.path}
|
||||
when {"GET", "/get"}
|
||||
response << "get"
|
||||
when {"POST", "/post"}
|
||||
response.status = :created
|
||||
response << "post"
|
||||
when {"GET", "/sleep"}
|
||||
duration = request.query_params["duration_sec"].to_i.seconds
|
||||
sleep duration
|
||||
end
|
||||
end
|
||||
|
||||
spawn server.listen 12345
|
||||
|
||||
Fiber.yield
|
||||
|
||||
Spectator.describe Invidious::ConnectionPool do
|
||||
describe "Pool" do
|
||||
it "Can make a requests through standard HTTP methods" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
|
||||
|
||||
expect(pool.get("/get").body).to eq("get")
|
||||
expect(pool.post("/post").body).to eq("post")
|
||||
end
|
||||
|
||||
it "Can make streaming requests" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
|
||||
|
||||
expect(pool.get("/get", &.body_io.gets_to_end)).to eq("get")
|
||||
expect(pool.get("/post", &.body)).to eq("")
|
||||
expect(pool.post("/post", &.body_io.gets_to_end)).to eq("post")
|
||||
end
|
||||
|
||||
it "Allows more than one clients to be checked out (if applicable)" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
|
||||
|
||||
pool.checkout do |_|
|
||||
expect(pool.post("/post").body).to eq("post")
|
||||
end
|
||||
end
|
||||
|
||||
it "Can make multiple requests with the same client" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
|
||||
|
||||
pool.checkout do |client|
|
||||
expect(client.get("/get").body).to eq("get")
|
||||
expect(client.post("/post").body).to eq("post")
|
||||
expect(client.get("/get").body).to eq("get")
|
||||
end
|
||||
end
|
||||
|
||||
it "Allows concurrent requests" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
|
||||
responses = [] of HTTP::Client::Response
|
||||
|
||||
WaitGroup.wait do |wg|
|
||||
100.times do
|
||||
wg.spawn { responses << pool.get("/get") }
|
||||
end
|
||||
end
|
||||
|
||||
expect(responses.map(&.body)).to eq(["get"] * 100)
|
||||
end
|
||||
|
||||
it "Raises on checkout timeout" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 2, timeout: 0.01) { next make_client(TEST_SERVER_URL) }
|
||||
|
||||
# Long running requests
|
||||
2.times do
|
||||
spawn { pool.get("/sleep?duration_sec=2") }
|
||||
end
|
||||
|
||||
Fiber.yield
|
||||
|
||||
expect { pool.get("/get") }.to raise_error(Invidious::ConnectionPool::Error)
|
||||
end
|
||||
|
||||
it "Raises when an error is encountered" do
|
||||
pool = Invidious::ConnectionPool::Pool.new(max_capacity: 100) { next make_client(TEST_SERVER_URL) }
|
||||
expect { pool.get("/get") { raise IO::Error.new } }.to raise_error(Invidious::ConnectionPool::Error)
|
||||
end
|
||||
end
|
||||
end
|
||||
15
spec/load_config_helper.cr
Normal file
15
spec/load_config_helper.cr
Normal file
@@ -0,0 +1,15 @@
|
||||
require "yaml"
|
||||
require "log"
|
||||
|
||||
abstract class Kemal::BaseLogHandler
|
||||
end
|
||||
|
||||
require "../src/invidious/config"
|
||||
require "../src/invidious/jobs/base_job"
|
||||
require "../src/invidious/jobs.cr"
|
||||
require "../src/invidious/user/preferences.cr"
|
||||
require "../src/invidious/helpers/logger"
|
||||
require "../src/invidious/helpers/utils"
|
||||
|
||||
CONFIG = Config.from_yaml(File.open("config/config.example.yml"))
|
||||
HMAC_KEY = CONFIG.hmac_key
|
||||
16
src/ext/kemal_content_for.cr
Normal file
16
src/ext/kemal_content_for.cr
Normal file
@@ -0,0 +1,16 @@
|
||||
# Overrides for Kemal's `content_for` macro in order to keep using
|
||||
# kilt as it was before Kemal v1.1.1 (Kemal PR #618).
|
||||
|
||||
require "kemal"
|
||||
require "kilt"
|
||||
|
||||
macro content_for(key, file = __FILE__)
|
||||
%proc = ->() {
|
||||
__kilt_io__ = IO::Memory.new
|
||||
{{ yield }}
|
||||
__kilt_io__.to_s
|
||||
}
|
||||
|
||||
CONTENT_FOR_BLOCKS[{{key}}] = Tuple.new {{file}}, %proc
|
||||
nil
|
||||
end
|
||||
@@ -71,7 +71,7 @@ def send_file(env : HTTP::Server::Context, file_path : String, data : Slice(UInt
|
||||
filesize = data.bytesize
|
||||
attachment(env, filename, disposition)
|
||||
|
||||
Kemal.config.static_headers.try(&.call(env, file_path, filestat))
|
||||
Kemal.config.static_headers.try(&.call(env.response, file_path, filestat))
|
||||
|
||||
file = IO::Memory.new(data)
|
||||
if env.request.method == "GET" && env.request.headers.has_key?("Range")
|
||||
|
||||
@@ -17,8 +17,10 @@
|
||||
require "digest/md5"
|
||||
require "file_utils"
|
||||
|
||||
# Require kemal, then our own overrides
|
||||
# Require kemal, kilt, then our own overrides
|
||||
require "kemal"
|
||||
require "kilt"
|
||||
require "./ext/kemal_content_for.cr"
|
||||
require "./ext/kemal_static_file_handler.cr"
|
||||
|
||||
require "http_proxy"
|
||||
@@ -33,6 +35,7 @@ require "protodec/utils"
|
||||
|
||||
require "./invidious/database/*"
|
||||
require "./invidious/database/migrations/*"
|
||||
require "./invidious/connection/*"
|
||||
require "./invidious/http_server/*"
|
||||
require "./invidious/helpers/*"
|
||||
require "./invidious/yt_backend/*"
|
||||
@@ -47,8 +50,7 @@ require "./invidious/channels/*"
|
||||
require "./invidious/user/*"
|
||||
require "./invidious/search/*"
|
||||
require "./invidious/routes/**"
|
||||
require "./invidious/jobs/base_job"
|
||||
require "./invidious/jobs/*"
|
||||
require "./invidious/jobs/**"
|
||||
|
||||
# Declare the base namespace for invidious
|
||||
module Invidious
|
||||
@@ -60,13 +62,7 @@ alias IV = Invidious
|
||||
CONFIG = Config.load
|
||||
HMAC_KEY = CONFIG.hmac_key
|
||||
|
||||
PG_DB = begin
|
||||
DB.open CONFIG.database_url
|
||||
rescue ex
|
||||
puts "Failed to connect to PostgreSQL database: #{ex.cause.try &.message}"
|
||||
puts "Check your 'config.yml' database settings or PostgreSQL settings."
|
||||
exit(1)
|
||||
end
|
||||
PG_DB = DB.open CONFIG.database_url
|
||||
ARCHIVE_URL = URI.parse("https://archive.org")
|
||||
PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
|
||||
REDDIT_URL = URI.parse("https://www.reddit.com")
|
||||
@@ -96,15 +92,31 @@ SOFTWARE = {
|
||||
"branch" => "#{CURRENT_BRANCH}",
|
||||
}
|
||||
|
||||
YT_POOL = YoutubeConnectionPool.new(YT_URL, capacity: CONFIG.pool_size)
|
||||
YT_POOL = Invidious::ConnectionPool::Pool.new(
|
||||
max_capacity: CONFIG.pool_size,
|
||||
timeout: CONFIG.pool_checkout_timeout
|
||||
) do
|
||||
next make_client(YT_URL, force_resolve: true)
|
||||
end
|
||||
|
||||
# Image request pool
|
||||
|
||||
GGPHT_POOL = YoutubeConnectionPool.new(URI.parse("https://yt3.ggpht.com"), capacity: CONFIG.pool_size)
|
||||
GGPHT_URL = URI.parse("https://yt3.ggpht.com")
|
||||
|
||||
COMPANION_POOL = CompanionConnectionPool.new(
|
||||
capacity: CONFIG.pool_size
|
||||
)
|
||||
GGPHT_POOL = Invidious::ConnectionPool::Pool.new(
|
||||
max_capacity: CONFIG.pool_size,
|
||||
timeout: CONFIG.pool_checkout_timeout
|
||||
) do
|
||||
next make_client(GGPHT_URL, force_resolve: true)
|
||||
end
|
||||
|
||||
COMPANION_POOL = Invidious::ConnectionPool::Pool.new(
|
||||
max_capacity: CONFIG.pool_size,
|
||||
reinitialize_proxy: false
|
||||
) do
|
||||
companion = CONFIG.invidious_companion.sample
|
||||
next make_client(companion.private_url, use_http_proxy: false)
|
||||
end
|
||||
|
||||
# CLI
|
||||
Kemal.config.extra_options do |parser|
|
||||
@@ -227,12 +239,12 @@ error 404 do |env|
|
||||
Invidious::Routes::ErrorRoutes.error_404(env)
|
||||
end
|
||||
|
||||
error 500 do |env, exception|
|
||||
error_template(500, exception)
|
||||
error 500 do |env, ex|
|
||||
error_template(500, ex)
|
||||
end
|
||||
|
||||
static_headers do |env|
|
||||
env.response.headers.add("Cache-Control", "max-age=2629800")
|
||||
static_headers do |response|
|
||||
response.headers.add("Cache-Control", "max-age=2629800")
|
||||
end
|
||||
|
||||
# Init Kemal
|
||||
|
||||
@@ -166,7 +166,7 @@ def fetch_channel(ucid, pull_all_videos : Bool)
|
||||
}
|
||||
|
||||
LOGGER.trace("fetch_channel: #{ucid} : Downloading RSS feed")
|
||||
rss = YT_POOL.client &.get("/feeds/videos.xml?channel_id=#{ucid}").body
|
||||
rss = YT_POOL.get("/feeds/videos.xml?channel_id=#{ucid}").body
|
||||
LOGGER.trace("fetch_channel: #{ucid} : Parsing RSS feed")
|
||||
rss = XML.parse(rss)
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ private IMAGE_QUALITIES = {320, 560, 640, 1280, 2000}
|
||||
# TODO: Add "sort_by"
|
||||
def fetch_channel_community(ucid, cursor, locale, format, thin_mode)
|
||||
if cursor.nil?
|
||||
# EgVwb3N0c_IGBAoCSgA%3D is the protobuf object to load "posts"
|
||||
initial_data = YoutubeAPI.browse(ucid, params: "EgVwb3N0c_IGBAoCSgA%3D")
|
||||
# Egljb21tdW5pdHk%3D is the protobuf object to load "community"
|
||||
initial_data = YoutubeAPI.browse(ucid, params: "Egljb21tdW5pdHk%3D")
|
||||
|
||||
items = [] of JSON::Any
|
||||
extract_items(initial_data) do |item|
|
||||
@@ -24,21 +24,15 @@ def fetch_channel_community(ucid, cursor, locale, format, thin_mode)
|
||||
return extract_channel_community(items, ucid: ucid, locale: locale, format: format, thin_mode: thin_mode)
|
||||
end
|
||||
|
||||
def decode_ucid_from_post_protobuf(params)
|
||||
decoded_protobuf = params.try { |i| URI.decode_www_form(i) }
|
||||
.try { |i| Base64.decode(i) }
|
||||
.try { |i| IO::Memory.new(i) }
|
||||
.try { |i| Protodec::Any.parse(i) }
|
||||
|
||||
return decoded_protobuf.try(&.["56:0:embedded"]["2:0:string"].as_s)
|
||||
end
|
||||
|
||||
def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode)
|
||||
object = {
|
||||
"56:embedded" => {
|
||||
"2:string" => ucid,
|
||||
"3:string" => post_id.to_s,
|
||||
"11:string" => ucid,
|
||||
"2:string" => "community",
|
||||
"25:embedded" => {
|
||||
"22:string" => post_id.to_s,
|
||||
},
|
||||
"45:embedded" => {
|
||||
"2:varint" => 1_i64,
|
||||
"3:varint" => 1_i64,
|
||||
},
|
||||
}
|
||||
params = object.try { |i| Protodec::Any.cast_json(i) }
|
||||
@@ -46,7 +40,7 @@ def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode)
|
||||
.try { |i| Base64.urlsafe_encode(i) }
|
||||
.try { |i| URI.encode_www_form(i) }
|
||||
|
||||
initial_data = YoutubeAPI.browse("FEpost_detail", params: params)
|
||||
initial_data = YoutubeAPI.browse(ucid, params: params)
|
||||
|
||||
items = [] of JSON::Any
|
||||
extract_items(initial_data) do |item|
|
||||
|
||||
@@ -6,19 +6,19 @@ def fetch_channel_playlists(ucid, author, continuation, sort_by)
|
||||
case sort_by
|
||||
when "last", "last_added"
|
||||
# Equivalent to "&sort=lad"
|
||||
# {"2:string": "playlists", "3:varint": 4, "4:varint": 1, "6:varint": 1, "110:embedded": {"1:embedded": {"8:string": ""}}}
|
||||
"EglwbGF5bGlzdHMYBCABMAHyBgQKAkIA"
|
||||
# {"2:string": "playlists", "3:varint": 4, "4:varint": 1, "6:varint": 1}
|
||||
"EglwbGF5bGlzdHMYBCABMAE%3D"
|
||||
when "oldest", "oldest_created"
|
||||
# formerly "&sort=da"
|
||||
# Not available anymore :c or maybe ??
|
||||
# {"2:string": "playlists", "3:varint": 2, "4:varint": 1, "6:varint": 1, "110:embedded": {"1:embedded": {"8:string": ""}}}
|
||||
"EglwbGF5bGlzdHMYAiABMAHyBgQKAkIA"
|
||||
# {"2:string": "playlists", "3:varint": 2, "4:varint": 1, "6:varint": 1}
|
||||
"EglwbGF5bGlzdHMYAiABMAE%3D"
|
||||
# {"2:string": "playlists", "3:varint": 1, "4:varint": 1, "6:varint": 1}
|
||||
# "EglwbGF5bGlzdHMYASABMAE%3D"
|
||||
when "newest", "newest_created"
|
||||
# Formerly "&sort=dd"
|
||||
# {"2:string": "playlists", "3:varint": 3, "4:varint": 1, "6:varint": 1, "110:embedded": {"1:embedded": {"8:string": ""}}}
|
||||
"EglwbGF5bGlzdHMYAyABMAHyBgQKAkIA"
|
||||
# {"2:string": "playlists", "3:varint": 3, "4:varint": 1, "6:varint": 1}
|
||||
"EglwbGF5bGlzdHMYAyABMAE%3D"
|
||||
end
|
||||
|
||||
initial_data = YoutubeAPI.browse(ucid, params: params || "")
|
||||
|
||||
@@ -16,27 +16,23 @@ module Invidious::Comments
|
||||
return parse_youtube(id, response, format, locale, thin_mode, sort_by)
|
||||
end
|
||||
|
||||
def fetch_community_post_comments(ucid, post_id, sort_by = "top")
|
||||
case sort_by
|
||||
when "top"
|
||||
sort_by_val = 0_i64
|
||||
when "new", "newest"
|
||||
sort_by_val = 1_i64
|
||||
else # top
|
||||
sort_by_val = 0_i64
|
||||
end
|
||||
|
||||
def fetch_community_post_comments(ucid, post_id)
|
||||
object = {
|
||||
"2:string" => "posts",
|
||||
"2:string" => "community",
|
||||
"25:embedded" => {
|
||||
"22:string" => post_id,
|
||||
},
|
||||
"45:embedded" => {
|
||||
"2:varint" => 1_i64,
|
||||
"3:varint" => 1_i64,
|
||||
},
|
||||
"53:embedded" => {
|
||||
"4:embedded" => {
|
||||
"6:varint" => sort_by_val,
|
||||
"15:varint" => 2_i64,
|
||||
"25:varint" => 0_i64,
|
||||
"6:varint" => 0_i64,
|
||||
"27:varint" => 1_i64,
|
||||
"29:string" => post_id,
|
||||
"30:string" => ucid,
|
||||
},
|
||||
"7:varint" => 0_i64,
|
||||
"8:string" => "comments-section",
|
||||
},
|
||||
}
|
||||
@@ -47,7 +43,7 @@ module Invidious::Comments
|
||||
|
||||
object2 = {
|
||||
"80226972:embedded" => {
|
||||
"2:string" => "FEcomment_post_detail_page_web_top_level",
|
||||
"2:string" => ucid,
|
||||
"3:string" => object_parsed,
|
||||
},
|
||||
}
|
||||
@@ -324,15 +320,6 @@ module Invidious::Comments
|
||||
end
|
||||
|
||||
def produce_continuation(video_id, cursor = "", sort_by = "top")
|
||||
case sort_by
|
||||
when "top"
|
||||
sort_by_val = 0_i64
|
||||
when "new", "newest"
|
||||
sort_by_val = 1_i64
|
||||
else # top
|
||||
sort_by_val = 0_i64
|
||||
end
|
||||
|
||||
object = {
|
||||
"2:embedded" => {
|
||||
"2:string" => video_id,
|
||||
@@ -353,12 +340,21 @@ module Invidious::Comments
|
||||
"1:string" => cursor,
|
||||
"4:embedded" => {
|
||||
"4:string" => video_id,
|
||||
"6:varint" => sort_by_val,
|
||||
"6:varint" => 0_i64,
|
||||
},
|
||||
"5:varint" => 20_i64,
|
||||
},
|
||||
}
|
||||
|
||||
case sort_by
|
||||
when "top"
|
||||
object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64
|
||||
when "new", "newest"
|
||||
object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 1_i64
|
||||
else # top
|
||||
object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64
|
||||
end
|
||||
|
||||
continuation = object.try { |i| Protodec::Any.cast_json(i) }
|
||||
.try { |i| Protodec::Any.from_json(i) }
|
||||
.try { |i| Base64.urlsafe_encode(i) }
|
||||
|
||||
@@ -52,8 +52,6 @@ struct ConfigPreferences
|
||||
property vr_mode : Bool = true
|
||||
property show_nick : Bool = true
|
||||
property save_player_pos : Bool = false
|
||||
@[YAML::Field(ignore: true)]
|
||||
property default_playlist : String? = nil
|
||||
|
||||
def to_tuple
|
||||
{% begin %}
|
||||
@@ -84,9 +82,6 @@ class Config
|
||||
|
||||
@[YAML::Field(converter: Preferences::URIConverter)]
|
||||
property public_url : URI = URI.parse("")
|
||||
|
||||
# Indicates if this companion instance uses the built-in proxy
|
||||
property builtin_proxy : Bool = false
|
||||
end
|
||||
|
||||
# Number of threads to use for crawling videos from channels (for updating subscriptions)
|
||||
@@ -162,8 +157,13 @@ class Config
|
||||
property host_binding : String = "0.0.0.0"
|
||||
# Path and permissions to make Invidious listen on a UNIX socket instead of a TCP port
|
||||
property socket_binding : SocketBindingConfig? = nil
|
||||
# Pool size for HTTP requests to youtube.com and ytimg.com (each domain has a separate pool of `pool_size`)
|
||||
|
||||
# Max pool size for HTTP requests to youtube.com and ytimg.com (each domain has a separate pool)
|
||||
property pool_size : Int32 = 100
|
||||
|
||||
# Amount of seconds to wait for a client to be free from the pool before rasing an error
|
||||
property pool_checkout_timeout : Float64 = 5
|
||||
|
||||
# HTTP Proxy configuration
|
||||
property http_proxy : HTTPProxyConfig? = nil
|
||||
|
||||
@@ -276,14 +276,6 @@ class Config
|
||||
puts "Config: The value of 'invidious_companion_key' needs to be a size of 16 characters."
|
||||
exit(1)
|
||||
end
|
||||
|
||||
# Set public_url to built-in proxy path when omitted
|
||||
config.invidious_companion.each do |companion|
|
||||
if companion.public_url.to_s.empty?
|
||||
companion.public_url = URI.parse("/companion")
|
||||
companion.builtin_proxy = true
|
||||
end
|
||||
end
|
||||
elsif config.signature_server
|
||||
puts("WARNING: inv-sig-helper is deprecated. Please switch to Invidious companion: https://docs.invidious.io/companion-installation/")
|
||||
else
|
||||
|
||||
53
src/invidious/connection/client.cr
Normal file
53
src/invidious/connection/client.cr
Normal file
@@ -0,0 +1,53 @@
|
||||
def add_yt_headers(request)
|
||||
request.headers.delete("User-Agent") if request.headers["User-Agent"] == "Crystal"
|
||||
request.headers["User-Agent"] ||= "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
|
||||
|
||||
request.headers["Accept-Charset"] ||= "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
|
||||
request.headers["Accept"] ||= "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
||||
request.headers["Accept-Language"] ||= "en-us,en;q=0.5"
|
||||
|
||||
# Preserve original cookies and add new YT consent cookie for EU servers
|
||||
request.headers["Cookie"] = "#{request.headers["cookie"]?}; CONSENT=PENDING+#{Random.rand(100..999)}"
|
||||
if !CONFIG.cookies.empty?
|
||||
request.headers["Cookie"] = "#{(CONFIG.cookies.map { |c| "#{c.name}=#{c.value}" }).join("; ")}; #{request.headers["cookie"]?}"
|
||||
end
|
||||
end
|
||||
|
||||
def make_client(url : URI, region = nil, force_resolve : Bool = false, force_youtube_headers : Bool = false, use_http_proxy : Bool = true)
|
||||
client = HTTP::Client.new(url)
|
||||
client.proxy = make_configured_http_proxy_client() if CONFIG.http_proxy && use_http_proxy
|
||||
|
||||
# Force the usage of a specific configured IP Family
|
||||
if force_resolve
|
||||
client.family = CONFIG.force_resolve
|
||||
client.family = Socket::Family::INET if client.family == Socket::Family::UNSPEC
|
||||
end
|
||||
|
||||
client.before_request { |r| add_yt_headers(r) } if url.host.try &.ends_with?("youtube.com") || force_youtube_headers
|
||||
client.read_timeout = 10.seconds
|
||||
client.connect_timeout = 10.seconds
|
||||
|
||||
return client
|
||||
end
|
||||
|
||||
def make_client(url : URI, region = nil, force_resolve : Bool = false, use_http_proxy : Bool = true, &)
|
||||
client = make_client(url, region, force_resolve: force_resolve, use_http_proxy: use_http_proxy)
|
||||
begin
|
||||
yield client
|
||||
ensure
|
||||
client.close
|
||||
end
|
||||
end
|
||||
|
||||
def make_configured_http_proxy_client
|
||||
# This method is only called when configuration for an HTTP proxy are set
|
||||
config_proxy = CONFIG.http_proxy.not_nil!
|
||||
|
||||
return HTTP::Proxy::Client.new(
|
||||
config_proxy.host,
|
||||
config_proxy.port,
|
||||
|
||||
username: config_proxy.user,
|
||||
password: config_proxy.password,
|
||||
)
|
||||
end
|
||||
116
src/invidious/connection/pool.cr
Normal file
116
src/invidious/connection/pool.cr
Normal file
@@ -0,0 +1,116 @@
|
||||
module Invidious::ConnectionPool
|
||||
# A connection pool to reuse `HTTP::Client` connections
|
||||
struct Pool
|
||||
getter pool : DB::Pool(HTTP::Client)
|
||||
|
||||
# Creates a connection pool with the provided options, and client factory block.
|
||||
def initialize(
|
||||
*,
|
||||
max_capacity : Int32 = 5,
|
||||
timeout : Float64 = 5.0,
|
||||
@reinitialize_proxy : Bool = true, # Whether or not http-proxy should be reinitialized on checkout
|
||||
&client_factory : -> HTTP::Client
|
||||
)
|
||||
pool_options = DB::Pool::Options.new(
|
||||
initial_pool_size: 0,
|
||||
max_pool_size: max_capacity,
|
||||
max_idle_pool_size: max_capacity,
|
||||
checkout_timeout: timeout
|
||||
)
|
||||
|
||||
@pool = DB::Pool(HTTP::Client).new(pool_options, &client_factory)
|
||||
end
|
||||
|
||||
{% for method in %w[get post put patch delete head options] %}
|
||||
# Streaming API for {{method.id.upcase}} request.
|
||||
# The response will have its body as an `IO` accessed via `HTTP::Client::Response#body_io`.
|
||||
def {{method.id}}(*args, **kwargs, &)
|
||||
self.checkout do | client |
|
||||
client.{{method.id}}(*args, **kwargs) do | response |
|
||||
result = yield response
|
||||
return result
|
||||
ensure
|
||||
response.body_io?.try &.skip_to_end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Executes a {{method.id.upcase}} request.
|
||||
# The response will have its body as a `String`, accessed via `HTTP::Client::Response#body`.
|
||||
def {{method.id}}(*args, **kwargs)
|
||||
self.checkout do | client |
|
||||
return client.{{method.id}}(*args, **kwargs)
|
||||
end
|
||||
end
|
||||
{% end %}
|
||||
|
||||
# Checks out a client in the pool
|
||||
def checkout(&)
|
||||
# If a client has been deleted from the pool
|
||||
# we won't try to release it
|
||||
client_exists_in_pool = true
|
||||
|
||||
http_client = pool.checkout
|
||||
|
||||
# When the HTTP::Client connection is closed, the automatic reconnection
|
||||
# feature will create a new IO to connect to the server with
|
||||
#
|
||||
# This new TCP IO will be a direct connection to the server and will not go
|
||||
# through the proxy. As such we'll need to reinitialize the proxy connection
|
||||
|
||||
http_client.proxy = make_configured_http_proxy_client() if @reinitialize_proxy && CONFIG.http_proxy
|
||||
|
||||
response = yield http_client
|
||||
rescue ex : DB::PoolTimeout
|
||||
# Failed to checkout a client
|
||||
raise ConnectionPool::PoolCheckoutError.new(ex.message)
|
||||
rescue ex
|
||||
# An error occurred with the client itself.
|
||||
# Delete the client from the pool and close the connection
|
||||
if http_client
|
||||
client_exists_in_pool = false
|
||||
@pool.delete(http_client)
|
||||
http_client.close
|
||||
end
|
||||
|
||||
# Raise exception for outer methods to handle
|
||||
raise ConnectionPool::Error.new(ex.message, cause: ex)
|
||||
ensure
|
||||
pool.release(http_client) if http_client && client_exists_in_pool
|
||||
end
|
||||
end
|
||||
|
||||
class Error < Exception
|
||||
end
|
||||
|
||||
# Raised when the pool failed to get a client in time
|
||||
class PoolCheckoutError < Error
|
||||
end
|
||||
|
||||
# Mapping of subdomain => Invidious::ConnectionPool::Pool
|
||||
# This is needed as we may need to access arbitrary subdomains of ytimg
|
||||
private YTIMG_POOLS = {} of String => ConnectionPool::Pool
|
||||
|
||||
# Fetches a HTTP pool for the specified subdomain of ytimg.com
|
||||
#
|
||||
# Creates a new one when the specified pool for the subdomain does not exist
|
||||
def self.get_ytimg_pool(subdomain)
|
||||
if pool = YTIMG_POOLS[subdomain]?
|
||||
return pool
|
||||
else
|
||||
LOGGER.info("ytimg_pool: Creating a new HTTP pool for \"https://#{subdomain}.ytimg.com\"")
|
||||
url = URI.parse("https://#{subdomain}.ytimg.com")
|
||||
|
||||
pool = ConnectionPool::Pool.new(
|
||||
max_capacity: CONFIG.pool_size,
|
||||
timeout: CONFIG.pool_checkout_timeout
|
||||
) do
|
||||
next make_client(url, force_resolve: true)
|
||||
end
|
||||
|
||||
YTIMG_POOLS[subdomain] = pool
|
||||
|
||||
return pool
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -91,7 +91,7 @@ module Invidious::Database::Playlists
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Select
|
||||
# Salect
|
||||
# -------------------
|
||||
|
||||
def select(*, id : String) : InvidiousPlaylist?
|
||||
@@ -113,7 +113,7 @@ module Invidious::Database::Playlists
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Select (filtered)
|
||||
# Salect (filtered)
|
||||
# -------------------
|
||||
|
||||
def select_like_iv(email : String) : Array(InvidiousPlaylist)
|
||||
@@ -213,7 +213,7 @@ module Invidious::Database::PlaylistVideos
|
||||
end
|
||||
|
||||
# -------------------
|
||||
# Select
|
||||
# Salect
|
||||
# -------------------
|
||||
|
||||
def select(plid : String, index : VideoIndex, offset, limit = 100) : Array(PlaylistVideo)
|
||||
|
||||
@@ -34,7 +34,7 @@ module Invidious::Frontend::WatchPage
|
||||
str << " class=\"pure-form pure-form-stacked\""
|
||||
str << " action='#{url}'"
|
||||
str << " method='post'"
|
||||
str << " rel='noopener noreferrer'"
|
||||
str << " rel='noopener'"
|
||||
str << " target='_blank'>"
|
||||
str << '\n'
|
||||
|
||||
|
||||
@@ -18,7 +18,16 @@ def github_details(summary : String, content : String)
|
||||
return HTML.escape(details)
|
||||
end
|
||||
|
||||
def get_issue_template(env : HTTP::Server::Context, exception : Exception) : Tuple(String, String)
|
||||
def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exception : Exception)
|
||||
if exception.is_a?(InfoException)
|
||||
return error_template_helper(env, status_code, exception.message || "")
|
||||
end
|
||||
|
||||
locale = env.get("preferences").as(Preferences).locale
|
||||
|
||||
env.response.content_type = "text/html"
|
||||
env.response.status_code = status_code
|
||||
|
||||
issue_title = "#{exception.message} (#{exception.class})"
|
||||
|
||||
issue_template = <<-TEXT
|
||||
@@ -31,24 +40,6 @@ def get_issue_template(env : HTTP::Server::Context, exception : Exception) : Tup
|
||||
|
||||
issue_template += github_details("Backtrace", exception.inspect_with_backtrace)
|
||||
|
||||
return issue_title, issue_template
|
||||
end
|
||||
|
||||
def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exception : Exception)
|
||||
if exception.is_a?(InfoException)
|
||||
return error_template_helper(env, status_code, exception.message || "")
|
||||
end
|
||||
|
||||
locale = env.get("preferences").as(Preferences).locale
|
||||
|
||||
env.response.content_type = "text/html"
|
||||
env.response.status_code = status_code
|
||||
|
||||
# Unpacking into issue_title, issue_template directly causes a compiler error
|
||||
# I have no idea why.
|
||||
issue_template_components = get_issue_template(env, exception)
|
||||
issue_title, issue_template = issue_template_components
|
||||
|
||||
# URLs for the error message below
|
||||
url_faq = "https://github.com/iv-org/documentation/blob/master/docs/faq.md"
|
||||
url_search_issues = "https://github.com/iv-org/invidious/issues"
|
||||
@@ -78,7 +69,7 @@ def error_template_helper(env : HTTP::Server::Context, status_code : Int32, exce
|
||||
<p>#{translate(locale, "crash_page_report_issue", url_new_issue)}</p>
|
||||
|
||||
<!-- TODO: Add a "copy to clipboard" button -->
|
||||
<pre class="error-issue-template">#{issue_template}</pre>
|
||||
<pre style="padding: 20px; background: rgba(0, 0, 0, 0.12345);">#{issue_template}</pre>
|
||||
</div>
|
||||
END_HTML
|
||||
|
||||
|
||||
@@ -61,13 +61,28 @@ class Kemal::ExceptionHandler
|
||||
end
|
||||
end
|
||||
|
||||
class FilteredCompressHandler < HTTP::CompressHandler
|
||||
class FilteredCompressHandler < Kemal::Handler
|
||||
exclude ["/videoplayback", "/videoplayback/*", "/vi/*", "/sb/*", "/ggpht/*", "/api/v1/auth/notifications"]
|
||||
exclude ["/api/v1/auth/notifications", "/data_control"], "POST"
|
||||
|
||||
def call(context)
|
||||
return call_next context if exclude_match? context
|
||||
super
|
||||
def call(env)
|
||||
return call_next env if exclude_match? env
|
||||
|
||||
{% if flag?(:without_zlib) %}
|
||||
call_next env
|
||||
{% else %}
|
||||
request_headers = env.request.headers
|
||||
|
||||
if request_headers.includes_word?("Accept-Encoding", "gzip")
|
||||
env.response.headers["Content-Encoding"] = "gzip"
|
||||
env.response.output = Compress::Gzip::Writer.new(env.response.output, sync_close: true)
|
||||
elsif request_headers.includes_word?("Accept-Encoding", "deflate")
|
||||
env.response.headers["Content-Encoding"] = "deflate"
|
||||
env.response.output = Compress::Deflate::Writer.new(env.response.output, sync_close: true)
|
||||
end
|
||||
|
||||
call_next env
|
||||
{% end %}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -55,11 +55,12 @@ macro templated(_filename, template = "template", navbar_search = true)
|
||||
{{ layout = "src/invidious/views/" + template + ".ecr" }}
|
||||
|
||||
__content_filename__ = {{filename}}
|
||||
render {{filename}}, {{layout}}
|
||||
content = Kilt.render({{filename}})
|
||||
Kilt.render({{layout}})
|
||||
end
|
||||
|
||||
macro rendered(filename)
|
||||
render("src/invidious/views/#{{{filename}}}.ecr")
|
||||
Kilt.render("src/invidious/views/#{{{filename}}}.ecr")
|
||||
end
|
||||
|
||||
# Similar to Kemals halt method but works in a
|
||||
|
||||
@@ -291,55 +291,6 @@ struct SearchHashtag
|
||||
end
|
||||
end
|
||||
|
||||
# A `ProblematicTimelineItem` is a `SearchItem` created by Invidious that
|
||||
# represents an item that caused an exception during parsing.
|
||||
#
|
||||
# This is not a parsed object from YouTube but rather an Invidious-only type
|
||||
# created to gracefully communicate parse errors without throwing away
|
||||
# the rest of the (hopefully) successfully parsed item on a page.
|
||||
struct ProblematicTimelineItem
|
||||
property parse_exception : Exception
|
||||
property id : String
|
||||
|
||||
def initialize(@parse_exception)
|
||||
@id = Random.new.hex(8)
|
||||
end
|
||||
|
||||
def to_json(locale : String?, json : JSON::Builder)
|
||||
json.object do
|
||||
json.field "type", "parse-error"
|
||||
json.field "errorMessage", @parse_exception.message
|
||||
json.field "errorBacktrace", @parse_exception.inspect_with_backtrace
|
||||
end
|
||||
end
|
||||
|
||||
# Provides compatibility with PlaylistVideo
|
||||
def to_json(json : JSON::Builder, *args, **kwargs)
|
||||
return to_json("", json)
|
||||
end
|
||||
|
||||
def to_xml(env, locale, xml : XML::Builder)
|
||||
xml.element("entry") do
|
||||
xml.element("id") { xml.text "iv-err-#{@id}" }
|
||||
xml.element("title") { xml.text "Parse Error: This item has failed to parse" }
|
||||
xml.element("updated") { xml.text Time.utc.to_rfc3339 }
|
||||
|
||||
xml.element("content", type: "xhtml") do
|
||||
xml.element("div", xmlns: "http://www.w3.org/1999/xhtml") do
|
||||
xml.element("div") do
|
||||
xml.element("h4") { translate(locale, "timeline_parse_error_placeholder_heading") }
|
||||
xml.element("p") { translate(locale, "timeline_parse_error_placeholder_message") }
|
||||
end
|
||||
|
||||
xml.element("pre") do
|
||||
get_issue_template(env, @parse_exception)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Category
|
||||
include DB::Serializable
|
||||
|
||||
@@ -382,4 +333,4 @@ struct Continuation
|
||||
end
|
||||
end
|
||||
|
||||
alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist | SearchHashtag | Category | ProblematicTimelineItem
|
||||
alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist | SearchHashtag | Category
|
||||
|
||||
@@ -262,7 +262,7 @@ def get_referer(env, fallback = "/", unroll = true)
|
||||
end
|
||||
|
||||
referer = referer.request_target
|
||||
referer = "/" + referer.gsub(/[^\/?@&%=\-_.:,*0-9a-zA-Z+]/, "").lstrip("/\\")
|
||||
referer = "/" + referer.gsub(/[^\/?@&%=\-_.:,*0-9a-zA-Z]/, "").lstrip("/\\")
|
||||
|
||||
if referer == env.request.path
|
||||
referer = fallback
|
||||
|
||||
@@ -26,7 +26,7 @@ def fetch_mix(rdid, video_id, cookies = nil, locale = nil)
|
||||
end
|
||||
|
||||
video_id = "CvFH_6DNRCY" if rdid.starts_with? "OLAK5uy_"
|
||||
response = YT_POOL.client &.get("/watch?v=#{video_id}&list=#{rdid}&gl=US&hl=en", headers)
|
||||
response = YT_POOL.get("/watch?v=#{video_id}&list=#{rdid}&gl=US&hl=en", headers)
|
||||
initial_data = extract_initial_data(response.body)
|
||||
|
||||
if !initial_data["contents"]["twoColumnWatchNextResults"]["playlist"]?
|
||||
|
||||
@@ -432,7 +432,7 @@ def get_playlist_videos(playlist : InvidiousPlaylist | Playlist, offset : Int32,
|
||||
offset = initial_data.dig?("contents", "twoColumnWatchNextResults", "playlist", "playlist", "currentIndex").try &.as_i || offset
|
||||
end
|
||||
|
||||
videos = [] of PlaylistVideo | ProblematicTimelineItem
|
||||
videos = [] of PlaylistVideo
|
||||
|
||||
until videos.size >= 200 || videos.size == playlist.video_count || offset >= playlist.video_count
|
||||
# 100 videos per request
|
||||
@@ -448,7 +448,7 @@ def get_playlist_videos(playlist : InvidiousPlaylist | Playlist, offset : Int32,
|
||||
end
|
||||
|
||||
def extract_playlist_videos(initial_data : Hash(String, JSON::Any))
|
||||
videos = [] of PlaylistVideo | ProblematicTimelineItem
|
||||
videos = [] of PlaylistVideo
|
||||
|
||||
if initial_data["contents"]?
|
||||
tabs = initial_data["contents"]["twoColumnBrowseResultsRenderer"]["tabs"]
|
||||
@@ -500,8 +500,6 @@ def extract_playlist_videos(initial_data : Hash(String, JSON::Any))
|
||||
index: index,
|
||||
})
|
||||
end
|
||||
rescue ex
|
||||
videos << ProblematicTimelineItem.new(parse_exception: ex)
|
||||
end
|
||||
|
||||
return videos
|
||||
|
||||
@@ -26,7 +26,7 @@ module Invidious::Routes::API::Manifest
|
||||
end
|
||||
|
||||
if dashmpd = video.dash_manifest_url
|
||||
response = YT_POOL.client &.get(URI.parse(dashmpd).request_target)
|
||||
response = YT_POOL.get(URI.parse(dashmpd).request_target)
|
||||
|
||||
if response.status_code != 200
|
||||
haltf env, status_code: response.status_code
|
||||
@@ -167,7 +167,7 @@ module Invidious::Routes::API::Manifest
|
||||
|
||||
# /api/manifest/hls_playlist/*
|
||||
def self.get_hls_playlist(env)
|
||||
response = YT_POOL.client &.get(env.request.path)
|
||||
response = YT_POOL.get(env.request.path)
|
||||
|
||||
if response.status_code != 200
|
||||
haltf env, status_code: response.status_code
|
||||
@@ -223,7 +223,7 @@ module Invidious::Routes::API::Manifest
|
||||
|
||||
# /api/manifest/hls_variant/*
|
||||
def self.get_hls_variant(env)
|
||||
response = YT_POOL.client &.get(env.request.path)
|
||||
response = YT_POOL.get(env.request.path)
|
||||
|
||||
if response.status_code != 200
|
||||
haltf env, status_code: response.status_code
|
||||
|
||||
@@ -436,7 +436,7 @@ module Invidious::Routes::API::V1::Channels
|
||||
if ucid.nil?
|
||||
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
|
||||
return error_json(400, "Invalid post ID") if response["error"]?
|
||||
ucid = decode_ucid_from_post_protobuf(response.dig("endpoint", "browseEndpoint", "params").as_s)
|
||||
ucid = response.dig("endpoint", "browseEndpoint", "browseId").as_s
|
||||
else
|
||||
ucid = ucid.to_s
|
||||
end
|
||||
@@ -460,15 +460,13 @@ module Invidious::Routes::API::V1::Channels
|
||||
|
||||
format = env.params.query["format"]?
|
||||
format ||= "json"
|
||||
sort_by = env.params.query["sort_by"]?.try &.downcase
|
||||
sort_by ||= "top"
|
||||
|
||||
continuation = env.params.query["continuation"]?
|
||||
|
||||
case continuation
|
||||
when nil, ""
|
||||
ucid = env.params.query["ucid"]
|
||||
comments = Comments.fetch_community_post_comments(ucid, id, sort_by: sort_by)
|
||||
comments = Comments.fetch_community_post_comments(ucid, id)
|
||||
else
|
||||
comments = YoutubeAPI.browse(continuation: continuation)
|
||||
end
|
||||
|
||||
@@ -190,30 +190,15 @@ module Invidious::Routes::API::V1::Misc
|
||||
|
||||
sub_endpoint = endpoint["watchEndpoint"]? || endpoint["browseEndpoint"]? || endpoint
|
||||
params = sub_endpoint.try &.dig?("params")
|
||||
|
||||
if sub_endpoint["browseId"]?.try &.as_s == "FEpost_detail"
|
||||
decoded_protobuf = params.try &.as_s.try { |i| URI.decode_www_form(i) }
|
||||
.try { |i| Base64.decode(i) }
|
||||
.try { |i| IO::Memory.new(i) }
|
||||
.try { |i| Protodec::Any.parse(i) }
|
||||
|
||||
ucid = decoded_protobuf.try(&.["56:0:embedded"]["2:0:string"].as_s)
|
||||
post_id = decoded_protobuf.try(&.["56:0:embedded"]["3:1:string"].as_s)
|
||||
else
|
||||
ucid = sub_endpoint["browseId"]? if sub_endpoint["browseId"]? && sub_endpoint["browseId"]?.try &.as_s.starts_with? "UC"
|
||||
post_id = nil
|
||||
end
|
||||
rescue ex
|
||||
return error_json(500, ex)
|
||||
end
|
||||
JSON.build do |json|
|
||||
json.object do
|
||||
json.field "browseId", sub_endpoint["browseId"].as_s if sub_endpoint["browseId"]?
|
||||
json.field "ucid", ucid if ucid != nil
|
||||
json.field "ucid", sub_endpoint["browseId"].as_s if sub_endpoint["browseId"]?
|
||||
json.field "videoId", sub_endpoint["videoId"].as_s if sub_endpoint["videoId"]?
|
||||
json.field "playlistId", sub_endpoint["playlistId"].as_s if sub_endpoint["playlistId"]?
|
||||
json.field "startTimeSeconds", sub_endpoint["startTimeSeconds"].as_i if sub_endpoint["startTimeSeconds"]?
|
||||
json.field "postId", post_id if post_id != nil
|
||||
json.field "params", params.try &.as_s
|
||||
json.field "pageType", page_type
|
||||
end
|
||||
|
||||
@@ -106,7 +106,7 @@ module Invidious::Routes::API::V1::Videos
|
||||
# Auto-generated captions often have cues that aren't aligned properly with the video,
|
||||
# as well as some other markup that makes it cumbersome, so we try to fix that here
|
||||
if caption.name.includes? "auto-generated"
|
||||
caption_xml = YT_POOL.client &.get(url).body
|
||||
caption_xml = YT_POOL.get(url).body
|
||||
|
||||
settings_field = {
|
||||
"Kind" => "captions",
|
||||
@@ -147,7 +147,7 @@ module Invidious::Routes::API::V1::Videos
|
||||
query_params = uri.query_params
|
||||
query_params["fmt"] = "vtt"
|
||||
uri.query_params = query_params
|
||||
webvtt = YT_POOL.client &.get(uri.request_target).body
|
||||
webvtt = YT_POOL.get(uri.request_target).body
|
||||
|
||||
if webvtt.starts_with?("<?xml")
|
||||
webvtt = caption.timedtext_to_vtt(webvtt)
|
||||
@@ -300,7 +300,7 @@ module Invidious::Routes::API::V1::Videos
|
||||
cache_annotation(id, annotations)
|
||||
end
|
||||
else # "youtube"
|
||||
response = YT_POOL.client &.get("/annotations_invideo?video_id=#{id}")
|
||||
response = YT_POOL.get("/annotations_invideo?video_id=#{id}")
|
||||
|
||||
if response.status_code != 200
|
||||
haltf env, response.status_code
|
||||
|
||||
@@ -20,6 +20,14 @@ module Invidious::Routes::BeforeAll
|
||||
env.response.headers["X-XSS-Protection"] = "1; mode=block"
|
||||
env.response.headers["X-Content-Type-Options"] = "nosniff"
|
||||
|
||||
# Allow media resources to be loaded from google servers
|
||||
# TODO: check if *.youtube.com can be removed
|
||||
if CONFIG.disabled?("local") || !preferences.local
|
||||
extra_media_csp = " https://*.googlevideo.com:443 https://*.youtube.com:443"
|
||||
else
|
||||
extra_media_csp = ""
|
||||
end
|
||||
|
||||
# Only allow the pages at /embed/* to be embedded
|
||||
if env.request.resource.starts_with?("/embed")
|
||||
frame_ancestors = "'self' file: http: https:"
|
||||
@@ -37,7 +45,7 @@ module Invidious::Routes::BeforeAll
|
||||
"font-src 'self' data:",
|
||||
"connect-src 'self'",
|
||||
"manifest-src 'self'",
|
||||
"media-src 'self' blob:",
|
||||
"media-src 'self' blob:" + extra_media_csp,
|
||||
"child-src 'self' blob:",
|
||||
"frame-src 'self'",
|
||||
"frame-ancestors " + frame_ancestors,
|
||||
@@ -63,7 +71,6 @@ module Invidious::Routes::BeforeAll
|
||||
"/videoplayback",
|
||||
"/latest_version",
|
||||
"/download",
|
||||
"/companion/",
|
||||
}.any? { |r| env.request.resource.starts_with? r }
|
||||
|
||||
if env.request.cookies.has_key? "SID"
|
||||
@@ -103,21 +110,6 @@ module Invidious::Routes::BeforeAll
|
||||
preferences.locale = locale
|
||||
env.set "preferences", preferences
|
||||
|
||||
# Allow media resources to be loaded from google servers
|
||||
# TODO: check if *.youtube.com can be removed
|
||||
#
|
||||
# `!preferences.local` has to be checked after setting and
|
||||
# reading `preferences` from the "PREFS" cookie and
|
||||
# saved user preferences from the database, otherwise
|
||||
# `https://*.googlevideo.com:443 https://*.youtube.com:443`
|
||||
# will not be set in the CSP header if
|
||||
# `default_user_preferences.local` is set to true on the
|
||||
# configuration file, causing preference “Proxy Videos”
|
||||
# not to work while having it disabled and using medium quality.
|
||||
if CONFIG.disabled?("local") || !preferences.local
|
||||
env.response.headers["Content-Security-Policy"] = env.response.headers["Content-Security-Policy"].gsub("media-src", "media-src https://*.googlevideo.com:443 https://*.youtube.com:443")
|
||||
end
|
||||
|
||||
current_page = env.request.path
|
||||
if env.request.query
|
||||
query = HTTP::Params.parse(env.request.query.not_nil!)
|
||||
|
||||
@@ -284,7 +284,7 @@ module Invidious::Routes::Channels
|
||||
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
|
||||
return error_template(400, "Invalid post ID") if response["error"]?
|
||||
|
||||
ucid = decode_ucid_from_post_protobuf(response.dig("endpoint", "browseEndpoint", "params").as_s)
|
||||
ucid = response.dig("endpoint", "browseEndpoint", "browseId").as_s
|
||||
post_response = fetch_channel_community_post(ucid, id, locale, "json", thin_mode)
|
||||
end
|
||||
|
||||
@@ -392,7 +392,7 @@ module Invidious::Routes::Channels
|
||||
value = env.request.resource.split("/")[2]
|
||||
body = ""
|
||||
{"channel", "user", "c"}.each do |type|
|
||||
response = YT_POOL.client &.get("/#{type}/#{value}/live?disable_polymer=1")
|
||||
response = YT_POOL.get("/#{type}/#{value}/live?disable_polymer=1")
|
||||
if response.status_code == 200
|
||||
body = response.body
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user