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

> Discover how Stremio-Web expertly handles MP4, HLS, DASH, and torrent streams using dedicated playback engines for smooth, uninterrupted media enjoyment.

- Repository: [Stremio/stremio-web](https://github.com/Stremio/stremio-web)
- Tags: deep-dive
- Published: 2026-05-23

---

**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`](https://github.com/Stremio/stremio-web/blob/main/src/components/Video/Video.js)) forwards this stream data to the player route. The central routing logic resides in [`src/routes/Player/VideoPlayer.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Player/VideoPlayer.js), the implementation sets the source directly:

```javascript
// 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`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Player/VideoPlayer.js) appears as:

```javascript
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:

```javascript
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`](https://github.com/Stremio/stremio-web/blob/main/package.json).

### Torrent and Magnet Links

Stremio-Web handles BitTorrent streams client-side using **WebTorrent**. The hook `useTorrent` (defined in [`src/common/useTorrent.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Player/SubtitleTrack.js) manages these elements:

```html
<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

- **[`src/components/Video/Video.js`](https://github.com/Stremio/stremio-web/blob/main/src/components/Video/Video.js)** – UI wrapper that receives stream data and initiates player routing.
- **[`src/routes/Player/VideoPlayer.js`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Player/VideoPlayer.js)** – Central dispatcher that detects formats and initializes hls.js, dash.js, or WebTorrent.
- **[`src/common/useTorrent.js`](https://github.com/Stremio/stremio-web/blob/main/src/common/useTorrent.js)** – React hook managing WebTorrent client lifecycle for P2P streams.
- **[`src/routes/Player/SubtitleTrack.js`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Player/SubtitleTrack.js)** – Handles `<track>` element injection for subtitle rendering.
- **[`package.json`](https://github.com/Stremio/stremio-web/blob/main/package.json)** – Defines dependencies ([`hls.js`](https://github.com/Stremio/stremio-web/blob/main/hls.js), `dashjs`, `webtorrent`) enabling the modular playback architecture.

## Summary

- Stremio-Web receives stream metadata from add-ons containing URLs and format identifiers.
- The [`VideoPlayer.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/useTorrent.js)) enables client-side torrent streaming without servers.
- Subtitles attach through standard HTML5 `<track>` elements managed by [`SubtitleTrack.js`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/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`](https://github.com/Stremio/stremio-web/blob/main/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.