Skip to main content

Javascript Widget Library

The widget library was created to allow simple integration of AudioShake's stem generation service into an existing web application. The widget allows any client's end users to choose the option of AI-generated stems for a song.

You can see an example of the widget at work in the Chordal music supervision platform.

Overview

The widget library was created by AudioShake to allow simple integration of AudioShake's stem generation service into an existing web application. The widget allows any client's end users to choose the option of AI-generated stems for a song.

Technical Details

The widget library uses web sockets to communicate with our server and get the status of stem generation requests in real time.

Integration

To integrate the widget library into an existing application, you need to include the script url into the webpages code

<script src="https://assets.audioshake.ai/audioshake1.1.min.js" type="text/javascript"></script>

Setup

To set up the widget library you need to add the following attributes to the button that you will use to trigger the widget. Below is an example snippet showing how to add attributes to your DOM elements.

<tr>
<td>Ibrahim's Song</td>
<td id="sample-element-id-123456"
audioshake-audio-id="sample-song-id-123456789"
audioshake-link="https://link/to/file.wav"
audioshake-filename="ibrahims-songs">Get Stems</td>
</tr>

The table below describes the uses for these attributes

Attribute NameDescription
idA unique id used to present widget popover. On click of this element, the widget popover will present itself next to this element with the given id.
audioshake-audio-idUnique identifier to represent the ID of the song.
audioshake-linkHTTP URL that points to a downloadable version of the song for upload.
audioshake-filenameThe name of the file for the audio asset. This name will be used to generate the downloadable stems package.

Once the elements attributes have been added, then the Library can be instantiated as in the following example:

/*
* Does the setup process for instantiating the AudioShake Widget
*/
function setupAudioShakeWidget() {
const stemOptions = ['vocals', 'instrumental', 'bass', 'drums', 'guitar', 'piano'];
const licenseId = '<licenseId-value>'
const format = 'wav';

var gAudioShakeWidget = new AudioShakeWidgetLib.WidgetPresenter({ licenseId, format, stemOptions, widgetUserSessionId });
console.log('New AudioShakeWidget: ', { gAudioShakeWidget });
}

The provided configuration parameters needed for setting up the library include:

licenseId - A unique Identifier provided by AudioShake to represent the client’s current license to access the widget and API.

stemOptions - An array of lowercase strings indicating the stem options that the user should be able to choose from. The available options are:

  • vocals
  • instrumental
  • bass
  • drums
  • guitar
  • other (removes vocals, drums, bass)
  • other-x-guitar (removes vocals, drums, bass, guitar)
  • piano
  • wind

format - A lowercase string indicating the output format to generate the stems. Options are:

  • wav
  • mp3
  • flac

Instantiation of Widget UI

Once the library is instantiated, any click on an element in the page that has a "audioshake-audio-id" attribute will make the widget popup appear and establish a socket connection to our servers. Once the connection is made, the server will send down the latest stem generation status, if any. If there are no existing processes running for this audio ID then the user will be allowed to pick their stems and generate new stems.

Alt text

Alt text

Generating Stems

Once the user chooses their stems, they will see the processing indicator while their stems are being generated.

Alt text

Alt text

Downloading Generated Stems

Once all of the stems have been generated, the user will then be able to download the stems as a zip file. The stems will be named accordingly based on the name provided in the “audioshake-filename” attribute on the element. For example, an audioshake-filename of "Rainbow Connection" will return as Rainbow Connection_vocal.wav

Alt text

Widget Library Dependencies

The AudioShake widget relies on JQuery and Bootstrap libraries to render and manage the UI/UX for the widget. When the widget is loaded, it injects these libraries into the DOM and waits for them to load. For this reason, these libraries may interfere with your existing JS dependencies. If this occurs, please contact AudioShake so that we can help with troubleshooting the issue.

Widget stem persistence

The stems created by AudioShake widget for a particular song will be available for download for 24 hours and then after that, they will be deleted. The end-user would then be able to generate more stems for that song after the 24 hour period.


Using AudioShake JS Library without Widget UI

In some cases you may want to design your own UI/UX for a widget to match your website's brand and style. To use the audioshake library without the existing widget UI template, there are a few other steps you will need to do.

Instantiation of AudioShake core library

After importing or referencing the JS library source at https://assets.audioshake.ai/audioshake1.1.min.js then you must instantiate the core library explicitly from your web application.

To instantiate the core library from your web app, you need to pass a few configuration parameters as illustrated below in the sample code:

const config = {
audioId,
domain,
licenseId,
onCallback: ({ method, message }) => { console.log(method, message) },
userSessionId
}

const audioShakeCoreLib = new AudioShakeLib.AudioShake(config);

The following table provides a description of each configuration parameter as well as describes which parameters are optional

Config Parameter NameDescription
licenseId(Required) A unique public Identifier provided by AudioShake to represent the client’s current license to access the widget and API. This is NOT an API token
userSessionId(Required) An Identifier you will need to provide that identifies the user making the request and a valid session that authorizes them to make the request. AudioShake server will use the userSessionId to authenticate with your server to verify this
useruser (Read more details below in “Configuring User Authorization” section)
audioId(Required) Unique identifier to represent the ID of the song
domain(Optional) A domain string of the calling website used to verify web calling host
onCallback(Required) A callback to receive messages for different request types.

