I’m working on RoR site to promote an album that a friend recently
released. We’d like to have the whole album streaming from the
website, so that listeners can try before they buy. For the streaming
audio, I’m using wimpy button (http://www.wimpyplayer.com/) which
works wonderfully. However, the html that I generate to embed the
wimpy button in my page includes the URL of the mp3 file that gets
streamed. It’s very easy for someone to “view source”, and then copy
and paste this URL into their browser and download the file. I know
it’s not possible to completely prevent the user from getting a copy
of the streaming mp3 (for example, there are tools that can capture it
as it plays and save it to an mp3 file)…but I’d like to make it more
difficult than just viewing the source.
I’ve got an idea of how to do this, but I wanted to post it here to
get feedback and see if anyone else has done anything similar…or
maybe there’s even a plugin that’ll do it for me? My basic idea is
that the streaming mp3 should be exposed at a URL that is randomly
generated and is valid to be used only once. So if the user copies
the URL from the source and pastes it in their browser, it should
return nothing (or maybe redirects to a page that says “Don’t try to
steal our music”), but the wimpy button should be able to use the URL
to get the mp3.
Details: instead of exposing the streaming mp3 at a URL that points to
a path in my public folder, I’ll expose it as an action on one of my
controllers. One of the parameters will be a randomly generated id.
When the action for the page gets called, it will generate this random
id and save it in the database in a table that also contains a
“has_been_downloaded” field (which is false by default). The wimpy
button will have the URL to the action with the random id parameter,
and this action will allow it to download the mp3. When the user
tries to go to this URL, the “has_been_downloaded” field will be true,
and the download will fail.
Has anyone done this before? Is there a plugin that I’m not aware of
that already implements this functionality? Are there any “gotchas”
here that I need to be aware of?