-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API: Return actual stream height, width and fps #4586
Conversation
I didn't mean to remove the |
quality_label += "60" | ||
end | ||
json.field "qualityLabel", quality_label | ||
quality_label = "#{width > height ? height : width}p" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something's not right here, but I can't figure out what (from the video hxQwWEOOyU8
you provided):
{
"size": "82x144",
"qualityLabel": "82p",
...
"size": "136x240",
"qualityLabel": "136p",
...
"size": "406x720",
"qualityLabel": "406p",
...
"size": "608x1080",
"qualityLabel": "608p",
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is another vertical video you can try, with more normal dimensions: https://youtu.be/HgEiag5zZc0 (/api/v1/videos/HgEiag5zZc0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the record, what threw me off was the first video's resolution.
I tested multiple videos and everything is working great:
Video 1 - 16:9 (but cropped I guess ?)
{
"type": "video",
"title": "nyan cat ✨🌈",
"videoId": "hxQwWEOOyU8",
"adaptiveFormats": [
{
"bitrate": "39063",
"itag": "160",
"type": "video/mp4; codecs=\"avc1.4d400b\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "82x144",
"resolution": "144p",
"qualityLabel": "82p",
},
{
"bitrate": "38119",
"itag": "278",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "82x144",
"resolution": "144p",
"qualityLabel": "82p",
},
{
"bitrate": "87476",
"itag": "133",
"type": "video/mp4; codecs=\"avc1.4d400c\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "136x240",
"resolution": "240p",
"qualityLabel": "136p",
},
{
"bitrate": "65871",
"itag": "242",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "136x240",
"resolution": "240p",
"qualityLabel": "136p",
},
{
"bitrate": "159836",
"itag": "134",
"type": "video/mp4; codecs=\"avc1.4d400d\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "202x360",
"resolution": "360p",
"qualityLabel": "202p",
},
{
"bitrate": "93569",
"itag": "243",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "202x360",
"resolution": "360p",
"qualityLabel": "202p",
},
{
"bitrate": "235362",
"itag": "135",
"type": "video/mp4; codecs=\"avc1.4d4015\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "270x480",
"resolution": "480p",
"qualityLabel": "270p",
},
{
"bitrate": "125716",
"itag": "244",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "270x480",
"resolution": "480p",
"qualityLabel": "270p",
},
{
"bitrate": "389160",
"itag": "136",
"type": "video/mp4; codecs=\"avc1.64001e\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "406x720",
"resolution": "720p",
"qualityLabel": "406p",
},
{
"bitrate": "174276",
"itag": "247",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "406x720",
"resolution": "720p",
"qualityLabel": "406p",
},
{
"bitrate": "606463",
"itag": "137",
"type": "video/mp4; codecs=\"avc1.64001f\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "608x1080",
"resolution": "1080p",
"qualityLabel": "608p",
},
{
"bitrate": "251663",
"itag": "248",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "608x1080",
"resolution": "1080p",
"qualityLabel": "608p",
},
{
"bitrate": "567223",
"itag": "271",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "810x1440",
"resolution": "1440p",
"qualityLabel": "810p",
},
{
"bitrate": "748687",
"itag": "313",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1080x1920",
"resolution": "1920p",
"qualityLabel": "1080p",
}
]
}
Video 2 - 2:1 (I guess?)
{
"type": "video",
"title": "I Bought the World’s First OLED TV from 2008!",
"videoId": "h01t5STfpbU",
"adaptiveFormats": [
{
"itag": "160",
"type": "video/mp4; codecs=\"avc1.4d400c\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "256x128",
"resolution": "128p",
"qualityLabel": "128p",
},
{
"itag": "278",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "256x128",
"resolution": "128p",
"qualityLabel": "128p",
},
{
"itag": "394",
"type": "video/mp4; codecs=\"av01.0.00M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "256x128",
"resolution": "128p",
"qualityLabel": "128p",
},
{
"itag": "133",
"type": "video/mp4; codecs=\"avc1.4d400d\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "426x214",
"resolution": "214p",
"qualityLabel": "214p",
},
{
"itag": "242",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "426x214",
"resolution": "214p",
"qualityLabel": "214p",
},
{
"itag": "395",
"type": "video/mp4; codecs=\"av01.0.00M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "426x214",
"resolution": "214p",
"qualityLabel": "214p",
},
{
"itag": "134",
"type": "video/mp4; codecs=\"avc1.4d401e\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "640x320",
"resolution": "320p",
"qualityLabel": "320p",
},
{
"itag": "243",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "640x320",
"resolution": "320p",
"qualityLabel": "320p",
},
{
"itag": "396",
"type": "video/mp4; codecs=\"av01.0.01M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "640x320",
"resolution": "320p",
"qualityLabel": "320p",
},
{
"itag": "135",
"type": "video/mp4; codecs=\"avc1.4d401f\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "854x428",
"resolution": "428p",
"qualityLabel": "428p",
},
{
"itag": "244",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "854x428",
"resolution": "428p",
"qualityLabel": "428p",
},
{
"itag": "397",
"type": "video/mp4; codecs=\"av01.0.04M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "854x428",
"resolution": "428p",
"qualityLabel": "428p",
},
{
"itag": "136",
"type": "video/mp4; codecs=\"avc1.4d401f\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1280x640",
"resolution": "640p",
"qualityLabel": "640p",
},
{
"itag": "247",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1280x640",
"resolution": "640p",
"qualityLabel": "640p",
},
{
"itag": "398",
"type": "video/mp4; codecs=\"av01.0.05M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1280x640",
"resolution": "640p",
"qualityLabel": "640p",
},
{
"itag": "137",
"type": "video/mp4; codecs=\"avc1.640028\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1920x960",
"resolution": "960p",
"qualityLabel": "960p",
},
{
"itag": "248",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1920x960",
"resolution": "960p",
"qualityLabel": "960p",
},
{
"itag": "399",
"type": "video/mp4; codecs=\"av01.0.08M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "1920x960",
"resolution": "960p",
"qualityLabel": "960p",
},
{
"itag": "271",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "2560x1280",
"resolution": "1280p",
"qualityLabel": "1280p",
},
{
"itag": "400",
"type": "video/mp4; codecs=\"av01.0.12M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "2560x1280",
"resolution": "1280p",
"qualityLabel": "1280p",
},
{
"itag": "313",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "3840x1920",
"resolution": "1920p",
"qualityLabel": "1920p",
},
{
"itag": "401",
"type": "video/mp4; codecs=\"av01.0.12M.08\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "3840x1920",
"resolution": "1920p",
"qualityLabel": "1920p",
}
]
}
Video 3 - 16:9 (Regular)
{
"type": "video",
"title": "Fireplace (10 Hours) 4K 50fps Ultra HD",
"videoId": "GbXYZwUigCM",
"adaptiveFormats": [
{
"itag": "160",
"type": "video/mp4; codecs=\"avc1.4d400c\"",
"clen": "497944280",
"lmt": "1700912826039206",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "256x144",
"resolution": "144p",
"qualityLabel": "144p",
},
{
"itag": "278",
"type": "video/webm; codecs=\"vp9\"",
"clen": "309320824",
"lmt": "1715449186384198",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "256x144",
"resolution": "144p",
"qualityLabel": "144p",
},
{
"itag": "394",
"type": "video/mp4; codecs=\"av01.0.00M.08\"",
"clen": "323587152",
"lmt": "1715445336472473",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "256x144",
"resolution": "144p",
"qualityLabel": "144p",
},
{
"itag": "133",
"type": "video/mp4; codecs=\"avc1.4d4015\"",
"clen": "1101070023",
"lmt": "1700912850877219",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "426x240",
"resolution": "240p",
"qualityLabel": "240p",
},
{
"itag": "242",
"type": "video/webm; codecs=\"vp9\"",
"clen": "715086560",
"lmt": "1715449186383356",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "426x240",
"resolution": "240p",
"qualityLabel": "240p",
},
{
"itag": "395",
"type": "video/mp4; codecs=\"av01.0.00M.08\"",
"clen": "760794993",
"lmt": "1715445473175780",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "426x240",
"resolution": "240p",
"qualityLabel": "240p",
},
{
"itag": "134",
"type": "video/mp4; codecs=\"avc1.4d401e\"",
"clen": "2211908324",
"lmt": "1700912897040357",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "640x360",
"resolution": "360p",
"qualityLabel": "360p",
},
{
"itag": "243",
"type": "video/webm; codecs=\"vp9\"",
"clen": "1627640617",
"lmt": "1715453154846763",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "640x360",
"resolution": "360p",
"qualityLabel": "360p",
},
{
"itag": "396",
"type": "video/mp4; codecs=\"av01.0.01M.08\"",
"clen": "1476697696",
"lmt": "1715445612358713",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "640x360",
"resolution": "360p",
"qualityLabel": "360p",
},
{
"itag": "135",
"type": "video/mp4; codecs=\"avc1.4d401e\"",
"clen": "3388637263",
"lmt": "1700912988297276",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "854x480",
"resolution": "480p",
"qualityLabel": "480p",
},
{
"itag": "244",
"type": "video/webm; codecs=\"vp9\"",
"clen": "2328248032",
"lmt": "1715449230957771",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "854x480",
"resolution": "480p",
"qualityLabel": "480p",
},
{
"itag": "397",
"type": "video/mp4; codecs=\"av01.0.04M.08\"",
"clen": "2249565215",
"lmt": "1715445572358813",
"projectionType": "RECTANGULAR",
"fps": 25,
"size": "854x480",
"resolution": "480p",
"qualityLabel": "480p",
},
{
"itag": "298",
"type": "video/mp4; codecs=\"avc1.4d4020\"",
"clen": "15609722608",
"lmt": "1700913443938645",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "1280x720",
"resolution": "720p",
"qualityLabel": "720p50",
},
{
"itag": "302",
"type": "video/webm; codecs=\"vp9\"",
"clen": "8601870156",
"lmt": "1715447235032087",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "1280x720",
"resolution": "720p",
"qualityLabel": "720p50",
},
{
"itag": "398",
"type": "video/mp4; codecs=\"av01.0.08M.08\"",
"clen": "8670647224",
"lmt": "1715449604465069",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "1280x720",
"resolution": "720p",
"qualityLabel": "720p50",
},
{
"itag": "299",
"type": "video/mp4; codecs=\"avc1.64002a\"",
"clen": "25989101086",
"lmt": "1700913923294659",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "1920x1080",
"resolution": "1080p",
"qualityLabel": "1080p50",
},
{
"itag": "303",
"type": "video/webm; codecs=\"vp9\"",
"clen": "23929689192",
"lmt": "1715451177539153",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "1920x1080",
"resolution": "1080p",
"qualityLabel": "1080p50",
},
{
"itag": "399",
"type": "video/mp4; codecs=\"av01.0.09M.08\"",
"clen": "15968233131",
"lmt": "1715467053652742",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "1920x1080",
"resolution": "1080p",
"qualityLabel": "1080p50",
},
{
"itag": "308",
"type": "video/webm; codecs=\"vp9\"",
"clen": "59795264954",
"lmt": "1715451702198477",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "2560x1440",
"resolution": "1440p",
"qualityLabel": "1440p50",
},
{
"itag": "400",
"type": "video/mp4; codecs=\"av01.0.12M.08\"",
"clen": "30062548712",
"lmt": "1715449064287628",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "2560x1440",
"resolution": "1440p",
"qualityLabel": "1440p50",
},
{
"itag": "315",
"type": "video/webm; codecs=\"vp9\"",
"clen": "119494104083",
"lmt": "1715458269734776",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "3840x2160",
"resolution": "2160p",
"qualityLabel": "2160p50",
},
{
"itag": "401",
"type": "video/mp4; codecs=\"av01.0.13M.08\"",
"clen": "60092333106",
"lmt": "1715456763590942",
"projectionType": "RECTANGULAR",
"fps": 50,
"size": "3840x2160",
"resolution": "2160p",
"qualityLabel": "2160p50",
}
]
}
Video 4 - 9:16 (Vertical)
{
"type": "video",
"title": "3 Tips for Filming with a Phone 🤳",
"videoId": "HgEiag5zZc0",
"adaptiveFormats": [
{
"bitrate": "118148",
"itag": "160",
"type": "video/mp4; codecs=\"avc1.4d400c\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "144x256",
"resolution": "256p",
"qualityLabel": "144p",
},
{
"bitrate": "108351",
"itag": "278",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "144x256",
"resolution": "256p",
"qualityLabel": "144p",
},
{
"bitrate": "271002",
"itag": "133",
"type": "video/mp4; codecs=\"avc1.4d4015\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "240x426",
"resolution": "426p",
"qualityLabel": "240p",
},
{
"bitrate": "211752",
"itag": "242",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "240x426",
"resolution": "426p",
"qualityLabel": "240p",
},
{
"bitrate": "470676",
"itag": "134",
"type": "video/mp4; codecs=\"avc1.4d401e\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "360x640",
"resolution": "640p",
"qualityLabel": "360p",
},
{
"bitrate": "382109",
"itag": "243",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "360x640",
"resolution": "640p",
"qualityLabel": "360p",
},
{
"bitrate": "881398",
"itag": "135",
"type": "video/mp4; codecs=\"avc1.4d401f\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "480x854",
"resolution": "854p",
"qualityLabel": "480p",
},
{
"bitrate": "716143",
"itag": "244",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "480x854",
"resolution": "854p",
"qualityLabel": "480p",
},
{
"bitrate": "1783799",
"itag": "136",
"type": "video/mp4; codecs=\"avc1.64001f\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "720x1280",
"resolution": "1280p",
"qualityLabel": "720p",
},
{
"bitrate": "1400901",
"itag": "247",
"type": "video/webm; codecs=\"vp9\"",
"projectionType": "RECTANGULAR",
"fps": 30,
"size": "720x1280",
"resolution": "1280p",
"qualityLabel": "720p",
}
]
}
Video 5 - 1:1 (= square)
{
"type": "video",
"title": "HD NYAN CAT!!!!",
"videoId": "96eWOlfsvW8",
"description": "How omg",
"dashUrl": "https://test.invidious.io/api/manifest/dash/id/96eWOlfsvW8",
"adaptiveFormats": [
{
"itag": "160",
"type": "video/mp4; codecs=\"avc1.4d400a\"",
"projectionType": "RECTANGULAR",
"fps": 15,
"size": "144x144",
"resolution": "144p",
"qualityLabel": "144p",
},
{
"itag": "134",
"type": "video/mp4; codecs=\"avc1.4d4015\"",
"projectionType": "RECTANGULAR",
"fps": 15,
"size": "360x360",
"resolution": "360p",
"qualityLabel": "360p",
},
{
"itag": "136",
"type": "video/mp4; codecs=\"avc1.64001f\"",
"projectionType": "RECTANGULAR",
"fps": 15,
"size": "720x720",
"resolution": "720p",
"qualityLabel": "720p",
},
{
"itag": "137",
"type": "video/mp4; codecs=\"avc1.640020\"",
"projectionType": "RECTANGULAR",
"fps": 15,
"size": "1080x1080",
"resolution": "1080p",
"qualityLabel": "1080p",
}
]
}
Co-authored-by: Samantaz Fox <coding@samantaz.fr>
17e0252
to
3b773c4
Compare
Thanks for the fix ^^ |
Invidious now reports the actual resolution and doesn’t hardcode them anymore. See: iv-org/invidious#4586 - Extended the list of possible resolutions in the StreamModel - trigger videoLoadFailureHandler if no streams are available - more logging for backend.bestPlayable Signed-off-by: Toni Förster <toni.foerster@gmail.com>
Invidious now reports the actual resolution and doesn’t hardcode them anymore. See: iv-org/invidious#4586 - Extended the list of possible resolutions in the StreamModel - trigger videoLoadFailureHandler if no streams are available - more logging for backend.bestPlayable Signed-off-by: Toni Förster <toni.foerster@gmail.com>
closes #4131
At the moment Invidious will return hardcoded data for the
size
,qualityLabel
andfps
of fields for streams, when 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/HgEiag5zZc0 (
/api/v1/videos/HgEiag5zZc0
)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.