Marsha, a self-hosted open source video and document provider
Marsha is a video management & playback service. It is intended to be operated independently: it's like having your very own YouTube for education.
Marsha also supports hosting documents and distribute them on all your courses.
Instructors & organizations can use Marsha to upload and manage their videos (and associated files, such as subtitles or transcripts) or documents directly from a course as they are creating it.
Once the course is published, learners simply see a video player or documents in the course.
Here is what
Marsha offers out of the box:
- automatic transcoding of videos to all suitable formats from a single video file uploaded by the instructor;
- adaptive-bitrate streaming playback (both HLS and DASH);
- accessibility through the player itself and support for subtitles, closed captions and transcripts;
- upload any type of documents;
- prevent disk storage quota by using AWS S3;
Moreover, Marsha provides:
- access control to resources through LTI authentication;
- easy deployment & management of environments through
Marsha is made up of 3 building blocks: a container-native
Django backend, an
AWS transcoding and file storage environment, and a
React frontend application.
Django backend is tasked with serving the LTI pages that are integrated into the LMS. It also manages all the objects with their relationships, user accounts and all authentication concerns. It exposes a JSON API to communicate with the part of the infrastructure that operates on
AWS lambdas and the
It is defined using a docker-compose file for development, and can be deployed on any container environment (such as
Kubernetes) for production.
The storage & transcoding environment
Source files (video, documents, subtitles,...) are directly uploaded to an
S3 bucket by instructors. Depending the uploaded resource a lambda will be triggered to do different jobs:
MediaConvertto generate all necessary video files (various formats and fragments & manifests for adaptive-bitrate streaming) into a destination
S3bucket. Those files are then served through the
- Convert any kind of subtitles (also captions and transcripts) in WebVTT format and encode them properly.
- Resize thumbnails in many formats.
- Copy documents from a source to a destination
S3Bucket accessible through the
Lambdas are used to manage and monitor the process and report back to the
This storage & transcoding environment requires
AWS as it heavily relies on
AWS MediaConvert to do the heavy lifting when it comes to transcoding. All the services it relies on are configured through
Terraform and can be deployed effortlessly through a
Please note that the only objects we handle in
AWS are the actual video, documents or subtitles files, from the upload to the distribution through transcoding and storage. It is not required to deploy any database or application backend to
AWS or send any user's personal information there.
React frontend is responsible for the interfaces with which users interact in the LTI Iframes. It gets an authenticated token with permissions
from the view and interacts with the
Django backend to manage objects and directly with
AWS s3 to upload files.
It also powers the same resource view when loaded by a learner to display a video player (thanks to Plyr) or a document reader.
To have the best possible user experience for instructors, we need to be able to change the size of the
<iframe> depending on its contents. This can be done through the iframe-resizer library.
iframe-resizer requires to run some JS inside the
<iframe> (which we include with our
React frontend bundle) and some JS inside the host page. It then communicates through message-passing to adjust the size of the
This means that to have the best interfaces for instructors, you need to include the host-side
iframe-resizer JS in your LMS pages. For Open edX, this is already done in our custom LTI consumer Xblock.
If you cannot or do not want to include this host-side JS, you can still run
Marsha. It will work exactly the same for learners (provided you adjust the size of the LTI
<iframe> for video), and instructors will only have to scroll inside the
<iframe> on some occasions.
Make sure you have a recent version of Docker and Docker Compose installed on your laptop:
$ docker -v Docker version 18.09.0, build 4d60db4 $ docker-compose --version docker-compose version 1.23.2, build 1110ad01
sudo but this can be avoided by assigning your user to the
The storage & transcoding environment
All tasks related to this environment are run from the
./src/aws directory. We use
Terraform to keep this infrastructure configuration as code and easily manage several independent deployments of the whole
./src/aws/env.d/development and replace the relevant values with your own. You can take a look at the environment documentation for more details on this topic. You can use this command to create the file from the existing model:
$ cp ./src/aws/env.d/development.dist ./src/aws/env.d/development
Create the shared state bucket where
Terraform will keep all the information on your deployments so different developers/machines/CI processes can interact with them:
$ make state-create
$ make init
Build the lambdas (using
yarn) and automatically configure the infrastructure (this will start incurring billing on
$ make deploy
Everything should be set up! You can check on your
AWS management console.
You may have noticed that the
AWS development environment requires a URL where the
Django backend is running. You can easily get a URL that points to your locally running
Django app using a tool such as
If you run several environments of Marsha, we suggest you take a look at
All tasks related to the
Django backend are run from the project root (where this
README.md is located).
The easiest way to start working on the project is to use our
$ make bootstrap
This command builds the
app container, installs back-end dependencies and performs database migrations. It's a good idea to use this command each time you are pulling code from the project repository to avoid dependency-related or migration-related issues.
./env.d/development file and replace the relevant values with your own. You can take a look at the environment documentation for more details on this topic.
Now that your
Docker services are ready to be used, start the application by running:
$ make run
You should be able to view the development view at localhost:8060/development/.
All tasks related to the
React frontend are run from the
yarn for all those tasks. Make sure you have a recent version installed:
$ yarn --version 1.13.0
If you need to install
yarn, please take a look at the official documentation.
Install all the dependencies:
$ yarn install
Run the build and copy the
iframe-resizer host-side JS into your local
$ yarn build $ yarn copy-iframe-resizer
The front application is tested using jest. Every js module has its corresponding spec file containing related tests:
├── VideoPlayer │ ├── index.spec.tsx │ ├── index.tsx │ ├── indexWithDashjs.spec.tsx │ └── VideoPlayer.css
Run the tests:
$ yarn test
Browser testing provided by:
Consumer Site and
Passport in Marsha's admin panel.
You should be all set to make the LTI request on the development view and access
Marsha's frontend interface!
This project is intended to be community-driven, so please, do not hesitate to get in touch if you have any question related to our implementation or design decisions.
We try to raise our code quality standards and expect contributors to follow the recommandations from our handbook.
This work is released under the MIT License (see LICENSE).