The AudioShake core library will immediately try to subscribe to the socket on instantiation. For this reason, we advise that you do not instantiate the library until you know the user is intent on generating stems. This would mean do not open/subscribe to the AudioShake socket until the user clicks on some action button to generate stems.

When the library successfully subscribes to the socket it will send a callback to the 'onCallback' function. The callback will provide a session token and an array of allowed stems for generation as a hint to which stem names are allowed when making requests.

NOTE: The core library will attempt to retry the subscription in the case of failure. If after a number of attempts to retry it is not able to connect, then it will send a callback to the 'subscribe' method with a payload indicating that it could not connect to AudioShake servers.

Setting up onCallback

The 'onCallback' callback notifies the caller of any triggered AudioShake operation. Within the callback function, clients can parse and use the following payloads to update their UI state.

The following pseudocode boilerplate is an example of how we would write our ‘onCallback’ function.

onCallback: ({ method, message }) => {
if (message.status === "failed") {
// Handle failures
return
}

if (method === "subscribe") {
// Setup the widget and save the sessionToken for use later. Update UI State
const { sessionToken, allowedModels } = message;
// Once you have sessionToken then it is ok to call generateStems
} else if (method === "create" || method === "status") {
// Retrieve job status and broadcast its current state (processing, failed, complete)
// Update UI state
const jobs = message.jobs;
} else if (method === "create-download-url") {
// Retrieve audioshake download url.
const jobs = message.url;
}
}

The following table provides a description of the expected request/intent method and its payload

Method NameMessage PayloadExplanation
All Failed Methods{ status: "failed", description: "Some Description" }All failed events will have a message payload containing a status as 'failed' and some brief description of what occurred.
subscribe{ status: ["vocals", "instrumental"], description: "abc" }Called on successful subscription. 'allowedModels' will contain an array of what stem types are allowed to be generated under this license. 'sessionToken' string will need to be used for all subsequent requests to the library to identify the socket session.
create{ jobs: [ JobModel ] }Called immediately after a generateStems request with initial processing status of request stem jobs. Also called when a retryStems.
status{ jobs: [ JobModel ] }Called subsequently multiple times as the status changes for each stem job request. All request stem jobs will be included, and for completed jobs, the job will have the appropriate stemAssets which will have links to the stem files.
create-download-url{ url: ["www.www.www"] }This will be called after a downloadStems request has been made. The 'url' returned will be a link to a zip package containing the stems. NOTE: this is only necessary if generating more than one stem.
retry-stems{ status: ["failed"], description: "Some description", jobId: "Job Id" }When a retry is called, we use the 'create' and 'status' callback methods to send job updates. The 'retry-stems' callback is only an acknowledgment that the retry process was kicked off.

Generating stems

Once you have received a callback with a session token, you can generate stems by calling the 'generateStems' function on the AudioShake core library.

function generateStems() {
const stemRequestParams = {
link,
name,
stemNames,
format,
audioId,
userSessionId,
sessionToken,
}
audioShakeCoreLib.generateStems(stemRequestParams)
}

Once a request is made to generate stems then the library will send the status of the stem generation job via the callback function. The initial callback returns a 'create' callback payload with an array of Job objects. Each job will have a stemName property that will map to the requested stem name and each job will have its initial state. All subsequent job statuses will be returned in the 'status 'callback payload with the same array of Job objects with their various statuses (See Job Model section for more details)

Downloading Stems

To download stems you can access the links to the stem assets from the job model. If you need to generate a zip file for all the stems, we have provided a convenient function that can do this for you. If you are only generating one stem then you will not need to do this step.

function generateDownloadUrl(jobs) {
let links = jobs.map(job => job.stemAssets[0].link);
let fileName = "my stems"
AudioShake.generateDownloadUrl(links, fileName, sessionToken);
}

After calling the downloadStems function then you will get a ‘create-download-url’ callback with a payload that has a url for downloading the zip file. These files will be streamed into a zip file during the download process so this process is relatively fast for most stems.

Disconnect from AudioShakeJS

You can close the AudioShake socket connection with the 'disconnect' method. This should be called once the user closes the custom widget UI.

function closeWidget() {
// Client triggers UI to close the widget.
// Close the AudioShake socket
audioShakeCoreLib.disconnect();
}

In case of failure: Retry Stems

You can initiate the retry stems process by calling the 'retryStems' method. This should be called if any stems have failed. Similar to 'generateStems', you should expect that the initial callback to return a 'create' callback payload. All subsequent callbacks being 'status' callbacks.

function resetStems() {
const resetStemsParams = {
audioId, userSessionId, sessionToken
}
audioShakeCoreLib.resetStems(resetStemsParams)
}

Configuring User Authorization

To authenticate each users session you will need to follow the following steps:

  1. Provide AudioShake with a server authorization URL that can be used to authenticate the user session. We will set this in our databases and associate it with the licenseId.
  2. Whenever a request is made to generate stems via the widget library, we will make a POST request to your authorization and pass the provided userSessionId as part of the JSON body. Your server should be able to associate this userSessionId with the appropriate user session and authorize