API: Return actual stream height, width and fps (#4586)
At the moment Invidious will return hardcoded data for the 'size', 'qualityLabel' and 'fps' fields for streams, when such hardcoded data is available, otherwise it just omits those fields from the response (e.g. with the AV1 formats). Those issues are especially noticable when Invidious claims that 50fps streams have 60fps and when it claims that the dimensions for a vertical video are landscape. The DASH manifests that Invidious generates already use the correct information. This pull request corrects that issue by returning the information that YouTube provides instead of hardcoded values and also fixes the long standing bug of Invidious claiming that audio streams have 30 fps. Here are two test cases: 50/25/13fps: https://youtu.be/GbXYZwUigCM (/api/v1/videos/GbXYZwUigCM) vertical video: https://youtu.be/hxQwWEOOyU8 (/api/v1/videos/hxQwWEOOyU8) Originally these problems were going to be solved by the complete refactor of stream handling in 3620, but as that pull request got closed by the stale bot over a month ago and has such a massive scope that it would require a massive amount of work to complete it, I decided to open this pull request that takes a less radical approach of just fixing bugs instead of a full on refactoring. FreeTube generates it's own DASH manifests instead of using Invidious' one, so that it can support multiple audio tracks and HDR. Unfortunately due to the missing and inaccurate information in the API responses, FreeTube has to request the DASH manifest from Invidious to extract the height, width and fps. With this pull request FreeTube could rely just on the API response, saving that extra request to the Invidious instance. It would also make it possible for FreeTube to use the vp9 streams with Invidious, which would reduce the load on the video proxies. Closes issue 4131
This commit is contained in:
commit
e62d4db752
1 changed files with 44 additions and 33 deletions
|
@ -114,25 +114,31 @@ module Invidious::JSONify::APIv1
|
||||||
|
|
||||||
json.field "projectionType", fmt["projectionType"]
|
json.field "projectionType", fmt["projectionType"]
|
||||||
|
|
||||||
if fmt_info = Invidious::Videos::Formats.itag_to_metadata?(fmt["itag"])
|
height = fmt["height"]?.try &.as_i
|
||||||
fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.as_i || 30
|
width = fmt["width"]?.try &.as_i
|
||||||
|
|
||||||
|
fps = fmt["fps"]?.try &.as_i
|
||||||
|
|
||||||
|
if fps
|
||||||
json.field "fps", fps
|
json.field "fps", fps
|
||||||
|
end
|
||||||
|
|
||||||
|
if height && width
|
||||||
|
json.field "size", "#{width}x#{height}"
|
||||||
|
json.field "resolution", "#{height}p"
|
||||||
|
|
||||||
|
quality_label = "#{width > height ? height : width}p"
|
||||||
|
|
||||||
|
if fps && fps > 30
|
||||||
|
quality_label += fps.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
json.field "qualityLabel", quality_label
|
||||||
|
end
|
||||||
|
|
||||||
|
if fmt_info = Invidious::Videos::Formats.itag_to_metadata?(fmt["itag"])
|
||||||
json.field "container", fmt_info["ext"]
|
json.field "container", fmt_info["ext"]
|
||||||
json.field "encoding", fmt_info["vcodec"]? || fmt_info["acodec"]
|
json.field "encoding", fmt_info["vcodec"]? || fmt_info["acodec"]
|
||||||
|
|
||||||
if fmt_info["height"]?
|
|
||||||
json.field "resolution", "#{fmt_info["height"]}p"
|
|
||||||
|
|
||||||
quality_label = "#{fmt_info["height"]}p"
|
|
||||||
if fps > 30
|
|
||||||
quality_label += "60"
|
|
||||||
end
|
|
||||||
json.field "qualityLabel", quality_label
|
|
||||||
|
|
||||||
if fmt_info["width"]?
|
|
||||||
json.field "size", "#{fmt_info["width"]}x#{fmt_info["height"]}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Livestream chunk infos
|
# Livestream chunk infos
|
||||||
|
@ -163,26 +169,31 @@ module Invidious::JSONify::APIv1
|
||||||
|
|
||||||
json.field "bitrate", fmt["bitrate"].as_i.to_s if fmt["bitrate"]?
|
json.field "bitrate", fmt["bitrate"].as_i.to_s if fmt["bitrate"]?
|
||||||
|
|
||||||
fmt_info = Invidious::Videos::Formats.itag_to_metadata?(fmt["itag"])
|
height = fmt["height"]?.try &.as_i
|
||||||
if fmt_info
|
width = fmt["width"]?.try &.as_i
|
||||||
fps = fmt_info["fps"]?.try &.to_i || fmt["fps"]?.try &.as_i || 30
|
|
||||||
|
fps = fmt["fps"]?.try &.as_i
|
||||||
|
|
||||||
|
if fps
|
||||||
json.field "fps", fps
|
json.field "fps", fps
|
||||||
|
end
|
||||||
|
|
||||||
|
if height && width
|
||||||
|
json.field "size", "#{width}x#{height}"
|
||||||
|
json.field "resolution", "#{height}p"
|
||||||
|
|
||||||
|
quality_label = "#{width > height ? height : width}p"
|
||||||
|
|
||||||
|
if fps && fps > 30
|
||||||
|
quality_label += fps.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
json.field "qualityLabel", quality_label
|
||||||
|
end
|
||||||
|
|
||||||
|
if fmt_info = Invidious::Videos::Formats.itag_to_metadata?(fmt["itag"])
|
||||||
json.field "container", fmt_info["ext"]
|
json.field "container", fmt_info["ext"]
|
||||||
json.field "encoding", fmt_info["vcodec"]? || fmt_info["acodec"]
|
json.field "encoding", fmt_info["vcodec"]? || fmt_info["acodec"]
|
||||||
|
|
||||||
if fmt_info["height"]?
|
|
||||||
json.field "resolution", "#{fmt_info["height"]}p"
|
|
||||||
|
|
||||||
quality_label = "#{fmt_info["height"]}p"
|
|
||||||
if fps > 30
|
|
||||||
quality_label += "60"
|
|
||||||
end
|
|
||||||
json.field "qualityLabel", quality_label
|
|
||||||
|
|
||||||
if fmt_info["width"]?
|
|
||||||
json.field "size", "#{fmt_info["width"]}x#{fmt_info["height"]}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue