get link to video preview on the thumbnails [ Youtube ]

北城余情 提交于 2020-07-18 06:44:52

问题


In Youtube, video thumbnails started to play a short preview when one hovered their cursor over them. Works only on desktop .

I tried to get the link for one

 https://i.ytimg.com/an_webp/d1w3CWfhzNQ/mqdefault_6s.webp?du=3000&sqp=CPyAhNIF&rs=AOn4CLBqWnVyWD9F_P4j_WFk7LAGs4pNUA

It works only for the above video, When I try to change the id in the link to view another video does`t work so how can I get a id dependent link for video preview?


回答1:


The spq parameter is base64 encoded protocol bufffer data. In this particular case, it's a 4 byte number with field number 1. I couldn't tell you what kind of number (float, signed integer, unsigned) it is or what it represents without having the spec sheet or more context about the file returned to make it possible to guess, or more samples.

The sqp parameter is also used in urls for custom-sized thumbnails. For instance, https://i.ytimg.com/vi/jNQXAC9IVRw/hqdefault.jpg?sqp=-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLAb9wuXOpXrY3TDtPwmmgz4l9PQxg instructs the server to return the thumbnail scaled and cropped so that it is 246x138, which is the resolution used for the thumbnails in the search results. This resolution isn't available from the standard selection of resolutions, namely,

https://i.ytimg.com/vi/[video id]/hqdefault.jpg
https://i.ytimg.com/vi/[video id]/mqdefault.jpg
https://i.ytimg.com/vi/[video id]/sddefault.jpg
https://i.ytimg.com/vi/[video id]/default.jpg

The sqp parameter in this case encodes the numbers 138 and 246, in addition to having a bunch of data whose purpose I'm not sure of. However, it's always the same data.

The rs parameter is also base 64 encoded data (but not protobuf). The first 5 bytes of that data are always the same. The remaining 20 bytes is likely an SHA-1 hash of the video id, the data in the sqp parameter, and possibly other secret data. I don't know how the data are combined, or what, if any, additional data is used in making the hash. If the video id and/or sqp parameter are changed, the hash will fail the server-side check and the image won't be resized. Instead it gives you the hqdefault.jpg image as if you never used an sqp/rs parameter.

It's almost certainly data that's intentionally kept secret so you can't generate these urls, to prevent denial-of-service attacks by mass-requesting differently-sized images in order to starve the server of resources through all the computationally intensive resizing.

So long story short, there's likely no way you could reproduce the rs parameter to get the links you're after, as it appears for the video previews you can't simply omit the parameters like you can with thumbnails.




回答2:


I wrote an example javascript function below that scrapes the video webp preview. It returns a promise that returns the url if found, otherwise the video has no preview available OR it means that by time you are running this function, Youtube changed their website html format which caused the function to not work anymore (this will definitely happen at some point in the future, so if you use this function in production on your site, be sure to also build a check that periodically verifies if the method still works. If it ever stops working, it might just need a minor change to work again)

The promise gives a result after a second or so; and there's several points where it can go wrong and not return a preview, so make sure to not make your website UX dependent on it to always return a preview.

Even better would be to run the code on your backend, and save the image on the backend. (However I'm not sure whether this is against Youtube's copyright rules)

const youtubeAnimation = id => {
    return fetch(
        `https://cors-anywhere.herokuapp.com/https://www.youtube.com/results?search_query=${id}&sp=QgIIAQ%253D%253D`,
        { headers: {} }
    )
        .then(r => r.text())
        .then(html => {
            const found = html.match(
                new RegExp(`["|']https://i.ytimg.com/an_webp/${id}/(.*?)["|']`)
            );
            if (found) {
                try {
                    const url = JSON.parse(found[0]);
                    return url;
                } catch (e) {}
            }
            throw "not found";
        })
        .catch(e => {
            return false;
        });
};

Example call:

youtubeAnimation('s86-Z-CbaHA').then(console.log)

Explanation:

  1. Fetch the actual Youtube search result page with the video ID as the search query. The URL parameter &sp=QgIIAQ%253D%253D is used to enforce exact match of the query.
  2. I use a common proxy on Heroku to circumvent CORS blockades. This is needed to be able to run the function in the browser.
  3. Search the entire html for the webp file format we are looking for (including our video ID)
  4. If found, parse it as JSON (the images are inside a JSON somewhere in the html). Otherwise return false.


来源:https://stackoverflow.com/questions/47970110/get-link-to-video-preview-on-the-thumbnails-youtube

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!