summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com>2023-11-14 23:35:11 -0500
committerChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com>2023-12-07 09:39:04 -0500
commitb344d98c25185ca4e163eeda128b9fc68ff865b6 (patch)
tree8284d694dcfd1d4a14ecb93dd646e1c94de46685 /src
parent8c22e6a640d458c5447fd8a841a6694f077864e4 (diff)
downloadinvidious-b344d98c25185ca4e163eeda128b9fc68ff865b6.tar.gz
invidious-b344d98c25185ca4e163eeda128b9fc68ff865b6.tar.bz2
invidious-b344d98c25185ca4e163eeda128b9fc68ff865b6.zip
Add API endpoint for Clips
Diffstat (limited to 'src')
-rw-r--r--src/invidious/routes/api/v1/videos.cr43
-rw-r--r--src/invidious/routes/watch.cr16
-rw-r--r--src/invidious/routing.cr1
-rw-r--r--src/invidious/videos/clip.cr20
4 files changed, 67 insertions, 13 deletions
diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr
index 1017ac9d..9281f4dd 100644
--- a/src/invidious/routes/api/v1/videos.cr
+++ b/src/invidious/routes/api/v1/videos.cr
@@ -363,4 +363,47 @@ module Invidious::Routes::API::V1::Videos
end
end
end
+
+ def self.clips(env)
+ locale = env.get("preferences").as(Preferences).locale
+
+ env.response.content_type = "application/json"
+
+ clip_id = env.params.url["id"]
+ region = env.params.query["region"]?
+ proxy = {"1", "true"}.any? &.== env.params.query["local"]?
+
+ response = YoutubeAPI.resolve_url("https://www.youtube.com/clip/#{clip_id}")
+ return error_json(400, "Invalid clip ID") if response["error"]?
+
+ video_id = response.dig?("endpoint", "watchEndpoint", "videoId").try &.as_s
+ return error_json(400, "Invalid clip ID") if video_id.nil?
+
+ start_time = nil
+ end_time = nil
+ clip_title = nil
+
+ if params = response.dig?("endpoint", "watchEndpoint", "params").try &.as_s
+ start_time, end_time, clip_title = parse_clip_parameters(params)
+ end
+
+ begin
+ video = get_video(video_id, region: region)
+ rescue ex : NotFoundException
+ return error_json(404, ex)
+ rescue ex
+ return error_json(500, ex)
+ end
+
+ return JSON.build do |json|
+ json.object do
+ json.field "startTime", start_time
+ json.field "endTime", end_time
+ json.field "clipTitle", clip_title
+ json.field "video" do
+ Invidious::JSONify::APIv1.video(video, json, locale: locale, proxy: proxy)
+ end
+ end
+ end
+ end
end
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
index 1b1169d8..1cba86f6 100644
--- a/src/invidious/routes/watch.cr
+++ b/src/invidious/routes/watch.cr
@@ -276,19 +276,9 @@ module Invidious::Routes::Watch
if video_id = response.dig?("endpoint", "watchEndpoint", "videoId")
if params = response.dig?("endpoint", "watchEndpoint", "params").try &.as_s
- decoded_protobuf = params.try { |i| URI.decode_www_form(i) }
- .try { |i| Base64.decode(i) }
- .try { |i| IO::Memory.new(i) }
- .try { |i| Protodec::Any.parse(i) }
-
- start_time = decoded_protobuf
- .try(&.["50:0:embedded"]["2:1:varint"].as_i64)
-
- end_time = decoded_protobuf
- .try(&.["50:0:embedded"]["3:2:varint"].as_i64)
-
- env.params.query["start"] = (start_time / 1000).to_s
- env.params.query["end"] = (end_time / 1000).to_s
+ start_time, end_time, _ = parse_clip_parameters(params)
+ env.params.query["start"] = start_time.to_s
+ env.params.query["end"] = end_time.to_s
end
return env.redirect "/watch?v=#{video_id}&#{env.params.query}"
diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr
index d6bd991c..ba05da19 100644
--- a/src/invidious/routing.cr
+++ b/src/invidious/routing.cr
@@ -235,6 +235,7 @@ module Invidious::Routing
get "/api/v1/captions/:id", {{namespace}}::Videos, :captions
get "/api/v1/annotations/:id", {{namespace}}::Videos, :annotations
get "/api/v1/comments/:id", {{namespace}}::Videos, :comments
+ get "/api/v1/clips/:id", {{namespace}}::Videos, :clips
# Feeds
get "/api/v1/trending", {{namespace}}::Feeds, :trending
diff --git a/src/invidious/videos/clip.cr b/src/invidious/videos/clip.cr
new file mode 100644
index 00000000..47f108a3
--- /dev/null
+++ b/src/invidious/videos/clip.cr
@@ -0,0 +1,20 @@
+require "json"
+
+# returns start_time, end_time and clip_title
+def parse_clip_parameters(params) : {Float64, Float64, String}
+ decoded_protobuf = params.try { |i| URI.decode_www_form(i) }
+ .try { |i| Base64.decode(i) }
+ .try { |i| IO::Memory.new(i) }
+ .try { |i| Protodec::Any.parse(i) }
+
+ start_time = decoded_protobuf
+ .try(&.["50:0:embedded"]["2:1:varint"].as_i64)
+
+ end_time = decoded_protobuf
+ .try(&.["50:0:embedded"]["3:2:varint"].as_i64)
+
+ clip_title = decoded_protobuf
+ .try(&.["50:0:embedded"]["4:3:string"].as_s)
+
+ return (start_time / 1000), (end_time / 1000), clip_title
+end