Speakup Article Player - JavaScript API
This documentation describes how to use the Speakup Article Player JavaScript API to receive events and control the player state.
Initializationβ
The API is automatically available through the global $sp object as soon as the player is loaded and initialized.
// Check if the API is ready
if ($sp?.isReady()) {
// The API is ready to use
console.log('Speakup Article Player API is ready!');
}
The $sp object is created immediately when the player loads, but isReady() returns true only after full initialization is complete.
Available Eventsβ
play Eventβ
Emitted when the player starts playing a track.
$sp.onPlay((eventData) => {
console.log('Player started playing:', eventData);
});
pause Eventβ
Emitted when the player is paused.
$sp.onPause((eventData) => {
console.log('Player paused:', eventData);
});
statechange Eventβ
Emitted when the player play/pause state changes.
This event is not emitted when the current song changes. Use the songchange event for track changes.
$sp.onStateChange((eventData) => {
console.log('Player state changed (play/pause):', eventData);
});
songchange Eventβ
Emitted when the current track changes.
$sp.onSongChange((eventData) => {
console.log('Song changed:', eventData);
});
destroy Eventβ
Emitted just before the player is destroyed. This allows listeners to perform their own cleanup operations.
$sp.onDestroy((eventData) => {
console.log('Player is being destroyed:', eventData);
// Perform your cleanup here
});
Event Data Structureβ
All events (play, pause, songchange) share the same data structure:
{
type: 'play', // Event type ('play', 'pause', 'songchange')
timestamp: 1640995200000, // Unix timestamp
currentState: { // Current player state
isPlaying: true,
currentSong: { ... },
timestamp: 1640995200000
},
song: { // Current track data
id: 'podcast-123',
title: 'Podcast Title',
articleUrl: 'https://example.com/article',
author: 'Author Name'
}
}
State Change Event Dataβ
The statechange event contains both current and previous state:
{
type: 'statechange',
timestamp: 1640995200000,
currentState: {
isPlaying: true,
currentSong: { ... },
timestamp: 1640995200000
},
previousState: {
isPlaying: false,
currentSong: { ... },
timestamp: 1640995100000
}
}
Destroy Event Dataβ
The destroy event contains the final state:
{
type: 'destroy',
timestamp: 1640995200000,
currentState: {
isPlaying: false,
currentSong: { ... },
timestamp: 1640995200000
}
}
API Methodsβ
Event Listener Methodsβ
| Method | Description | Returns |
|---|---|---|
onPlay(callback) | Registers a listener for the play event | Function to remove the listener |
onPause(callback) | Registers a listener for the pause event | Function to remove the listener |
onStateChange(callback) | Registers a listener for state changes | Function to remove the listener |
onSongChange(callback) | Registers a listener for track changes | Function to remove the listener |
onDestroy(callback) | Registers a listener for the destroy event | Function to remove the listener |
on(eventType, callback) | Generic method to register listeners | Function to remove the listener |
off(eventType, callback) | Removes a specific listener | - |
removeAllListeners(eventType?) | Removes all listeners for an event type | - |
State Methodsβ
| Method | Description | Returns |
|---|---|---|
getState() | Returns the current player state | { isPlaying, currentSong, timestamp } |
isPlaying() | Checks if the player is playing | boolean |
getCurrentSong() | Returns info about the current track | Song object or null |
isReady() | Checks if the API is ready | boolean |
destroy() | Destroys the player and cleans up | - |
reinit(options?) | Reinitializes the player | - |
Method Detailsβ
onPlay(callback)β
Registers a listener for the play event.
Parameters:
callback(function): Function called when the player starts playing
Returns: Function to remove the listener
const removeListener = $sp.onPlay((data) => {
console.log('Playing:', data.song.title);
});
// To remove the listener later
removeListener();
onPause(callback)β
Registers a listener for the pause event.
Parameters:
callback(function): Function called when the player is paused
Returns: Function to remove the listener
onStateChange(callback)β
Registers a listener for state changes.
Parameters:
callback(function): Function called when the player state changes
Returns: Function to remove the listener
onSongChange(callback)β
Registers a listener for track changes.
Parameters:
callback(function): Function called when the track changes
Returns: Function to remove the listener
$sp.onSongChange((data) => {
console.log('Now playing:', data.song.title);
console.log('Author:', data.song.author);
});
onDestroy(callback)β
Registers a listener for the destroy event. This event is emitted just before the player is destroyed.
Parameters:
callback(function): Function called when the player is about to be destroyed
Returns: Function to remove the listener
$sp.onDestroy((data) => {
console.log('Player is being destroyed');
// Clean up your custom resources here
});
on(eventType, callback)β
Generic method to register listeners.
Parameters:
eventType(string): Event type ('play','pause','statechange','songchange','destroy')callback(function): Callback function
Returns: Function to remove the listener
$sp.on('play', (data) => {
console.log('Playing via generic method');
});
off(eventType, callback)β
Removes a specific listener.
Parameters:
eventType(string): Event typecallback(function): Callback function to remove
removeAllListeners(eventType)β
Removes all listeners for an event type.
Parameters:
eventType(string, optional): Event type. If not specified, removes all listeners
getState()β
Returns the current player state.
Returns: Object with the current state
const state = $sp.getState();
console.log('Current state:', state);
// { isPlaying: true, currentSong: {...}, timestamp: 1640995200000 }
isPlaying()β
Checks if the player is playing.
Returns: boolean - true if the player is playing
if ($sp.isPlaying()) {
console.log('Player is currently playing');
}
getCurrentSong()β
Returns information about the current track.
Returns: Object with the current track data or null if not available
const currentSong = $sp.getCurrentSong();
if (currentSong) {
console.log('Current song:', currentSong.title);
}
isReady()β
Checks if the API is initialized and ready to use.
Returns: boolean - true if the API is ready
destroy()β
Destroys the Speakup Article Player and cleans up all resources.
This method will:
- Stop player playback
- Reset the DOM to its original state
- Remove all event listeners and timers
- Clean up internal state
After calling destroy(), if another player is set up on the page, all event listeners will need to be re-instantiated.
// Listen for destroy event before destroying
$sp.onDestroy((data) => {
console.log('Cleaning up my custom resources...');
});
// Destroy the player
$sp.destroy();
// After destroy, isReady() returns false
console.log($sp.isReady()); // false
reinit(options?)β
Reinitializes the Speakup Article Player. This is useful for Single Page Applications (SPA) where the page content changes without a full page reload, or when you need to switch podcast or render the player into a different container.
This method will:
- Destroy the current player (stop playback, clean up resources)
- Remove all event listeners (they need to be re-registered)
- Initialize a new player with the specified options
Signature:
$sp.reinit({ url, podcastId, container });
Parameters:
options(object, optional): Options object
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | No | Article URL to load. Defaults to the current page URL. |
podcastId | string | No | Base32-encoded podcast identifier β the same value used in the script tag's data-podcast attribute. |
container | Element | No | DOM Element (nodeType 1) to render the player into. Must be attached to the document. Overrides the default #speakup-player element. |
After calling reinit(), all event listeners will be removed and need to be re-registered. The destroy event will be emitted before the player is destroyed, allowing you to perform cleanup.
- The
podcastIdvalue must be the base32-encoded token (same asdata-podcast), not a raw numeric or UUID identifier. You can find this value in the SpeakUp CMS. - When using a custom
container, the element must be an Element node already attached to the document.DocumentFragmentand other node types are not supported. - If no
containeris provided, the player renders into the default#speakup-playerdiv, which must exist in the DOM.
// Reinit with no params (reloads current page URL)
$sp.reinit();
// Reinit with a different article URL
$sp.reinit({ url: 'https://example.com/article' });
// Reinit with a specific podcast (base32-encoded data-podcast value)
$sp.reinit({ podcastId: 'exvqebk1chq6pwkfdtqq6bk3...' });
// Reinit into a custom container element
$sp.reinit({ container: document.getElementById('my-player') });
// Combine all options
$sp.reinit({
url: 'https://example.com/article',
podcastId: 'exvqebk1chq6pwkfdtqq6bk3...',
container: document.getElementById('my-player'),
});
SPA Navigation Example:
// Listen for route changes in your SPA
router.on('routeChange', (newRoute) => {
// Re-register event listeners after reinit
const setupListeners = () => {
$sp.onPlay((data) => {
console.log('Playing:', data.song.title);
});
};
// Reinitialize the player with the new article URL
$sp.reinit({ url: newRoute.url });
// Re-register listeners after reinit
setupListeners();
});
Usage Examplesβ
Basic Exampleβ
// Wait for the API to be ready
function waitForSpeakUpAPI() {
return new Promise((resolve) => {
const checkAPI = () => {
if ($sp?.isReady()) {
resolve();
} else {
setTimeout(checkAPI, 100);
}
};
checkAPI();
});
}
// Use the API
waitForSpeakUpAPI().then(() => {
// Register event listeners
$sp.onPlay((data) => {
console.log('π΅ Started playing:', data.song.title);
});
$sp.onPause((data) => {
console.log('βΈοΈ Paused:', data.song.title);
});
$sp.onSongChange((data) => {
console.log('π Song changed to:', data.song.title);
});
// Check the current state
console.log('Current state:', $sp.getState());
});
Example with Error Handlingβ
if ($sp?.isReady()) {
try {
const removePlayListener = $sp.onPlay((data) => {
// Handle the play event
updateUI(data);
});
// Remove the listener after 30 seconds
setTimeout(() => {
removePlayListener();
console.log('Play listener removed');
}, 30000);
} catch (error) {
console.error('Error setting up Speakup Article Player listeners:', error);
}
} else {
console.warn('Speakup Article Player API not available');
}
Important Notesβ
-
Initialization: The API is available as soon as the PlayerContext component mounts. The
$spobject is created immediately, butisReady()returnstrueonly after full initialization. -
Error Handling: Always check if the API is available before using it.
-
Performance: Listeners are called asynchronously and do not block the user interface.
-
Cleanup: Remember to remove listeners when they are no longer needed to avoid memory leaks.
-
Browser Support: The API is compatible with all modern browsers that support ES6+.
-
SPA Support: For Single Page Applications, use
reinit()to reload the player when navigating to a new article. Remember to re-register event listeners after callingreinit().
Troubleshootingβ
API is not availableβ
if (!$sp) {
console.error('Speakup Article Player not loaded');
} else if (!$sp.isReady()) {
console.warn('Speakup Article Player not ready yet');
}
Listeners are not being calledβ
- Verify that the API is initialized with
isReady() - Check that the player is actually loaded on the page
- Verify that there are no JavaScript errors in the console
Performance issuesβ
- Remove unused listeners
- Avoid heavy operations in event callbacks
- Use
removeAllListeners()to clean up all listeners if necessary
Need Help?β
If you have any doubts, do not hesitate to contact us at support@audioboost.com.