Archive
This post is archived and may contain outdated information. It has been set to 'noindex' and should stop showing up in search results.
This post is archived and may contain outdated information. It has been set to 'noindex' and should stop showing up in search results.
How YouTube Streams Video & Audio
Nov 20, 2014Web and InternetComments (15)
This is a technical post on how the YouTube player works, including the kinds of http requests it makes and how it streams video and audio. This information was researched with the modern HTML5 player. It will likely differ from the discontinued legacy Flash player that YouTube used to use.
When the YouTube video player is started, either on a youtube.com page or an embed, it first sends a request to http://www.youtube.com/get_video_info with about 13 query string parameters. These parameters contain information such as the video ID, the player width/height, and what host is requesting the video.
get_video_info then returns a large JSON string with information about the video and each video/audio file associated with it. get_video_info may also return an error if it determines the requestor shouldn't have access in the given environment (restricted in a certain country, not embeddable, etc).
Some YouTube videos have content restrictions, depending on where the video is being accessed from. For example, a VEVO video will probably not work if you try to access the embed URL directly, but will work fine inside its iframe embed or on the YouTube website.
get_video_info can also be accessed directly to obtain information about YouTube video and audio, as well as download links to them (for any public and unrestricted video). Since the information is returned in a JSON string, it can be hard to read it. You can access this information in a friendly interface using this YouTube video info utility that I created.
The YouTube player does not play one large video/audio file for users. It instead constantly sends requests for small chunks of video or audio as the player is playing. You can see this if you look at the network traffic while watching a video:
These requests are made to googlevideo.com/videoplayback and have a long subdomain with many query string parameters. The query string parameters tell googlevideo.com information about the file it should return to the YouTube player. This includes what type of file (video or audio and the format), what part of the file to return, when the request should expire, the ip address of the requestor, and other information.
In order for YouTube to constantly pull small chunks of the video or audio and be able to piece them together in the player, it uses the range parameter to tell googlevideo.com the starting and ending bytes that should be returned for each chunk. Here is a sample http request showing just the range parameter:
The above is an example of the YouTube video player requesting the part of the file that is from 262778 bytes to 341069 bytes. The returned file will be the 78291 byte size chunk.
The reason YouTube makes requests for small chunks may be to improve performance. It doesn't know when a user might simply close the window, and by only sending small chunks this could potentially save a lot of bandwidth. Also, if the user changes the video quality in the middle of the video, YouTube will only have to change the video stream (it keeps playing the exact same audio).
The more important reason I suspect is security when it comes to restricted content videos. By streaming videos in chunks, users can't simply open up the page source or developer tools and download the complete video directly from a URL. The YouTube player is piecing together each chunk of video and audio on the fly, so you would need a program that does the same thing in order to acquire a complete video with audio.
YouTube does make unrestricted and public videos available for download in a couple different pre-made sizes (usually 720p and 360p). You can use the same YouTube Video Info utility to get links to these downloads (under the "Stream Maps"). Keep in mind that videos with restrictions by YouTube will not work with this utility.
To determine what audio bitrate YouTube is actually playing, you can download the audio file (or all of the chunks individually and add their size together), and compare the total file size of the audio against the length of the video. With a few calculations you can arrive at the kbps (or average kbps if it's VBR).
For example, one of my test videos is 21.1 seconds long. I downloaded the full audio stream by copying the YouTube http request and modifying it so that the range encompassed the entire audio. The audio file ended up being 341070 bytes. Dividing by the length (21.1 seconds) gives 16164.5 bytes per second, which equals 129315.6 bits per second or 126.3 kbps audio (k/bits per second).
In my test video, I had originally uploaded it with 320 kbps audio and a video resolutions of 3840x2160 (4k). So it was quite surprising to find that YouTube was streaming just 126 kbps audio. In their defense, their compression is very good. I can't tell the difference between their 126 kbps and the 192 kbps AAC version of the audio, even when creating a JavaScript audio player that seamlessly switches between the two streams on the fly.
Get YouTube Video Info
When the YouTube video player is started, either on a youtube.com page or an embed, it first sends a request to http://www.youtube.com/get_video_info with about 13 query string parameters. These parameters contain information such as the video ID, the player width/height, and what host is requesting the video.
get_video_info then returns a large JSON string with information about the video and each video/audio file associated with it. get_video_info may also return an error if it determines the requestor shouldn't have access in the given environment (restricted in a certain country, not embeddable, etc).
Some YouTube videos have content restrictions, depending on where the video is being accessed from. For example, a VEVO video will probably not work if you try to access the embed URL directly, but will work fine inside its iframe embed or on the YouTube website.
get_video_info can also be accessed directly to obtain information about YouTube video and audio, as well as download links to them (for any public and unrestricted video). Since the information is returned in a JSON string, it can be hard to read it. You can access this information in a friendly interface using this YouTube video info utility that I created.
Chunks Of Video
The YouTube player does not play one large video/audio file for users. It instead constantly sends requests for small chunks of video or audio as the player is playing. You can see this if you look at the network traffic while watching a video:
These requests are made to googlevideo.com/videoplayback and have a long subdomain with many query string parameters. The query string parameters tell googlevideo.com information about the file it should return to the YouTube player. This includes what type of file (video or audio and the format), what part of the file to return, when the request should expire, the ip address of the requestor, and other information.
In order for YouTube to constantly pull small chunks of the video or audio and be able to piece them together in the player, it uses the range parameter to tell googlevideo.com the starting and ending bytes that should be returned for each chunk. Here is a sample http request showing just the range parameter:
[...].googlevideo.com/videoplayback?[...]&range=262778-341069
The above is an example of the YouTube video player requesting the part of the file that is from 262778 bytes to 341069 bytes. The returned file will be the 78291 byte size chunk.
Security And Speed
The reason YouTube makes requests for small chunks may be to improve performance. It doesn't know when a user might simply close the window, and by only sending small chunks this could potentially save a lot of bandwidth. Also, if the user changes the video quality in the middle of the video, YouTube will only have to change the video stream (it keeps playing the exact same audio).
The more important reason I suspect is security when it comes to restricted content videos. By streaming videos in chunks, users can't simply open up the page source or developer tools and download the complete video directly from a URL. The YouTube player is piecing together each chunk of video and audio on the fly, so you would need a program that does the same thing in order to acquire a complete video with audio.
YouTube does make unrestricted and public videos available for download in a couple different pre-made sizes (usually 720p and 360p). You can use the same YouTube Video Info utility to get links to these downloads (under the "Stream Maps"). Keep in mind that videos with restrictions by YouTube will not work with this utility.
Audio Bitrate
To determine what audio bitrate YouTube is actually playing, you can download the audio file (or all of the chunks individually and add their size together), and compare the total file size of the audio against the length of the video. With a few calculations you can arrive at the kbps (or average kbps if it's VBR).
For example, one of my test videos is 21.1 seconds long. I downloaded the full audio stream by copying the YouTube http request and modifying it so that the range encompassed the entire audio. The audio file ended up being 341070 bytes. Dividing by the length (21.1 seconds) gives 16164.5 bytes per second, which equals 129315.6 bits per second or 126.3 kbps audio (k/bits per second).
In my test video, I had originally uploaded it with 320 kbps audio and a video resolutions of 3840x2160 (4k). So it was quite surprising to find that YouTube was streaming just 126 kbps audio. In their defense, their compression is very good. I can't tell the difference between their 126 kbps and the 192 kbps AAC version of the audio, even when creating a JavaScript audio player that seamlessly switches between the two streams on the fly.