See types for available type declarations
const player = new JSONg(
path?:string,
options?: {
onload?: ()=>void,
context?: AudioContext,
verbose?: boolean,
disconnected?: boolean,
debug?: boolean
}
)
You can provide a song to load right away upon the creation, but you will have to provide a callback using options.onload
as the constructor cannot be async
.
You can also provide your own AudioContext
into the player using option.context
If you specify option.disconnected = true
, the player will not be automatically connected to the audio context output node. This is done so that you can manually route the player through other effect nodes manually using the output
property.
This JSONg
object is instantiated with the new
keyword and has the following public methods:
The following public properties are available for usage also:
-
trackList: { name: string; source: string; db: number; audioOffsetSeconds:number; }[]
This list provides the names of the tracks, the source that it uses, as well as any audio offset that is being used.
-
tracks: { [key: string]: Volume; }
This is a set of output nodes for all tracks, this way individual track volumes may be controlled externally.
-
sections: PlayerSectionGroup
These are the loaded song sections that have been parsed from the manifest file. This is what the player uses to reference region lengths and flow rules for repeats, as well as transitioning directives and information regarding scheduling.
-
beginning: PlayerIndex
This is the first section that will be used to start from by default.
-
current: PlayerSection
This is the current section that is playing now.
-
next: [PlayerSection | undefined, PlayerIndex[] | undefined]
This will be the next section that the player will transition to, if not cancelled.
-
state: PlayerState
This is the current state of the player, reflecting any actions that the player is about to take. States are described in detail in docs/LOGIC.md
-
timingInfo: { bpm: number; meter: [number, number]; grain: number; beatDuration: number; metronome: { db: number; high: string; low: string; enabled: boolean; }; }
This is internal information used by the player sourced from the manifest file to determine key timing parameters for scheduling sections.
-
output: Volume
This is the main output node that is connected to the
AudioContext
output by default
This function allows you to pre process a manifest file in the background, in order to check if the file is adequate for loading into the player. This gives you the ability to preload the file as to not interrupt the player. You can even preload several files and all their audio sources for hot-swapping them without interrupting audio playback.
Parameter: file
- either a string or an already parsed JSON file as a JavaScript object.
Returns: Promise
- with a resulting JS object that contains all necessary details to load a song into the player. Use this later with the useManifest
function.
async useManifest(manifest: PlayerJSONg, options?:{origin?: string, loadSound?: PlayerAudioSources}) : Promise<void>
This function uses pre-parsed manifest files in order to actually load the player with music information. You can provide options which are there to stop the default behaviour of trying to load audio sources from the manifest.
You can manually create the appropriate audio buffers and either feed them later using useAudio
or provide them here using options.loadSound
.
Parameter: manifest
- a JS object retured by a successful call to parseManifest()
Parameter: options
- an optional option set for directing the player on if / how to load audio sources. You can provide the origin url which is used as a base to fetch audio files from. You can also provide a whole object full of audio buffers to be used by the player
Returns: Promise
- resolved when all is loaded correctly, and rejected if any errors take place
useAudio(sources: JSONgDataSources | PlayerAudioSources, origin?: string, offset?: number): Promise<undefined>
This section is used internally by useManifest
as a default strategy to loading audio sources. You can specify that useManifest
should not load audio, and proceed to do so manually. This is useful for other applications which could for example use Electron.js and load files that are local on the user's machine.
Parameter: sources
- a set of key pair values, keys are track names as strings, values are either:
- a URL to the file, where the
origin
parameter is considered if provided - a
ToneAudioBuffer
which can also use a URL to fetch audio data - an AudioBuffer that is manually loaded with the correct audio data, this is likely to be done using the player's
AudioContext.decodeAudioData()
Parameter: origin
- a base URL host to fetch files from
Parameter: offest
- you can offset the audio source in seconds. This is useful if the audio file has silent whitespace
at the beginning, which is often a case with mp3 files generated using cetrain encoders.
Used to initiate the song playback. (not applicable if player is already playing)
After the first call from stopped state, the player is put into a playing state.
Any subsequent calls to play will be ignored until in the stopped
state again.
Parameter: from
- You may play from
any section or from the beginning if unspecified
returns Promise
- awaits the player to finish playing
in the case that the beginning section has a once
directive.
Throws on cancellation, i.e. the stop
command
Used to initiate the next section to advance to. (not applicable if player is stopped)
Parameter breakout
- if breakout
is true, repeat rules do not apply,
You may also breakout to any section if breakout
is a PlayerIndex
or advance to the next logical section automatically if nothing is provided
If forcing a different section and breaking up the natural progression, section repeat counter are not advanced
Returns Promise
- fired when the player switches to the queued section
Throws on cancellation, i.e. the stop
or cancel
command
This stop audio playback (not applicable if player is not already playing)
This function also cancels any pending changes.
You may specify that the stop occur abruptly via synced = false
, otherwise
the stop will wait the appropriate amount of time according to the current section directives.
Parameter: synced
- if false, stop is immediate
Returns: Promise
- resolved when the stop takes place
Throws on cancellation using the cancel
command
This function will cancel any pending changes that are queued up
Returns serialised information about where in the song the player is. Details like the current section as well as the potential next section, which group repeat counters will be incremented, and the current group repeat counters.
Returns: object
- name refers to the current section name
{
name: string;
index: PlayerIndex;
next: PlayerIndex | undefined;
increments: PlayerIndex[] | undefined;
repeatCount: number;
repeatLimit: number;
}
This is a ratio of the current section progression, you can also get this by listening to the TransportEvent
.
Returns: number
in the range 0 - 1, derived from currentSectionBeat / beatsInCurrentSection
This returns more precise details about the player's transport information, section progress, and metronome clicks.
Returns: object
- section
property being the progress [sectionBeat, sectionBeats]
{
section: number[];
countdown: number;
transport: {
beat: number;
transport: string;
};
lastLaunchTime: string | null;
contextTime: number;
}
Toggle the current metronome state or manually specify the metronome enable state
Parameter: state
- optional boolean to either turn of the metronome or turn off
Convert beats to seconds. Uses song BMP for the calculation.
*Parameter: beats
- number of beats to convert to seconds.
Convert seconds to number of beats. Uses song BMP for the calculation.
*Parameter: seconds
- number of seconds to convert to beats.
Wait for a number of beats.
*Parameter: beats
- number of beats to wait
*Returns: Promise<void>
- resolves after beats
number has elapsed
Wait for a duration of the section, expressed as a percentage of the bar progression.
*Parameter: percentage
- used to calculate the required wait time using the current section's progress as a percentage
*Returns: Promise<void>
- resolves after the calculated time duration
Returns boolean whether the master output node is muted or not
Explicitly mute the master output
node with a 1 second fadein
Parameter: value
- specify the db value to raise the volume to
Used to schedule synchronized callbacks that alter the DOM or which can cause audio glitches Parameter: callback callback is invoked at the correct time.
The player is also capable of emitting several events, musically tied to the song. See src/types/events.ts
interface JSONgEventsList {
'state': StateEvent;
'transport': TransportEvent;
'click': ClickEvent;
'queue': QueueEvent;
'cancel': CancelQueueEvent;
'change': ChangeEvent;
'repeat': RepeatEvent;
'loop': LoopEvent;
}
const jsong = new JSONg("example.jsong")
jsong.addEventListener("queue",(ev)=>{
console.log("Will change sections",ev.from, ev.to)
//do visual effects to signal upcoming changing of sections
})
jsong.addEventListener("change",(ev)=>{
console.log("Did change sections",ev.from, ev.to)
//stop effects on section change
})
jsong.play()
setTimeout(async ()=>{
await jsong.play()
json.play()
},1000)
The following shows the breakdown of event properties per event type.
Used to signal any player state change, including when audio is loaded or a manifest is applied.
/** A section that will take action */
to?: PlayerSection;
/** A section that will be impacted by current section */
from?: PlayerSection;
Timing information regarding the current section.
progress: [number, number]; // section beat / section beat count
countdown?: number; // if action is queued, countdown in beats until next queue event takes place
Metronome click events. Only fired when the player is playing music
current: [number, number]; // current beat / beats in a bar
Shows what sections will change if not cancelled. The countdown to the actual action is in TransportEvent
/** A section that will take action */
to?: PlayerSection;
/** A section that will be impacted by current section */
from?: PlayerSection;
Shows which section transitions were cancelled
/** A section that will take action */
to?: PlayerSection;
/** A section that will be impacted by current section */
from?: PlayerSection;
Shows which sections just changed
/** A section that will take action */
to?: PlayerSection;
/** A section that will be impacted by current section */
from?: PlayerSection;
Shows which group just repeated from the last section to its first section
group: PlayerSectionGroup;
counter: [number,number]; // current repeat count / repeat limit
Shows which group has had its repeat counter expire / reach its limit.
group: PlayerSectionGroup;