RxPlayer is a streaming engine that leaves the interface to you
DASH/Smooth HTML5 Video Player
At a glance
- What is it?
- RxPlayer is Canal+'s TypeScript library for playing DASH and Microsoft Smooth Streaming in a browser through Media Source Extensions and Encrypted Media Extensions. It ships no user interface, and it concentrates on the hard parts: DRM with several keys, fallback when a quality cannot be deciphered, subtitles, and moving the core out of the main thread.
- Who is it for?
- Adopt RxPlayer when you need adaptive streaming with real DRM handling and a custom interface, and verify first that your target browsers expose the MSE and EME APIs you rely on. Do not adopt it for progressive MP4 playback or for HLS on browsers without native support, since those paths are either out of scope or dependent on the platform.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
No controls, no skin, no opinion about your layout
Most video libraries hand you a player with a progress bar in it. RxPlayer refuses that. The README says the library only implements the core, non-UI part of a media player, you provide the interface while it handles the streaming. The project calls itself an engine, and the bundled demo is a small React application built to demonstrate a simple usage of the player. That split is the whole design decision. If you are building a broadcast style product, a learning platform or a set top box interface, you already know what your transport bar looks like, and you want the pipeline to handle adaptive bitrate selection and key management rather than to also make layout decisions. The audience is engineers integrating adaptive streaming into an application. The README says it was initially built for Canal+'s complex requirements across diverse devices, and that it prioritises configurability and integration flexibility over an opinionated component. The homepage is https://developers.canal-plus.com/rx-player/, where the documentation, the demo and the getting started pages live. It also matters what this is not. There is no caption overlay component, no playlist UI, no analytics hook. Everything above the media element is your code.
Adaptive streaming built on MSE and EME rather than on a native element
The implementation is described at the top of the README: the library implements a DASH and Microsoft Smooth Streaming media player on a browser by relying on the HTML5 Media Source Extensions and Encrypted Media Extensions browser APIs. That dependency is the source of both the capability and the constraint. MSE is what makes adaptive bitrate possible in a browser, since it lets the application feed segments into a media element itself. EME is the browser side of DRM, and it is where licence requests, key systems and the whole encryption story live. Because RxPlayer sits on those APIs rather than around them, it can do things a wrapper around a single src attribute cannot. The feature list makes that concrete. It supports live and VoD DASH including low latency, Smooth, HLS on devices with native support like Safari, downloaded contents, MP4 and WebM contents. Subtitles come in TTML, WebVTT, SAMI and SRT. On top of that sit audio only mode, video track selection, manual garbage collection of segments, Peer-To-Peer integration and quality filtering. Note the asterisk on HLS in the feature list. The README marks it as supported only on devices with native support, which is a deliberate boundary rather than an oversight.
Multiple DRM keys and automatic fallback when a quality cannot be deciphered
Encryption is where a broadcast player earns its keep, and the README describes the advanced configuration in unusual detail. You can have multiple keys in a single licence or in separate licences for a given content. There is automatic fallback on undecipherable contents, so if one representation of the stream cannot be decrypted the player moves on rather than stalling. Persistent licences are supported, and the MediaKeySystemConfiguration can be complex. The fallback story is the part worth emphasising, because it is a failure mode that plain browser playback handles badly. A single encrypted manifest with a single key gives you one chance: if that key is refused or the licence request fails, playback ends. With several keys and fallback rules, the engine can try another route. The README also mentions advanced heuristics to keep the playback going as a general capability, alongside multiple DRM keys, subtitle formats and the fallback mechanisms for undecipherable or undecodable qualities. Undecodable is a separate case from undecipherable, and the project claims to handle both. If your use case is a single key on a single device with no DRM at all, all of this machinery is overhead, and the minimal build exists precisely so you can leave it out.
Multi-threading: the core can move out of the main thread
The README describes a multi-threaded architecture where core logic can be offloaded to a separate thread, keeping the player from blocking your application and vice versa. This matters more than it first appears. A player that parses manifests, computes quality selection and manages segment buffers does a lot of work on the critical path of a page that is also running a user interface. The split also lets a build target a device with a slow main thread. The README says the player is production tested across a wide device range, from low-end set-top boxes to high-end computers, with optimisations for constrained environments. Whether a particular device gets the worker path is a configuration question, and the API is documented in detail at the developers site. The trade-off is that threading adds a boundary to debug. When playback stalls, you now have two contexts to reason about, and the API documentation rather than the README is where the configuration details live.
Installing rx-player and loading your first DASH manifest
The fastest route is to add the repository as a dependency of your application, through npm or yarn.
# when using npm:
npm install --save rx-player
# or, when using yarn instead:
yarn add rx-playerThe import then follows the package name, and the player takes the video element you point it at.
import RxPlayer from "rx-player";
const player = new RxPlayer({
videoElement: document.querySelector("video"),
});
// play a video
player.loadVideo({
url: "http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_6s/Manifest.mpd",
transport: "dash",
autoPlay: true,
});The url in that snippet points at the DASH industry test manifest, so the example loads without any setup. What you should see is a video element playing an adaptive stream, with the transport given explicitly as dash rather than left to detection. The README then points at four short tutorials, a quick start into the API, playing contents with DRMs, selecting a track, and listening to events contained in the content. The last one matters for production work, since event streams carry the discontinuity and period information a viewer interface needs. There are also live editable demos, one for a clear DASH content, one for an encrypted DASH content and one for an RxPlayer specific MetaPlaylist content.
Minimal builds: addFeatures keeps unused code out of your bundle
Bundle size is the argument the README makes for the minimal entry point. To reduce the size of the final code, you can import a minimal version of the player and only import the features you need. The minimal import path is rx-player/minimal, and features come from rx-player/features.
import RxPlayer from "rx-player/minimal";
import { DASH, EME } from "rx-player/features";
// Allow to play encrypted DASH contents
RxPlayer.addFeatures([DASH, EME]);The pattern is a whitelist. Nothing is enabled until you say so, and the example enables exactly DASH and EME for encrypted DASH playback. A player that only serves progressive MP4 or only plays unencrypted DASH would register a smaller set. The package.json shows how wide the surface is. Beyond the main entry point there are exports for ./experimental and ./experimental/config, ./experimental/features, ./experimental/features/embeds and a wildcard for individual experimental features and tools, with both import and require conditions mapping to a commonjs build and an es2017 build. The package is type module, and the version field reads 4.5.0. The experimental namespace is where the risk sits. Its contents are not covered by the same compatibility promise as the main entry point, so treat anything you import from there as something you may have to rework on the next major bump.
Where RxPlayer is the wrong tool
There are clear cases where this library is more than you need, and a couple where it will not help at all. If you serve progressive MP4 or WebM files and want a simple player, the adaptive machinery, the DRM configuration and the multi-threaded core are pure cost. A native video element is less code and fewer failure modes. HLS is the other boundary. The feature list marks it with an asterisk and points to devices with native support like Safari. If your users are on browsers without native HLS and you need HLS, this library is not the answer as documented. There is also a size and complexity consideration for teams that just want a video tag. The API is described as extensive and granular, and the documentation is large enough that the project publishes it per version so that older documentation stays reachable. Learning cost is real, even if the first integration is a ten line example. Finally, note what the README does not promise. It does not describe an accessibility layer, and it does not describe a UI kit for captions or for a settings panel. The demo shows how it can be wired into React, but the controls themselves are yours to build.
Apache 2 licence, an active dev branch, and versioned documentation
The licence field on the repository says Apache-2.0. That is a permissive licence which includes an explicit patent grant, and it is generally compatible with proprietary applications, though the notice and attribution requirements in the licence text are what to preserve when you redistribute parts of the code. The repository is not archived and the last push was on 2026-10-21, on the dev branch rather than master. Recent releases show a steady line: v4.5.0 on 2026-07-06, v4.4.1 on 2025-12-10 and v4.4.0 on 2025-09-25. The documentation is versioned alongside the code. The API pages are generated from the doc/api directory in the repository, and the site keeps documentation pages for previous versions plus demo pages for previous versions. That is a genuine upgrade cost reducer: when v4.5.0 changes a method, you can read the v4.4 documentation for the old behaviour rather than reading the diff. The repository also carries the usual engineering scaffolding, with a tests directory, vitest configuration files for unit and parser runs, an eslint config, a sonar project properties file and a CHANGELOG.md at the root. For contributors, the README says to run npm install after cloning and then npm run list to see the available scripts for testing and running a demo locally, with the details in CONTRIBUTING.md.
Editorial conclusion
Adopt RxPlayer when you need adaptive streaming with real DRM handling and a custom interface, and verify first that your target browsers expose the MSE and EME APIs you rely on. Do not adopt it for progressive MP4 playback or for HLS on browsers without native support, since those paths are either out of scope or dependent on the platform. Before shipping, check the minimal build entry points in package.json against the features your application actually calls, because the default import pulls in more code than a targeted feature set needs.
Frequently asked questions
How do I install RxPlayer in a JavaScript project?
Add it as a dependency with npm install --save rx-player, or with yarn add rx-player if you use yarn. Then import it with import RxPlayer from "rx-player" and pass the video element to the constructor.
What streaming formats does RxPlayer support?
The README lists live and VoD DASH including low-latency, Microsoft Smooth Streaming, HLS on devices with native support such as Safari, downloaded contents, MP4 and WebM. It relies on Media Source Extensions and Encrypted Media Extensions browser APIs.
Does RxPlayer provide a user interface?
No. The library only implements the core, non-UI part of a media player, and you provide the interface. The bundled demo is a small React application that shows one way of wiring the player into an application.
How do I reduce the RxPlayer bundle size?
Import the minimal version with import RxPlayer from "rx-player/minimal" and register only the features you need, for example RxPlayer.addFeatures([DASH, EME]) for encrypted DASH content.
Can RxPlayer handle several DRM keys for one content?
Yes. The README describes multiple keys in a single or separate licences, automatic fallback on undecipherable contents, persistent licences and a configurable MediaKeySystemConfiguration.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/canalplus-rx-player)Was this useful?