summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOmar Roth <omarroth@protonmail.com>2019-05-01 07:14:10 -0500
committerGitHub <noreply@github.com>2019-05-01 07:14:10 -0500
commitba02be08bb9c19e6c41c6c7764bd8377ee7f4435 (patch)
tree6329f9d272a96eedfa1c1342bf4d3e404b8c4bfb /src
parent6d1c150ff5fbc0f69d29f05a6067b7d29378fb80 (diff)
parent56fe3ede5b4639ce7e3c2a17fdce7e66bc0e8f3a (diff)
downloadinvidious-ba02be08bb9c19e6c41c6c7764bd8377ee7f4435.tar.gz
invidious-ba02be08bb9c19e6c41c6c7764bd8377ee7f4435.tar.bz2
invidious-ba02be08bb9c19e6c41c6c7764bd8377ee7f4435.zip
Merge pull request #303 from glmdgrielson/annotations
Add annotation player
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr108
-rw-r--r--src/invidious/helpers/helpers.cr44
-rw-r--r--src/invidious/users.cr44
-rw-r--r--src/invidious/videos.cr61
-rw-r--r--src/invidious/views/components/player.ecr79
-rw-r--r--src/invidious/views/components/player_sources.ecr5
-rw-r--r--src/invidious/views/embed.ecr20
-rw-r--r--src/invidious/views/preferences.ecr10
-rw-r--r--src/invidious/views/watch.ecr53
9 files changed, 276 insertions, 148 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 98c18b55..dc6ba734 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -338,8 +338,8 @@ get "/watch" do |env|
preferences = env.get("preferences").as(Preferences)
- if env.get? "user"
- user = env.get("user").as(User)
+ user = env.get?("user").try &.as(User)
+ if user
subscriptions = user.subscriptions
watched = user.watched
end
@@ -347,9 +347,10 @@ get "/watch" do |env|
params = process_video_params(env.params.query, preferences)
env.params.query.delete_all("listen")
+ env.params.query.delete_all("iv_load_policy")
begin
- video = get_video(id, PG_DB, proxies, region: params[:region])
+ video = get_video(id, PG_DB, proxies, region: params.region)
rescue ex : VideoRedirect
next env.redirect "/watch?v=#{ex.message}"
rescue ex
@@ -358,6 +359,10 @@ get "/watch" do |env|
next templated "error"
end
+ if preferences.annotations_subscribed && subscriptions.includes? video.ucid
+ params.annotations = true
+ end
+
if watched && !watched.includes? id
PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.as(User).email)
end
@@ -404,7 +409,7 @@ get "/watch" do |env|
fmt_stream = video.fmt_stream(decrypt_function)
adaptive_fmts = video.adaptive_fmts(decrypt_function)
- if params[:local]
+ if params.local
fmt_stream.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
adaptive_fmts.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
end
@@ -415,12 +420,12 @@ get "/watch" do |env|
captions = video.captions
preferred_captions = captions.select { |caption|
- params[:preferred_captions].includes?(caption.name.simpleText) ||
- params[:preferred_captions].includes?(caption.languageCode.split("-")[0])
+ params.preferred_captions.includes?(caption.name.simpleText) ||
+ params.preferred_captions.includes?(caption.languageCode.split("-")[0])
}
preferred_captions.sort_by! { |caption|
- (params[:preferred_captions].index(caption.name.simpleText) ||
- params[:preferred_captions].index(caption.languageCode.split("-")[0])).not_nil!
+ (params.preferred_captions.index(caption.name.simpleText) ||
+ params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
}
captions = captions - preferred_captions
@@ -441,11 +446,11 @@ get "/watch" do |env|
thumbnail = "/vi/#{video.id}/maxres.jpg"
- if params[:raw]
+ if params.raw
url = fmt_stream[0]["url"]
fmt_stream.each do |fmt|
- if fmt["label"].split(" - ")[0] == params[:quality]
+ if fmt["label"].split(" - ")[0] == params.quality
url = fmt["url"]
end
end
@@ -533,8 +538,15 @@ get "/embed/:id" do |env|
params = process_video_params(env.params.query, preferences)
+ user = env.get?("user").try &.as(User)
+ if user
+ subscriptions = user.subscriptions
+ watched = user.watched
+ end
+ subscriptions ||= [] of String
+
begin
- video = get_video(id, PG_DB, proxies, region: params[:region])
+ video = get_video(id, PG_DB, proxies, region: params.region)
rescue ex : VideoRedirect
next env.redirect "/embed/#{ex.message}"
rescue ex
@@ -542,10 +554,18 @@ get "/embed/:id" do |env|
next templated "error"
end
+ if preferences.annotations_subscribed && subscriptions.includes? video.ucid
+ params.annotations = true
+ end
+
+ if watched && !watched.includes? id
+ PG_DB.exec("UPDATE users SET watched = watched || $1 WHERE email = $2", [id], user.as(User).email)
+ end
+
fmt_stream = video.fmt_stream(decrypt_function)
adaptive_fmts = video.adaptive_fmts(decrypt_function)
- if params[:local]
+ if params.local
fmt_stream.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
adaptive_fmts.each { |fmt| fmt["url"] = URI.parse(fmt["url"]).full_path }
end
@@ -556,12 +576,12 @@ get "/embed/:id" do |env|
captions = video.captions
preferred_captions = captions.select { |caption|
- params[:preferred_captions].includes?(caption.name.simpleText) ||
- params[:preferred_captions].includes?(caption.languageCode.split("-")[0])
+ params.preferred_captions.includes?(caption.name.simpleText) ||
+ params.preferred_captions.includes?(caption.languageCode.split("-")[0])
}
preferred_captions.sort_by! { |caption|
- (params[:preferred_captions].index(caption.name.simpleText) ||
- params[:preferred_captions].index(caption.languageCode.split("-")[0])).not_nil!
+ (params.preferred_captions.index(caption.name.simpleText) ||
+ params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
}
captions = captions - preferred_captions
@@ -582,11 +602,11 @@ get "/embed/:id" do |env|
thumbnail = "/vi/#{video.id}/maxres.jpg"
- if params[:raw]
+ if params.raw
url = fmt_stream[0]["url"]
fmt_stream.each do |fmt|
- if fmt["label"].split(" - ")[0] == params[:quality]
+ if fmt["label"].split(" - ")[0] == params.quality
url = fmt["url"]
end
end
@@ -1236,6 +1256,14 @@ post "/preferences" do |env|
video_loop ||= "off"
video_loop = video_loop == "on"
+ annotations = env.params.body["annotations"]?.try &.as(String)
+ annotations ||= "off"
+ annotations = annotations == "on"
+
+ annotations_subscribed = env.params.body["annotations_subscribed"]?.try &.as(String)
+ annotations_subscribed ||= "off"
+ annotations_subscribed = annotations_subscribed == "on"
+
autoplay = env.params.body["autoplay"]?.try &.as(String)
autoplay ||= "off"
autoplay = autoplay == "on"
@@ -1313,27 +1341,29 @@ post "/preferences" do |env|
notifications_only = notifications_only == "on"
preferences = {
- "video_loop" => video_loop,
- "autoplay" => autoplay,
- "continue" => continue,
- "continue_autoplay" => continue_autoplay,
- "listen" => listen,
- "local" => local,
- "speed" => speed,
- "quality" => quality,
- "volume" => volume,
- "comments" => comments,
- "captions" => captions,
- "related_videos" => related_videos,
- "redirect_feed" => redirect_feed,
- "locale" => locale,
- "dark_mode" => dark_mode,
- "thin_mode" => thin_mode,
- "max_results" => max_results,
- "sort" => sort,
- "latest_only" => latest_only,
- "unseen_only" => unseen_only,
- "notifications_only" => notifications_only,
+ "video_loop" => video_loop,
+ "annotations" => annotations,
+ "annotations_subscribed" => annotations_subscribed,
+ "autoplay" => autoplay,
+ "continue" => continue,
+ "continue_autoplay" => continue_autoplay,
+ "listen" => listen,
+ "local" => local,
+ "speed" => speed,
+ "quality" => quality,
+ "volume" => volume,
+ "comments" => comments,
+ "captions" => captions,
+ "related_videos" => related_videos,
+ "redirect_feed" => redirect_feed,
+ "locale" => locale,
+ "dark_mode" => dark_mode,
+ "thin_mode" => thin_mode,
+ "max_results" => max_results,
+ "sort" => sort,
+ "latest_only" => latest_only,
+ "unseen_only" => unseen_only,
+ "notifications_only" => notifications_only,
}.to_json
if user = env.get? "user"
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index d1bda9f0..becf54b4 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -59,27 +59,29 @@ struct ConfigPreferences
end
yaml_mapping({
- autoplay: {type: Bool, default: false},
- captions: {type: Array(String), default: ["", "", ""], converter: StringToArray},
- comments: {type: Array(String), default: ["youtube", ""], converter: StringToArray},
- continue: {type: Bool, default: false},
- continue_autoplay: {type: Bool, default: true},
- dark_mode: {type: Bool, default: false},
- latest_only: {type: Bool, default: false},
- listen: {type: Bool, default: false},
- local: {type: Bool, default: false},
- locale: {type: String, default: "en-US"},
- max_results: {type: Int32, default: 40},
- notifications_only: {type: Bool, default: false},
- quality: {type: String, default: "hd720"},
- redirect_feed: {type: Bool, default: false},
- related_videos: {type: Bool, default: true},
- sort: {type: String, default: "published"},
- speed: {type: Float32, default: 1.0_f32},
- thin_mode: {type: Bool, default: false},
- unseen_only: {type: Bool, default: false},
- video_loop: {type: Bool, default: false},
- volume: {type: Int32, default: 100},
+ annotations: {type: Bool, default: false},
+ annotations_subscribed: {type: Bool, default: false},
+ autoplay: {type: Bool, default: false},
+ captions: {type: Array(String), default: ["", "", ""], converter: StringToArray},
+ comments: {type: Array(String), default: ["youtube", ""], converter: StringToArray},
+ continue: {type: Bool, default: false},
+ continue_autoplay: {type: Bool, default: true},
+ dark_mode: {type: Bool, default: false},
+ latest_only: {type: Bool, default: false},
+ listen: {type: Bool, default: false},
+ local: {type: Bool, default: false},
+ locale: {type: String, default: "en-US"},
+ max_results: {type: Int32, default: 40},
+ notifications_only: {type: Bool, default: false},
+ quality: {type: String, default: "hd720"},
+ redirect_feed: {type: Bool, default: false},
+ related_videos: {type: Bool, default: true},
+ sort: {type: String, default: "published"},
+ speed: {type: Float32, default: 1.0_f32},
+ thin_mode: {type: Bool, default: false},
+ unseen_only: {type: Bool, default: false},
+ video_loop: {type: Bool, default: false},
+ volume: {type: Int32, default: 100},
})
end
diff --git a/src/invidious/users.cr b/src/invidious/users.cr
index 2e9ec1e5..d452b9f2 100644
--- a/src/invidious/users.cr
+++ b/src/invidious/users.cr
@@ -84,27 +84,29 @@ struct Preferences
end
json_mapping({
- autoplay: {type: Bool, default: CONFIG.default_user_preferences.autoplay},
- captions: {type: Array(String), default: CONFIG.default_user_preferences.captions, converter: StringToArray},
- comments: {type: Array(String), default: CONFIG.default_user_preferences.comments, converter: StringToArray},
- continue: {type: Bool, default: CONFIG.default_user_preferences.continue},
- continue_autoplay: {type: Bool, default: CONFIG.default_user_preferences.continue_autoplay},
- dark_mode: {type: Bool, default: CONFIG.default_user_preferences.dark_mode},
- latest_only: {type: Bool, default: CONFIG.default_user_preferences.latest_only},
- listen: {type: Bool, default: CONFIG.default_user_preferences.listen},
- local: {type: Bool, default: CONFIG.default_user_preferences.local},
- locale: {type: String, default: CONFIG.default_user_preferences.locale},
- max_results: {type: Int32, default: CONFIG.default_user_preferences.max_results},
- notifications_only: {type: Bool, default: CONFIG.default_user_preferences.notifications_only},
- quality: {type: String, default: CONFIG.default_user_preferences.quality},
- redirect_feed: {type: Bool, default: CONFIG.default_user_preferences.redirect_feed},
- related_videos: {type: Bool, default: CONFIG.default_user_preferences.related_videos},
- sort: {type: String, default: CONFIG.default_user_preferences.sort},
- speed: {type: Float32, default: CONFIG.default_user_preferences.speed},
- thin_mode: {type: Bool, default: CONFIG.default_user_preferences.thin_mode},
- unseen_only: {type: Bool, default: CONFIG.default_user_preferences.unseen_only},
- video_loop: {type: Bool, default: CONFIG.default_user_preferences.video_loop},
- volume: {type: Int32, default: CONFIG.default_user_preferences.volume},
+ annotations: {type: Bool, default: CONFIG.default_user_preferences.annotations},
+ annotations_subscribed: {type: Bool, default: CONFIG.default_user_preferences.annotations_subscribed},
+ autoplay: {type: Bool, default: CONFIG.default_user_preferences.autoplay},
+ captions: {type: Array(String), default: CONFIG.default_user_preferences.captions, converter: StringToArray},
+ comments: {type: Array(String), default: CONFIG.default_user_preferences.comments, converter: StringToArray},
+ continue: {type: Bool, default: CONFIG.default_user_preferences.continue},
+ continue_autoplay: {type: Bool, default: CONFIG.default_user_preferences.continue_autoplay},
+ dark_mode: {type: Bool, default: CONFIG.default_user_preferences.dark_mode},
+ latest_only: {type: Bool, default: CONFIG.default_user_preferences.latest_only},
+ listen: {type: Bool, default: CONFIG.default_user_preferences.listen},
+ local: {type: Bool, default: CONFIG.default_user_preferences.local},
+ locale: {type: String, default: CONFIG.default_user_preferences.locale},
+ max_results: {type: Int32, default: CONFIG.default_user_preferences.max_results},
+ notifications_only: {type: Bool, default: CONFIG.default_user_preferences.notifications_only},
+ quality: {type: String, default: CONFIG.default_user_preferences.quality},
+ redirect_feed: {type: Bool, default: CONFIG.default_user_preferences.redirect_feed},
+ related_videos: {type: Bool, default: CONFIG.default_user_preferences.related_videos},
+ sort: {type: String, default: CONFIG.default_user_preferences.sort},
+ speed: {type: Float32, default: CONFIG.default_user_preferences.speed},
+ thin_mode: {type: Bool, default: CONFIG.default_user_preferences.thin_mode},
+ unseen_only: {type: Bool, default: CONFIG.default_user_preferences.unseen_only},
+ video_loop: {type: Bool, default: CONFIG.default_user_preferences.video_loop},
+ volume: {type: Int32, default: CONFIG.default_user_preferences.volume},
})
end
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index 643b7654..755ee4d7 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -241,6 +241,28 @@ VIDEO_FORMATS = {
"251" => {"ext" => "webm", "format" => "DASH audio", "acodec" => "opus", "abr" => 160},
}
+struct VideoPreferences
+ json_mapping({
+ annotations: Bool,
+ autoplay: Bool,
+ continue: Bool,
+ continue_autoplay: Bool,
+ controls: Bool,
+ listen: Bool,
+ local: Bool,
+ preferred_captions: Array(String),
+ quality: String,
+ raw: Bool,
+ region: String?,
+ related_videos: Bool,
+ speed: (Float32 | Float64),
+ video_end: (Float64 | Int32),
+ video_loop: Bool,
+ video_start: (Float64 | Int32),
+ volume: Int32,
+ })
+end
+
struct Video
property player_json : JSON::Any?
@@ -1199,6 +1221,7 @@ def itag_to_metadata?(itag : String)
end
def process_video_params(query, preferences)
+ annotations = query["iv_load_policy"]?.try &.to_i?
autoplay = query["autoplay"]?.try &.to_i?
continue = query["continue"]?.try &.to_i?
continue_autoplay = query["continue_autoplay"]?.try &.to_i?
@@ -1214,6 +1237,7 @@ def process_video_params(query, preferences)
if preferences
# region ||= preferences.region
+ annotations ||= preferences.annotations.to_unsafe
autoplay ||= preferences.autoplay.to_unsafe
continue ||= preferences.continue.to_unsafe
continue_autoplay ||= preferences.continue_autoplay.to_unsafe
@@ -1227,6 +1251,7 @@ def process_video_params(query, preferences)
volume ||= preferences.volume
end
+ annotations ||= CONFIG.default_user_preferences.annotations.to_unsafe
autoplay ||= CONFIG.default_user_preferences.autoplay.to_unsafe
continue ||= CONFIG.default_user_preferences.continue.to_unsafe
continue_autoplay ||= CONFIG.default_user_preferences.continue_autoplay.to_unsafe
@@ -1239,6 +1264,7 @@ def process_video_params(query, preferences)
video_loop ||= CONFIG.default_user_preferences.video_loop.to_unsafe
volume ||= CONFIG.default_user_preferences.volume
+ annotations = annotations == 1
autoplay = autoplay == 1
continue = continue == 1
continue_autoplay = continue_autoplay == 1
@@ -1272,24 +1298,25 @@ def process_video_params(query, preferences)
controls ||= 1
controls = controls >= 1
- params = {
- autoplay: autoplay,
- continue: continue,
- continue_autoplay: continue_autoplay,
- controls: controls,
- listen: listen,
- local: local,
+ params = VideoPreferences.new(
+ annotations: annotations,
+ autoplay: autoplay,
+ continue: continue,
+ continue_autoplay: continue_autoplay,
+ controls: controls,
+ listen: listen,
+ local: local,
preferred_captions: preferred_captions,
- quality: quality,
- raw: raw,
- region: region,
- related_videos: related_videos,
- speed: speed,
- video_end: video_end,
- video_loop: video_loop,
- video_start: video_start,
- volume: volume,
- }
+ quality: quality,
+ raw: raw,
+ region: region,
+ related_videos: related_videos,
+ speed: speed,
+ video_end: video_end,
+ video_loop: video_loop,
+ video_start: video_start,
+ volume: volume,
+ )
return params
end
diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr
index 3ab44899..eecaf160 100644
--- a/src/invidious/views/components/player.ecr
+++ b/src/invidious/views/components/player.ecr
@@ -3,26 +3,26 @@
onmouseenter='this["data-title"]=this["title"];this["title"]=""'
onmouseleave='this["title"]=this["data-title"];this["data-title"]=""'
oncontextmenu='this["title"]=this["data-title"]'
- <% if params[:autoplay] %>autoplay<% end %>
- <% if params[:video_loop] %>loop<% end %>
- <% if params[:controls] %>controls<% end %>>
+ <% if params.autoplay %>autoplay<% end %>
+ <% if params.video_loop %>loop<% end %>
+ <% if params.controls %>controls<% end %>>
<% if hlsvp %>
<source src="<%= hlsvp %>?local=true" type="application/x-mpegURL" label="livestream">
<% else %>
- <% if params[:listen] %>
+ <% if params.listen %>
<% audio_streams.each_with_index do |fmt, i| %>
- <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params[:local] %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["bitrate"] %>k" selected="<%= i == 0 ? true : false %>">
+ <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["bitrate"] %>k" selected="<%= i == 0 ? true : false %>">
<% end %>
<% else %>
- <% if params[:quality] == "dash" %>
+ <% if params.quality == "dash" %>
<source src="/api/manifest/dash/id/<%= video.id %>?local=true" type='application/dash+xml' label="dash">
<% end %>
<% fmt_stream.each_with_index do |fmt, i| %>
- <% if params[:quality] %>
- <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params[:local] %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= params[:quality] == fmt["label"].split(" - ")[0] %>">
+ <% if params.quality %>
+ <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= params.quality == fmt["label"].split(" - ")[0] %>">
<% else %>
- <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params[:local] %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= i == 0 ? true : false %>">
+ <source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= i == 0 ? true : false %>">
<% end %>
<% end %>
<% end %>
@@ -161,7 +161,7 @@ player.on('error', function(event) {
}
});
-<% if params[:video_start] > 0 || params[:video_end] > 0 %>
+<% if params.video_start > 0 || params.video_end > 0 %>
player.markers({
onMarkerReached: function(marker) {
if (marker.text === "End") {
@@ -173,22 +173,22 @@ player.markers({
}
},
markers: [
- { time: <%= params[:video_start] %>, text: "Start" },
- <% if params[:video_end] < 0 %>
+ { time: <%= params.video_start %>, text: "Start" },
+ <% if params.video_end < 0 %>
{ time: <%= video.info["length_seconds"].to_f - 0.5 %>, text: "End" }
<% else %>
- { time: <%= params[:video_end] %>, text: "End" }
+ { time: <%= params.video_end %>, text: "End" }
<% end %>
]
});
-player.currentTime(<%= params[:video_start] %>);
+player.currentTime(<%= params.video_start %>);
<% end %>
-player.volume(<%= params[:volume].to_f / 100 %>);
-player.playbackRate(<%= params[:speed] %>);
+player.volume(<%= params.volume.to_f / 100 %>);
+player.playbackRate(<%= params.speed %>);
-<% if params[:autoplay] %>
+<% if params.autoplay %>
var bpb = player.getChild('bigPlayButton');
if (bpb) {
@@ -211,7 +211,52 @@ if (bpb) {
}
<% end %>
+<% if !params.listen && params.quality == "dash" %>
player.httpSourceSelector();
+<% end %>
+
+<% if !params.listen && params.annotations %>
+var video_container = document.getElementById("player");
+let xhr = new XMLHttpRequest();
+xhr.responseType = "text";
+xhr.timeout = 60000;
+xhr.open("GET", "/api/v1/annotations/<%= video.id %>", true);
+xhr.send();
+
+xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ videojs.registerPlugin("youtubeAnnotationsPlugin", youtubeAnnotationsPlugin);
+ if (!player.paused()) {
+ player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
+ } else {
+ player.one('play', function(event) {
+ player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
+ });
+ }
+ }
+ }
+};
+
+window.addEventListener("__ar_annotation_click", e => {
+ const { url, target, seconds } = e.detail;
+
+ var path = new URL(url);
+
+ if (path.href.startsWith("https://www.youtube.com/watch?") && seconds) {
+ path.search += "&t=" + seconds;
+ }
+
+ path = path.pathname + path.search;
+
+ if (target === "current") {
+ window.location.href = path;
+ }
+ else if (target === "new") {
+ window.open(path, "_blank");
+ }
+});
+<% end %>
// Since videojs-share can sometimes be blocked, we try to load it last
player.share(shareOptions);
diff --git a/src/invidious/views/components/player_sources.ecr b/src/invidious/views/components/player_sources.ecr
index 37fac6b1..d4e1c2f7 100644
--- a/src/invidious/views/components/player_sources.ecr
+++ b/src/invidious/views/components/player_sources.ecr
@@ -2,14 +2,15 @@
<link rel="stylesheet" href="/css/videojs-http-source-selector.css">
<link rel="stylesheet" href="/css/videojs.markers.min.css">
<link rel="stylesheet" href="/css/videojs-share.css">
+<link rel="stylesheet" href="/css/videojs-youtube-annotations.css">
<script src="/js/video.min.js"></script>
<script src="/js/videojs-contrib-quality-levels.min.js"></script>
<script src="/js/videojs-http-source-selector.min.js"></script>
<script src="/js/videojs.hotkeys.min.js"></script>
<script src="/js/videojs-markers.min.js"></script>
<script src="/js/videojs-share.min.js"></script>
-
-<% if params[:quality] != "dash" %>
+<script src="/js/videojs-youtube-annotations.js"></script>
+<% if params.listen || params.quality != "dash" %>
<link rel="stylesheet" href="/css/quality-selector.css">
<script src="/js/silvermine-videojs-quality-selector.min.js"></script>
<% end %> \ No newline at end of file
diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr
index 93078cdd..51097df1 100644
--- a/src/invidious/views/embed.ecr
+++ b/src/invidious/views/embed.ecr
@@ -55,14 +55,14 @@ function get_playlist(timeouts = 0) {
location.assign("/embed/"
+ xhr.response.nextVideo
+ "?list=<%= plid %>"
- <% if params[:listen] != preferences.listen %>
- + "&listen=<%= params[:listen] %>"
+ <% if params.listen != preferences.listen %>
+ + "&listen=<%= params.listen %>"
<% end %>
- <% if params[:autoplay] || params[:continue_autoplay] %>
+ <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1"
<% end %>
- <% if params[:speed] != preferences.speed %>
- + "&speed=<%= params[:speed] %>"
+ <% if params.speed != preferences.speed %>
+ + "&speed=<%= params.speed %>"
<% end %>
);
});
@@ -85,14 +85,14 @@ player.on('ended', function() {
<% if !video_series.empty? %>
+ "?playlist=<%= video_series.join(",") %>"
<% end %>
- <% if params[:listen] != preferences.listen %>
- + "&listen=<%= params[:listen] %>"
+ <% if params.listen != preferences.listen %>
+ + "&listen=<%= params.listen %>"
<% end %>
- <% if params[:autoplay] || params[:continue_autoplay] %>
+ <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1"
<% end %>
- <% if params[:speed] != preferences.speed %>
- + "&speed=<%= params[:speed] %>"
+ <% if params.speed != preferences.speed %>
+ + "&speed=<%= params.speed %>"
<% end %>
);
});
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index 5d2c35b1..9128c3f5 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -94,6 +94,11 @@ function update_value(element) {
<input name="related_videos" id="related_videos" type="checkbox" <% if preferences.related_videos %>checked<% end %>>
</div>
+ <div class="pure-control-group">
+ <label for="annotations"><%= translate(locale, "Show annotations by default? ") %></label>
+ <input name="annotations" id="annotations" type="checkbox" <% if preferences.annotations %>checked<% end %>>
+ </div>
+
<legend><%= translate(locale, "Visual preferences") %></legend>
<div class="pure-control-group">
@@ -119,6 +124,11 @@ function update_value(element) {
<legend><%= translate(locale, "Subscription preferences") %></legend>
<div class="pure-control-group">
+ <label for="annotations_subscribed"><%= translate(locale, "Show annotations by default for subscribed channels? ") %></label>
+ <input name="annotations_subscribed" id="annotations_subscribed" type="checkbox" <% if preferences.annotations_subscribed %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
<label for="redirect_feed"><%= translate(locale, "Redirect homepage to feed: ") %></label>
<input name="redirect_feed" id="redirect_feed" type="checkbox" <% if preferences.redirect_feed %>checked<% end %>>
</div>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index 476117e2..f74cf594 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -34,7 +34,7 @@
<div class="h-box">
<h1>
<%= HTML.escape(video.title) %>
- <% if params[:listen] %>
+ <% if params.listen %>
<a title="<%=translate(locale, "Video mode")%>" href="/watch?<%= env.params.query %>&listen=0">
<i class="icon ion-ios-videocam"></i>
</a>
@@ -56,6 +56,17 @@
<div class="pure-u-1 pure-u-lg-1-5">
<div class="h-box">
<p><a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch on YouTube") %></a></p>
+ <p>
+ <% if params.annotations %>
+ <a href="/watch?<%= env.params.query %>&iv_load_policy=3">
+ <%= translate(locale, "Hide annotations") %>
+ </a>
+ <% else %>
+ <a href="/watch?<%= env.params.query %>&iv_load_policy=1">
+ <%=translate(locale, "Show annotations")%>
+ </a>
+ <% end %>
+ </p>
<% if CONFIG.dmca_content.includes? video.id %>
<p>Download is disabled.</p>
@@ -122,7 +133,7 @@
</div>
</div>
- <div class="pure-u-1 <% if params[:related_videos] || plid %>pure-u-lg-3-5<% else %>pure-u-md-4-5<% end %>">
+ <div class="pure-u-1 <% if params.related_videos || plid %>pure-u-lg-3-5<% else %>pure-u-md-4-5<% end %>">
<div class="h-box">
<p>
<a href="/channel/<%= video.ucid %>">
@@ -153,21 +164,21 @@
</div>
</div>
</div>
- <% if params[:related_videos] || plid %>
+ <% if params.related_videos || plid %>
<div class="pure-u-1 pure-u-lg-1-5">
<% if plid %>
<div id="playlist" class="h-box">
</div>
<% end %>
- <% if params[:related_videos] %>
+ <% if params.related_videos %>
<div class="h-box">
<% if !rvs.empty? %>
<div <% if plid %>style="display:none"<% end %>>
<div class="pure-control-group">
<label for="continue"><%= translate(locale, "Autoplay next video: ") %></label>
- <input name="continue" onclick="continue_autoplay(this)" id="continue" type="checkbox" <% if params[:continue] %>checked<% end %>>
+ <input name="continue" onclick="continue_autoplay(this)" id="continue" type="checkbox" <% if params.continue %>checked<% end %>>
</div>
<hr>
</div>
@@ -205,19 +216,19 @@
</div>
<script>
-<% if !rvs.empty? && !plid && params[:continue] %>
+<% if !rvs.empty? && !plid && params.continue %>
player.on('ended', function() {
location.assign("/watch?v="
+ "<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>"
+ "&continue=1"
- <% if params[:listen] != preferences.listen %>
- + "&listen=<%= params[:listen] %>"
+ <% if params.listen != preferences.listen %>
+ + "&listen=<%= params.listen %>"
<% end %>
- <% if params[:autoplay] || params[:continue_autoplay] %>
+ <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1"
<% end %>
- <% if params[:speed] != preferences.speed %>
- + "&speed=<%= params[:speed] %>"
+ <% if params.speed != preferences.speed %>
+ + "&speed=<%= params.speed %>"
<% end %>
);
});
@@ -229,14 +240,14 @@ function continue_autoplay(target) {
location.assign("/watch?v="
+ "<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>"
+ "&continue=1"
- <% if params[:listen] != preferences.listen %>
- + "&listen=<%= params[:listen] %>"
+ <% if params.listen != preferences.listen %>
+ + "&listen=<%= params.listen %>"
<% end %>
- <% if params[:autoplay] || params[:continue_autoplay] %>
+ <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1"
<% end %>
- <% if params[:speed] != preferences.speed %>
- + "&speed=<%= params[:speed] %>"
+ <% if params.speed != preferences.speed %>
+ + "&speed=<%= params.speed %>"
<% end %>
);
});
@@ -295,14 +306,14 @@ function get_playlist(timeouts = 0) {
location.assign("/watch?v="
+ xhr.response.nextVideo
+ "&list=<%= plid %>"
- <% if params[:listen] != preferences.listen %>
- + "&listen=<%= params[:listen] %>"
+ <% if params.listen != preferences.listen %>
+ + "&listen=<%= params.listen %>"
<% end %>
- <% if params[:autoplay] || params[:continue_autoplay] %>
+ <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1"
<% end %>
- <% if params[:speed] != preferences.speed %>
- + "&speed=<%= params[:speed] %>"
+ <% if params.speed != preferences.speed %>
+ + "&speed=<%= params.speed %>"
<% end %>
);
});