Skip to content

bishabosha/Scone-player

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

56 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Scone

Scone app icon

Scone is a media player built with Scala.js, Calico, Electron, and WebTorrent.

It features a plugin system for backend playback, see bishabosha/Scone-plugin-VLC (based on Scala Native).

Features

  • Local file playback
  • Streaming torrent playback from 🧲 magnet links or .torrent files
  • Queue multiple files and switch between them
  • Audio track and subtitle

Screenshots

Scone streaming Big Buck Bunny with the playback controls visible

Scone opening a Big Buck Bunny torrent and showing download progress in the queue

Screenshots above use the Big Buck Bunny magnet listed on WebTorrent's free torrents page.

Prerequisites

  • Node.js and npm
  • JDK 17+ for building Scala.js code
  • sbt
  • cwebp for regenerating icon assets

Build And Run

Install dependencies first:

npm install

Start the development app:

npm run dev

This does three things together:

  1. fast-links the Scala.js projects
  2. starts the Vite dev server
  3. launches Electron

Build production assets:

npm run build

Create a macOS app bundle in dist/:

npm run package:mac

Build a distributable package:

npm run dist

Regenerate the app and README icons:

npm run icon:generate

Plugin Loading

Scone does not bundle a playback backend inside the host app. Instead, it discovers plugins from a player-plugins directory.

Dev

When running npm run dev, Scone discovers plugins from:

player-plugins/<plugin-id>/

Each plugin must live in its own direct child directory under player-plugins.

If you are building a plugin in a separate repo, (e.g. bishabosha/Scone-plugin-VLC) the typical flow is:

  1. build the plugin in its own repo
  2. copy or symlink the built plugin directory into player-plugins/<plugin-id>
  3. start Scone with npm run dev

The build does not build external plugins for you. The host app only discovers what is already present when Electron launches.

Packaged App

In packaged builds, Scone discovers plugins from the app's resources directory.

On macOS that means:

Scone.app/Contents/Resources/player-plugins/<plugin-id>/

The packaged app already ships a small player-plugins scaffold, including:

  • Contents/Resources/player-plugins/README.txt
  • Contents/Resources/player-plugins/package.json

Leave that root package.json in place. It is part of how plugin entry files are loaded.

After installing, removing, or updating a plugin in a packaged app, quit and reopen Scone.

Plugin Directory Shape

The host expects a plugin directory to contain a plugin.json manifest. Entry files are resolved relative to the plugin directory.

A typical shape looks like this:

<plugin-id>/
  plugin.json
  generated/
    main.js
  native/
  runtime/

The exact extra folders are plugin-specific. The host only cares about the manifest and the selected JavaScript entrypoint.

Example plugin.json shape:

{
  "id": "example-player",
  "name": "Example Player",
  "kind": "native",
  "bundled": true,
  "main": "generated/main.js",
}

main can be either:

  • a single string entrypoint
  • or an object with separate dev and prod entrypoints, Scone will pick either based on the launch mode.

Shared Plugin API

The public host/plugin boundary lives in shared/src/main/scala/sconeplayer/shared/PlayerPluginJsApi.scala.

That API defines:

  • the plugin manifest shape
  • the load context passed into a plugin
  • the registration entrypoint
  • the generic player bridge methods the shell expects

If an external plugin repo depends on the shared API through local Ivy, publish it first from the host repo:

npm run plugin-api:publish-local

App Architecture

Scone uses Scala.js as the primary programming language.

Renderer

The renderer lives in src/main/scala/sconeplayer.

It is built with:

The main renderer app is src/main/scala/sconeplayer/MediaPlayerApp.scala. It uses functional reactive programming to drive UI changes via streaming of state changes.

Electron Shell

The Electron main process bootstrap is tiny and lives in electron/main.mjs.

Its job is:

  1. choose dev or prod generated Scala.js modules
  2. discover player plugins before the shell starts
  3. import the generated shell entrypoint

Most Electron-side behavior is implemented in Scala.js under shell/src/main/scala/sconeplayer/shell, including:

  • IPC handlers
  • window lifecycle
  • media inspection
  • torrent support
  • player plugin dispatch

The shell runtime starts from shell/src/main/scala/sconeplayer/shell/ElectronShellRuntime.scala.

Preload

The preload bridge is also Scala.js and lives in preload/src/main/scala/sconeplayer/preload/PreloadMain.scala.

It exposes a narrow mediaShell API into the renderer instead of letting UI code reach directly into Electron globals.

Plugin Loader

Plugin discovery and dynamic loading are implemented in Scala.js in plugin-loader/src/main/scala/sconeplayer/pluginloader/PlayerPluginLoader.scala.

The loader:

  • enumerates plugin directories
  • reads plugin.json
  • picks the right entrypoint for dev or packaged mode
  • imports the plugin module dynamically
  • stores discovered plugins and load errors for the shell runtime

Shared Data Model

JSON payloads exchanged between renderer, preload, shell, and plugins are defined in shared/src/main/scala/sconeplayer/shared/model.scala.

This keeps playback snapshots, source items, track info, and plugin descriptors aligned across every runtime boundary.

Build Layout

The sbt build in build.sbt is split into several Scala.js projects:

  • root: renderer
  • shell: Electron shell runtime
  • preload: preload bridge
  • plugin-loader: plugin discovery bootstrap
  • pluginApi: shared plugin API

Dev and prod link outputs are written under:

electron/generated/dev/
electron/generated/prod/

Vite is responsible for the browser-facing renderer assets, while Scala.js owns the application logic.

Related Docs

About

Scone is a media player for torrents build with Scala.js and Electron

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors