This document is intended for mediasoup developers.
The package.json file in the main folder includes the following scripts:
Compiles mediasoup TypeScript code (node/src folder) JavaScript and places it into the node/lib directory.
Compiles mediasoup TypeScript code (node/src folder) JavaScript, places it into the node/lib directory an watches for changes in the TypeScript files.
Builds the mediasoup-worker binary. It invokes invokebelow.
Prints the name of the corresponding mediasoup-worker prebuild tar file.
Creates a prebuilt of mediasoup-worker binary in the worker/prebuild folder.
Runs both lint:node and lint:worker tasks.
Validates mediasoup TypeScript files using ESLint, Prettier and Knip.
Validates mediasoup worker C++ files using clang-format. It invokes invoke lint below.
See Install clang-format for requirements.
Runs both format:node and format:worker tasks.
Format TypeScript and JavaScript code using Prettier.
Rewrites mediasoup worker C++ files using clang-format. It invokes invoke format below.
See Install clang-format for requirements.
Runs clang-tidy and performs C++ code checks following worker/.clang-tidy rules. It invokes invoke tidy below.
See Install clang-tidy for requirements.
Same as npm run tidy:worker but it also applies fixes.
Runs both flatc:node and flatc:worker tasks.
Compiles FlatBuffers .fbs files in worker/fbs to TypeScript code.
Compiles FlatBuffers .fbs files in worker/fbs to C++ code.
Runs both test:node and test:worker tasks.
Runs Jest test units located at node/test folder.
Jest command arguments can be given using -- as follows:
npm run test:node -- --testPathPatterns "node/src/test/test-Worker.ts" --testNamePattern "createWorker"Runs Catch2 test units located at worker/test folder. It invokes invoke test below.
Runs coverage:node task.
Same as test:node task but it also opens a browser window with TypeScript coverage results.
Runs linters and tests in Node and C++ code. Also verifies that CHANGELOG.md has an entry matching the mediasoup version in package.json.
Prepares and triggers the release of a new version "x.y.z" of the mediasoup NPM package. The actual GitHub release and NPM publish are done by GitHub Actions (mediasoup-npm-publish.yaml) once the pushed tag arrives. It:
- Performs checks (lint + test + build + publish dry-run +
CHANGELOG.mdentry check). It runs before the version bump, so the CHANGELOG check validates the previous version's entry (still in package.json), which is harmless. - Bumps the version to "x.y.z" in
package.jsonandpackage-lock.jsonwithnpm version x.y.z --no-git-tag-version, and sets the top### NEXTheading ofCHANGELOG.mdto### x.y.z. - Commits the bump (with a "release x.y.z [no-ci]" message), creates the "x.y.z" tag, and pushes the branch and the tag.
Requirements for it to work:
- Must be called with a SEMVER version as single argument.
- Must be in the main branch.
- Work tree must be clean.
- Changes for the new version must be under the
### NEXTheading inCHANGELOG.md.
Runs linters and tests in Rust code (cargo fmt, cargo clippy, cargo test and cargo doc). Also verifies that rust/CHANGELOG.md has an entry matching the mediasoup crate version in rust/Cargo.toml. Finally, when that version is not yet published on crates.io (i.e. it has been bumped and is about to be released), it also runs the publish dry-run (cargo publish --dry-run for the three crates as a group).
The publish dry-run is skipped when the mediasoup crate version is already published, because Cargo would then resolve the dependencies among the three crates against the already-published copies on crates.io and any schema/API change made since the last release would fail verification spuriously even though nothing is being published.
Prepares and triggers the release of a new version "x.y.z" of a mediasoup Rust crate (mediasoup, mediasoup-sys or mediasoup-types). The actual GitHub release (if any) and crates.io publish are done by GitHub Actions (mediasoup-crate-publish.yaml) once the pushed commit/tag arrives. It:
- Performs checks (lint + test + build + publish dry-run, plus the
rust/CHANGELOG.mdentry check when releasing themediasoupcrate). They run before the version bump, so the CHANGELOG check validates the previous version's entry (still in the manifest), which is harmless. - Bumps the crate version to "x.y.z" in its
Cargo.toml(rust/Cargo.toml,worker/Cargo.tomlorrust/types/Cargo.toml) and reflects it in the (workspace root)Cargo.lock. When releasingmediasoup-sys/mediasoup-types, it also bumps the matchingversionrequirement of that dependency in themediasoupcrate'srust/Cargo.toml(committed together with the release), so themediasoupcrate keeps depending on the just-released version.
Then, depending on the crate:
- For
mediasoup: it also sets the top### NEXTheading ofrust/CHANGELOG.mdto### x.y.z, commits the bump (with arelease rust-x.y.z [no-ci]message), creates therust-x.y.ztag and pushes the branch and the tag. The tag triggersmediasoup-crate-publish.yaml, which creates the GitHub release fromrust/CHANGELOG.mdand publishes the crate. - For
mediasoup-sys/mediasoup-types: it commits the bump with a<crate> x.y.z [crate-publish] [no-ci]message and pushes the branch (no tag, no CHANGELOG change). The[crate-publish]marker is whatmediasoup-crate-publish.yamldetects on the branch push to publish that crate (without a GitHub release).
Since mediasoup depends on mediasoup-sys and mediasoup-types, when several crates need a new version publish the dependencies first (mediasoup-types / mediasoup-sys) and mediasoup last, so each crate's dependencies are already on crates.io. The releases can be run back to back without waiting for the dependencies' GitHub Actions runs to complete: mediasoup-crate-publish.yaml runs are serialized through a single concurrency queue, so the mediasoup one stays queued until the sibling crates are published (see Rust-crates.md). Requirements for it to work:
- Must be called with a crate name and a SEMVER version as the two arguments.
- Must be in the main branch.
- Work tree must be clean.
Cargo.lockmust be in sync (runcargo buildand commit it if needed), otherwise the release aborts before doing anything irreversible.- When releasing the
mediasoupcrate, the changes for the new version must be under the### NEXTheading inrust/CHANGELOG.md.
The only special feature in Rust case is special environment variable "MEDIASOUP_LOCAL_DEV", that when set to "true" will allow incremental recompilation of changed C++ sources during hacking on mediasoup.
It is not necessary for normal usage of mediasoup as a dependency.
Other than that and normal cargo commands, see npm run release:rust:check and npm run release:rust above.
mediasoup uses Python Invoke library for managing and organizing tasks in the worker folder (mediasoup worker C++ subproject). Invoke is basically a replacemente of make + Makefile written in Python. mediasoup automatically installs Invoke in a local custom path during the installation process (in both Node and Rust) so the user doesn't need to worry about it.
Tasks are defined in worker/tasks.py. For development purposes, developers or contributors can install Invoke using pip3 install invoke and run tasks below within the worker folder.
See all the tasks by running invoke --list within the worker folder.
NOTE: For some of these tasks to work, npm dependencies of worker/scripts/package.json must be installed:
npm ci --prefix worker/scriptsAlias of invoke mediasoup-worker task below.
Installs meson and ninja into a local custom path.
Cleans built objects and binaries.
Cleans built objects and other artifacts, but keeps mediasoup-worker binary in place.
Cleans meson and ninja installed in local prefix with pip.
Cleans subprojects downloaded with Meson.
Cleans built objects and binaries, meson and ninja installed in local prefix with pip and all subprojects downloaded with Meson.
Check the status of the Meson subprojects. It also prints whether there are updates available.
Updates the wrap file of a Meson subproject (those in worker/subprojects folder). After updating it, invoke setup must be called by passing MESON_ARGS="--reconfigure" environment variable. Usage example:
cd worker
invoke update-wrap-file openssl
MESON_ARGS="--reconfigure" invoke setupBuilds the mediasoup-worker binary at worker/out/Release.
If the "MEDIASOUP_MAX_CORES" environment variable is set, the build process will use that number of CPU cores. Otherwise it will auto-detect the number of cores in the machine.
"MEDIASOUP_BUILDTYPE" environment variable controls build types, "Release" and "Debug" are presets optimized for those use cases. Other build types are possible too, but they are not presets and will require "MESON_ARGS" use to customize build configuration.
Check the meaning of useful macros in the worker/include/Logger.hpp header file if you want to enable tracing or other debug information.
Binary is built at worker/out/MEDIASOUP_BUILDTYPE/build.
In order to instruct the mediasoup Node.js module to use the "Debug" mediasoup-worker` binary, an environment variable must be set before running the Node.js application:
MEDIASOUP_BUILDTYPE=Debug node myapp.jsIf the "MEDIASOUP_WORKER_BIN" environment variable is set (it must be an absolute file path), mediasoup will use the it as mediasoup-worker binary and won't compile the binary:
MEDIASOUP_WORKER_BIN="/home/xxx/src/foo/mediasoup-worker" node myapp.jsBuilds the libmediasoup-worker static library at worker/out/Release.
"MEDIASOUP_MAX_CORES"` and "MEDIASOUP_BUILDTYPE" environment variables from above still apply for static library build.
Builds a Xcode project for the mediasoup worker subproject.
Validates mediasoup worker C++ files using clang-format and rules in worker/.clang-format. It also validates Python code within worker folder (i.e. worker/tasks.py file).
Requirements:
- A specific version of
clang-formatis required. See Install clang-format. clang-format-VERSIONorclang-format(corresponding to the required version) must be in thePATH. If not, add it before running the command.
Rewrites mediasoup worker C++ files using clang-format.
Requirements:
- A specific version of
clang-formatis required. See Install clang-format. clang-format-VERSIONorclang-format(corresponding to the required version) must be in thePATH. If not, add it before running the command.
Runs clang-tidy and performs C++ code checks following worker/.clang-tidy rules.
Requirements:
invoke cleanmust have been called first.- A specific version of
clang-tidyis required. See Install clang-tidy. clang-tidy-VERSIONorclang-tidy(corresponding to the required version) must be in thePATH. If not, add it before running the command. Same for otherclang-tidyrelated executables such asrun-clang-tidyandclang-apply-replacements,
Environment variables:
- "MEDIASOUP_TIDY_CHECKS": Optional. Comma separated list of checks. Overrides the checks defined in
worker/.clang-tidyfile. - "MEDIASOUP_TIDY_FILES": Optional. Space separated source file paths to process. All
.cppfiles will be processes by default.- File paths must be relative to
worker/folder. - File paths can use glob syntax. Example:
"src/RTC/SCTP/**/*.cpp".
- File paths must be relative to
Usage example in macOS:
PATH="/opt/homebrew/opt/llvm/bin/:$PATH" invoke tidyIt may happens that clang-tidy doesn't know where C++ standard libraries are so it shows lot of warnings about them. Depending on your local setup this may work:
PATH="/opt/homebrew/opt/llvm/bin/:$PATH" CPATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1 invoke tidySame as invoke tidy but it also applies fixes.
Builds and runs the mediasoup-worker-test binary at worker/out/Release (or at worker/out/Debug if the "MEDIASOUP_BUILDTYPE" environment variable is set to "Debug"), which uses Catch2 to run test units located at worker/test folder.
Run test with Address Sanitizer with -fsanitize=address.
Run test with Address Sanitizer with -fsanitize=undefined.
Builds the mediasoup-worker-fuzzer binary (which uses libFuzzer) at worker/out/Release (or at worker/out/Debug/ if the "MEDIASOUP_BUILDTYPE" environment variable is set to "Debug").
Requirements:
- Linux with fuzzer capable clang++.
- "CC" environment variable must point to
clang. - "CXX" environment variable must point to
clang++.
Read the Fuzzer documentation for detailed information.
Runs all fuzzer cases.
Builds a Linux Ubuntu Docker image with fuzzer capable clang++ and all dependencies to run mediasoup.
Runs a container of the Ubuntu Docker image created with invoke docker. It automatically executes a bash session in the mediasoup directory, which is a Docker volume that points to the mediasoup root folder.
NOTE: To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the worker directory and running invoke clean-all.
Builds a Linux Alpine Docker image with all dependencies to run mediasoup.
Runs a container of the Alpine Docker image created with invoke docker-alpine. It automatically executes an ash session in the mediasoup directory, which is a Docker volume that points to the mediasoup root folder.
NOTE: To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the worker directory and running invoke clean-all.
Builds a 386 Linux Debian (32 bits arch) Docker image with all dependencies to run mediasoup.
Runs a container of the 386 Linux Debian (32 bits arch) Docker image created with invoke docker-386. It automatically executes an ash session in the mediasoup directory, which is a Docker volume that points to the mediasoup root folder.
NOTE: To install and run mediasoup in the container, previous installation (if any) must be properly cleaned by entering the worker directory and running invoke clean-all.
NOTE: Due to the very old Node v18 in this image, in order to run mediasoup Node tests, npm ci must be executed with --ignore-scripts --engine-strict=false arguments.
The worker folder contains a Makefile file for the mediasoup worker C++ subproject. It acts as a proxy to the Invoke tasks defined in tasks.py. The Makefile file exists to help developers or contributors that prefer keep using make commands.
All tasks defined in tasks.py (see above) are available in Makefile. There is only one exception:
- The
update-wrap-fileneeds a "SUBPROJECT" environment variable indicating the subproject to update. Usage example:cd worker make update-wrap-file SUBPROJECT=openssl
A specific clang-format version is required to be installed in the system, which is defined in clang-scripts.mjs.
macOS:
brew install clang-format@VERSIONLinux:
apt-get install clang-format-VERSIONA specific clang-tidy version is required to be installed in the system, which is defined in clang-scripts.mjs.
macOS:
brew install clang-tidy@VERSIONLinux:
apt-get install clang-tidy-VERSION