Merge branch 'master' into patch-2

This commit is contained in:
TheFrenchGhosty 2021-05-22 14:10:09 +02:00 committed by GitHub
commit f66cfa1299
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 839 additions and 481 deletions

View file

@ -95,7 +95,7 @@ The complete documentation is available on https://docs.invidious.io/ (or altern
## Contact:
Feel free to join our [Matrix room](https://matrix.to/#/#invidious:matrix.org), or #invidious on freenode. Both platforms are bridged together.
Feel free to join our [Matrix room](https://matrix.to/#/#invidious:matrix.org).
---

View file

@ -310,194 +310,15 @@ footer a {
}
}
/* Control Bar */
@media screen and (max-width: 640px) {
.video-js .vjs-control-bar,
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
overflow-x: scroll;
}
}
ul.vjs-menu-content::-webkit-scrollbar {
display: none;
}
.vjs-user-inactive {
cursor: none;
}
.video-js .vjs-text-track-display > div > div > div {
background-color: rgba(0, 0, 0, 0.75) !important;
border-radius: 9px !important;
padding: 5px !important;
}
.vjs-play-control,
.vjs-volume-panel,
.vjs-current-time,
.vjs-time-control,
.vjs-duration,
.vjs-progress-control,
.vjs-remaining-time {
order: 1;
}
.vjs-captions-button {
order: 2;
}
.vjs-quality-selector,
.video-js .vjs-http-source-selector {
order: 3;
}
.vjs-playback-rate {
order: 4;
}
.vjs-share-control {
order: 5;
}
.vjs-fullscreen-control {
order: 6;
}
.vjs-playback-rate > .vjs-menu {
width: 50px;
}
.vjs-control-bar {
display: flex;
flex-direction: row;
scrollbar-width: none;
}
.vjs-control-bar::-webkit-scrollbar {
display: none;
}
.video-js .vjs-icon-cog {
font-size: 18px;
}
.video-js .vjs-control-bar,
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
background-color: rgba(35, 35, 35, 0.75);
}
.vjs-menu li.vjs-menu-item:focus,
.vjs-menu li.vjs-menu-item:hover {
background-color: rgba(255, 255, 255, 0.75);
color: rgba(49, 49, 51, 0.75);
}
.vjs-menu li.vjs-selected,
.vjs-menu li.vjs-selected:focus,
.vjs-menu li.vjs-selected:hover {
background-color: rgba(0, 182, 240, 0.75);
}
/* Progress Bar */
.video-js .vjs-slider {
background-color: rgba(15, 15, 15, 0.5);
}
fieldset > select,
span > select {
color: rgba(49, 49, 51, 1);
}
.video-js .vjs-load-progress,
.video-js .vjs-load-progress div {
background: rgba(87, 87, 88, 1);
}
.video-js .vjs-slider:hover,
.video-js button:hover {
color: rgba(0, 182, 240, 1);
}
.video-js .vjs-play-progress {
background-color: rgba(0, 182, 240, 1);
}
/* Overlay */
.video-js .vjs-overlay {
background-color: rgba(35, 35, 35, 0.75);
color: rgba(255, 255, 255, 1);
}
/* ProgressBar marker */
.vjs-marker {
background-color: rgba(255, 255, 255, 1);
z-index: 0;
}
/* Big "Play" Button */
.video-js .vjs-big-play-button {
background-color: rgba(35, 35, 35, 0.5);
}
.video-js:hover .vjs-big-play-button {
background-color: rgba(35, 35, 35, 0.75);
}
.video-js .vjs-current-time,
.video-js .vjs-time-divider,
.video-js .vjs-duration {
display: block;
}
.video-js .vjs-time-divider {
min-width: 0px;
padding-left: 0px;
padding-right: 0px;
}
.video-js .vjs-poster {
background-size: cover;
object-fit: cover;
}
.player-dimensions.vjs-fluid {
padding-top: 82vh;
}
video.video-js {
position: absolute;
height: 100%;
}
#player-container {
position: relative;
padding-bottom: 82vh;
height: 0;
}
.pure-control-group label {
word-wrap: normal;
}
.video-js.player-style-invidious {
/* This is already the default */
}
.video-js.player-style-youtube .vjs-control-bar {
display: flex;
flex-direction: row;
}
.video-js.player-style-youtube .vjs-big-play-button {
/*
Styles copied from video-js.min.css, definition of
.vjs-big-play-centered .vjs-big-play-button
*/
top: 50%;
left: 50%;
margin-top: -0.81666em;
margin-left: -1.5em;
}
/*
* Light theme
*/
@ -669,3 +490,28 @@ See https://stackoverflow.com/a/34372979 for more info */
hr {
margin: auto 0 auto 0;
}
/* Description Expansion Styling*/
#description-box {
display: flex;
flex-direction: column;
}
#descexpansionbutton {
display: none
}
#descexpansionbutton ~ div {
overflow: hidden;
height: 8.3em;
}
#descexpansionbutton:checked ~ div {
overflow: unset;
height: 100%;
}
#descexpansionbutton + label {
order: 1;
margin-top: 20px;
}

View file

@ -8,3 +8,19 @@
height: auto;
z-index: -100;
}
.watch-on-invidious {
font-size: 1.3em !important;
font-weight: bold;
white-space: nowrap;
margin: 0 1em 0 1em !important;
order: 3;
}
.watch-on-invidious > a {
color: white;
}
.watch-on-invidious > a:hover {
color: rgba(0, 182, 240, 1);;
}

250
assets/css/player.css Normal file
View file

@ -0,0 +1,250 @@
/* Youtube player style */
.video-js.player-style-youtube .vjs-progress-control {
height: 0;
}
.video-js.player-style-youtube .vjs-progress-control .vjs-progress-holder, .video-js.player-style-youtube .vjs-progress-control {
position: absolute;
right: 0;
left: 0;
width: 100%;
margin: 0;
}
.video-js.player-style-youtube .vjs-control-bar {
background: linear-gradient(rgba(0,0,0,0.1), rgba(0, 0, 0,0.5));
}
.video-js.player-style-youtube .vjs-slider {
background-color: rgba(255,255,255,0.2);
}
.video-js.player-style-youtube .vjs-load-progress > div {
background-color: rgba(255,255,255,0.5);
}
.video-js.player-style-youtube .vjs-play-progress {
background-color: red;
}
.video-js.player-style-youtube .vjs-progress-control:hover .vjs-progress-holder {
font-size: 15px;
}
.video-js.player-style-youtube .vjs-control-bar > .vjs-spacer {
flex: 1;
order: 2;
}
.video-js.player-style-youtube .vjs-play-progress .vjs-time-tooltip {
display: none;
}
.video-js.player-style-youtube .vjs-play-progress::before {
color: red;
font-size: 0.85em;
display: none;
}
.video-js.player-style-youtube .vjs-progress-holder:hover .vjs-play-progress::before {
display: unset;
}
.video-js.player-style-youtube .vjs-control-bar {
display: flex;
flex-direction: row;
}
.video-js.player-style-youtube .vjs-big-play-button {
/*
Styles copied from video-js.min.css, definition of
.vjs-big-play-centered .vjs-big-play-button
*/
top: 50%;
left: 50%;
margin-top: -0.81666em;
margin-left: -1.5em;
}
.video-js.player-style-youtube .vjs-menu-button-popup .vjs-menu {
margin-bottom: 2em;
}
ul.vjs-menu-content::-webkit-scrollbar {
display: none;
}
.vjs-user-inactive {
cursor: none;
}
.video-js .vjs-text-track-display > div > div > div {
background-color: rgba(0, 0, 0, 0.75) !important;
border-radius: 9px !important;
padding: 5px !important;
}
.vjs-play-control,
.vjs-volume-panel,
.vjs-current-time,
.vjs-time-control,
.vjs-duration,
.vjs-progress-control,
.vjs-remaining-time {
order: 1;
}
.vjs-captions-button {
order: 2;
}
.vjs-quality-selector,
.video-js .vjs-http-source-selector {
order: 3;
}
.vjs-playback-rate {
order: 4;
}
.vjs-share-control {
order: 5;
}
.vjs-fullscreen-control {
order: 6;
}
.vjs-playback-rate > .vjs-menu {
width: 50px;
}
.vjs-control-bar {
display: flex;
flex-direction: row;
scrollbar-width: none;
}
.vjs-control-bar::-webkit-scrollbar {
display: none;
}
.video-js .vjs-icon-cog {
font-size: 18px;
}
.video-js .vjs-control-bar,
.vjs-menu-button-popup .vjs-menu .vjs-menu-content {
background-color: rgba(35, 35, 35, 0.75);
}
.vjs-menu li.vjs-menu-item:focus,
.vjs-menu li.vjs-menu-item:hover {
background-color: rgba(255, 255, 255, 0.75);
color: rgba(49, 49, 51, 0.75);
}
.vjs-menu li.vjs-selected,
.vjs-menu li.vjs-selected:focus,
.vjs-menu li.vjs-selected:hover {
background-color: rgba(0, 182, 240, 0.75);
}
/* Progress Bar */
.video-js .vjs-slider {
background-color: rgba(15, 15, 15, 0.5);
}
.video-js .vjs-load-progress,
.video-js .vjs-load-progress div {
background: rgba(87, 87, 88, 1);
}
.video-js .vjs-slider:hover,
.video-js button:hover {
color: rgba(0, 182, 240, 1);
}
.video-js.player-style-invidious .vjs-play-progress {
background-color: rgba(0, 182, 240, 1);
}
vjs-menu-content
/* Overlay */
.video-js .vjs-overlay {
background-color: rgba(35, 35, 35, 0.75);
color: rgba(255, 255, 255, 1);
}
/* ProgressBar marker */
.vjs-marker {
background-color: rgba(255, 255, 255, 1);
z-index: 0;
}
/* Big "Play" Button */
.video-js .vjs-big-play-button {
background-color: rgba(35, 35, 35, 0.5);
}
.video-js:hover .vjs-big-play-button {
background-color: rgba(35, 35, 35, 0.75);
}
.video-js .vjs-current-time,
.video-js .vjs-time-divider,
.video-js .vjs-duration {
display: block;
}
.video-js .vjs-time-divider {
min-width: 0px;
padding-left: 0px;
padding-right: 0px;
}
.video-js .vjs-poster {
background-size: cover;
object-fit: cover;
}
.player-dimensions.vjs-fluid {
padding-top: 82vh;
}
video.video-js {
position: absolute;
height: 100%;
}
#player-container {
position: relative;
padding-bottom: 82vh;
height: 0;
}
.mobile-operations-bar {
display: flex;
position: absolute;
top: 0;
right: 1px !important;
left: initial !important;
width: initial !important;
}
.mobile-operations-bar ul {
position: absolute !important;
bottom: unset !important;
top: 1.5em;
}
@media screen and (max-width: 700px) {
.video-js .vjs-share {
justify-content: unset;
}
}
@media screen and (max-width: 650px) {
.vjs-modal-dialog-content {
overflow-x: hidden;
}
}

