MuseScore's libmscore (the core library) in WebAssembly!
- Parse
msczfile data - Get score metadata
- Export part score
- Generate music sheets in SVG/PNG/PDF format
- Generate MIDI
- Generate audio files in WAV, OGG, MP3, or FLAC format
- Synthesize raw audio frames, can be used in the Web Audio API
- Export as MusicXML compressed/uncompressed
- Generate position information of measures or segments on the generated sheets
- Run inside a Web Worker thread
Important
The latest version available on npm corresponds to MuseScore 3, published by the original LibreScore project. For other versions, refer to (successively) CarlGao4 (v4.3.2) augustin64 (v4.6.5) partitioncloud (this repo, v4.6.5-1 to current)
The package is available on npm: https://www.npmjs.com/package/webmscore
npm i webmscore<!-- using a CDN -->
<script src="https://cdn.jsdelivr.net/npm/webmscore/webmscore.js"></script>
<script>
WebMscore.ready.then(async () => {
const score = await WebMscore.load('mscz', msczdata)
})
</script>For latest browsers which support ES Modules
import WebMscore from 'https://cdn.jsdelivr.net/npm/webmscore/webmscore.mjs'Minimum version: v8.9.0 with ES Modules support
The --experimental-modules flag is required for Node.js versions under 14,
Also require "type": "module" in package.json
Node.js greater or equal to v18 is not supported. Node.js v16 is recommended.
import WebMscore from 'webmscore'
WebMscore.ready.then(async () => {
const score = await WebMscore.load('mscz', msczdata)
})(TBD)
If your score sheet contains characters out of the range of the bundled FreeFont, those characters will be shown as tofu characters (□ or �) in SVG/PNG/PDF files. Loading extra fonts is required.
webmscore can load any font format supported by FreeType.
const score = await WebMscore.load('mscz', msczdata, [...arrOfFontData])CJK fonts are no longer bundled inside webmscore since v0.6.0
Loading a soudfont (sf2/sf3) file is required before generating/synthesizing audio.
await score.setSoundFont(soudfontData)Soudfonts can be found on musescore.org website.
Example: (FluidR3Mono_GM.sf3)
const soudfontData = new Uint8Array(
await (
await fetch('https://cdn.jsdelivr.net/gh/musescore/MuseScore@2.1/share/sound/FluidR3Mono_GM.sf3')
).arrayBuffer()
)Sometimes you only want to process a bunch of score metadata, so drawing sheet images internally is a waste of time and system resource.
You can enable the Boost Mode by setting the doLayout parameter in WebMscore.load to false.
Example:
const score = await WebMscore.load('mscz', msczdata, [], false)
const metadata = await score.metadata()
score.destroy()webmscore's Boost Mode is about 3x faster than the batch converter feature (-j) of the musescore software, according to the benchmark result.
WebAssembly vs native C++ program!
Tip
You can use act to download these dependencies and handle the build process for you, in a container.
-
Install essential tools like
make,cmake,ninja,llvm, etc. -
Install
emscriptenv4.0.7 usingemsdkhttps://emscripten.org/docs/getting_started/downloads.html -
Get Qt6 for WebAssembly and apply patches
MuseScore 4.7 requires Qt >= 6.8, webmscore is built with Qt 6.10 (single threaded). Cross compiling also needs a host Qt of the same version, for the build tools (moc, rcc, ...).
AQT_PREFIX=$PWD/build.qt6
Qt6_VER=6.10.2
Qt6_DIR=${AQT_PREFIX}/${Qt6_VER}/wasm_singlethread
# if you change the install directory or Qt version, remember to also change the
# `Qt6_VER` / `QT6_ROOT` variables in the `web/Makefile` file
# Download Qt using aqtinstall (https://github.com/miurahr/aqtinstall)
pip install aqtinstall
aqt install-qt linux desktop ${Qt6_VER} linux_gcc_64 --outputdir ${AQT_PREFIX} --archives qtbase qtdeclarative qtsvg icu --modules qt5compat
aqt install-qt all_os wasm ${Qt6_VER} wasm_singlethread --outputdir ${AQT_PREFIX} --archives qtbase qtdeclarative qtsvg --modules qt5compat
# Apply patches, which
# enable the prebuilt `offscreen` QPA platform plugin (https://doc.qt.io/qt-6/qpa.html), and
# exclude the `wasm` QPA platform plugin, which requires a DOM
cp -r buildscripts/qt/* ${Qt6_DIR}
find ${Qt6_DIR}/lib/cmake/Qt6Gui/ -name 'Qt6QWasmIntegration*' -deleteThe prebuilt offscreen plugin is committed in buildscripts/qt;
run build_offscreen_plugin.sh to rebuild it
(needed when the Qt or emsdk version changes).
- Checkout submodules
git submodule init
git submodule update- Compile
webmscore
cd web-public
npm i
npm run buildBuild artifacts are in the web-public directory
All modern browsers which support WebAssembly and Async Functions
| Name | Minimum Version |
|---|---|
| Chrome | 57 |
| Firefox | 53, 52 (non-ESR) |
| Edge | 16 (Fall Creators Update) |
| Safari | 11 |
| IE | NO! |
| Other browsers | I don't know! |
Only tested on the latest version of Chrome and Firefox.
see files in the web-example directory
cd ./web-example
npm i
npm start # Node.js example
npm run start:browser # browser exampleThe test suite (Node.js ≥ 22) runs against the package installed in web-example:
cd ./web-example
npm i ../web-public --install-links
npm testTests live in web-example/test, one file per area (loading, exports, positions,
metadata, audio). Known bugs are kept as todo tests: they are reported but do not fail the run.
See How to look up function names in the .symbols file?
webmscore is part of the LibreScore project.