diff --git a/src/invidious.cr b/src/invidious.cr
index dc61c105..383a12d7 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -390,6 +390,7 @@ get "/embed/:id" do |env|
end
# Playlists
+
get "/playlist" do |env|
plid = env.params.query["list"]?
if !plid
@@ -415,6 +416,25 @@ get "/playlist" do |env|
templated "playlist"
end
+get "/mix" do |env|
+ rdid = env.params.query["list"]?
+ if !rdid
+ next env.redirect "/"
+ end
+
+ continuation = env.params.query["continuation"]?
+ continuation ||= rdid.lchop("RD")
+
+ begin
+ mix = fetch_mix(rdid, continuation)
+ rescue ex
+ error_message = ex.message
+ next templated "error"
+ end
+
+ templated "mix"
+end
+
# Search
get "/results" do |env|
@@ -2166,12 +2186,13 @@ get "/api/v1/insights/:id" do |env|
end
get "/api/v1/videos/:id" do |env|
+ env.response.content_type = "application/json"
+
id = env.params.url["id"]
begin
video = get_video(id, PG_DB, proxies)
rescue ex
- env.response.content_type = "application/json"
error_message = {"error" => ex.message}.to_json
halt env, status_code: 500, response: error_message
end
@@ -2181,7 +2202,6 @@ get "/api/v1/videos/:id" do |env|
captions = video.captions
- env.response.content_type = "application/json"
video_info = JSON.build do |json|
json.object do
json.field "title", video.title
@@ -2945,6 +2965,55 @@ get "/api/v1/playlists/:plid" do |env|
response
end
+get "/api/v1/mixes/:rdid" do |env|
+ env.response.content_type = "application/json"
+
+ rdid = env.params.url["rdid"]
+
+ continuation = env.params.query["continuation"]?
+ continuation ||= rdid.lchop("RD")
+
+ begin
+ mix = fetch_mix(rdid, continuation)
+ rescue ex
+ error_message = {"error" => ex.message}.to_json
+ halt env, status_code: 500, response: error_message
+ end
+
+ response = JSON.build do |json|
+ json.object do
+ json.field "title", mix.title
+ json.field "mixId", mix.id
+
+ json.field "videos" do
+ json.array do
+ mix.videos.each do |video|
+ json.object do
+ json.field "title", video.title
+ json.field "videoId", video.id
+ json.field "author", video.author
+
+ json.field "authorId", video.ucid
+ json.field "authorUrl", "/channel/#{video.ucid}"
+
+ json.field "videoThumbnails" do
+ json.array do
+ generate_thumbnails(json, video.id)
+ end
+ end
+
+ json.field "index", video.index
+ json.field "lengthSeconds", video.length_seconds
+ end
+ end
+ end
+ end
+ end
+ end
+
+ response
+end
+
get "/api/manifest/dash/id/videoplayback" do |env|
env.response.headers["Access-Control-Allow-Origin"] = "*"
env.redirect "/videoplayback?#{env.params.query}"
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 906d9fa5..ab33c3af 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -244,11 +244,22 @@ def extract_items(nodeset, ucid = nil)
plid = HTTP::Params.parse(URI.parse(id).query.not_nil!)["list"]
anchor = node.xpath_node(%q(.//div[contains(@class, "yt-lockup-meta")]/a))
+
if !anchor
anchor = node.xpath_node(%q(.//ul[@class="yt-lockup-meta-info"]/li/a))
end
- if anchor
- video_count = anchor.content.match(/View full playlist \((? <%= number_with_separator(item.subscriber_count) %> subscribers<%= item.description_html %>
<% when SearchPlaylist %>
-
+ <% if item.id.starts_with? "RD" %>
+ <% url = "/mix?list=#{item.id}&continuation=#{item.videos[0]?.try &.id}" %>
+ <% else %>
+ <% url = "/playlist?list=#{item.id}" %>
+ <% end %>
+
<% if env.get?("user") && env.get("user").as(User).preferences.thin_mode %>
<% else %>
@@ -26,6 +31,17 @@
<%= number_with_separator(item.video_count) %> videos
PLAYLIST
+ <% when MixVideo %> + + <% if env.get?("user") && env.get("user").as(User).preferences.thin_mode %> + <% else %> + + <% end %> +<%= item.title %>
+ + <% else %> <% if item.responds_to?(:playlists) && !item.playlists.empty? %> <% params = "&list=#{item.playlists[0]}" %> diff --git a/src/invidious/views/mix.ecr b/src/invidious/views/mix.ecr new file mode 100644 index 00000000..139e01b9 --- /dev/null +++ b/src/invidious/views/mix.ecr @@ -0,0 +1,22 @@ +<% content_for "header" do %> +