Working With AmplitudeJS Song Object Metadata

Part 2 of 7 in AmplitudeJS: From the Ground Up
Dan Pastori avatar
Dan Pastori August 22nd, 2018

At the core of AmplitudeJS there are song objects. Whether you initialize your player with these song objects, or without (dynamically loaded players will be covered later in the course) you will have to work with them at some point. A song object is simply a JSON representation of an audio file. This file could be either a song, podcast, live stream, etc. Pretty much anything that can be played in the modern browser. I’ll reference these objects as song objects, but just know they can be pretty much any audio file.

When building your player, you have the option to add song objects. For example, from our playlist player here: Blue Playlist Example – AmplitudeJS the songs array looks like:

"songs": [
      {
        "name": "Risin' High (feat Raashan Ahmad)",
        "artist": "Ancient Astronauts",
        "album": "We Are to Answer",
        "url": "/songs/Ancient Astronauts - Risin' High (feat Raashan Ahmad).mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/we-are-to-answer.jpg"
      },
      {
        "name": "The Gun",
        "artist": "Lorn",
        "album": "Ask The Dust",
        "url": "/songs/08 The Gun.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/ask-the-dust.jpg"
      },
      {
        "name": "Anvil",
        "artist": "Lorn",
        "album": "Anvil",
        "url": "/songs/LORN - ANVIL.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/anvil.jpg"
      },
      {
        "name": "I Came Running",
        "artist": "Ancient Astronauts",
        "album": "We Are to Answer",
        "url": "/songs/ICameRunning-AncientAstronauts.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/we-are-to-answer.jpg"
      },
      {
        "name": "First Snow",
        "artist": "Emancipator",
        "album": "Soon It Will Be Cold Enough",
        "url": "/songs/FirstSnow-Emancipator.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/soon-it-will-be-cold-enough.jpg"
      },
      {
        "name": "Terrain",
        "artist": "pg.lost",
        "album": "Key",
        "url": "/songs/Terrain-pglost.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/key.jpg"
      },
      {
        "name": "Vorel",
        "artist": "Russian Circles",
        "album": "Guidance",
        "url": "/songs/Vorel-RussianCircles.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/guidance.jpg"
      },
      {
        "name": "Intro / Sweet Glory",
        "artist": "Jimkata",
        "album": "Die Digital",
        "url": "/songs/IntroSweetGlory-Jimkata.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/die-digital.jpg"
      },
      {
        "name": "Offcut #6",
        "artist": "Little People",
        "album": "We Are But Hunks of Wood Remixes",
        "url": "/songs/Offcut6-LittlePeople.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/we-are-but-hunks-of-wood.jpg"
      },
      {
        "name": "Dusk To Dawn",
        "artist": "Emancipator",
        "album": "Dusk To Dawn",
        "url": "/songs/DuskToDawn-Emancipator.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/from-dusk-to-dawn.jpg"
      },
      {
        "name": "Anthem",
        "artist": "Emancipator",
        "album": "Soon It Will Be Cold Enough",
        "url": "/songs/Anthem-Emancipator.mp3",
        "cover_art_url": "/img/open-source/amplitudejs/album-art/soon-it-will-be-cold-enough.jpg"
      }
    ]

Each object contains some very basic meta data regarding the song. However, if you really wanted to, you ONLY NEED the url for the song. The rest of this information can be handled in any way that you want. Now considering that you don’t need anything but the URL most player designs would benefit from having the name, artist, album, and cover_art_url. You can set up your player to automatically display these fields. So, when a song changes, the visual side of your player changes as well.

Now Playing and Playlist Now Playing Fields

As mentioned, when the song changes, you can have certain fields change. This should be dependent upon your player design. Say you have one element that displays the name of the active song being played. This element would look something like this:

<span amplitude-song-info="name" amplitude-main-song-info="true"></span>

AmplitudeJS will now fill in the text of this element with the name attribute of the active song being played. You also notice that there is another parameter named amplitude-main-song-info and this is set to true. What this means is it will update to whatever song is played no matter if it’s a playlist or the global now playing from the songs array.

If you had your songs organized in a playlist, this element would look like this:

<span amplitude-song-info="name" amplitude-playlist="{playlist_index}"></span>

Instead of amplitude-main-song-info=“true” we have amplitude-playlist=“{playlist_index}”, which would be the index of the playlist you defined when you initialized the player (more on this later). Now when you have two playlists on the page, this will be the now playing for the song in the playlist that is now playing.

