Embedded Player Customization

Way back when we released our embedded music player, we made a conscious effort to keep it simple and small so we could get it to you and get it to you quickly.  Customization was pretty much nonexistent, but the player was lean and mean and sharing didn’t involve making any choices. Then we got […]

Way back when we released our embedded music player, we made a conscious effort to keep it simple and small so we could get it to you and get it to you quickly.  Customization was pretty much nonexistent, but the player was lean and mean and sharing didn’t involve making any choices.

Then we got feedback that people wanted some options, so we added a few layouts and a cute naming scheme inspired by a sign on the wall at Bandcamp’s Seattle office (also known as a Starbucks), and figured we pretty much had everyone covered for a while.  While making this change, we got more requests for additional layouts, so I did a bit of work to move from the old hardcoded-in-actionscript layout model to a model that was easier to modify (for my own benefit) by having some internal data structures that described each layout by name.  This was pretty simple stuff — just positioning and sizing of the various elements.  I didn’t want to reinvent CSS in actionscript or anything.

This served us well enough for a long time, until we decided to finally create a player with a full track listing on it.  At that point, we were up to 6 layouts, which is about the max that will fit comfortably into our Share dialog. We decided that the next logical step was to expose this “add new layouts” functionality to everyone, so if you have a site where you have the ability to include arbitrary HTML, you can make the player look exactly like you want it. Note that I’m shrewdly excluding sites like MySpace and Facebook and tons of others that are very particular about what you can paste into them and will, in fact, modify what you paste.

So if you’d like to make a player that looks like this:

or like this:

and you’re kind of excited about dorking with JSON and hitting reload a lot, then this blog post is for you.

How it works

Normally, the embed code for a player contains a /size=grande/ portion of the URL which selects the layout for your player.  The dimensions of the <object> tag(s) are also set explicitly in the embed code, and must match the layout specified by the “size” argument, or things will look funny (this is because we can’t assume the Flash widget has script access to the host page’s DOM, so we can’t set that size from within the layer-outer ourselves).  Instead of using this “size” argument, you may provide a “layout” argument which specifies the URL to a layout file.  This layout file is a raw blob of JSON which simply tells us where everything in the player goes, how big it is, and maybe a few pieces of style information (like whether its text should be centered).

The layout specification

Here’s the layout for what I’d argue is the simplest possible functional player you can make:

    "play": { "x": 0, "y": 0, "w": 31, "h": 30, "show": true }

It’s just a play/pause button.  We set the position and the width and height of the overall layout, then we have an element in there that describes the play button and specifies that it should be visible.  Pretty straightforward.

You can also add overrides that only apply to either the track or album versions of the player.  For example:

    "play": { "x": 0, "y": 0, "w": 31, "h": 30, "show": true,
        "album": { "x": 10 }

This tells us that the play button should be at (0,0) unless we’re looking at an album player, in which case its x coordinate should be changed to 10.  You could specify this the other way around, too, by saying that it’s at 10,0 unless we’re looking at a track player, in which case the x should be 0.  Same difference.  If you’re wondering why we have this feature, just take a look at the difference between the track and album versions of any of the standard layouts (except ‘short’) — we move the buttons around and hide or show the next/prev buttons appropriately, and there are a couple other subtle differences as well.


The final piece of information you can specify per-element is “styles”.  Flash programmers will be comfortable with this one.  This is a named set of styles which will get applied to the various mx.* elements directly using setStyle().  Of course, we don’t say much about what types the elements are, so it’s hard for you to know exactly what styles apply, but if you stick to the basic, obvious ones (“color”, “textAlign”, “fontFamily”, “fontSize”, “fontWeight”), in addition to our custom styles documented in the “Special Styles” section below, you should be fine.  Here’s an example of a style blob for the “currenttime” element:

    "currenttime" : { "x": 100, "y": 0, "w":50, "h":16, "show": true,
        "styles": { "color" : "#000000", "textAlign": "right" }

The elements

Ok, so what elements do you have to work with?

element name(s) description
“art” This is the track or album art.  It should be square, and as of this writing, either 100×100 or 150×150 pixels in size.  It will load the correct resolution art for one of these sizes.  In the future, maybe we’ll support arbitrary sizes, but for now it’s just those two.  Use a different size at your own risk.
“maintext” and “subtext” These are the main header and the subheader.  What exactly we display here has shifted slightly, hence the vague names, but at the moment the main header is the item (album or track) title and the subheader is the artist name.  This could conceivably change in the future, but it seems kind of unlikely.  As an example of how this could change, in the past, I believe the subheader was “from <album> by <artist>” for tracks that are part of an album.
“play” The play/pause button.  Should be either 31×30 or 47×45 — we’ll switch the image appropriately.
“next” and “prev” The next/prev buttons.  Each should be 17 pixels wide and 11 pixels tall. Only useful on album players.
“currenttitle” This is the section that shows the title of the currently playing item.  This is only useful in an album player, since it would otherwise be redundant [note: see “Special Styles” below]
“currenttime” The current location in the track, expressed as mm:ss
“totaltime” The total time in the current track, expressed as mm:ss
“linkarea” The spot where we stick the “Buy”, “Download”, and “Share” links as appropriate
“timeline” The progress/seek bar.  You should probably keep this to 16 pixels tall or things might look funny
“tracklist” the clickable and scrollable track list.  Only really appropriate on album players.

Making an Embed Code

To create the custom player embed code, you must provide three additional parameters to the Flash embed: “height”, “width” and “layout.” The height and width are self-explanatory; the browser needs to know how big to make the <object> tag. The “layout” parameter is a specially-encoded version of the URL to your layout’s JSON description. To make creation of the embed code easier, we’ve provided a secret set of options in the Share dialog. Open the Share dialog by clicking “Share” on the track or album page, then to reveal the secret options, just shift-click on the radio button for “Venti” and the standard size options will change into boxes where you can enter the URL and the dimensions.

Special Styles

There are a couple of styles that can be added to items that are not standard Flash element styles:

  • The “currenttitle” item can have a style called “isMenu”, which, if set to the string “true”, causes the item to also act as a popup track list menu.
  • The “tracklist” item can have a style called “rowHeight” which defines the height, in pixels, of each row in the track list.

Other Notes

If you add a “debug=true” argument to your player, it will “cache-bust” the layout URL by appending some random junk to it.  This makes it a lot easier to tweak a layout by reloading it repeatedly, because Flash seems to be fairly aggressive about its caching and everyone probably doesn’t have control over the cache control headers on their web servers. This argument is added automatically in the preview in the “Share” dialog when you’ve selected a custom layout (see “Making an Embed Code” above), so you can just click the “Refresh player” link below the sample player to reload your url ad infinitum.


  1. Every element that is visible must have “show” set to true in your layout spec.  If your element is not showing up, double check that.
  2. Because our Flash is going to grab your layout file from your server, you must have a crossdomain.xml file which allows requests from bandcamp.com. To save you the trouble of googling the details, here is an example of a crossdomain.xml file that would work.

Happy custom-layouting!

Source: Bandcamp