How Stremio-Web Handles Different Media Formats: MP4, HLS, DASH, and Torrents

Stremio-Web detects media formats from stream URLs and routes them through specialized playback engines—including HTML5 video, hls.js, dash.js, and WebTorrent—to ensure seamless playback across MP4, HLS, DASH, and torrent streams.

Stremio-Web is the browser-based client for the Stremio media streaming platform, responsible for rendering video content from various add-ons. Understanding how stremio-web handles different media formats reveals a modular architecture that switches playback engines based on URL patterns and MIME types, ensuring broad codec support without requiring browser plugins.

Stream Ingestion and Format Detection

When a user selects content, the application receives stream metadata through the Stremio Add-on API. Each stream object includes a URL and a format identifier (such as mp4, webm, hls, dash, or torrent).

The UI component Video (located in src/components/Video/Video.js) forwards this stream data to the player route. The central routing logic resides in src/routes/Player/VideoPlayer.js, which inspects the URL extension and MIME type to determine the appropriate playback strategy.

Playback Engine Selection

The player implements a cascading decision tree to select the correct engine for each format.

Direct File Playback (MP4, WebM, OGG)

For standard progressive download formats, Stremio-Web relies on the browser's native HTML5 <video> element.

In src/routes/Player/VideoPlayer.js, the implementation sets the source directly:

// Native HTML5 video for MP4/WebM/OGG
<video src={url} controls />

This approach leverages built-in browser decoders for formats like MP4 (H.264), WebM (VP8/VP9), and OGG (Theora), requiring no additional JavaScript libraries.

HLS Streaming (.m3u8)

When the URL ends with .m3u8 or reports the application/vnd.apple.mpegurl MIME type, the player initializes hls.js to handle the HTTP Live Streaming protocol.

The detection and initialization logic in src/routes/Player/VideoPlayer.js appears as:

if (url.endsWith('.m3u8')) {
  const hls = new Hls();
  hls.loadSource(url);
  hls.attachMedia(videoEl);
}

This attaches the HLS controller to the video element, enabling adaptive bitrate streaming in browsers that lack native HLS support (such as Chrome and Firefox on desktop).

MPEG-DASH (.mpd)

For Dynamic Adaptive Streaming over HTTP, identified by the .mpd extension, the application uses dash.js.

The implementation creates a MediaPlayer instance and binds it to the video element:

if (url.endsWith('.mpd')) {
  const dash = dashjs.MediaPlayer().create();
  dash.initialize(videoEl, url, false);
}

This pattern mirrors the HLS approach, providing consistent API interaction across adaptive streaming protocols while maintaining separate library dependencies defined in package.json.

Stremio-Web handles BitTorrent streams client-side using WebTorrent. The hook useTorrent (defined in src/common/useTorrent.js) manages the WebTorrent client instance.

The process involves:

  • Creating a WebTorrent client
  • Adding the torrent via magnet URI or infohash
  • Extracting the video file and generating a blob URL
  • Feeding that URL to the video element's MediaSource

This allows peer-to-peer streaming directly in the browser without proxying through a server, reducing infrastructure load while maintaining privacy.

Subtitle Rendering

Subtitle files in VTT or SRT format are attached to the video element via the <track> API. The component src/routes/Player/SubtitleTrack.js manages these elements:

<track kind="subtitles" src={subtitleUrl} srclang="en" label="English" />

The player supports multiple concurrent subtitle tracks, allowing users to switch languages without reloading the video stream.

Native Fallback and Feature Detection

Before initializing external libraries, the player checks for native format support using videoEl.canPlayType(). If the browser reports capability for HLS (as Safari does) or DASH, Stremio-Web bypasses the JavaScript polyfills and uses the browser's built-in decoders for better performance and battery efficiency.

Key Implementation Files

Summary

  • Stremio-Web receives stream metadata from add-ons containing URLs and format identifiers.
  • The VideoPlayer.js router detects formats by URL extension (.m3u8, .mpd) and MIME type.
  • HTML5 video handles direct MP4/WebM files natively.
  • hls.js provides HLS support for non-native browsers.
  • dash.js manages MPEG-DASH adaptive streaming.
  • WebTorrent (via useTorrent.js) enables client-side torrent streaming without servers.
  • Subtitles attach through standard HTML5 <track> elements managed by SubtitleTrack.js.

Frequently Asked Questions

Does Stremio-Web require browser plugins to play torrents?

No. Stremio-Web uses the WebTorrent library implemented in src/common/useTorrent.js to handle BitTorrent protocols natively within the browser using WebRTC and standard web APIs, eliminating the need for external plugins or native applications.

Why does Stremio-Web use JavaScript libraries for HLS and DASH instead of native playback?

While Safari supports HLS natively and some browsers support DASH, Stremio-Web uses hls.js and dash.js to ensure consistent behavior across all browsers. The code checks videoEl.canPlayType() first and falls back to these libraries only when native support is unavailable, balancing compatibility with performance.

How does Stremio-Web handle subtitle files in different formats?

The application accepts subtitle files (typically VTT or converted SRT) and attaches them to the video element using HTML5 <track> tags, as implemented in src/routes/Player/SubtitleTrack.js. The browser's native text track API renders these over the video without requiring custom rendering layers.

What happens when Stremio-Web encounters an unknown media format?

If the format is unrecognized and the browser cannot play it natively (failing the canPlayType() check), the player will not initialize a specific engine. The video element will attempt to load the source directly, which typically results in a playback error handled by the UI error boundary, prompting the user to select a different stream source.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →