When serving large media files, it's desirable to allow clients to start playback of the media
before the entire file has been downloaded, so that they don't have to wait.
Here we show the use of HTTP Progressive Download
to serve videos in that manner.
TL;DR flow explanation:
- The client makes an initial request for a video and receives a server response with no payload so far, but with the headers "Accept-Ranges: bytes" and "Content-Length: video_length_in_bytes" indicating that it accepts range requests to deliver partial contents.
- The client then makes a range request for the first part of the video using the header "Range: bytes=0-" and receives a 206 Partial Content response back from the server with the bytes corresponding to the first part of the video as payload, together with the header "Content-Range: 0-video_part_byte_end_position/video_length_in_bytes".
- The client keeps making new requests as the video parts are played, e.g. "Range: bytes=next_video_part_byte_start_position-next_video_part_byte_end_position".
- Since we are serving potentially large files, it makes sense to take advantage of HTTP caching mechanisms in order to avoid unnecessary retransmissions over the wire. We achieve that via Conditional Requests (RFC 7232, https://github.com/andreschaffer/http-caching-and-concurrency-examples); in this project specifically we explored that with the headers "Last-Modified" and "If-Range".
This project does not explore adapting playback to the viewers' network conditions. So, depending on their bandwith, even with progressive downloads, buffering waiting times may still happen. A common technique to improve on that is known as Adaptive Bitrate Streaming, which aims to deliver the optimal viewer experience considering their bandwith.
For a complete read about video streaming, check the excellent source HowVideo.works.
- Java 14
- Maven
- Run ./run.sh .
This will build, test and run the application. You'll be prompted for the videos directory where you have the mp4 files you want to serve. (Note: there is no pagination in place here, so beware if you are trying to serve a directory with lots of files) - Browse to the videos at http://localhost:8080/videos.
- Pick a video to watch to!
You can see in your browser Network Panel or in the video progress bar that parts of the video are being downloaded as it gets played.
If you would like to help making this project better, see the CONTRIBUTING.md.
Send any other comments, flowers and suggestions to André Schaffer.
This project is distributed under the MIT License.