All Projects → leolabs → ableton-js

leolabs / ableton-js

Licence: other
Control Ableton Live with Node.js

Programming Languages

typescript
32286 projects
python
139335 projects - #7 most used programming language
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to ableton-js

Scribbletune
Create music with JavaScript
Stars: ✭ 3,509 (+3061.26%)
Mutual labels:  live, ableton
P2P-DPlayer
DPLayer powered by CDNBye P2P Engine
Stars: ✭ 63 (-43.24%)
Mutual labels:  live
blrec
Bilibili Live Streaming Recorder 哔哩哔哩直播录制
Stars: ✭ 124 (+11.71%)
Mutual labels:  live
twilio-live-interactive-video
An interactive live video app built with Twilio Live and Twilio Video
Stars: ✭ 23 (-79.28%)
Mutual labels:  live
streaming-pt
Live TV 📺 and Radio 📻 shell scripts from Portugal 🇵🇹.
Stars: ✭ 52 (-53.15%)
Mutual labels:  live
LFLiveKit-ReplayKit
A ReplayKit Version
Stars: ✭ 46 (-58.56%)
Mutual labels:  live
hexblade
My own Linux desktop and docker image on top of Ubuntu.
Stars: ✭ 15 (-86.49%)
Mutual labels:  live
Diffy
🎞️💓🍿 Love streaming - It's always best to watch a movie together ! 🤗
Stars: ✭ 37 (-66.67%)
Mutual labels:  live
Kanon
A live programming environment specialized for data structure programming.
Stars: ✭ 57 (-48.65%)
Mutual labels:  live
vuepress-plugin-example-preview
Easily display the preview of a code snippet
Stars: ✭ 15 (-86.49%)
Mutual labels:  live
ipchub
一个即拷即用、支持摄像头集中管理、多级路由及h5播放的流媒体服务器。
Stars: ✭ 138 (+24.32%)
Mutual labels:  live
hackupc-landing
🚀 HackUPC's landing page
Stars: ✭ 31 (-72.07%)
Mutual labels:  live
termbacktime
Terminal recording and playback.
Stars: ✭ 33 (-70.27%)
Mutual labels:  live
live-form-validation
⛔ Nice client-side live form validation for Nette Forms.
Stars: ✭ 55 (-50.45%)
Mutual labels:  live
vuepress-plugin-live
Make your markdown code examples come alive
Stars: ✭ 37 (-66.67%)
Mutual labels:  live
like-fx-miniapp
微信小程序直播点赞效果
Stars: ✭ 19 (-82.88%)
Mutual labels:  live
squashible
Cross-Platform Linux Live Image Builder
Stars: ✭ 22 (-80.18%)
Mutual labels:  live
KSYAirStreamer iOS
金山云 iOS Airplay 录屏直播SDK
Stars: ✭ 44 (-60.36%)
Mutual labels:  live
recurse
re<urse is a declarative language for generating musical patterns
Stars: ✭ 32 (-71.17%)
Mutual labels:  ableton
BlueSkyTv
简单的安卓TV 超纯净
Stars: ✭ 17 (-84.68%)
Mutual labels:  live

Ableton.js

Current Version

Ableton.js lets you control your instance or instances of Ableton using Node.js. It tries to cover as many functions as possible.

This package is still a work-in-progress. My goal is to expose all of Ableton's MIDI Remote Script functions to TypeScript. If you'd like to contribute, please feel free to do so.

Sponsored Message

I've used Ableton.js to build a setlist manager called AbleSet. AbleSet allows you to easily manage and control your Ableton setlists from any device, re-order songs and add notes to them, and get an overview of the current of your set.

AbleSet Header

Prerequisites

To use this library, you'll need to install and activate the MIDI Remote Script in Ableton.js. To do that, copy the midi-script folder of this repo to Ableton's Remote Scripts folder. If you prefer, you can rename it to something like AbletonJS for better identification. The MIDI Remote Scripts folder is usually located at:

  • Windows: {path to Ableton}\Resources\MIDI\Remote Scripts
  • macOS: /Applications/Ableton Live {version}/Contents/App-Resources/MIDI Remote Scripts

After starting Ableton Live, add the script to your list of control surfaces:

Ableton Live Settings

