Ripping MP3s From Bleep

by mOther

Bleep (www.bleep.com) is Warp Records' online MP3 and FLAC store.

You can purchase music and download it, much like iTunes, except without any DRM.  Warp's catalog is available, as well as many other record labels, such as Domino, XL Recordings, Rough Trade, and Skam.

You can preview all tracks using their Flash player.  The annoying thing about this player is that it stops the playback after 30 seconds, and you have to click on the seek bar to start it playing again.  I'm guessing they did this to stop people from recording the stream.

After a little hacking around, I discovered an easy way to download the full MP3s.

Track links look like this:

http://www.bleep.com/player.php?track=<releaseID>_DM-<track>

releaseID is a code corresponding to the album, and track is a two-digit number, such as 01, which is obviously the track number of the song.

This URL returns the HTML code to embed their Flash MP3 player, and pass the player parameters, such as the track title.

One of these parameters is key.  This key is used by their player to retrieve the MP3 from the following URL:

http://listen.bleep.com/player.php?key=<key>

I discovered this by using Ethereal to sniff the HTTP traffic.  The above URL returns the MP3 in its entirety.  The player itself is what stops playback after 30 seconds.

So, you can retrieve the full MP3 as follows:

$ wget -O test.mp3 http://listen.bleep.com/player.php?key=<key>

I was going to try and determine how the key is calculated from the release ID and track number (database lookup?), but then I realized, why bother?  It's a lot easier to just navigate to the first URL, and parse the key out of the HTML.

I've written a simple Python script which automates this process.  Run it without any parameters for details on how to use it.  The script also gleans the album cover, and the artist and album names.  Read the source for details.

Don't be a jerk.  Buy the music you enjoy, and support the artists.  Remember, these MP3s are only 96 kbps (or less).   Trust me, Autechre sounds excellent in FLAC.

Here is the Python script:

#!/usr/bin/python

# Rips mp3s from bleep.com
# by mOther, Aug 07 2007

import urllib
import re
import sys

def bleep_get_title_and_key(release, track):
    release_dash_track = "%s-%02d" % (release, track)
    url = "http://www.bleep.com/player.php?track=" + release_dash_track
    response = urllib.urlopen(url)
    page = response.read()
    title = None
    key = None
    pattern = re.compile("title=([^&]+)&")
    match = pattern.search(page)
    if match:
        title = match.group(1)
    pattern = re.compile("key=([^\"]+)\"")
    match = pattern.search(page)
    if match:
        key = match.group(1)
    return title, key

def bleep_get_album_and_artist(release):
    album = None
    artist = None
    url = "http://www.bleep.com/current_item.php?selection=" + release
    response = urllib.urlopen(url)
    page = response.read()
    pattern = re.compile('target="bleep1">([^<]+)</a>(<br />)+([^<]+)<br />')
    match = pattern.search(page)
    if match:
        album = match.group(3)
        artist = match.group(1)
    return album, artist

def bleep_save_cover_image(release, album, artist):
    pretty_release = release[:-3]
    filename = artist + " - " + album + ".jpg"
    print("Downloading: " + filename)
    url = "http://www.bleep.com/pack101/" + pretty_release + ".jpg"
    response = urllib.urlopen(url)
    f = open(filename, "wb")
    f.write(response.read())
    f.close()

def bleep_save_mp3(key, filename):
    url = "http://listen.bleep.com/player.php?key=" + key
    print("Downloading: " + filename)
    response = urllib.urlopen(url)
    f = open(filename, "wb")
    f.write(response.read())
    f.close()

def usage():
        print("""
Usage: bleep_ripper.py <release_id> [ <first_track> [ <last_track> ] ]

To rip mp3s from bleep.com, first find the track or release you want 
on bleep. Then, hover over the Play link on one of the tracks. It will
look something like this:

    http://www.bleep.com/player.php?track=PURE194DL_DM-01

In this case, PURE194DL is the release ID.

If you do not specify first_track or last_track, it rips all tracks.
If you specify only first_track, it rips from that track to the last track.
If you specify first_track and end_track, it rips tracks in the specified range.
(To rip a single track, specify the same track for first and last.)
""")

def main():
    if len(sys.argv[1:]) == 1:
        release = sys.argv[1]
        first_track = 1
        last_track = 99
    elif len(sys.argv[1:]) == 2:
        release = sys.argv[1]
        first_track = int(sys.argv[2])
        last_track = 99
    elif len(sys.argv[1:]) == 3:
        release = sys.argv[1]
        first_track = int(sys.argv[2])
        last_track = int(sys.argv[3])
    else:
        usage()
        sys.exit(1)
    release = release.upper()
    if release[-3:] != "_DM":
        release += "_DM"   
    album, artist = bleep_get_album_and_artist(release)
    if not album or not artist:
        print("Couldn't find release '" + release + "'.")
        sys.exit(1)
    bleep_save_cover_image(release, album, artist)
    track = first_track
    while track <= last_track:
        title, key = bleep_get_title_and_key(release, track)
        if not title or not key or not album or not artist:
            break
        title = title.replace("+", " ")
        title = urllib.unquote(title)
        filename = artist + " - " + album + " - " + ("%02d - " % (track))
        filename += title + ".mp3"
        bleep_save_mp3(key, filename)
        track += 1

main()

Code: bleep_ripper.py

Return to $2600 Index