summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--assets/css/default.css38
-rw-r--r--assets/js/player.js50
-rw-r--r--docker/Dockerfile9
-rw-r--r--docker/Dockerfile.arm646
-rw-r--r--kubernetes/Chart.lock6
-rw-r--r--kubernetes/Chart.yaml2
-rw-r--r--src/invidious/jsonify/api_v1/video_json.cr1
-rw-r--r--src/invidious/routes/watch.cr8
-rw-r--r--src/invidious/user/imports.cr8
-rw-r--r--src/invidious/videos/parser.cr5
-rw-r--r--src/invidious/views/watch.ecr33
12 files changed, 126 insertions, 42 deletions
diff --git a/README.md b/README.md
index 88770383..8c3b460a 100644
--- a/README.md
+++ b/README.md
@@ -149,7 +149,7 @@ Weblate also allows you to log-in with major SSO providers like Github, Gitlab,
- [CloudTube](https://sr.ht/~cadence/tube/): A JavaScript-rich alternate YouTube player.
- [PeerTubeify](https://gitlab.com/Cha_de_L/peertubeify): On YouTube, displays a link to the same video on PeerTube, if it exists.
- [MusicPiped](https://github.com/deep-gaurav/MusicPiped): A material design music player that streams music from YouTube.
-- [HoloPlay](https://github.com/stephane-r/holoplay-wa): Progressive Web App connecting on Invidious API's with search, playlists and favorites.
+- [HoloPlay](https://github.com/stephane-r/holoplay-pwa): Progressive Web App connecting on Invidious API's with search, playlists and favorites.
- [WatchTube](https://github.com/WatchTubeTeam/WatchTube): Powerful YouTube client for Apple Watch.
- [Yattee](https://github.com/yattee/yattee): Alternative YouTube frontend for iPhone, iPad, Mac and Apple TV.
- [TubiTui](https://codeberg.org/777/TubiTui): A lightweight, libre, TUI-based YouTube client.
diff --git a/assets/css/default.css b/assets/css/default.css
index b4053b5c..c902fbac 100644
--- a/assets/css/default.css
+++ b/assets/css/default.css
@@ -441,16 +441,26 @@ p.video-data { margin: 0; font-weight: bold; font-size: 80%; }
*/
footer {
- color: #919191;
margin-top: auto;
padding: 1.5em 0;
text-align: center;
max-height: 30vh;
}
-footer a {
- color: #919191 !important;
- text-decoration: underline;
+.light-theme footer {
+ color: #7c7c7c;
+}
+
+.dark-theme footer {
+ color: #adadad;
+}
+
+.light-theme footer a {
+ color: #7c7c7c !important;
+}
+
+.dark-theme footer a {
+ color: #adadad !important;
}
footer span {
@@ -556,6 +566,14 @@ span > select {
color: #303030;
}
+ .no-theme footer {
+ color: #7c7c7c;
+ }
+
+ .no-theme footer a {
+ color: #7c7c7c !important;
+ }
+
.light-theme .pure-menu-heading {
color: #565d64;
}
@@ -589,7 +607,7 @@ span > select {
}
.dark-theme a {
- color: #a0a0a0;
+ color: #adadad;
text-decoration: none;
}
@@ -643,7 +661,7 @@ body.dark-theme {
}
.no-theme a {
- color: #a0a0a0;
+ color: #adadad;
text-decoration: none;
}
@@ -674,6 +692,14 @@ body.dark-theme {
background-color: inherit;
color: inherit;
}
+
+ .no-theme footer {
+ color: #adadad;
+ }
+
+ .no-theme footer a {
+ color: #adadad !important;
+ }
}
diff --git a/assets/js/player.js b/assets/js/player.js
index bb53ac24..16bb2752 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -98,11 +98,13 @@ if (video_data.params.quality === 'dash') {
/**
* Function for add time argument to url
+ *
* @param {String} url
+ * @param {String} [base]
* @returns {URL} urlWithTimeArg
*/
-function addCurrentTimeToURL(url) {
- var urlUsed = new URL(url);
+function addCurrentTimeToURL(url, base) {
+ var urlUsed = new URL(url, base);
urlUsed.searchParams.delete('start');
var currentTime = Math.ceil(player.currentTime());
if (currentTime > 0)
@@ -112,6 +114,50 @@ function addCurrentTimeToURL(url) {
return urlUsed;
}
+/**
+ * Global variable to save the last timestamp (in full seconds) at which the external
+ * links were updated by the 'timeupdate' callback below.
+ *
+ * It is initialized to 5s so that the video will always restart from the beginning
+ * if the user hasn't really started watching before switching to the other website.
+ */
+var timeupdate_last_ts = 5;
+
+/**
+ * Callback that updates the timestamp on all external links
+ */
+player.on('timeupdate', function () {
+ // Only update once every second
+ let current_ts = Math.floor(player.currentTime());
+ if (current_ts > timeupdate_last_ts) timeupdate_last_ts = current_ts;
+ else return;
+
+ // YouTube links
+
+ let elem_yt_watch = document.getElementById('link-yt-watch');
+ let elem_yt_embed = document.getElementById('link-yt-embed');
+
+ let base_url_yt_watch = elem_yt_watch.getAttribute('data-base-url');
+ let base_url_yt_embed = elem_yt_embed.getAttribute('data-base-url');
+
+ elem_yt_watch.href = addCurrentTimeToURL(base_url_yt_watch);
+ elem_yt_embed.href = addCurrentTimeToURL(base_url_yt_embed);
+
+ // Invidious links
+
+ let domain = window.location.origin;
+
+ let elem_iv_embed = document.getElementById('link-iv-embed');
+ let elem_iv_other = document.getElementById('link-iv-other');
+
+ let base_url_iv_embed = elem_iv_embed.getAttribute('data-base-url');
+ let base_url_iv_other = elem_iv_other.getAttribute('data-base-url');
+
+ elem_iv_embed.href = addCurrentTimeToURL(base_url_iv_embed, domain);
+ elem_iv_other.href = addCurrentTimeToURL(base_url_iv_other, domain);
+});
+
+
var shareOptions = {
socials: ['fbFeed', 'tw', 'reddit', 'email'],
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 761bbdca..c9644ca6 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -1,4 +1,5 @@
-FROM crystallang/crystal:1.4.1-alpine AS builder
+FROM crystallang/crystal:1.8.2-alpine AS builder
+
RUN apk add --no-cache sqlite-static yaml-static
ARG release
@@ -19,8 +20,7 @@ COPY ./assets/ ./assets/
COPY ./videojs-dependencies.yml ./videojs-dependencies.yml
RUN crystal spec --warnings all \
- --link-flags "-lxml2 -llzma"
-
+ --link-flags "-lxml2 -llzma"
RUN if [[ "${release}" == 1 ]] ; then \
crystal build ./src/invidious.cr \
--release \
@@ -32,8 +32,7 @@ RUN if [[ "${release}" == 1 ]] ; then \
--link-flags "-lxml2 -llzma"; \
fi
-
-FROM alpine:3.16
+FROM alpine:3.18
RUN apk add --no-cache librsvg ttf-opensans tini
WORKDIR /invidious
RUN addgroup -g 1000 -S invidious && \
diff --git a/docker/Dockerfile.arm64 b/docker/Dockerfile.arm64
index cf9231fb..d9a4eeaf 100644
--- a/docker/Dockerfile.arm64
+++ b/docker/Dockerfile.arm64
@@ -1,5 +1,5 @@
-FROM alpine:3.16 AS builder
-RUN apk add --no-cache 'crystal=1.4.1-r0' shards sqlite-static yaml-static yaml-dev libxml2-dev zlib-static openssl-libs-static openssl-dev musl-dev
+FROM alpine:3.18 AS builder
+RUN apk add --no-cache 'crystal=1.8.2-r0' shards sqlite-static yaml-static yaml-dev libxml2-static zlib-static openssl-libs-static openssl-dev musl-dev xz-static
ARG release
@@ -32,7 +32,7 @@ RUN if [[ "${release}" == 1 ]] ; then \
--link-flags "-lxml2 -llzma"; \
fi
-FROM alpine:3.16
+FROM alpine:3.18
RUN apk add --no-cache librsvg ttf-opensans tini
WORKDIR /invidious
RUN addgroup -g 1000 -S invidious && \
diff --git a/kubernetes/Chart.lock b/kubernetes/Chart.lock
index cc76e920..ef12b0b6 100644
--- a/kubernetes/Chart.lock
+++ b/kubernetes/Chart.lock
@@ -1,6 +1,6 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami/
- version: 12.1.9
-digest: sha256:71ff342a6c0a98bece3d7fe199983afb2113f8db65a3e3819de875af2c45add7
-generated: "2023-01-20T20:42:32.757707004Z"
+ version: 12.11.1
+digest: sha256:3c10008175c4f5c1cec38782f5a7316154b89074c77ebbd9bcc4be4f5ff21122
+generated: "2023-09-14T22:40:43.171275362Z"
diff --git a/kubernetes/Chart.yaml b/kubernetes/Chart.yaml
index 4e4295ba..d22f6254 100644
--- a/kubernetes/Chart.yaml
+++ b/kubernetes/Chart.yaml
@@ -17,6 +17,6 @@ maintainers:
email: mail@leonklingele.de
dependencies:
- name: postgresql
- version: ~12.1.6
+ version: ~12.11.0
repository: "https://charts.bitnami.com/bitnami/"
engine: gotpl
diff --git a/src/invidious/jsonify/api_v1/video_json.cr b/src/invidious/jsonify/api_v1/video_json.cr
index fe4b5223..1651559a 100644
--- a/src/invidious/jsonify/api_v1/video_json.cr
+++ b/src/invidious/jsonify/api_v1/video_json.cr
@@ -39,6 +39,7 @@ module Invidious::JSONify::APIv1
json.field "author", video.author
json.field "authorId", video.ucid
json.field "authorUrl", "/channel/#{video.ucid}"
+ json.field "authorVerified", video.author_verified
json.field "authorThumbnails" do
json.array do
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
index e5cf3716..3d935f0a 100644
--- a/src/invidious/routes/watch.cr
+++ b/src/invidious/routes/watch.cr
@@ -30,14 +30,6 @@ module Invidious::Routes::Watch
return env.redirect "/"
end
- embed_link = "/embed/#{id}"
- if env.params.query.size > 1
- embed_params = HTTP::Params.parse(env.params.query.to_s)
- embed_params.delete_all("v")
- embed_link += "?"
- embed_link += embed_params.to_s
- end
-
plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
continuation = process_continuation(env.params.query, plid, id)
diff --git a/src/invidious/user/imports.cr b/src/invidious/user/imports.cr
index 86d0ce6e..0d21bc44 100644
--- a/src/invidious/user/imports.cr
+++ b/src/invidious/user/imports.cr
@@ -228,8 +228,12 @@ struct Invidious::User
subs = matches.map(&.["channel_id"])
if subs.empty?
- data = JSON.parse(body)["subscriptions"]
- subs = data.as_a.map(&.["id"].as_s)
+ profiles = body.split('\n', remove_empty: true)
+ profiles.each do |profile|
+ if data = JSON.parse(profile)["subscriptions"]?
+ subs += data.as_a.map(&.["id"].as_s)
+ end
+ end
end
user.subscriptions += subs
diff --git a/src/invidious/videos/parser.cr b/src/invidious/videos/parser.cr
index 06ff96b1..551ce2cb 100644
--- a/src/invidious/videos/parser.cr
+++ b/src/invidious/videos/parser.cr
@@ -137,9 +137,8 @@ end
def try_fetch_streaming_data(id : String, client_config : YoutubeAPI::ClientConfig) : Hash(String, JSON::Any)?
LOGGER.debug("try_fetch_streaming_data: [#{id}] Using #{client_config.client_type} client.")
- # CgIQBg is a workaround for streaming URLs that returns a 403.
- # See https://github.com/iv-org/invidious/issues/4027#issuecomment-1666944520
- response = YoutubeAPI.player(video_id: id, params: "CgIQBg", client_config: client_config)
+ # 2AMBCgIQBg is a workaround for streaming URLs that returns a 403.
+ response = YoutubeAPI.player(video_id: id, params: "2AMBCgIQBg", client_config: client_config)
playability_status = response["playabilityStatus"]["status"]
LOGGER.debug("try_fetch_streaming_data: [#{id}] Got playabilityStatus == #{playability_status}.")
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index 62a154a4..07474896 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -113,19 +113,36 @@ we're going to need to do it here in order to allow for translations.
<div class="pure-u-1 pure-u-lg-1-5">
<div class="h-box">
<span id="watch-on-youtube">
- <a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "videoinfo_watch_on_youTube") %></a>
- (<a href="https://www.youtube.com/embed/<%= video.id %>"><%= translate(locale, "videoinfo_youTube_embed_link") %></a>)
+ <%-
+ link_yt_watch = URI.new(scheme: "https", host: "www.youtube.com", path: "/watch", query: "v=#{video.id}")
+ link_yt_embed = URI.new(scheme: "https", host: "www.youtube.com", path: "/embed/#{video.id}")
+
+ if !plid.nil? && !continuation.nil?
+ link_yt_param = URI::Params{"plid" => [plid], "index" => [continuation.to_s]}
+ link_yt_watch = IV::HttpServer::Utils.add_params_to_url(link_yt_watch, link_yt_param)
+ link_yt_embed = IV::HttpServer::Utils.add_params_to_url(link_yt_embed, link_yt_param)
+ end
+ -%>
+ <a id="link-yt-watch" data-base-url="<%= link_yt_watch %>" href="<%= link_yt_watch %>"><%= translate(locale, "videoinfo_watch_on_youTube") %></a>
+ (<a id="link-yt-embed" data-base-url="<%= link_yt_embed %>" href="<%= link_yt_embed %>"><%= translate(locale, "videoinfo_youTube_embed_link") %></a>)
</span>
+
<p id="watch-on-another-invidious-instance">
- <% if env.get("preferences").as(Preferences).automatic_instance_redirect%>
- <a href="/redirect?referer=<%= env.get?("current_page") %>"><%= translate(locale, "Switch Invidious Instance") %></a>
- <% else %>
- <a href="https://redirect.invidious.io<%= env.request.resource %>"><%= translate(locale, "Switch Invidious Instance") %></a>
- <% end %>
+ <%- link_iv_other = IV::Frontend::Misc.redirect_url(env) -%>
+ <a id="link-iv-other" data-base-url="<%= link_iv_other %>" href="<%= link_iv_other %>"><%= translate(locale, "Switch Invidious Instance") %></a>
</p>
+
<p id="embed-link">
- <a href="<%= embed_link %>"><%= translate(locale, "videoinfo_invidious_embed_link") %></a>
+ <%-
+ params_iv_embed = env.params.query.dup
+ params_iv_embed.delete_all("v")
+
+ link_iv_embed = URI.new(path: "/embed/#{id}")
+ link_iv_embed = IV::HttpServer::Utils.add_params_to_url(link_iv_embed, params_iv_embed)
+ -%>
+ <a id="link-iv-embed" data-base-url="<%= link_iv_embed %>" href="<%= link_iv_embed %>"><%= translate(locale, "videoinfo_invidious_embed_link") %></a>
</p>
+
<p id="annotations">
<% if params.annotations %>
<a href="/watch?<%= env.params.query %>&iv_load_policy=3">