If you've forked this project on macOS, you can also use yarn to do that for you. Running yarn ableton:start will copy the midi-script folder, open Ableton and show a stream of log messages until you kill it.

Using Ableton.js

This library exposes an Ableton class which lets you control the entire application. You can instantiate it once and use TS to explore available features.

Example:

import { Ableton } from "ableton-js";

const ableton = new Ableton();

const test = async () => {
  ableton.song.addListener("is_playing", (p) => console.log("Playing:", p));
  ableton.song.addListener("tempo", (t) => console.log("Tempo:", t));

  const cues = await ableton.get("cue_points");
  console.log(cues.map((c) => c.raw));
};

test();

Events

There are a few events you can use to get more under-the-hood insights:

// A connection to Ableton is established
ab.on("connect", (e) => console.log("Connect", e));

// Connection to Ableton was lost,
// also happens when you load a new project
ab.on("disconnect", (e) => console.log("Disconnect", e));

// A raw message was received from Ableton
ab.on("message", (m) => console.log("Message:", m));

// A received message could not be parsed
ab.on("error", (e) => console.error("Error:", e));

// Fires on every response with the current ping
ab.on("ping", (ping) => console.log("Ping:", ping, "ms"));

Protocol

Ableton.js uses UDP to communicate with the MIDI Script. Each message is a JSON object containing required data and a UUID so request and response can be associated with each other.

Compression and Chunking

To allow sending large JSON payloads, requests to and responses from the MIDI Script are compressed using gzip and chunked every 7500 bytes. The first byte of every message contains the chunk index (0x00-0xFF) followed by the gzipped chunk. The last chunk always has the index 0xFF. This indicates to the JS library that the previous received messages should be stiched together, unzipped, and processed.

Commands

A command payload consists of the following properties:

{
  "uuid": "a20f25a0-83e2-11e9-bbe1-bd3a580ef903", // A unique command id
  "ns": "song", // The command namespace
  "nsid": null, // The namespace id, for example to address a specific track or device
  "name": "get_prop", // Command name
  "args": { "prop": "current_song_time" } // Command arguments
}

The MIDI Script answers with a JSON object looking like this:

{
  "data": 0.0, // The command's return value, can be of any JSON-compatible type
  "event": "result", // This can be 'result' or 'error'
  "uuid": "a20f25a0-83e2-11e9-bbe1-bd3a580ef903"
}

Events

To attach an event listener to a specific property, the client sends a command object:

{
  "uuid": "922d54d0-83e3-11e9-ba7c-917478f8b91b", // A unique command id
  "ns": "song", // The command namespace
  "name": "add_listener", // The command to add an event listener
  "args": {
    "prop": "current_song_time", // The property that should be watched
    "eventId": "922d2dc0-83e3-11e9-ba7c-917478f8b91b" // A unique event id
  }
}

The MIDI Script answers with a JSON object looking like this to confirm that the listener has been attached:

{
  "data": "922d2dc0-83e3-11e9-ba7c-917478f8b91b", // The unique event id
  "event": "result", // Should be result, is error when something goes wrong
  "uuid": "922d54d0-83e3-11e9-ba7c-917478f8b91b" // The unique command id
}

From now on, when the observed property changes, the MIDI Script sends an event object:

{
  "data": 68.0, // The new value, can be any JSON-compatible type
  "event": "922d2dc0-83e3-11e9-ba7c-917478f8b91b", // The event id
  "uuid": null // Is always null and may be removed in future versions
}

Note that for some values, this event is emitted multiple times per second. 20-30 updates per second are not unusual.

Connection Events

The MIDI Script sends events when it starts and when it shuts down. These look like this:

{
  "data": null, // Is always null
  "event": "connect", // Can be connect or disconnect
  "uuid": null // Is always null and may be removed in future versions
}

When you open a new Project in Ableton, the script will shut down and start again.

When Ableton.js receives a disconnect event, it clears all current event listeners and pending commands. It is usually a good idea to attach all event listeners and get properties each time the connect event is emitted.

Findings

In this section, I'll note interesting pieces of information related to Ableton's Python framework that I stumble upon during the development of this library.

  • It seems like Ableton's listener to output_meter_level doesn't quite work as well as expected, hanging every few 100ms. Listening to output_meter_left or output_meter_right works better. See Issue #4
  • The playing_status listener of clip slots never fires in Ableton. See Issue #25
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].