br\u016bhi Script
br\u016bhi Script is a minimal, sandboxed scripting language built into the Desktop app. Use it to write automation programs that are more expressive than the visual rule builder — for example, pulling tracks by multiple criteria, mixing sources, or computing queue logic.
Safety Model
Section titled “Safety Model”Scripts run in a hard sandbox:
- No file I/O — scripts cannot read or write files.
- No network access — scripts cannot make HTTP requests or open sockets.
- No system calls — scripts cannot launch processes or access the OS.
- 5-second timeout — a script that runs longer than 5 seconds is killed automatically.
Scripts are safe to run on any user input. Error messages include the line number of the failure.
Syntax Basics
Section titled “Syntax Basics”br\u016bhi Script is a simple expression language with shell-style comments and method chaining.
# This is a comment
# Assign a valuetracks = library.search("genre:Jazz")
# Method chainingresult = library.search("genre:Jazz").shuffle().limit(20)
# Set the playlist contentplaylist.set(result)- Lines starting with
#are comments. - Variables are dynamically typed.
- Strings use double quotes.
- There are no loops or conditionals — all logic is expressed via method chains.
Objects
Section titled “Objects”library
Section titled “library”Queries your media library.
| Method | Arguments | Returns | Description |
|---|---|---|---|
search(query) | String | TrackList | Full-text search across title, artist, album, genre |
genre(name) | String | TrackList | Filter by exact genre name |
artist(name) | String | TrackList | Filter by exact artist name |
recent(days) | Integer | TrackList | Tracks added in the last N days |
all() | — | TrackList | All tracks in the library |
Search query syntax:
| Pattern | Matches |
|---|---|
"jazz" | Any field containing “jazz” |
"genre:Jazz" | Genre field exactly |
"artist:Miles Davis" | Artist field exactly |
"bpm>120" | BPM greater than 120 |
"duration<300" | Duration less than 300 seconds |
TrackList
Section titled “TrackList”The result of any library query. All TrackList methods return a new TrackList, so they chain.
| Method | Arguments | Returns | Description |
|---|---|---|---|
shuffle() | — | TrackList | Fisher-Yates shuffle |
limit(n) | Integer | TrackList | Keep only the first N tracks |
sort(field) | String | TrackList | Sort by "title", "artist", "bpm", "year", "duration", "added" |
reverse() | — | TrackList | Reverse the current order |
append(other) | TrackList | TrackList | Concatenate two track lists |
playlist
Section titled “playlist”Controls the smart playlist being defined (in Smart Playlist script mode) or the active playlist (in automation scripts).
| Method | Arguments | Description |
|---|---|---|
set(tracks) | TrackList | Replace the playlist entirely with these tracks |
append(tracks) | TrackList | Add tracks to the end of the playlist |
clear() | — | Empty the playlist |
Controls the broadcast queue for the active deck.
| Method | Arguments | Description |
|---|---|---|
add(tracks) | TrackList | Append tracks to the end of the queue |
clear() | — | Empty the queue |
Controls the deck player (automation scripts only).
| Method | Arguments | Description |
|---|---|---|
load(track) | Track | Load a single track to the active deck |
play() | — | Start playback |
pause() | — | Pause playback |
stop() | — | Stop and return to cue point |
schedule
Section titled “schedule”Reads the current schedule state (read-only).
| Property / Method | Returns | Description |
|---|---|---|
schedule.current() | Block or null | The currently active schedule block |
schedule.next() | Block or null | The next upcoming schedule block |
Examples
Section titled “Examples”Jazz shuffle for the evening show
Section titled “Jazz shuffle for the evening show”tracks = library.search("genre:Jazz").shuffle().limit(30)playlist.set(tracks)Uptempo music for drive time
Section titled “Uptempo music for drive time”fast = library.search("bpm>120").sort("bpm")playlist.set(fast.limit(25))Mix genres for a variety show
Section titled “Mix genres for a variety show”rock = library.genre("Rock").shuffle().limit(8)jazz = library.genre("Jazz").shuffle().limit(8)blues = library.genre("Blues").shuffle().limit(4)playlist.set(rock.append(jazz).append(blues).shuffle())Recently added tracks first
Section titled “Recently added tracks first”new_music = library.recent(14).sort("added").reverse()older = library.all().sort("added")playlist.set(new_music.append(older).limit(40))Fill the queue if it is empty
Section titled “Fill the queue if it is empty”# Used as a "Queue is empty" automation actiontracks = library.search("genre:Ambient").shuffle().limit(10)queue.add(tracks)The Script Editor
Section titled “The Script Editor”The Script Editor is in the Schedule tab → Scripts section.
- Create named scripts with
+. - Edit in the monospace code editor.
- Click Run to execute the script immediately.
- Click Preview to evaluate the script and show which tracks would be affected, without making any changes.
- Errors are shown in the error panel below the editor with line number and message.
Ctrl+Ssaves the script.
Error Messages
Section titled “Error Messages”| Message | Meaning |
|---|---|
Timeout after 5000ms | The script exceeded the 5-second limit |
Unknown method 'xyz' on TrackList | Typo in a method name |
Expected string argument | Wrong argument type passed to a method |
Library search error: invalid query | Malformed search query string |