View file

@ -0,0 +1,7 @@
/**
* videojs-mobile-ui
* @version 0.5.2
* @copyright 2021 mister-ben <git@misterben.me>
* @license MIT
*/
@keyframes fadeAndScale{0%{opacity:0}25%{opacity:1}100%{opacity:0}}.video-js.vjs-has-started .vjs-touch-overlay{position:absolute;pointer-events:auto;top:0}.video-js .vjs-touch-overlay{display:block;width:100%;height:100%;pointer-events:none}.video-js .vjs-touch-overlay.skip{opacity:0;animation:fadeAndScale 0.6s linear;background-repeat:no-repeat;background-position:80% center;background-size:10%;background-image:url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>')}.video-js .vjs-touch-overlay.skip.reverse{background-position:20% center;background-image:url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>')}.video-js .vjs-touch-overlay .vjs-play-control{top:50%;left:50%;transform:translate(-50%, -50%);position:absolute;width:30%;height:80%;pointer-events:none;opacity:0;transition:opacity 0.3s ease}.video-js .vjs-touch-overlay .vjs-play-control .vjs-icon-placeholder::before{content:'';background-size:60%;background-position:center center;background-repeat:no-repeat;background-image:url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>')}.video-js .vjs-touch-overlay .vjs-play-control.vjs-paused .vjs-icon-placeholder::before{content:'';background-image:url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>')}.video-js .vjs-touch-overlay .vjs-play-control.vjs-ended .vjs-icon-placeholder::before{content:'';background-image:url('data:image/svg+xml;utf8,<svg fill="%23FFFFFF" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></svg>')}.video-js .vjs-touch-overlay.show-play-toggle .vjs-play-control{opacity:1;pointer-events:auto}.video-js.vjs-mobile-ui-disable-end.vjs-ended .vjs-touch-overlay{display:none}

View file