Now with meta data, this can really be anything. We used the name attribute, but you can replicate this with any attribute. You can also add more attributes than what we listed. Here is another example.

Say you have a song with a genre of rock, like this:

{
  "name": "Anthem",
  "artist": "Emancipator",
  "album": "Soon It Will Be Cold Enough",
  "url": "/songs/Anthem-Emancipator.mp3",
  "cover_art_url": "/img/open-source/amplitudejs/album-art/soon-it-will-be-cold-enough.jpg",
  "genre": "Rock"
}

You can display that in an element like this:

<span amplitude-song-info="genre" amplitude-main-song-info="true"></span>

AmplitudeJS will insert your value in that HTML.

Essentially, you can have ANY meta data you want attached to a song and display it anywhere on the screen structuring your elements like this:

<span amplitude-song-info="{key}" amplitude-main-song-info="true"></span>

or in a playlist like this:

<span amplitude-song-info="{key}" amplitude-playlist="{playlist_index}"></span>

Now the extra caveat, is these do not have to be span elements. These can be div, p, a or any other tag that you can fill the HTML with. This allows you free structure to whatever you want! There are a few special fields that we will talk about next.

Image Meta Data

With images, we are not actually setting the HTML of an element, we are setting the src attribute instead. There are 3 reserved keys in a song object that will be set as an src value to an img element and those are:

  1. cover_art_url (geared for songs)
  2. station_art_url (geared for live radio stations)
  3. podcast_episode_cover_art_url (geared for podcasts)

These elements function very similarly in the attributes that determine what should be set except they HAVE to be an img tag. So to do the main player now playing for an image, you’d have an element like this:

<img src="" amplitude-song-info="cover_art_url" amplitude-main-song-info="true"/>

This will fill in with the now playing song’s image. For a station or podcast it’d look like this:

<img src="" amplitude-song-info="station_art_url" amplitude-main-song-info="true"/>
<img src="" amplitude-song-info="podcast_episode_cover_art_url" amplitude-main-song-info="true"/>

Now if you wanted this in a playlist mode, you’d do the same as with text by removing the amplitude-main-song-info attribute and replacing it with the amplitude-playlist attribute and have it set to the playlist key that you defined. Unlike text metadata, the URL for a song’s artwork has to be in one of the key’s defined. I added 3 different keys to hopefully match the use case of your players,.

Since you can implement a song without any metadata besides the url, I’d recommend doing some sort of back up for album art. You can define this when you initialize AmplitudeJS like so:

Amplitude.init({
  default_album_art: "url_to_default_art"
})

Now instead of a broken image screen element, you will have a back up. This image will display if the active song object does not have an image defined in either of the 3 ways.

Time Meta Data

The time elements are computed fields which are a little bit different than the defined fields that you can pass to a song object BUT are dependent upon the song. So there’s 5 different elements that can be used in different ways.

Current Time

This displays the the current time the user is into a song in either HH:MM:SS or MM:SS format. If the song is over an hour, it will display the hour before hand. Like other meta data, you can scope this for a main player (whatever the current song is), a playlist player (whatever the current song is in the playlist), OR an individual song player. The individual song player would be like if you had 3 players that each related to one episode of a podcast on the page. Since this is text meta data, it will insert the text into an element so you can set up your element to be any one that allows text insertion.

To do current time on a global state, you’d have an element like this:

<span class="amplitude-current-time" amplitude-main-current-time="true"></span>

This will have the current time the user is into the audio no matter what state it’s in. This will update every second.

For a playlist it would be:

<span class="amplitude-current-time" amplitude-playlist-main-current-time="{playlist_key}"></span>

So this would be the current time for whatever song is playing in a playlist. If you have two playlists on the screen, each one would have this.

Now you can do this for an individual song as well like this:

<span class="amplitude-current-time" amplitude-song-index="{song_index}"></span>

This is a little different since this would be for a specific song object. It’s very similar to a playlist but the attribute amplitude-song-index will be set to the index of the song in the songs array. Now since it’s programming, this starts at 0. For example, if we wanted the current time of Anvil by Lorn as listed in our array above, this would have a song index of 2 even though it’s the 3rd song in the array.

These elements will also default to 00:00 in the sense of a playlist or song element if they are not active and not being played.

Current Hours, Minutes, Seconds

