FFmpeg-backed media player for the browser and VS Code. The player demuxes and decodes in WebAssembly, paints video tracks to canvas, plays audio through Web Audio, and does not require a backend server.
Clone the repository and fetch submodules:
git clone --recurse-submodules <repo-url> ffplayer
cd ffplayerFor an existing checkout:
git submodule update --init --recursiveCreate and activate the local conda environment:
conda env create --prefix ./.conda -f environment.yml
conda activate ./.condaBuild everything from the repo root:
npm run buildThis creates the browser and VS Code assets in:
app/browser/dist/
app/vscode/dist/
Clean generated files:
npm run cleanServe the built assets:
npm run serveThis starts a local server and opens the page. To serve without opening a browser:
npm run serve:no-openThen choose Open file or Open directory.
The browser build is static and can be hosted on GitHub Pages. In the repository settings, set Pages to deploy from GitHub Actions, then run the Publish Pages workflow or push to main.
Build the wasm assets first:
npm run buildRun from source:
code .Press F5, or run Run and Debug: Start Debugging. In the Extension Development Host, open a supported media file. The extension is registered as the default editor for supported media extensions; use Open With... to switch manually.
Package and install:
npm run package
code --install-extension app/vscode/dist-package/ffplayer-0.1.0.vsixReload VS Code after installing.
ffplayer uses one root package version for the browser build, VS Code extension, and git tag. Use plain major.minor.patch versions:
npm version <version> --workspaces --include-workspace-root --allow-same-version
git push origin main --tagsnpm version updates the root package.json and workspace package manifests, creates the release commit, and creates a tag such as v0.1.1.
The VS Code Marketplace does not accept prerelease SemVer strings such as 0.1.0-alpha.0. Prerelease publishing is controlled by the vsce --pre-release flag, not by a version suffix. Publishing the same version twice is rejected by the Marketplace, so every Marketplace upload needs a new global release version.
Publish an alpha build to the VS Code Marketplace:
VSCE_PAT=<publisher-token> npm run vscode:publishFor GitHub Actions, add a repository secret named VSCE_PAT, then run the Publish VS Code Extension workflow or push a v* tag. The workflow builds the Wasm assets and publishes the VS Code alpha. Make sure publisher in app/vscode/package.json matches your Marketplace publisher id before publishing.
Open this repository through Remote-SSH, WSL, or Dev Containers, build the wasm assets in that workspace, then press F5 from the remote VS Code window.
The extension declares "extensionKind": ["ui", "workspace"], so VS Code can run it in either host. It uses vscode.workspace.fs and bundled app/vscode/dist/ assets; it does not use a backend server or direct Node filesystem paths.
The current VS Code bridge transfers the opened file as one Uint8Array, so it refuses files larger than 256 MB to avoid making the extension host unresponsive. Large media should move to a range-read bridge between the webview and extension host.
The root package.json is a thin npm workspace orchestrator. App-specific scripts live in:
app/browser/package.json
app/vscode/package.json
app/wasm/package.json
The Wasm workspace shell scripts are small adapters around upstream build systems: FFmpeg uses configure/make, dav1d uses Meson/Ninja, and this project uses CMake for the Wasm binding.