I watched a video from YouTube, and I decided to explore some parts of its video player. I noticed that unlike most HTML5 videos I've seen, the Youtube video player doesn't use a regular video source and instead uses the blob URL as the source.
I used to test HTML5 video, and I found that the server starts streaming all video from the beginning and buffers in the background for the rest of the video. This means that if your video is 300 megabytes, all 300 megabytes will be downloaded. If you are looking for the middle, it will start loading from the search position to the end.
Youtube doesn't work that way (at least in chrome). Instead, it manages to control buffering, so it only pauses a certain amount when paused. It also seems to only buffer the corresponding fragments, so if you skip it, be sure not to buffer parts that are unlikely to be observed.
In my attempts to investigate how this worked, I noticed that the src tag for the video is blob:http%3A//www.youtube.com/ee625eee-2802-49b2-a13f-eb374d551d54 , which pointed to blobs , which then led me to typed arrays . Using these two resources, I can upload mp4 video to blob and display it in HTML5 tag.
However, what I'm stuck with right now is how YouTube deals with pieces. Considering network traffic, it sends requests to http://r6---sn-p5q7ynee.c.youtube.com/videoplayback , which returns binary video data back to 1.1 MB chunks. It also seems worth noting that most of the common requests, due to HTML5 video ads, seem to receive a 206 response code during its stream, but the playvideo calls for youtube get 200 back.
I tried to try to load only a range of bytes (via the Range http header parameter), which, unfortunately, failed (I assume because there was no metadata for the video coming from the video).
At this point, I was stuck in figuring out how Youtube handles this. I came up with several ideas, although none of which I completely sold:
1) Youtube sends offline video and audio fragments with each call /videoplayback . This seems like a pretty heavy burden on the download side, and it seems that it would be difficult to stitch them together so that they look like one unemotional video. In addition, the video tag seems to consider it one complete video, judging by the calls to $('video').duration and $('video').currentTime , which makes me think that the video tag considers it to be the only video file. Finally, the vidoe src tag never changes, which leads me to believe that it works with a special blob and does not disable blobs.
2) Youtube creates an empty block, predefined to the full array of videos, and updates the piece with pieces when it loads it. Then he must make sure that the user is not too close to the last downloaded fragment (so that the user cannot enter the unoccupied blob section). The problem that I see with this, I see no way to dynamically update blob via javascript (although maybe I just have problems finding it)
3) Youtube uploads metadata, and then starts to build blob in order, adding video fragments when it uploads them. The problem that I see in this method is that I do not understand how it will handle requests in the area after buffering.
Perhaps I just miss the obvious answer that is right in front of me. Does anyone have any idea?
edit: I just thought about the fourth option. Another idea is that they can use the API file to write binary fragments to the file and use this file for streaming. The file’s API seems to be able to search for specific positions, so it allows you to fill in videos with empty bytes and fill them as they are received. This will certainly include a video search.