These elements are all very similar in that they display the current hours, minutes or seconds as defined. To be honest, these are probably going to be used very rarely. I’ve included them in the library because it gives you fine grained control if you wanted to apply unique fonts to a certain piece of the time display. Similar to the other time elements, these can be keyed to be for the global state of AmplitudeJS, for a playlist, or for an individual song. There are current hours, minutes, seconds for global, playlist and song scopes. If you want to see an example of all of the different ways you can make an element to display this data, check out: AmplitudeJS Time MetaData. The elements can be any HTML element that you want to put text into.

Duration Hours, Minutes, Seconds

Similar to the current time, these are for the duration of the song. The only caveat with these is that the song has to have been initially loaded to grab this data UNLESS you save it to the HTML yourself (or you add the metadata to the song object) .We can’t grab the duration of the song until the entire song has been loaded. Like the current hours, minutes and seconds, you can create an element for each section. The elements can be any HTML element that you can put text into. For all of the examples check out: AmplitudeJS Time MetaData.

Song Time Remaining

Now this is a more unique and probably more heavily used element. This element shows how much of the song is remaining, like a countdown. You can apply this to any scope as well, such as global, playlist, or song scope. To add a global countdown, add an element like this:

<span class="amplitude-time-remaining" amplitude-main-time-remaining="true"></span>

This will add a countdown for the global player. To scope for a playlist it’d look like this:

<span class="amplitude-time-remaining" amplitude-playlist-main-time-remaining="{playlist_key}"></span>

You can even add a countdown for an individual song so when the song is being played, this data gets filled:

<span class="amplitude-time-remaining" amplitude-song-index="{song_index}"></span>

Initializing with Meta Data

One of the newer features that we added in 3.3 is the ability to initialize AmplitudeJS with the meta data for each song. Before, in your visual display if you had like a playlist or a song listing, you had to enter the data in the HTML. This didn’t make much sense since you had all the data in the song object.

What this will do is when AmplitudeJS is initialized, it will fill in the appropriate metadata into elements on the screen with the data from the song object. This initializes everything right off the bat!

Let’s say we are making a list of all the songs visually in HTML from the songs array above. We’d have repeating span and div tags for each of these elements. Instead of typing out each song name, or artist we can have AmplitudeJS inject that information into these elements on initialize.

For the name field we would have something like this:

<span amplitude-song-info="name" amplitude-song-index="{song_index}"></span>

What this does is inject the name key in the song object at the index defined. We can do this for all of the elements in our song object as long as the amplitude-song-index is set, it will be bound to that song in the array. This is super helpful for dynamic song addition as well because if you call Amplitude.bindNewElements() it will re-sync as well and auto fill the appropriate fields.

Soundcloud Meta Data

AmplitudeJS also supports Soundcloud integration: Documentation – AmplitudeJS. When using Soundcloud, you can get a lot of other useful information returned from the Soundcloud API. When AmplitudeJS loads the Soundcloud URLs (when configured properly) we make an API call to Soundcloud to get the data we need for the song. When the data is returned we set the cover_art_url key to that provided by Soundcloud. However, we also store ALL other data returned in a key for each song object called soundcloud_data. If you want to access this data at any time after it’s loaded you can call either of these public functions:

  • Amplitude.getActiveSongMetadata();
  • Amplitude.getSongByIndex( {index} );

These will return the song object with all of it’s metadata. From there, you can access the soundcloud_data key and get the information you want for your player.

We will take about setting up Soundcloud and making it work with AmplitudeJS in an upcoming tutorial.

If you have any questions about how to use song meta data with AmplitudeJS, definitely reach out below and I can help with the implementation.

Keep Reading
View the course View the Course AmplitudeJS: From the Ground Up
Up Next → Building a Single Song Player

Support future content

The Ultimate Guide to Building APIs and Single-Page Applications with Laravel + VueJS + Capacitor book cover.

Psst... any earnings that we make off of our book is being reinvested to bringing you more content. If you like what you read, consider getting our book or get sweet perks by becoming a sponsor.

Written By Dan

Dan Pastori avatar Dan Pastori

Builder, creator, and maker. Dan Pastori is a Laravel certified developer with over 10 years experience in full stack development. When you aren't finding Dan exploring new techniques in programming, catch him at the beach or hiking in the National Parks.

Stay Up To Date

Be the first to know about AmplitudeJS updates, when you sign up for our email list.