Embedded Player Customization

by

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.

Styles

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.

Gotchas:

  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!

About these ads

12 Responses to “Embedded Player Customization”

  1. Jeff Hume Says:

    This is fantastic stuff. You guys go all out for us.

    I’m curious about the status of embeddable HTML players though. You guys mentioned here back on the post about the HTML players on bandcamp that embeddable HTML players were coming in the future. Is there any more information on this?

    I’m just trying to decide whether I should take the time to implement this stuff if the HTML players are far enough away or if I should just hold out for HTML.

    Again, though, this is so fantastic.

  2. Neal Says:

    Hi Jeff,
    We don’t have an ETA on pure HTML5-based embedded players at the moment, although our embedded players do use HTML5 instead of Flash in certain circumstances. If you view a site with an embedded player on an iOS device (iPhone, etc), the contents of the tag will be an iframe containing an HTML5-based player. If you want a pure HTML5 player on your own site in the near future, I’m afraid your quickest option is to implement it yourself. Our API will allow you to get all the info you need in order to duplicate our player’s functionality in JS/HTML.

  3. Jeff Hume Says:

    Thanks so much for the info Neal. I didn’t know that the embedded players would switch to HTML5 on iOS. That’s very nice and great to hear.

    Unfortunately mine don’t appear to be doing that and show up as blank. Perhaps I’m using old code?

  4. Neal Says:

    Yes, that’s possible. You do need to re-embed the players in order to get the iPod action, as the old embed code method linked directly to the Flash (SWF) file.

  5. Neal Says:

    Also, full disclosure: a recent iOS update totally hosed up the positioning of embedded players on iPhones and other iDevices. We are investigating workarounds while secretly hoping Apple is rushing out a bug fix.

  6. Howlin' Hobbit Says:

    That first player (the minimalist one) that you show looks very much like the really cool one that comes (IIRC) as a WP plug-in.

    Could you please give us a step-by-step on how to do that sort of thing for a single song (just the play button, title, time and share links) instead of your more generic explanation?

    Thanks much!

    (Bandcamp rocks me.)

  7. dealingwith Says:

    Is it possible to have an album player but have it queued to a certain track?

  8. Neal Says:

    @dealingwith: sorry, but the only way to queue up a particular track on an album player is to move it to the number one spot on the album.

  9. Neal Says:

    @Howlin’ Hobbit: I’m not sure what your exact question is. Could you email support@bandcamp.com with more detail? Tell them Neal sent you.

  10. Eric Says:

    This is fabulous! I was in need of a 260px wide player and this post comes right on time. Love you all at Bandcamp!

    So here goes: http://bit.ly/gWXAvp
    Layout JSON file: http://bit.ly/ehMbBD

    The only limitation I’ve faced is that apparently the requested height and width are entirely ignored for the “tracklist” element (hooray for the rowHeight style!). Now I am already wishing for more features! Custom images and text areas! Flexible “linkarea”! I18N! I am sure that you guys have this on a post-it board somewhere :)

    Thanks a whole lot!

  11. Neal Says:

    Those look great, Eric. If you like, I can post the layout files to bandcamp.com so others can use them without relying on your server. Regarding the “tracklist” size: uh, yeah, that’s a little bit of special case I neglected to eliminate: it’s so the person doing the embedding can tweak the height of our standard players and have the tracklist expand or contract. The obvious consequence is that you can’t put anything below the tracklist. I think I’ll eliminate this by allowing you to specify something like “*” for the h and w in order to do the expand-to-fit behavior. It’s on the to-do.

    As for the other features: yes, definitely on a list somewhere. :)

  12. Eric Says:

    Thank you Neal :)

    Uh, yes, I was so eager to share the *content* of the configuration file that I totally forgot that it could be used remotely once in the wild! Yes, I would be very happy if you could post the example layout on bandcamp.com for the benefit of all (keeping in mind that it will look bad for 7 tracks and more).

    Smart expand-to-fit behaviour for some elements would be really rocking. Glad to hear that it’s only the beginning!

    Cheers!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: