Videos: Use start time and end time for clips (#4264)

This PR parses the start and end time for clips.

It also adds a new, dedicated API endpoint (`/api/v1/clips/{id}`) for
retrieving the start and end time of a clip.

Here is a sample response from that new endpoint (`video` is a video object,
as described in https://docs.invidious.io/api/common_types/#videoobject):

GET `/api/v1/clips/UgkxxPM3BRphCAPLP88YoUGuj79KXPfpNNO_?pretty=1`

Response:
```
{
  "startTime": 8842.645,
  "endTime": 8855.856,
  "clipTitle": "✂️ Kirby is pink!",
  "video": {}
}
```

Closes issue 3921
This commit is contained in:
Samantaz Fox
2024-02-12 22:10:16 +01:00
4 changed files with 72 additions and 0 deletions

View File

@@ -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

View File

@@ -275,6 +275,12 @@ module Invidious::Routes::Watch
return error_template(400, "Invalid clip ID") if response["error"]?
if video_id = response.dig?("endpoint", "watchEndpoint", "videoId")
if params = response.dig?("endpoint", "watchEndpoint", "params").try &.as_s
start_time, end_time, _ = parse_clip_parameters(params)
env.params.query["start"] = start_time.to_s if start_time != nil
env.params.query["end"] = end_time.to_s if end_time != nil
end
return env.redirect "/watch?v=#{video_id}&#{env.params.query}"
else
return error_template(404, "The requested clip doesn't exist")