@ -14,6 +14,7 @@ var options = {
'durationDisplay',
'progressControl',
'remainingTimeDisplay',
'Spacer',
'captionsButton',
'qualitySelector',
'playbackRateMenuButton',
@ -73,6 +74,55 @@ if (location.pathname.startsWith('/embed/')) {
});
}
// Detect mobile users and initalize mobileUi for better UX
// Detection code taken from https://stackoverflow.com/a/20293441
function isMobile() {
try{ document.createEvent("TouchEvent"); return true; }
catch(e){ return false; }
}
if (isMobile()) {
player.mobileUi();
buttons = ["playToggle", "volumePanel", "captionsButton"];
if (video_data.params.quality !== 'dash') {
buttons.push("qualitySelector")
}
// Create new control bar object for operation buttons
const ControlBar = videojs.getComponent("controlBar");
let operations_bar = new ControlBar(player, {
children: [],
playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
});
buttons.slice(1).forEach(child => operations_bar.addChild(child))
// Remove operation buttons from primary control bar
primary_control_bar = player.getChild("controlBar");
buttons.forEach(child => primary_control_bar.removeChild(child));
operations_bar_element = operations_bar.el();
operations_bar_element.className += " mobile-operations-bar"
player.addChild(operations_bar)
// Playback menu doesn't work when its initalized outside of the primary control bar
playback_element = document.getElementsByClassName("vjs-playback-rate")[0]
operations_bar_element.append(playback_element)
// The share and http source selector element can't be fetched till the players ready.
player.one("playing", () => {
share_element = document.getElementsByClassName("vjs-share-control")[0]
operations_bar_element.append(share_element)
if (video_data.params.quality === 'dash') {
http_source_selector = document.getElementsByClassName("vjs-http-source-selector vjs-menu-button")[0]
operations_bar_element.append(http_source_selector)
}
})
}
player.on('error', function (event) {
if (player.error().code === 2 || player.error().code === 4) {
setTimeout(function (event) {
@ -566,3 +616,20 @@ if (navigator.vendor == "Apple Computer, Inc." && video_data.params.listen) {
});
});
}
// Watch on Invidious link
if (window.location.pathname.startsWith("/embed/")) {
const Button = videojs.getComponent('Button');
let watch_on_invidious_button = new Button(player);
// Create hyperlink for current instance
redirect_element = document.createElement("a");
redirect_element.setAttribute("href", `http://${window.location.host}/watch?v=${window.location.pathname.replace("/embed/","")}`)
redirect_element.appendChild(document.createTextNode("Invidious"))
watch_on_invidious_button.el().appendChild(redirect_element)
watch_on_invidious_button.addClass("watch-on-invidious")
cb = player.getChild('ControlBar')
cb.addChild(watch_on_invidious_button)
};

7
assets/js/videojs-mobile-ui.min.js vendored Normal file
View file

@ -0,0 +1,7 @@
/**
* videojs-mobile-ui
* @version 0.5.2
* @copyright 2021 mister-ben <git@misterben.me>
* @license MIT
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js"),require("global/window")):"function"==typeof define&&define.amd?define(["video.js","global/window"],t):e.videojsMobileUi=t(e.videojs,e.window)}(this,function(e,t){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e,t=t&&t.hasOwnProperty("default")?t.default:t;var n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},o=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},i=e.getComponent("Component"),r=e.dom||e,a=function(e){function i(t,r){n(this,i);var a=o(this,e.call(this,t,r));return a.seekSeconds=r.seekSeconds,a.tapTimeout=r.tapTimeout,a.addChild("playToggle",{}),t.on(["playing","userinactive"],function(e){a.removeClass("show-play-toggle")}),0===a.player_.options_.inactivityTimeout&&(a.player_.options_.inactivityTimeout=5e3),a.enable(),a}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(i,e),i.prototype.createEl=function(){return r.createEl("div",{className:"vjs-touch-overlay",tabIndex:-1})},i.prototype.handleTap=function(e){var n=this;e.target===this.el_&&(e.preventDefault(),this.firstTapCaptured?(this.firstTapCaptured=!1,this.timeout&&t.clearTimeout(this.timeout),this.handleDoubleTap(e)):(this.firstTapCaptured=!0,this.timeout=t.setTimeout(function(){n.firstTapCaptured=!1,n.handleSingleTap(e)},this.tapTimeout)))},i.prototype.handleSingleTap=function(e){this.removeClass("skip"),this.toggleClass("show-play-toggle")},i.prototype.handleDoubleTap=function(e){var n=this,o=this.el_.getBoundingClientRect(),i=e.changedTouches[0].clientX-o.left;if(i<.4*o.width)this.player_.currentTime(Math.max(0,this.player_.currentTime()-this.seekSeconds)),this.addClass("reverse");else{if(!(i>o.width-.4*o.width))return;this.player_.currentTime(Math.min(this.player_.duration(),this.player_.currentTime()+this.seekSeconds)),this.removeClass("reverse")}this.removeClass("show-play-toggle"),this.removeClass("skip"),t.requestAnimationFrame(function(){n.addClass("skip")})},i.prototype.enable=function(){this.firstTapCaptured=!1,this.on("touchend",this.handleTap)},i.prototype.disable=function(){this.off("touchend",this.handleTap)},i}(i);i.registerComponent("TouchOverlay",a);var s={fullscreen:{enterOnRotate:!0,exitOnRotate:!0,lockOnRotate:!0,iOS:!1},touchControls:{seekSeconds:10,tapTimeout:300,disableOnEnd:!1}},l=t.screen,u=function(n,o){n.addClass("vjs-mobile-ui"),(o.touchControls.disableOnEnd||"function"==typeof n.endscreen)&&n.addClass("vjs-mobile-ui-disable-end"),o.fullscreen.iOS&&e.browser.IS_IOS&&e.browser.IOS_VERSION>9&&!n.el_.ownerDocument.querySelector(".bc-iframe")&&(n.tech_.el_.setAttribute("playsinline","playsinline"),n.tech_.supportsFullScreen=function(){return!1});var i=void 0,r=e.VERSION.split("."),a=parseInt(r[0],10),s=parseInt(r[1],10);i=a<7||7===a&&s<7?Array.prototype.indexOf.call(n.el_.children,n.getChild("ControlBar").el_):n.children_.indexOf(n.getChild("ControlBar")),n.addChild("TouchOverlay",o.touchControls,i);var u=!1,c=function(){var i="number"==typeof t.orientation?t.orientation:l&&l.orientation&&l.orientation.angle?t.orientation:(e.log("angle unknown"),0);90!==i&&270!==i&&-90!==i||!o.enterOnRotate||!1===n.paused()&&(n.requestFullscreen(),o.fullscreen.lockOnRotate&&l.orientation&&l.orientation.lock&&l.orientation.lock("landscape").then(function(){u=!0}).catch(function(){e.log("orientation lock not allowed")})),0!==i&&180!==i||!o.exitOnRotate||n.isFullscreen()&&n.exitFullscreen()};e.browser.IS_IOS?t.addEventListener("orientationchange",c):l.orientation&&(l.orientation.onchange=c),n.on("ended",function(e){!0===u&&(l.orientation.unlock(),u=!1)})},c=function(){var t=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(n.forceForTesting||e.browser.IS_ANDROID||e.browser.IS_IOS)&&this.ready(function(){u(t,e.mergeOptions(s,n))})};return(e.registerPlugin||e.plugin)("mobileUi",c),c.VERSION="0.5.2",c});

View file

@ -18,13 +18,14 @@ RUN apk add --no-cache librsvg ttf-opensans
WORKDIR /invidious
RUN addgroup -g 1000 -S invidious && \
adduser -u 1000 -S invidious -G invidious
COPY --chown=invidious ./assets/ ./assets/
COPY ./assets/ ./assets/
COPY --chown=invidious ./config/config.* ./config/
RUN mv -n config/config.example.yml config/config.yml
RUN sed -i 's/host: \(127.0.0.1\|localhost\)/host: postgres/' config/config.yml
COPY --chown=invidious ./config/sql/ ./config/sql/
COPY --chown=invidious ./locales/ ./locales/
COPY ./config/sql/ ./config/sql/
COPY ./locales/ ./locales/
COPY --from=builder /invidious/invidious .
RUN chmod o+rX -R ./assets ./config ./locales
EXPOSE 3000
USER invidious

View file

@ -4,79 +4,80 @@
"": "`x` المشتركين"
},
"`x` videos": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` الفيديوهات",
"": "`x` الفيديوهات"
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` المقاطع المرئيَّة",
"": "`x` المقاطع المرئيَّة"
},
"`x` playlists": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` قوائم التشغيل",
"": "`x` قوائم التشغيل"
},
"LIVE": باشر",
"Shared `x` ago": "تم رفع الفيديو منذ `x`",
"LIVE": ُباشِر",
"Shared `x` ago": "تمَّ رفع المقطع المرئيّ مُنذ `x`",
"Unsubscribe": "إلغاء الإشتراك",
"Subscribe": "إشتراك",
"Subscribe": "الإشتراك",
"View channel on YouTube": "زيارة القناة على موقع يوتيوب",
"View playlist on YouTube": "عرض قائمة التشغيل على اليوتيوب",
"newest": "الأجدد",
"oldest": "الأقدم",
"popular": "الأكثر شعبية",
"last": "اخر قوائم التشغيل المعدلة",
"Next page": "الصفحة الثانية",
"last": "الأخيرة",
"Next page": "الصفحة التالية",
"Previous page": "الصفحة السابقة",
"Clear watch history?": "مسح السجل ؟",
"New password": "الرقم السرى الجديد",
"New passwords must match": "الأرقام السرية يجب ان تكون متطابقة",
"Cannot change password for Google accounts": "لا يستطيع تغيير الرقم السرى لحساب جوجل",
"Authorize token?": "رمز الإذن ؟",
"Authorize token for `x`?": "تصريح الرمز لـ `x` ؟",
"Clear watch history?": "هل تريد محو سجل المشاهدة؟",
"New password": "كلمة مرور جديدة",
"New passwords must match": "يَجبُ أن تكون كلمتي المرور متطابقتان",
"Cannot change password for Google accounts": "لا يُمكن تغيير كلمة المرور لِحسابات جوجل",
"Authorize token?": "رمز التفويض؟",
"Authorize token for `x`?": "رمز التفويض لِـ `x` ؟",
"Yes": "نعم",
"No": "لا",
"Import and Export Data": "استخراج و إضافة البيانات",
"Import": "إضافة",
"Import Invidious data": "إضافة بيانات Invidious",
"Import YouTube subscriptions": "إضافةالإشتراكات من موقع يوتيوب",
"Import FreeTube subscriptions (.db)": "إضافةالمشتركين من FreeTube (.db)",
"Import NewPipe subscriptions (.json)": "إضافة المشتركين من NewPipe (.json)",
"Import NewPipe data (.zip)": "إضافة بيانات NewPipe (.zip)",
"Export": "استخراج",
"Export subscriptions as OPML": "استخراج المشتركين كـ OPML",
"Export subscriptions as OPML (for NewPipe & FreeTube)": "استخراج المشتركين كـ OPML (لـ NewPipe و FreeTube)",
"Export data as JSON": "استخراج البيانات كـ JSON",
"Import and Export Data": "اِستيراد البيانات وتصديرها",
"Import": "استيراد",
"Import Invidious data": "استيراد بيانات انفيدياس",
"Import YouTube subscriptions": "استيراد اشتراكات يوتيوب",
"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",
"Delete account?": "حذف الحساب؟",
"History": "السجل",
"An alternative front-end to YouTube": "البديل الكامل لموقع يوتيوب",
"JavaScript license information": "معلومات ترخيص JavaScript",
"History": "السِّجل",
"An alternative front-end to YouTube": "واجهة أمامية بديلة لموقع يوتيوب",
"JavaScript license information": "معلومات ترخيص جافا سكربت",
"source": "المصدر",
"Log in": "تسجيل الدخول",
"Log in/register": "تسجيل الدخول \\ إنشاء حساب",
"Log in with Google": "تسجيل الدخول بإستخدام جوجل",
"User ID": "إسم المستخدم",
"Password": "الرقم السرى",
"Time (h:mm:ss):": "(يجب ان يكتب مثل هذا التنسيق) الوقت (h(ساعات):mm(دقائق):ss(ثوانى)):",
"Text CAPTCHA": "CAPTCHA كلامية",
"Image CAPTCHA": "CAPTCHA صورية",
"Log in with Google": "تسجيل الدخول باستخدام جوجل",
"User ID": "مُعرِّف المُستخدم",
"Password": "كلمة المرور",
"Time (h:mm:ss):": "الوقت (h:mm:ss):",
"Text CAPTCHA": "نص الكابتشا",
"Image CAPTCHA": "صورة الكابتشا",
"Sign In": "تسجيل الدخول",
"Register": "انشاء الحساب",
"E-mail": "الإيميل",
"Register": "التسجيل",
"E-mail": "البريد الإلكتروني",
"Google verification code": "رمز تحقق جوجل",
"Preferences": "التفضيلات",
"Player preferences": "التفضيلات المشغل",
"Always loop: ": "كرر الفيديو دائما: ",
"Autoplay: ": "تشغيل تلقائى: ",
"Play next by default: ": "شغل الفيديو التالي تلقائيا: ",
"Autoplay next video: ": "شغل الفيديو التالي تلقائيا (في قوائم التشغيل) ",
"Listen by default: ": "تشغيل النسخة السمعية تلقائى: ",
"Proxy videos: ": "عرض الفيديوهات عن طريق البروكسي؟ ",
"Player preferences": "التفضيلات المُشغِّل",
"Always loop: ": "كرر المقطع المرئيّ دائما: ",
"Autoplay: ": "تشغيل تلقائي: ",
"Play next by default: ": "شغل المقطع التالي تلقائيًا: ",
"Autoplay next video: ": "شغل المقطع التالي تلقائيًا: ",
"Listen by default: ": "تشغيل النسخة السمعية تلقائيًا: ",
"Proxy videos: ": "بروكسي المقاطع المرئيّة؟ ",
"Default speed: ": "السرعة الإفتراضية: ",
"Preferred video quality: ": "الجودة المفضلة للفيديوهات: ",
"Preferred video quality: ": "الجودة المفضلة للمقاطع: ",
"Player volume: ": "صوت المشغل: ",
"Default comments: ": "إضهار التعليقات الإفتراضية لـ: ",
"Default comments: ": "التعليقات الإفتراضية: ",
"youtube": "يوتيوب",
"reddit": "Reddit",
"Default captions: ": "الترجمات الإفتراضية: ",
"Fallback captions: ": "الترجمات المصاحبة: ",
"reddit": "ريديت",
"Default captions: ": "التسميات التوضيحية الإفتراضية: ",
"Fallback captions: ": "التسميات التوضيحية الاحتياطيَّة: ",
"Show related videos: ": "اعرض الفيديوهات ذات الصلة: ",
"Show annotations by default: ": "اعرض الملاحظات في الفيديو تلقائيا: ",
"Automatically extend video description: ": "",
"Visual preferences": "التفضيلات المرئية",
"Player style: ": "شكل مشغل الفيديوهات: ",
"Dark mode: ": "الوضع الليلى: ",
@ -156,6 +157,8 @@
"Title": "العنوان",
"Playlist privacy": "إعدادات الخصوصيه",
"Editing playlist `x`": "تعديل قائمه التشفيل `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "مشاهدة الفيديو على اليوتيوب",
"Hide annotations": "إخفاء الملاحظات فى الفيديو",
"Show annotations": "عرض الملاحظات فى الفيديو",

View file

@ -71,6 +71,7 @@
"Fallback captions: ": "",
"Show related videos: ": "",
"Show annotations by default: ": "",
"Automatically extend video description: ": "",
"Visual preferences": "",
"Player style: ": "",
"Dark mode: ": "",
@ -144,6 +145,8 @@
"Title": "",
"Playlist privacy": "",
"Editing playlist `x`": "",
"Show more": "",
"Show less": "",
"Watch on YouTube": "",
"Hide annotations": "",
"Show annotations": "",

View file

@ -8,15 +8,15 @@
"": "`x` videí."
},
"`x` playlists": {
"([^.,0-9]|^)1([^.,0-9]|$)": "",
"": ""
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` playlist",
"": "`x` playlisty."
},
"LIVE": "ŽIVĚ",
"Shared `x` ago": "",
"Shared `x` ago": "Sdíleno před `x`",
"Unsubscribe": "Odhlásit odběr",
"Subscribe": "Odebírat",
"View channel on YouTube": "Otevřít kanál na YouTube",
"View playlist on YouTube": "",
"View playlist on YouTube": "Zobrazit playlist na YouTube",
"newest": "nejnovější",
"oldest": "nejstarší",
"popular": "populární",
@ -28,7 +28,7 @@
"New passwords must match": "Hesla se musí schodovat",
"Cannot change password for Google accounts": "Nelze změnit heslo pro účty Google",
"Authorize token?": "Autorizovat token?",
"Authorize token for `x`?": "",
"Authorize token for `x`?": "Autorizovat token pro `x`?",
"Yes": "Ano",
"No": "Ne",
"Import and Export Data": "Import a Export údajů",
@ -63,107 +63,110 @@
"Player preferences": "Nastavení přehravače",
"Always loop: ": "Vždy opakovat: ",
"Autoplay: ": "Automatické přehrávání: ",
"Play next by default: ": "",
"Autoplay next video: ": "",
"Listen by default: ": "",
"Proxy videos: ": "",
"Default speed: ": "",
"Preferred video quality: ": "",
"Play next by default: ": "Přehrát další ve výchozím stavu: ",
"Autoplay next video: ": "Automaticky přehrát další video: ",
"Listen by default: ": "Poslouchat ve výchozím nastavení: ",
"Proxy videos: ": "Video přes proxy: ",
"Default speed: ": "Základní Rychlost: ",
"Preferred video quality: ": "Preferovaná kvalita videa: ",
"Player volume: ": "Hlasitost přehrávače: ",
"Default comments: ": "",
"youtube": "youtube",
"Default comments: ": "Předpřipravené komentáře: ",
"youtube": "YouTube",
"reddit": "reddit",
"Default captions: ": "",
"Fallback captions: ": "",
"Default captions: ": "Standartní Titulky: ",
"Fallback captions: ": "Záložní titulky: ",
"Show related videos: ": "Zobrazit podobné videa: ",
"Show annotations by default: ": "",
"Visual preferences": "",
"Show annotations by default: ": "Zobrazovat poznámky ve výchozím nastavení: ",
"Automatically extend video description: ": "Rozšířit automaticky popis u videa: ",
"Visual preferences": "Nastavení vzhledu",
"Player style: ": "Styl přehrávače ",
"Dark mode: ": "Tmavý režim ",
"Theme: ": "",
"dark": "",
"light": "",
"Thin mode: ": "",
"Subscription preferences": "",
"Show annotations by default for subscribed channels: ": "",
"Redirect homepage to feed: ": "",
"Number of videos shown in feed: ": "",
"Theme: ": "Vzhled: ",
"dark": "tmavý",
"light": "světlý",
"Thin mode: ": "Kompaktní režim: ",
"Subscription preferences": "Nastavení předplatných",
"Show annotations by default for subscribed channels: ": "Ve výchozím nastavení zobrazovat poznámky u odebíraných kanálů: ",
"Redirect homepage to feed: ": "Přesměrovávat domovskou stránku na informační kanál: ",
"Number of videos shown in feed: ": "Počet videí zobrazovaných v informačním kanále: ",
"Sort videos by: ": "Roztřídit videa podle: ",
"published": "publikováno",
"published - reverse": "",
"published - reverse": "podle publikování - obrátit",
"alphabetically": "podle abecedy",
"alphabetically - reverse": "",
"alphabetically - reverse": "podle abecedy - převrátit",
"channel name": "název kanálu",
"channel name - reverse": "",
"channel name - reverse": "podle jména kanálu - převrátit",
"Only show latest video from channel: ": "Jenom zobrazit nejnovjejší video z kanálu: ",
"Only show latest unwatched video from channel: ": "",
"Only show unwatched: ": "",
"Only show notifications (if there are any): ": "",
"Only show latest unwatched video from channel: ": "Zobrazit jen nejnovější nezhlédnuté video z daného kanálu: ",
"Only show unwatched: ": "Zobrazit jen již nezhlédnuté: ",
"Only show notifications (if there are any): ": "Zobrazit pouze upozornění (pokud nějaká jsou): ",
"Enable web notifications": "Povolit webové upozornění",
"`x` uploaded a video": "`x` nahrál(a) video",
"`x` is live": "`x` je živě",
"Data preferences": "",
"Data preferences": "Nastavení dat",
"Clear watch history": "Smazat historii",
"Import/export data": "",
"Import/export data": "importovat/exportovat data",
"Change password": "Změnit heslo",
"Manage subscriptions": "",
"Manage tokens": "",
"Watch history": "",
"Delete account": "",
"Administrator preferences": "",
"Default homepage: ": "",
"Feed menu: ": "",
"Manage subscriptions": "Spravovat odebírané kanály",
"Manage tokens": "Spravovat klíče",
"Watch history": "Historie Sledování",
"Delete account": "Smazat Účet",
"Administrator preferences": "Administrátorská nastavení",
"Default homepage: ": "Základní domovská stránka: ",
"Feed menu: ": "Menu doporučených: ",
"Top enabled: ": "",
"CAPTCHA enabled: ": "",
"Login enabled: ": "",
"Registration enabled: ": "",
"Report statistics: ": "",
"Save preferences": "",
"Subscription manager": "",
"Token manager": "",
"Token": "",
"CAPTCHA enabled: ": "CAPTCHA povolena: ",
"Login enabled: ": "Přihlášení povoleno: ",
"Registration enabled: ": "Registrace povolena ",
"Report statistics: ": "Oznámit statistiky: ",
"Save preferences": "Uložit nastavení",
"Subscription manager": "Správa Odběrů",
"Token manager": "Správa klíčů",
"Token": "Klíč",
"`x` subscriptions": {
"([^.,0-9]|^)1([^.,0-9]|$)": "",
"": ""
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` Odběry.([^.,0-9]|^)1([^.,0-9]|$)",
"": "`x` Odebíraných kanálů."
},
"`x` tokens": {
"([^.,0-9]|^)1([^.,0-9]|$)": "",
"": ""
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` Klíčů",
"": "`x` klíčů."
},
"Import/export": "",
"unsubscribe": "",
"revoke": "",
"Subscriptions": "",
"Import/export": "Importovat/exportovat",
"unsubscribe": "odhlásit odběr",
"revoke": "vrátit zpět",
"Subscriptions": "Odběry",
"`x` unseen notifications": {
"([^.,0-9]|^)1([^.,0-9]|$)": "",
"": ""
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` nezhlédnutých oznámení",
"": "`x` nezhlédnutých oznámení."
},
"search": "",
"Log out": "",
"Released under the AGPLv3 by Omar Roth.": "",
"Source available here.": "",
"View JavaScript license information.": "",
"View privacy policy.": "",
"Trending": "",
"Public": "",
"Unlisted": "",
"Private": "",
"View all playlists": "",
"Updated `x` ago": "",
"Delete playlist `x`?": "",
"Delete playlist": "",
"Create playlist": "",
"Title": "",
"search": "hledat",
"Log out": "Odhlásit se",
"Released under the AGPLv3 by Omar Roth.": "Vydáno Omarem Roth pod AGPLv3.",
"Source available here.": "Zdrojový kód dostupný zde.",
"View JavaScript license information.": "Zobrazit informace o licenci JavaScript .",
"View privacy policy.": "Zobrazit Zásady ochrany osobních údajů.",
"Trending": "Trendy",
"Public": "Veřejné",
"Unlisted": "Nevypsáno",
"Private": "Soukromé",
"View all playlists": "Zobrazit všechny playlisty",
"Updated `x` ago": "Aktualizováno před `x`",
"Delete playlist `x`?": "Smazat playlist `x`?",
"Delete playlist": "Smazat playlist",
"Create playlist": "Vytvořit playlist",
"Title": "Název",
"Playlist privacy": "",
"Editing playlist `x`": "",
"Watch on YouTube": "",
"Hide annotations": "",
"Show annotations": "",
"Genre: ": "",
"License: ": "",
"Family friendly? ": "",
"Editing playlist `x`": "Upravování playlistu `x`",
"Show more": "Zobrazit více",
"Show less": "Zobrazit méně",
"Watch on YouTube": "Sledovat na YouTube",
"Hide annotations": "Skrýt vysvětlivky",
"Show annotations": "Zobrazit vysvětlivky",
"Genre: ": "Žánr: ",
"License: ": "Licence: ",
"Family friendly? ": "Vhodné pro děti? ",
"Wilson score: ": "",
"Engagement: ": "",
"Engagement: ": "Závaznost: ",
"Whitelisted regions: ": "",
"Blacklisted regions: ": "",
"Shared `x`": "",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Alternative undertekster: ",
"Show related videos: ": "Vis relaterede videoer: ",
"Show annotations by default: ": "Vis annotationer som standard: ",
"Automatically extend video description: ": "",
"Visual preferences": "Visuelle præferencer",
"Player style: ": "Afspiller stil: ",
"Dark mode: ": "Mørk tilstand: ",
@ -156,6 +157,8 @@
"Title": "Titel",
"Playlist privacy": "Privatlivsindstillinger for afspilningsliste",
"Editing playlist `x`": "Redigerer afspilningsliste `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Se på YouTube",
"Hide annotations": "Skjul annotationer",
"Show annotations": "Vis annotationer",

View file

@ -25,7 +25,7 @@
"Previous page": "Vorherige Seite",
"Clear watch history?": "Verlauf löschen?",
"New password": "Neues Passwort",
"New passwords must match": "Neue Passwörter müssen gleich sein",
"New passwords must match": "Neue Passwörter müssen übereinstimmen",
"Cannot change password for Google accounts": "Ich kann das Passwort deines Google Kontos nicht ändern",
"Authorize token?": "Token autorisieren?",
"Authorize token for `x`?": "Token für `x` autorisieren?",
@ -50,7 +50,7 @@
"Log in": "Anmelden",
"Log in/register": "Anmelden/registrieren",
"Log in with Google": "Mit Google anmelden",
"User ID": "Benutzer ID",
"User ID": "Benutzer-ID",
"Password": "Passwort",
"Time (h:mm:ss):": "Zeit (h:mm:ss):",
"Text CAPTCHA": "Text CAPTCHA",
@ -77,12 +77,13 @@
"Fallback captions: ": "Ersatzuntertitel: ",
"Show related videos: ": "Ähnliche Videos anzeigen? ",
"Show annotations by default: ": "Standardmäßig Anmerkungen anzeigen? ",
"Automatically extend video description: ": "",
"Visual preferences": "Anzeigeeinstellungen",
"Player style: ": "Abspielgeräterstil: ",
"Dark mode: ": "Nachtmodus: ",
"Theme: ": "Modus: ",
"dark": "Nachtmodus",
"light": "klarer Modus",
"light": "heller Modus",
"Thin mode: ": "Schlanker Modus: ",
"Subscription preferences": "Abonnementeinstellungen",
"Show annotations by default for subscribed channels: ": "Anmerkungen für abonnierte Kanäle standardmäßig anzeigen? ",
@ -104,7 +105,7 @@
"`x` is live": "`x` ist live",
"Data preferences": "Dateneinstellungen",
"Clear watch history": "Verlauf löschen",
"Import/export data": "Daten im-/exportieren",
"Import/export data": "Daten importieren/exportieren",
"Change password": "Passwort ändern",
"Manage subscriptions": "Abonnements verwalten",
"Manage tokens": "Tokens verwalten",
@ -156,6 +157,8 @@
"Title": "Titel",
"Playlist privacy": "Vertrauliche Wiedergabeliste",
"Editing playlist `x`": "Wiedergabeliste bearbeiten `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Video auf YouTube ansehen",
"Hide annotations": "Anmerkungen ausblenden",
"Show annotations": "Anmerkungen anzeigen",
@ -215,10 +218,10 @@
"": "`x` Punkte"
},
"Could not create mix.": "Mix konnte nicht erstellt werden.",
"Empty playlist": "Playlist ist leer",
"Not a playlist.": "Ungültige Playlist.",
"Playlist does not exist.": "Playlist existiert nicht.",
"Could not pull trending pages.": "Trending Seiten konnten nicht geladen werden.",
"Empty playlist": "Wiedergabeliste ist leer",
"Not a playlist.": "Ungültige Wiedergabeliste.",
"Playlist does not exist.": "Wiedergabeliste existiert nicht.",
"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",
@ -361,7 +364,7 @@
},
"Fallback comments: ": "Alternative Kommentare: ",
"Popular": "Populär",
"Search": "",
"Search": "Suchen",
"Top": "Top",
"About": "Über",
"Rating: ": "Bewertung: ",
@ -384,32 +387,32 @@
"Videos": "Videos",
"Playlists": "Wiedergabelisten",
"Community": "Gemeinschaft",
"relevance": "",
"rating": "",
"date": "",
"views": "",
"content_type": "",
"duration": "",
"features": "",
"sort": "",
"hour": "",
"today": "",
"week": "",
"month": "",
"year": "",
"video": "",
"channel": "",
"playlist": "",
"movie": "",
"relevance": "Relevanz",
"rating": "Bewertung",
"date": "Datum",
"views": "Aufrufe",
"content_type": "Inhaltstyp",
"duration": "Dauer",
"features": "Eigenschaften",
"sort": "sortieren",
"hour": "Letzte Stunde",
"today": "Heute",
"week": "Diese Woche",
"month": "Diesen Monat",
"year": "Dieses Jahr",
"video": "Video",
"channel": "Kanal",
"playlist": "Wiedergabeliste",
"movie": "Film",
"show": "",
"hd": "",
"subtitles": "",
"creative_commons": "",
"3d": "",
"live": "",
"4k": "",
"location": "",
"hdr": "",
"filter": "",
"hd": "HD",
"subtitles": "Untertitel / CC",
"creative_commons": "Creative Commons",
"3d": "3D",
"live": "Live",
"4k": "4K",
"location": "Standort",
"hdr": "HDR",
"filter": "Filtern",
"Current version: ": "Aktuelle Version: "
}

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Εναλλακτικοί υπότιτλοι: ",
"Show related videos: ": "Προβολή σχετικών βίντεο; ",
"Show annotations by default: ": "Αυτόματη προβολή σημειώσεων: ",
"Automatically extend video description: ": "",
"Visual preferences": "Προτιμήσεις εμφάνισης",
"Player style: ": "Τεχνοτροπία της συσκευής αναπαραγωγης: ",
"Dark mode: ": "Σκοτεινή λειτουργία: ",
@ -156,6 +157,8 @@
"Title": "Τίτλος",
"Playlist privacy": "Ιδιωτικότητα καταλόγων αναπαραγωγής",
"Editing playlist `x`": "Επεξεργασία `x` καταλόγου αναπαραγωγής",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Προβολή στο YouTube",
"Hide annotations": "Απόκρυψη σημειώσεων",
"Show annotations": "Προβολή σημειώσεων",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Fallback captions: ",
"Show related videos: ": "Show related videos: ",
"Show annotations by default: ": "Show annotations by default: ",
"Automatically extend video description: ": "Automatically extend video description: ",
"Visual preferences": "Visual preferences",
"Player style: ": "Player style: ",
"Dark mode: ": "Dark mode: ",
@ -156,6 +157,8 @@
"Title": "Title",
"Playlist privacy": "Playlist privacy",
"Editing playlist `x`": "Editing playlist `x`",
"Show more": "Show more",
"Show less": "Show less",
"Watch on YouTube": "Watch on YouTube",
"Hide annotations": "Hide annotations",
"Show annotations": "Show annotations",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Retrodefaŭltaj subtekstoj: ",
"Show related videos: ": "Ĉu montri rilatajn filmetojn? ",
"Show annotations by default: ": "Ĉu montri prinotojn defaŭlte? ",
"Automatically extend video description: ": "Aŭtomate etendi priskribon de filmeto: ",
"Visual preferences": "Vidaj preferoj",
"Player style: ": "Ludila stilo: ",
"Dark mode: ": "Malhela reĝimo: ",
@ -156,6 +157,8 @@
"Title": "Titolo",
"Playlist privacy": "Privateco de ludlisto",
"Editing playlist `x`": "Redaktante ludlisto `x`",
"Show more": "Montri pli",
"Show less": "Montri malpli",
"Watch on YouTube": "Vidi filmeton en JuTubo",
"Hide annotations": "Kaŝi prinotojn",
"Show annotations": "Montri prinotojn",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Subtítulos alternativos: ",
"Show related videos: ": "¿Mostrar vídeos relacionados? ",
"Show annotations by default: ": "¿Mostrar anotaciones por defecto? ",
"Automatically extend video description: ": "Extender automáticamente la descripción del vídeo: ",
"Visual preferences": "Preferencias visuales",
"Player style: ": "Estilo de reproductor: ",
"Dark mode: ": "Modo oscuro: ",
@ -156,6 +157,8 @@
"Title": "Título",
"Playlist privacy": "Privacidad de la lista de reproducción",
"Editing playlist `x`": "Editando la lista de reproducción 'x'",
"Show more": "Mostrar más",
"Show less": "Mostrar menos",
"Watch on YouTube": "Ver el vídeo en Youtube",
"Hide annotations": "Ocultar anotaciones",
"Show annotations": "Mostrar anotaciones",

View file

@ -68,6 +68,7 @@
"Fallback captions: ": "",
"Show related videos: ": "Erakutsi erlazionatutako bideoak: ",
"Show annotations by default: ": "Erakutsi oharrak modu lehenetsian: ",
"Automatically extend video description: ": "",
"Visual preferences": "Hobespen bisualak",
"Player style: ": "Erreproduzigailu mota: ",
"Dark mode: ": "Gai iluna: ",
@ -138,6 +139,8 @@
"Title": "",
"Playlist privacy": "",
"Editing playlist `x`": "",
"Show more": "",
"Show less": "",
"Watch on YouTube": "",
"Hide annotations": "",
"Show annotations": "",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "عقب گرد زیرنویس ها: ",
"Show related videos: ": "نمایش ویدیو های مرتبط: ",
"Show annotations by default: ": "نمایش حاشیه نویسی ها به طور پیشفرض: ",
"Automatically extend video description: ": "",
"Visual preferences": "ترجیحات بصری",
"Player style: ": "حالت پخش کننده: ",
"Dark mode: ": "حالت تاریک: ",
@ -156,6 +157,8 @@
"Title": "عنوان",
"Playlist privacy": "حریم خصوصی لیست پخش",
"Editing playlist `x`": "تغییر لیست پخش `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "تماشا در یوتیوب",
"Hide annotations": "مخفی کردن حاشیه نویسی ها",
"Show annotations": "نمایش حاشیه نویسی ها",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Toissijaiset tekstitykset: ",
"Show related videos: ": "Näytä aiheeseen liittyviä videoita: ",
"Show annotations by default: ": "Näytä huomautukset oletuksena: ",
"Automatically extend video description: ": "",
"Visual preferences": "Visuaaliset asetukset",
"Player style: ": "Soittimen tyyli: ",
"Dark mode: ": "Tumma tila: ",
@ -156,6 +157,8 @@
"Title": "Nimi",
"Playlist privacy": "Soittolistan yksityisyys",
"Editing playlist `x`": "Muokataan soittolistaa `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Katso YouTubessa",
"Hide annotations": "Piilota merkkaukset",
"Show annotations": "Näytä merkkaukset",

View file

@ -27,7 +27,7 @@
"New password": "Nouveau mot de passe",
"New passwords must match": "Les nouveaux mots de passe doivent correspondre",
"Cannot change password for Google accounts": "Le mot de passe d'un compte Google ne peut pas être changé depuis Invidious",
"Authorize token?": "Autoriser le token ?",
"Authorize token?": "Autoriser le token ?",
"Authorize token for `x`?": "Autoriser le token pour `x` ?",
"Yes": "Oui",
"No": "Non",
@ -48,7 +48,7 @@
"JavaScript license information": "Informations sur les licences JavaScript",
"source": "source",
"Log in": "Se connecter",
"Log in/register": "Se connecter/Créer un compte",
"Log in/register": "Se connecter/S'inscrire",
"Log in with Google": "Se connecter avec Google",
"User ID": "Identifiant utilisateur",
"Password": "Mot de passe",
@ -77,6 +77,7 @@
"Fallback captions: ": "Sous-titres alternatifs : ",
"Show related videos: ": "Voir les vidéos liées : ",
"Show annotations by default: ": "Afficher les annotations par défaut : ",
"Automatically extend video description: ": "",
"Visual preferences": "Préférences du site",
"Player style: ": "Style du lecteur : ",
"Dark mode: ": "Mode sombre : ",
@ -120,7 +121,7 @@
"Report statistics: ": "Télémétrie activé : ",
"Save preferences": "Enregistrer les préférences",
"Subscription manager": "Gestionnaire d'abonnement",
"Token manager": "Gestionnaire de tokens",
"Token manager": "Gestionnaire de token",
"Token": "Token",
"`x` subscriptions": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` abonnements",
@ -139,7 +140,7 @@
"": "`x` notifications non vues"
},
"search": "rechercher",
"Log out": "Déconnexion",
"Log out": "Se déconnecter",
"Released under the AGPLv3 by Omar Roth.": "Publié sous licence AGPLv3 par Omar Roth.",
"Source available here.": "Code source disponible ici.",
"View JavaScript license information.": "Informations des licences JavaScript.",
@ -156,6 +157,8 @@
"Title": "Titre",
"Playlist privacy": "Paramètres de confidentialité de la liste de lecture",
"Editing playlist `x`": "Liste de lecture modifier le `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Voir la vidéo sur Youtube",
"Hide annotations": "Masquer les annotations",
"Show annotations": "Afficher les annotations",
@ -388,11 +391,11 @@
"rating": "évaluation",
"date": "date",
"views": "nombre de vues",
"content_type": "type de contenu",
"content_type": "type",
"duration": "durée",
"features": "fonctionnalités",
"sort": "Trier par",
"hour": "heure",
"hour": "dernière heure",
"today": "aujourd'hui",
"week": "semaine",
"month": "mois",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "כתוביות גיבוי ",
"Show related videos: ": "הצגת סרטונים קשורים: ",
"Show annotations by default: ": "הצגת הערות כברירת מחדל: ",
"Automatically extend video description: ": "",
"Visual preferences": "העדפות חזותיות",
"Player style: ": "סגנון הנגן: ",
"Dark mode: ": "מצב כהה: ",
@ -156,6 +157,8 @@
"Title": "",
"Playlist privacy": "Playlist privacy",
"Editing playlist `x`": "",
"Show more": "",
"Show less": "",
"Watch on YouTube": "צפייה ב־YouTube",
"Hide annotations": "",
"Show annotations": "",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Alternativni titlovi: ",
"Show related videos: ": "Prikaži povezana videa: ",
"Show annotations by default: ": "Standardno prikaži napomene: ",
"Automatically extend video description: ": "Automatski proširi opis videa: ",
"Visual preferences": "Postavke prikaza",
"Player style: ": "Stil playera: ",
"Dark mode: ": "Tamni modus: ",
@ -156,6 +157,8 @@
"Title": "Naslov",
"Playlist privacy": "Privatnost playliste",
"Editing playlist `x`": "Uređivanje playliste `x`",
"Show more": "Pokaži više",
"Show less": "Pokaži manje",
"Watch on YouTube": "Gledaj na YouTubeu",
"Hide annotations": "Sakrij napomene",
"Show annotations": "Prikaži napomene",

View file

@ -68,6 +68,7 @@
"Fallback captions: ": "Másodlagos feliratok: ",
"Show related videos: ": "Kapcsolódó videók mutatása: ",
"Show annotations by default: ": "Annotációk mutatása alapértelmetésben: ",
"Automatically extend video description: ": "",
"Visual preferences": "Vizuális preferenciák",
"Player style: ": "Lejátszó stílusa: ",
"Dark mode: ": "Sötét mód: ",
@ -138,6 +139,8 @@
"Title": "Címe",
"Playlist privacy": "Lejátszási lista láthatósága",
"Editing playlist `x`": "`x` lista szerkesztése",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Megtekintés a YouTube-on",
"Hide annotations": "Annotációk elrejtése",
"Show annotations": "Annotációk mutatása",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Subtitel fallback: ",
"Show related videos: ": "Tampilkan video terkait: ",
"Show annotations by default: ": "Tampilkan anotasi secara default: ",
"Automatically extend video description: ": "",
"Visual preferences": "Preferensi visual",
"Player style: ": "Gaya pemutar: ",
"Dark mode: ": "Mode gelap: ",
@ -156,6 +157,8 @@
"Title": "Judul",
"Playlist privacy": "Privasi daftar putar",
"Editing playlist `x`": "Menyunting daftar putar `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Tonton di YouTube",
"Hide annotations": "Sembunyikan anotasi",
"Show annotations": "Tampilkan anotasi",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Varatextar: ",
"Show related videos: ": "Sýna tengd myndbönd? ",
"Show annotations by default: ": "Á að sýna glósur sjálfgefið? ",
"Automatically extend video description: ": "",
"Visual preferences": "Sjónrænar stillingar",
"Player style: ": "Spilara stíl: ",
"Dark mode: ": "Myrkur ham: ",
@ -156,6 +157,8 @@
"Title": "Titill",
"Playlist privacy": "Spilunarlista opinberri",
"Editing playlist `x`": "Að breyta spilunarlista `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Horfa á YouTube",
"Hide annotations": "Fela glósur",
"Show annotations": "Sýna glósur",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Sottotitoli alternativi: ",
"Show related videos: ": "Mostra video correlati: ",
"Show annotations by default: ": "Mostra le annotazioni in modo predefinito: ",
"Automatically extend video description: ": "",
"Visual preferences": "Preferenze grafiche",
"Player style: ": "Stile riproduttore: ",
"Dark mode: ": "Tema scuro: ",
@ -156,6 +157,8 @@
"Title": "Titolo",
"Playlist privacy": "Privacy playlist",
"Editing playlist `x`": "Modificando la playlist `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Guarda su YouTube",
"Hide annotations": "Nascondi annotazioni",
"Show annotations": "Mostra annotazioni",
@ -361,7 +364,7 @@
},
"Fallback comments: ": "Commenti alternativi: ",
"Popular": "Popolare",
"Search": "",
"Search": "Cerca",
"Top": "Top",
"About": "Al riguardo",
"Rating: ": "Punteggio: ",
@ -384,32 +387,32 @@
"Videos": "Video",
"Playlists": "Playlist",
"Community": "Comunità",
"relevance": "",
"rating": "",
"date": "",
"views": "",
"content_type": "",
"duration": "",
"features": "",
"sort": "",
"hour": "",
"today": "",
"week": "",
"month": "",
"year": "",
"video": "",
"channel": "",
"playlist": "",
"movie": "",
"relevance": "Pertinenza",
"rating": "Valutazione",
"date": "Data di caricamento",
"views": "Numero di visualizzazioni",
"content_type": "Tipo",
"duration": "Durata",
"features": "Caratteristiche",
"sort": "Ordina per",
"hour": "Ultima ora",
"today": "Oggi",
"week": "Questa settimana",
"month": "Questo mese",
"year": "Quest'anno",
"video": "Video",
"channel": "Canale",
"playlist": "Playlist",
"movie": "Film",
"show": "",
"hd": "",
"subtitles": "",
"creative_commons": "",
"3d": "",
"live": "",
"4k": "",
"location": "",
"hdr": "",
"filter": "",
"hd": "AD",
"subtitles": "Sottotitoli / CC",
"creative_commons": "Creative Commons",
"3d": "3D",
"live": "In diretta",
"4k": "4K",
"location": "Posizione",
"hdr": "HDR",
"filter": "Filtra",
"Current version: ": "Versione attuale: "
}

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "フォールバック時の字幕: ",
"Show related videos: ": "関連動画を表示: ",
"Show annotations by default: ": "デフォルトでアノテーションを表示: ",
"Automatically extend video description: ": "動画の説明文を自動的に拡張: ",
"Visual preferences": "外観設定",
"Player style: ": "プレイヤースタイル: ",
"Dark mode: ": "ダークモード: ",
@ -156,6 +157,8 @@
"Title": "タイトル",
"Playlist privacy": "再生リストのプライバシー",
"Editing playlist `x`": "再生リスト `x` を編集中",
"Show more": "表示を増やす",
"Show less": "表示を減らす",
"Watch on YouTube": "YouTube で視聴",
"Hide annotations": "アノテーションを隠す",
"Show annotations": "アノテーションを表示",
@ -361,7 +364,7 @@
},
"Fallback comments: ": "フォールバック時のコメント: ",
"Popular": "人気",
"Search": "",
"Search": "検索",
"Top": "トップ",
"About": "このサービスについて",
"Rating: ": "評価: ",
@ -384,11 +387,11 @@
"Videos": "動画",
"Playlists": "プレイリスト",
"Community": "コミュニティ",
"relevance": "",
"rating": "",
"relevance": "関連",
"rating": "評価",
"date": "",
"views": "",
"content_type": "",
"content_type": "コンテンツの種類",
"duration": "",
"features": "",
"sort": "",
@ -399,7 +402,7 @@
"year": "",
"video": "",
"channel": "",
"playlist": "",
"playlist": "再生リスト",
"movie": "",
"show": "",
"hd": "",

View file

@ -1,15 +1,15 @@
{
"`x` subscribers": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` abonnenter",
"": "`x` abonnenter"
"": "`x` abonnenter."
},
"`x` videos": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` videoer",
"": "`x` videoer"
"": "`x` videoer."
},
"`x` playlists": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` spillelister",
"": "`x` spillelister"
"": "`x` spillelister."
},
"LIVE": "SANNTIDSVISNING",
"Shared `x` ago": "Delt for `x` siden",
@ -77,6 +77,7 @@
"Fallback captions: ": "Tilbakefallsundertitler: ",
"Show related videos: ": "Vis relaterte videoer? ",
"Show annotations by default: ": "Vis merknader som forvalg? ",
"Automatically extend video description: ": "Utvid videobeskrivelse automatisk: ",
"Visual preferences": "Visuelle innstillinger",
"Player style: ": "Avspillerstil: ",
"Dark mode: ": "Mørk drakt: ",
@ -124,11 +125,11 @@
"Token": "Symbol",
"`x` subscriptions": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` abonnementer",
"": "`x` abonnementer"
"": "`x` abonnementer."
},
"`x` tokens": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` symboler",
"": "`x` symboler"
"": "`x` symboler."
},
"Import/export": "Importer/eksporter",
"unsubscribe": "opphev abonnement",
@ -136,7 +137,7 @@
"Subscriptions": "Abonnement",
"`x` unseen notifications": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` usette merknader",
"": "`x` usette merknader"
"": "`x` usette merknader."
},
"search": "søk",
"Log out": "Logg ut",
@ -156,6 +157,8 @@
"Title": "Tittel",
"Playlist privacy": "Vern av spilleliste",
"Editing playlist `x`": "Endre spilleliste «x»",
"Show more": "Vis mer",
"Show less": "Vis mindre",
"Watch on YouTube": "Vis video på YouTube",
"Hide annotations": "Skjul merknader",
"Show annotations": "Vis merknader",
@ -169,7 +172,7 @@
"Shared `x`": "Delt `x`",
"`x` views": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` visninger",
"": "`x` visninger"
"": "`x` visninger."
},
"Premieres in `x`": "Premiere om `x`",
"Premieres `x`": "Première `x`",
@ -178,7 +181,7 @@
"View more comments on Reddit": "Vis flere kommenterer på Reddit",
"View `x` comments": {
"([^.,0-9]|^)1([^.,0-9]|$)": "Vis `x` kommentarer",
"": "Vis `x` kommentarer"
"": "Vis `x` kommentarer."
},
"View Reddit comments": "Vis Reddit-kommentarer",
"Hide replies": "Skjul svar",
@ -206,13 +209,13 @@
"Could not fetch comments": "Kunne ikke hente kommentarer",
"View `x` replies": {
"([^.,0-9]|^)1([^.,0-9]|$)": "Vis `x` svar",
"": "Vis `x` svar"
"": "Vis `x` svar."
},
"`x` ago": "`x` siden",
"Load more": "Last inn flere",
"`x` points": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` poeng",
"": "`x` poeng"
"": "`x` poeng."
},
"Could not create mix.": "Kunne ikke opprette miks.",
"Empty playlist": "Spillelisten er tom",
@ -333,35 +336,35 @@
"Zulu": "Zulu",
"`x` years": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` år",
"": "`x` år"
"": "`x` år."
},
"`x` months": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` måneder",
"": "`x` måneder"
"": "`x` måneder."
},
"`x` weeks": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` uker",
"": "`x` uker"
"": "`x` uker."
},
"`x` days": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` dager",
"": "`x` dager"
"": "`x` dager."
},
"`x` hours": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` timer",
"": "`x` timer"
"": "`x` timer."
},
"`x` minutes": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` minutter",
"": "`x` minutter"
"": "`x` minutter."
},
"`x` seconds": {
"([^.,0-9]|^)1([^.,0-9]|$)": "`x` sekunder",
"": "`x` sekunder"
"": "`x` sekunder."
},
"Fallback comments: ": "Tilbakefallskommentarer: ",
"Popular": "Populært",
"Search": "",
"Search": "Søk",
"Top": "Topp",
"About": "Om",
"Rating: ": "Vurdering: ",
@ -384,32 +387,32 @@
"Videos": "Videoer",
"Playlists": "Spillelister",
"Community": "Gemenskap",
"relevance": "",
"rating": "",
"date": "",
"views": "",
"content_type": "",
"duration": "",
"features": "",
"sort": "",
"hour": "",
"today": "",
"week": "",
"month": "",
"year": "",
"video": "",
"channel": "",
"playlist": "",
"movie": "",
"show": "",
"hd": "",
"subtitles": "",
"creative_commons": "",
"3d": "",
"live": "",
"4k": "",
"location": "",
"hdr": "",
"filter": "",
"relevance": "relevans",
"rating": "vurdering",
"date": "dato",
"views": "visninger",
"content_type": "innholdstype",
"duration": "varighet",
"features": "funksjoner",
"sort": "sorter",
"hour": "time",
"today": "i dag",
"week": "uke",
"month": "måned",
"year": "år",
"video": "video",
"channel": "kanal",
"playlist": "spilleliste",
"movie": "film",
"show": "vis",
"hd": "HD",
"subtitles": "undertekster",
"creative_commons": "Creative Commons",
"3d": "3D",
"live": "direkte",
"4k": "4k",
"location": "sted",
"hdr": "HDR",
"filter": "filtrer",
"Current version: ": "Gjeldende versjon: "
}

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Alternatieve ondertiteling: ",
"Show related videos: ": "Gerelateerde video's tonen? ",
"Show annotations by default: ": "Standaard annotaties tonen? ",
"Automatically extend video description: ": "",
"Visual preferences": "Visuele instellingen",
"Player style: ": "Speler vormgeving ",
"Dark mode: ": "Donkere modus: ",
@ -156,6 +157,8 @@
"Title": "Titel",
"Playlist privacy": "Afspeellijst privacy",
"Editing playlist `x`": "Afspeellijst `x` wijzigen",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Video bekijken op YouTube",
"Hide annotations": "Annotaties verbergen",
"Show annotations": "Annotaties tonen",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Zastępcze napisy: ",
"Show related videos: ": "Pokaż powiązane filmy? ",
"Show annotations by default: ": "Domyślnie pokazuj adnotacje: ",
"Automatically extend video description: ": "",
"Visual preferences": "Preferencje Wizualne",
"Player style: ": "Styl odtwarzacza: ",
"Dark mode: ": "Ciemny motyw: ",
@ -156,6 +157,8 @@
"Title": "Tytuł",
"Playlist privacy": "Widoczność playlisty",
"Editing playlist `x`": "Edycja playlisty `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Zobacz film na YouTube",
"Hide annotations": "Ukryj adnotacje",
"Show annotations": "Pokaż adnotacje",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Legendas alternativas: ",
"Show related videos: ": "Mostrar vídeos relacionados: ",
"Show annotations by default: ": "Sempre mostrar anotações: ",
"Automatically extend video description: ": "",
"Visual preferences": "Preferências visuais",
"Player style: ": "Estilo do tocador: ",
"Dark mode: ": "Modo escuro: ",
@ -156,6 +157,8 @@
"Title": "Título",
"Playlist privacy": "Privacidade da playlist",
"Editing playlist `x`": "Editando playlist `x`",
"Show more": "Mostrar mais",
"Show less": "Mostrar menos",
"Watch on YouTube": "Assistir no YouTube",
"Hide annotations": "Ocultar anotações",
"Show annotations": "Mostrar anotações",
@ -361,7 +364,7 @@
},
"Fallback comments: ": "Comentários alternativos: ",
"Popular": "Populares",
"Search": "",
"Search": "Procurar",
"Top": "No topo",
"About": "Sobre",
"Rating: ": "Avaliação: ",
@ -384,12 +387,12 @@
"Videos": "Vídeos",
"Playlists": "Listas de reprodução",
"Community": "Comunidade",
"relevance": "",
"rating": "",
"date": "",
"views": "",
"relevance": "relevância",
"rating": "avaliação",
"date": "data",
"views": "visualizações",
"content_type": "",
"duration": "",
"duration": "duração",
"features": "",
"sort": "",
"hour": "",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Legendas alternativas: ",
"Show related videos: ": "Mostrar vídeos relacionados: ",
"Show annotations by default: ": "Mostrar sempre anotações: ",
"Automatically extend video description: ": "",
"Visual preferences": "Preferências visuais",
"Player style: ": "Estilo do reprodutor: ",
"Dark mode: ": "Modo escuro: ",
@ -156,6 +157,8 @@
"Title": "Título",
"Playlist privacy": "Privacidade da lista de reprodução",
"Editing playlist `x`": "A editar lista de reprodução 'x'",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Ver no YouTube",
"Hide annotations": "Ocultar anotações",
"Show annotations": "Mostrar anotações",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Subtitrări alternative: ",
"Show related videos: ": "Afișați videoclipurile asemănătoare: ",
"Show annotations by default: ": "Afișați adnotările în mod implicit: ",
"Automatically extend video description: ": "",
"Visual preferences": "Preferințele site-ului",
"Player style: ": "Stilul player-ului : ",
"Dark mode: ": "Modul întunecat : ",
@ -156,6 +157,8 @@
"Title": "Titlu",
"Playlist privacy": "Parametrii de confidențialitate ai listei de redare",
"Editing playlist `x`": "Modificați lista de redare `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Urmăriți videoclipul pe YouTube",
"Hide annotations": "Ascundeți adnotările",
"Show annotations": "Afișați adnotările",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Дополнительный язык субтитров: ",
"Show related videos: ": "Показывать похожие видео? ",
"Show annotations by default: ": "Всегда показывать аннотации? ",
"Automatically extend video description: ": "",
"Visual preferences": "Настройки сайта",
"Player style: ": "Стиль проигрывателя: ",
"Dark mode: ": "Тёмное оформление: ",
@ -156,6 +157,8 @@
"Title": "Заголовок",
"Playlist privacy": "Конфиденциальность плейлиста",
"Editing playlist `x`": "Редактирование плейлиста `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Смотреть на YouTube",
"Hide annotations": "Скрыть аннотации",
"Show annotations": "Показать аннотации",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "",
"Show related videos: ": "",
"Show annotations by default: ": "",
"Automatically extend video description: ": "",
"Visual preferences": "",
"Player style: ": "",
"Dark mode: ": "",
@ -156,6 +157,8 @@
"Title": "",
"Playlist privacy": "",
"Editing playlist `x`": "",
"Show more": "",
"Show less": "",
"Watch on YouTube": "",
"Hide annotations": "",
"Show annotations": "",

View file

@ -71,6 +71,7 @@
"Fallback captions: ": "Náhradné titulky: ",
"Show related videos: ": "Zobraziť súvisiace videá: ",
"Show annotations by default: ": "Predvolene zobraziť anotácie: ",
"Automatically extend video description: ": "",
"Visual preferences": "Vizuálne nastavenia",
"Player style: ": "Štýl prehrávača: ",
"Dark mode: ": "Tmavý režim: ",
@ -144,6 +145,8 @@
"Title": "",
"Playlist privacy": "",
"Editing playlist `x`": "",
"Show more": "",
"Show less": "",
"Watch on YouTube": "",
"Hide annotations": "",
"Show annotations": "",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "",
"Show related videos: ": "",
"Show annotations by default: ": "",
"Automatically extend video description: ": "",
"Visual preferences": "",
"Player style: ": "",
"Dark mode: ": "",
@ -156,6 +157,8 @@
"Title": "",
"Playlist privacy": "",
"Editing playlist `x`": "",
"Show more": "",
"Show less": "",
"Watch on YouTube": "",
"Hide annotations": "",
"Show annotations": "",

View file

@ -68,6 +68,7 @@
"Fallback captions: ": "Алтернативни титлови: ",
"Show related videos: ": "Прикажи сличне видее: ",
"Show annotations by default: ": "Увек приказуј анотације: ",
"Automatically extend video description: ": "",
"Visual preferences": "Подешавања изгледа",
"Player style: ": "Стил плејера: ",
"Dark mode: ": "Тамни режим: ",
@ -138,6 +139,8 @@
"Title": "Наслов",
"Playlist privacy": "Видљивост плејлисте",
"Editing playlist `x`": "Уређујете плејлисту `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Гледајте на YouTube-у",
"Hide annotations": "Сакриј анотације",
"Show annotations": "Прикажи анотације",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Ersättningsundertexter: ",
"Show related videos: ": "Visa relaterade videor? ",
"Show annotations by default: ": "Visa länkar-i-videon som förval? ",
"Automatically extend video description: ": "",
"Visual preferences": "Visuella inställningar",
"Player style: ": "Spelarstil: ",
"Dark mode: ": "Mörkt läge: ",
@ -156,6 +157,8 @@
"Title": "Titel",
"Playlist privacy": "Privatläge på spellista",
"Editing playlist `x`": "Redigerer spellistan `x`",
"Show more": "Visa mer",
"Show less": "Visa mindre",
"Watch on YouTube": "Titta på YouTube",
"Hide annotations": "Dölj länkar-i-video",
"Show annotations": "Visa länkar-i-video",
@ -361,7 +364,7 @@
},
"Fallback comments: ": "Fallback-kommentarer: ",
"Popular": "Populärt",
"Search": "",
"Search": "Sök",
"Top": "Topp",
"About": "Om",
"Rating: ": "Betyg: ",
@ -384,32 +387,32 @@
"Videos": "Videor",
"Playlists": "Spellistor",
"Community": "Gemenskap",
"relevance": "",
"rating": "",
"date": "",
"views": "",
"relevance": "relevans",
"rating": "rankning",
"date": "datum",
"views": "visningar",
"content_type": "",
"duration": "",
"features": "",
"sort": "",
"hour": "",
"today": "",
"week": "",
"month": "",
"year": "",
"video": "",
"channel": "",
"playlist": "",
"movie": "",
"show": "",
"hd": "",
"subtitles": "",
"creative_commons": "",
"3d": "",
"live": "",
"4k": "",
"location": "",
"hdr": "",
"hour": "timme",
"today": "idag",
"week": "vecka",
"month": "månad",
"year": "år",
"video": "video",
"channel": "kanal",
"playlist": "spellista",
"movie": "film",
"show": "tv-serie",
"hd": "hd",
"subtitles": "undertexter",
"creative_commons": "creative_commons",
"3d": "3d",
"live": "live",
"4k": "4k",
"location": "plats",
"hdr": "hdr",
"filter": "",
"Current version: ": "Nuvarande version: "
}

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Yedek altyazılar: ",
"Show related videos: ": "İlgili videoları göster: ",
"Show annotations by default: ": "Öntanımlı olarak ek açıklamaları göster: ",
"Automatically extend video description: ": "Video açıklamasını otomatik olarak genişlet: ",
"Visual preferences": "Görsel tercihler",
"Player style: ": "Oynatıcı biçimi: ",
"Dark mode: ": "Karanlık mod: ",
@ -156,6 +157,8 @@
"Title": "Başlık",
"Playlist privacy": "Oynatma listesi gizliliği",
"Editing playlist `x`": "`x` oynatma listesi düzenleniyor",
"Show more": "Daha fazla göster",
"Show less": "Daha az göster",
"Watch on YouTube": "YouTube'da izle",
"Hide annotations": "Ek açıklamaları gizle",
"Show annotations": "Ek açıklamaları göster",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "Запасна мова субтитрів: ",
"Show related videos: ": "Показувати схожі відео? ",
"Show annotations by default: ": "Завжди показувати анотації? ",
"Automatically extend video description: ": "",
"Visual preferences": "Налаштування сайту",
"Player style: ": "Стиль програвача: ",
"Dark mode: ": "Темне оформлення: ",
@ -156,6 +157,8 @@
"Title": "Заголовок",
"Playlist privacy": "Конфіденційність списку відтворення",
"Editing playlist `x`": "Редагування списку відтворення \"x\"",
"Show more": "",
"Show less": "",
"Watch on YouTube": "Дивитися на YouTube",
"Hide annotations": "Приховати анотації",
"Show annotations": "Показати анотації",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "后备字幕语言: ",
"Show related videos: ": "是否显示相关视频: ",
"Show annotations by default: ": "是否默认显示视频注释: ",
"Automatically extend video description: ": "",
"Visual preferences": "视觉选项",
"Player style: ": "播放器样式: ",
"Dark mode: ": "深色模式: ",
@ -156,6 +157,8 @@
"Title": "标题",
"Playlist privacy": "播放列表隐私设置",
"Editing playlist `x`": "正在编辑播放列表 `x`",
"Show more": "",
"Show less": "",
"Watch on YouTube": "在 YouTube 观看",
"Hide annotations": "隐藏注释",
"Show annotations": "显示注释",

View file

@ -77,6 +77,7 @@
"Fallback captions: ": "汰退字幕: ",
"Show related videos: ": "顯示相關的影片: ",
"Show annotations by default: ": "預設顯示註釋: ",
"Automatically extend video description: ": "自動展開影片描述: ",
"Visual preferences": "視覺偏好設定",
"Player style: ": "播放器樣式: ",
"Dark mode: ": "深色模式: ",
@ -156,6 +157,8 @@
"Title": "標題",
"Playlist privacy": "播放清單隱私",
"Editing playlist `x`": "已編輯播放清單 `x`",
"Show more": "顯示更多",
"Show less": "顯示較少",
"Watch on YouTube": "在 YouTube 上觀看",
"Hide annotations": "隱藏註釋",
"Show annotations": "顯示註釋",

View file

@ -185,12 +185,14 @@ def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, so
json.field "published", published.to_unix
json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale))
json.field "likeCount", node_comment["likeCount"]
comment_action_buttons_renderer = node_comment["actionButtons"]["commentActionButtonsRenderer"]
json.field "likeCount", comment_action_buttons_renderer["likeButton"]["toggleButtonRenderer"]["accessibilityData"]["accessibilityData"]["label"].as_s.scan(/\d/).map(&.[0]).join.to_i
json.field "commentId", node_comment["commentId"]
json.field "authorIsChannelOwner", node_comment["authorIsChannelOwner"]
if node_comment["actionButtons"]["commentActionButtonsRenderer"]["creatorHeart"]?
hearth_data = node_comment["actionButtons"]["commentActionButtonsRenderer"]["creatorHeart"]["creatorHeartRenderer"]["creatorThumbnail"]
if comment_action_buttons_renderer["creatorHeart"]?
hearth_data = comment_action_buttons_renderer["creatorHeart"]["creatorHeartRenderer"]["creatorThumbnail"]
json.field "creatorHeart" do
json.object do
json.field "creatorThumbnail", hearth_data["thumbnails"][-1]["url"]

View file

@ -50,6 +50,7 @@ struct ConfigPreferences
property thin_mode : Bool = false
property unseen_only : Bool = false
property video_loop : Bool = false
property extend_desc : Bool = false
property volume : Int32 = 100
def to_tuple
@ -679,7 +680,7 @@ def create_notification_stream(env, topics, connection_channel)
end
def extract_initial_data(body) : Hash(String, JSON::Any)
return JSON.parse(body.match(/(window\["ytInitialData"\]|var\s*ytInitialData)\s*=\s*(?<info>\{.*?\});/mx).try &.["info"] || "{}").as_h
return JSON.parse(body.match(/(window\["ytInitialData"\]|var\s*ytInitialData)\s*=\s*(?<info>{.*?});<\/script>/mx).try &.["info"] || "{}").as_h
end
def proxy_file(response, env)

View file

@ -78,6 +78,7 @@ struct Preferences
property thin_mode : Bool = CONFIG.default_user_preferences.thin_mode
property unseen_only : Bool = CONFIG.default_user_preferences.unseen_only
property video_loop : Bool = CONFIG.default_user_preferences.video_loop
property extend_desc : Bool = CONFIG.default_user_preferences.extend_desc
property volume : Int32 = CONFIG.default_user_preferences.volume
module BoolToString

View file

@ -242,6 +242,7 @@ struct VideoPreferences
property speed : Float32 | Float64
property video_end : Float64 | Int32
property video_loop : Bool
property extend_desc : Bool
property video_start : Float64 | Int32
property volume : Int32
end
@ -818,7 +819,7 @@ end
def extract_polymer_config(body)
params = {} of String => JSON::Any
player_response = body.match(/(window\["ytInitialPlayerResponse"\]|var\sytInitialPlayerResponse)\s*=\s*(?<info>{.*?});/m)
player_response = body.match(/(window\["ytInitialPlayerResponse"\]|var\sytInitialPlayerResponse)\s*=\s*(?<info>{.*?});\s*var\s*meta/m)
.try { |r| JSON.parse(r["info"]).as_h }
if body.includes?("To continue with your YouTube experience, please fill out the form below.") ||
@ -1050,6 +1051,7 @@ def process_video_params(query, preferences)
related_videos = query["related_videos"]?.try { |q| (q == "true" || q == "1").to_unsafe }
speed = query["speed"]?.try &.rchop("x").to_f?
video_loop = query["loop"]?.try { |q| (q == "true" || q == "1").to_unsafe }
extend_desc = query["extend_desc"]?.try { |q| (q == "true" || q == "1").to_unsafe }
volume = query["volume"]?.try &.to_i?
if preferences
@ -1068,6 +1070,7 @@ def process_video_params(query, preferences)
related_videos ||= preferences.related_videos.to_unsafe
speed ||= preferences.speed
video_loop ||= preferences.video_loop.to_unsafe
extend_desc ||= preferences.extend_desc.to_unsafe
volume ||= preferences.volume
end
@ -1085,6 +1088,7 @@ def process_video_params(query, preferences)
related_videos ||= CONFIG.default_user_preferences.related_videos.to_unsafe
speed ||= CONFIG.default_user_preferences.speed
video_loop ||= CONFIG.default_user_preferences.video_loop.to_unsafe
extend_desc ||= CONFIG.default_user_preferences.extend_desc.to_unsafe
volume ||= CONFIG.default_user_preferences.volume
annotations = annotations == 1
@ -1095,6 +1099,7 @@ def process_video_params(query, preferences)
local = local == 1
related_videos = related_videos == 1
video_loop = video_loop == 1
extend_desc = extend_desc == 1
if CONFIG.disabled?("dash") && quality == "dash"
quality = "high"
@ -1141,6 +1146,7 @@ def process_video_params(query, preferences)
speed: speed,
video_end: video_end,
video_loop: video_loop,
extend_desc: extend_desc,
video_start: video_start,
volume: volume,
})

View file

@ -3,7 +3,10 @@
<link rel="stylesheet" href="/css/videojs.markers.min.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-share.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-vtt-thumbnails.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-mobile-ui.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/player.css?v=<%= ASSET_COMMIT %>">
<script src="/js/video.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-mobile-ui.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-contrib-quality-levels.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-http-source-selector.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-markers.min.js?v=<%= ASSET_COMMIT %>"></script>

View file

@ -149,6 +149,20 @@
</td>
</tr>
<tr>
<td>
<a href="/js/videojs-mobile-ui.min.js?v=<%= ASSET_COMMIT %>">videojs-mobile-ui.min.js</a>
</td>
<td>
<a href="https://choosealicense.com/licenses/mit/">MIT</a>
</td>
<td>
<a href="https://github.com/mister-ben/videojs-mobile-ui"><%= translate(locale, "source") %></a>
</td>
</tr>
<tr>
<td>
<a href="/js/videojs-markers.min.js?v=<%= ASSET_COMMIT %>">videojs-markers.min.js</a>

View file

@ -106,6 +106,12 @@
<input name="annotations" id="annotations" type="checkbox" <% if preferences.annotations %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="extend_desc"><%= translate(locale, "Automatically extend video description: ") %></label>
<input name="extend_desc" id="extend_desc" type="checkbox" <% if preferences.extend_desc %>checked<% end %>>
</div>
<legend><%= translate(locale, "Visual preferences") %></legend>
<div class="pure-control-group">

View file

@ -16,7 +16,7 @@
<div class="pure-u-1 pure-u-md-12-24 searchbar">
<form class="pure-form" action="/search" method="get">
<fieldset>
<input type="search" style="width:100%" name="q" placeholder="<%= translate(locale, "search") %>" value="<%= env.get?("search").try {|x| HTML.escape(x.as(String)) } %>">
<input autofocus type="search" style="width:100%" name="q" placeholder="<%= translate(locale, "search") %>" value="<%= env.get?("search").try {|x| HTML.escape(x.as(String)) } %>">
</fieldset>
</form>
</div>

View file

@ -25,6 +25,19 @@
<link rel="alternate" href="https://www.youtube.com/watch?v=<%= video.id %>">
<%= rendered "components/player_sources" %>
<title><%= HTML.escape(video.title) %> - Invidious</title>
<!-- Description expansion also updates the 'Show more' button to 'Show less' so
we're going to need to do it here in order to allow for translations.
-->
<style>
#descexpansionbutton + label > a::after {
content: "<%= translate(locale, "Show more") %>"
}
#descexpansionbutton:checked + label > a::after {
content: "<%= translate(locale, "Show less") %>"
}
</style>
<% end %>
<script id="video_data" type="application/json">
@ -227,8 +240,18 @@
<% end %>
</p>
<div>
<div id="description-box"> <!-- Description -->
<% if video.description.size < 200 || params.extend_desc %>
<%= video.description_html %>
<% else %>
<input id="descexpansionbutton" type="checkbox"/>
<label for="descexpansionbutton" style="order: 1;">
<a></a>
</label>
<div id="descriptionWrapper">
<%= video.description_html %>
</div>
<% end %>
</div>
<hr>