Explain Codes LogoExplain Codes Logo

Html5 - How to stream large .mp4 files?

html
responsive-design
performance
best-practices
Nikita BarsukovbyNikita Barsukov·Jan 12, 2025
TLDR

For streaming large .mp4 files, use HTML5's <video> tag. It leverages server-side support for HTTP Range requests, allowing chunking of video loading. This results in seamless playback and seeking without the need to fully download the file. For correct functionality, configure your server appropriately. For Apache, mod_headers should be enabled, and for Nginx, http_slice_module is required. Here's a simplistic demonstration:

<video controls> <source src="large_video.mp4" type="video/mp4"> </video>

Your server needs to return complete byte-range headers for efficient streaming.

Optimising for speed

With large .mp4 files, the position of metadata (moov atom) greatly influences playback speed. Prioritize placing the moov atom at the file's start. Tools like Handbrake or ffmpeg can re-encode your videos for this. Here's how you might use ffmpeg:

// Move over moov atom, it's time to lead! ffmpeg -i input.mp4 -movflags +faststart output.mp4

Careful, avoid double compression. As .mp4 files are already compressed, additional gzip or deflate leads to increased CPU load without practical benefits.

Tailoring server for efficient delivery

Server configuration matters too! Equip your server to manage HTTP Range requests, ensuring Content-Type is set to video/mp4. Curl can help you double-check:

// "Knock, knock." // "Who's there?" // "It's curl, just checking your headers!" curl -I http://example.com/large_video.mp4

The HTTP Response Header should contain Content-Type: video/mp4 and Accept-Ranges: bytes without featuring Content-Encoding: gzip or deflate.

Enabling range requests via C#

Custom video streaming might feature a C# Web API. Here, FileAccess and FileStream control reading and serving pieces of video:

// FileAccess and FileStream, the dynamic duo in action! FileAccess fa = FileAccess.Read; FileStream fs = new FileStream(path, FileMode.Open, fa);

Identify partial requests using the Range header from the HTTP Request. Cater to complete video for non-partial requests, and for partial ones, use ByteRangeStreamContent in responses:

if (isRangeRequest) { // "Just a byte please!" response.Content = new ByteRangeStreamContent(fs, request.Headers.Range, mediaType); } else { // "Gimme all you got!" response.Content = new StreamContent(fs); }

Proactively manage InvalidByteRangeException to handle invalid range requests gracefully. Refrain from sending Content-Encoding headers for streamed content.

Handling network volatility with adaptive streaming

When met with varying bandwidths, consider using adaptive streaming. Technologies like HLS (HTTP Live Streaming) and MPEG-DASH adjust video quality dynamically based on user's network status.

Boosting accessibility and testing browser compatibility

Strive for wide-ranging accessibility. Weave in subtitles and duly consider autoplay policies. Given browser-specific nuances, test across different platforms and browsers to verify compatibility with HTML5 <video> tag.

Employing analytics for performance insights

Deploy analytics tools to track streaming performance, providing insights to fine-tune your encoding settings and server configurations. This enhances user experience.