Help get this topic noticed by sharing it on Twitter, Facebook, or email.
I’m happy with the product but unsure I can use it.

Can I protect my audio files whilst using SoundManager?

Hi! I'm developing an online phrase guide for people learning English and would like to have it so that users can click on any phrase to hear how it sounds.

I've successfully installed SoundManager 2 on a test page and it's working well.

However, I'm keen to prevent users from downloading the MP3 files themselves as I don't want them to be used elsewhere on the web without my consent. As it stands, a user could simply look up the path to any MP3 file from the HTML code and then download it directly.

Is there any way I can prevent this? I tried placing the sound files in a separate directory and protecting that using Apache authentication, but that led to a password prompt when I tried to play a sound.

If it can't be done using SoundManager 2, is there another solution you could suggest, preferably also using using Flash/Javascript?

Many thanks,
Chris
Speak English!
www.speakenglish.co.uk
2 people have
this question
+1
Reply
  • I’m going to look into it.
    I don't think that SM2 has anything built in for such an issue but you might try checking the headers of what is trying to access the files so that you can prevent certain things from accessing them. Flash objects may have a special header when trying to access the music (or other for that matter) files. If that's the case then you would need to filter out the non-flash and non-local website headers using your server configurations. You would need to figure out what the difference is with the headers when using flash vs browser and also local/external.
    Worst comes to worst I'm sure that somewhere in the SM2 code there could be a line added to give a special header that only you know about.
    I'll see what I can dig up on how to actually make all that mumbo jumbo work!
    • Thanks, I appreciate your reply.

      I experimented with watching the server logs whilst accessing some sound clips via SM2, but the log entries were identical whether they were accessed via SM2 or directly through the browser. If I'm missing something, please let me know, but otherwise this doesn't seem to be a runner.

      In case it's of interest, I've added a reply with more complete run-down of my situation and current thinking below.

      Cheers,
      Chris
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • EMPLOYEE
    I’m amused and mildly cynical regarding "DRM"
    Scott (Official Rep) August 07, 2008 19:44
    Hi Chris,

    In short, "If you can see (or hear) it, you can steal it."

    The most realistic way to protect files on the web, is to simply not post them. Consider music, movies and games, all of which are protected by copyright law, as some fine examples of the relative simplicity of copying. ;)

    Jokes aside, taking the logical security approach with what's available on the browser end: To "selectively" serve them in some cases and deny them in others is a bit of a can of worms. I'll explain a few options, which could also be applied to images, movies or any other asset.

    Right-clicking/copy to clipboard
    Try to discourage right-clicking on links, "save as" etc. I have an option for this in the inline MP3 player demo, but of course that is only one way of many people can copy or save a link. Additionally, browsers have options which include, "don't let scripts block right-clicking". ;) Alternately I could tab to the link and hit CTRL-C to copy, or view source, etc. There's always a way around these sort of methods.

    Discouraging right-clicking is actually likely to prevent the most casual/common attempts to save your MP3 files by most people without technical know-how however, so while I don't encourage it myself, the option is included in the in-page MP3 player demo.

    HTTP caching
    You can serve MP3s with basic HTTP headers such as no-cache etc., an "expires" header in the past, and I have heard that Flash should obey these headers and not cache the file after loading.

    Session authentication/tokens, HTTP referral checking
    You could try to check that requests are coming from your own site before serving the MP3 files (eg. your site is on foo.com and the HTTP referrer which the browser sends is also from foo.com, and it's then "valid" to serve - thus, a direct link from bar.com to your MP3 would fail when clicked, or "save as" etc.) However this information is relatively trivial to fake by people who know what they're doing, so it'll stop casual linking but not people who are "determined." The same applies to session and cookie authentication schemes.

    Even after all of this, someone could still record your audio through the system output, so it's never "really" protected - same as with DRM-encoded files. However, the most realistic thing you can do is discourage "casual" copying/downloading attempts by blocking right-clicks; additionally, checking HTTP referrers doesn't involve too much work and will discourage "hot-linking" by MP3 search engines, crawlers and so on.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited sad, anxious, confused, frustrated

  • I’m looking forward to a lie-in tomorrow
    Thanks very much for your answers.

    > In short, "If you can see (or hear) it, you can steal it."

    Understood. So I suppose my aim here is to deter “casual” copying by at least making the process of stealing the files as difficult and/or inconvenient as possible.

    Also, the plan for my site is that users will gain access to the sound in return for a small subscription fee. So another requirement is to prevent users who aren’t logged in and subscribed from accessing the files.

    Location of the sound files

    One problem with my current prototype is that the sound files are in a publicly accessible location, let’s say:

    /user/public_html/sound_files/

    From the code on each page (which shows the path to each sound file in the “soundManager.createSound” statements), it’d be easy for a user to identify the location of the sound files and then download them directly using their browser.

    However, my understanding is that Flash can access and serve files from parts of the filesystem which aren’t publicly accessible, eg:

    /user/sound_files/

    Is there any way that SM can serve files from that sort of location? Or in theory could it be made to do so with some modification?

    If the files could be served from a non-accessible location, with cacheing switched off, I assume that would mean the only way to save the sound would be to capture it from the system output. Still possible, but obviously it’d be considerably more difficult than saving the files straight from the browser. To be useful, the captured sound would also need chopping into the individual phrases again which would be a further inconvenience.

    HTTP referer checking

    This seems like a good idea, as I know the same technique is often used to protect image files.

    However, I experimented accessing some sound clips on my site using SM, whilst watching what was entered into the log file.

    The surprise was that although GET requests for the sound files were recorded when I clicked on the phrases, there was no HTTP Referer listed for these requests. That field was simply blank “-“.

    That’s in contrast to requests for images which showed the page to which they belonged as the HTTP Referer.

    So I’m in doubt as to whether HTTP Referer checking could be used in this case to prevent “direct” accesses to the files. Am I missing something?

    Cacheing

    I’m debating the pros and cons of switching cacheing off.

    I’m not sure I want to switch it off completely, as users will often want to hear the same phrase several times before moving on to another one. Clearly it will slow things down if the clip has to be downloaded each time.

    If I were to set an expiry time of, say, 5 minutes after the file was first accessed, do you happen to know if the file would be automatically deleted from the browser cache after that? Or do files typically stay in the cache after their expiry date until they’re displaced by other more recent files?

    My thinking is that if the sound clips were deleted from the cache a few minutes after being accessed, that would allow the most immediate repetition of the phrases to happen without needing to download the files again, whilst making things more difficult for users wanting to copy files from the cache.

    Right-clicking/copy to clipboard

    Users saving the files via the “right-click” method isn’t really relevant in my case as I plan to use onclick events to play the files rather than linking to them directly.

    DRM

    I don’t know the exact mechanics of how this would work, but I haven’t given it a great deal of consideration so far. For one thing, I’m going to have around 10,000 sound clips of only a few seconds each and I’m not sure DRM is appropriate for such short items. Also, I assume the calls made to check the user was entitled to use each file would have some sort of negative impact on performance.

    Authentication

    I intend to use some sort of cookie-based authentication scheme. So only users who are logged in will see the SM code and links to play the sound, which means I won’t have to worry about spiders or robots finding the files.

    Incidentally, I’ve been working on this project for almost two years now, and getting the sound in place is the final piece of the puzzle. So I’m very grateful for any assistance received. If you have any thoughts about any of the above, I’d be very interested to hear them.

    Thanks again, and have a great weekend!

    Chris
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited sad, anxious, confused, frustrated

  • EMPLOYEE
    I’m still amused and mildly cynical about "protecting" assets over HTTP, an open protocol (though at times, I can relate. :D)
    Scott (Official Rep) August 09, 2008 06:43
    It sounds like from your findings on the referrer side, Flash may not pass a HTTP referrer along with MP3 requests; that's interesting to hear, as I haven't tested this. That would rule out referrer checking as a basic form of "security", yes.

    There is no way to really "hide" resources on a server which can be accessed by a browser, flash or any other internet app, as those requests can pretty easily faked and the output piped to a file instead of a program, etc.

    Cookies and/or URL tokens would be the next logical approach for some sort of basic authentication on MP3 URLs. Regarding caching: If you don't recycle, destroy or unload the sound objects, Flash should retain the MP3 in memory (if not cache) provided the sound files are small enough, and should then not involve the sound being downloaded again when played multiple times, particularly when on the same page.

    I'm unsure on expiry and actual deletion from the cache, as cache management varies by browser and user settings (size, etc.) But logically once an expiry date is reached, the file should be eligible to be removed from the cache when that space is needed by newer, fresher data at the latest.

    Again requests can be forged, HTTP referrers faked, session/cookies scraped from a "live" session and then could be automated/scripted to download many files, so YMMV - but you can at least take some basic steps to discourage this sort of thing. Also, request or bandwidth throttling could be useful if you wanted to get serious about preventing scripted/mass-downloading of MP3 assets, but that is a separate project and an area outside the scope of this discussion - and one where I might question the effort for return of value ratio, also. ;)
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • To Scott: Is there a way to tell flash to add certain headers to the urls?
    There's nothing like that from what I've seen but I really don't have much experience with AS. It might not be something for the main application but if Chris can compile it with a couple extra lines then he can fake some headers in there as well. Even add the Referer header maybe.

    To Chris: I think that it would probably be easiest to tell users that they need to log in to a server authenticated page and then the extra "invisible" headers should be automatically added by the browsers. Assuming that they have to log in to get them anyway it would just be a matter of switching the way they log in. And then you could pretty much assume that your "demo" sounds are going to be stolen anyway (there's really no good way to protect them).
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I’m poking my tongue out
    I think you need to focus on what is your business – what sets your site above others. For instance they might be able to rip your mp3s, but I'm presuming your site will have 'added value' such as a nice interface and be the official source, with forums etc. If a few of your audio tracks appeared elsewhere, it shouldn't compete all that much (If they cloned your whole site, well that is obviously a matter for lawyers). And if your business is reasonably priced that is even less motivation.

    Re:security, some music sites encode their clips in 'useless' formats like timeline synched swfs which have less appeal for downloading - I've discussed this with Scott here: http://getsatisfaction.com/schillmani... but SoundManager does not currently support files of this type (for good reason in that they are non-standard)

    PS: Flash does not pass any useful referrer headers. That is what makes protecting game scoreboards a challenge.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I like the idea of parsing the HTTP request headers (bum51). The REFERRER idea doesn't work, because when SoundManager makes the request, Firefox doesn't pass the REFERRER header (you can see the request headers client-side with Firebug). Since the request is coming from flash, I can do nothing to circumvent the request through the JS API. Is there anyway the developer can add an extra header to the request?
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I’m confident
    Here's what I've done to secure my website:

    1) in your database have a "logged-on" users table, with a special (session specific) key for each one.
    2) when logging in, assign a key, then save it to the table with a timestamp
    3) pass the key with the url as a GET parameter.
    4) update the timestamp when accessed and still logged in

    this way:
    -after a certain amount of time you can delete (or ignore) the old logged in records so that no one can get real urls without having logged in
    -if you have session issues (php seems to crap out if you try to use regular session variables) then the users can still access their songs
    -you can "hide" all of the sounds through a non-http accessible folder, then stream using whatever language you're using

    the only thing here is that you have to make absolute certain that you provide the keys when accessing the sounds.

    It's still impossible to hide it completely, but at least it would force people to have an account and log in.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • Let me see if I understand this. The music files are contained in a non-http accessible folder, so even if people get the URL, they can't listen or download. SoundManager requests the files through PHP, which does have access to that directory. Furthermore, this PHP music request script will only execute if it receives a valid key. This prevents people from faking a request to the the script with their browser and downloading the file. (They could possibly do so, however, if they're already logged in and they look at the URLs with keys that SM is using for the requests.)

    Is this correct?

    Thanks,
    Nick
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • Almost exactly correct, you can also access the files if you guess the right key without being logged in (as there's one for each user that IS logged in) but if you make it a big enough key (md5 the timestamp or something) then it's very difficult to guess.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I’m following with interest
    > -you can "hide" all of the sounds through a non-http accessible folder, then stream using whatever language you're using

    Interesting. But how, practically speaking, do you get PHP (or any other scripting language for that matter) to retrieve the sound files from a non-http accessible location whilst still using SoundManager? Doesn't SoundManager require the sound files to be in a publicly-accessible location in order to work?

    Also, just to clarify, how exactly would the sound files be protected? Would that be done through the web server software, eg apache? What kind of module or configuration settings would I need to use?

    Do you by any chance have any examples of code you'd be able to share? I'm struggling really to understand how this would be implemented.

    Cheers,
    Chris
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I can only respond in general -- don't know the particulars of how bum51 set it up.

    The music file that SM requests is actually a PHP script -- the playlist contains entries that, perhaps, look like this:

    getmusic.php?file=the_filename&key=wertpoiudfhjkjl3457896

    getmusic.php is in a publicly accessible area. When SM calls for the file, the script executes, determines that the key is valid, then pulls the_filename.mp3 from a private directory and sends it to SM. Ultimately, SM just sees a stream of mp3 data to play.

    Apache allows you to set permissions for directories as well as for PHP itself. If PHP has admin privileges, of course, it can access the files in the private directory. (Sorry, I'd be digging through reference books to figure out how to set that up. But I've done some research about this on the web in the past, and you shouldn't have too much trouble locating an explanation.)

    bum51's approach probably provides good protection against most casual attempts to download the mp3, but -- as discussed above -- there are ways around it:

    1) If the user is logged in and uses Firebug to look at a URL that SM is calling, they may be able to paste that URL into a browser window and download the mp3 data themselves.

    2) Even if the login has expired, they can take one of the URLs in the format above and try to guess the key.

    3) It might be possible to get the file out of the browser's cache. (Not sure how the browsers and/or SM and/or Flash interact with the cache.)

    4) Easiest: They can use a program like Audio Hijack (mac) to steal the music from the computer's sound system as it streams. (I don't think there's any way to protect any streaming music from this approach.)

    N
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • OK, thanks for your explanation. I get the idea now.

    I'm only aiming to stop casual attempts to download the sound files as I appreciate, for the reasons you give, that it's impossible to stop someone who's determined to steal them.

    However, requiring the user to be logged in would be something as my intention is that most of the sound on my site will only be available to those who have subscribed.

    Incidentally, I did some tests on how SM interacts with the cache some time ago. If I remember correctly, sound files played by SM do stay in the browser cache, although you can reduce the time they spend there or prevent cacheing altogether by modifying the HTTP headers.

    Thanks,
    Chris
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • Nicholas has my method to a T.
    One extra little tidbit would be that you don't even need to have the sound files directory in the http accessible folders. You could have them in a completely separate location on the hard drive that apache doesn't allow access to, and then the "getmusic.php" file would be able to access them regardless. This way you can even protect against admin priviledges.

    And of course for the HTTP headers thing, you could add that directly to the getmusic script. It should only be a problem of telling it to expire immediately so that as soon as you unload the sound it vanishes. Hadn't thought of that one, good call!
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I was looking to hide the URL of the MP3 in the browser status bar (i.e. when you hold your mouse over an anchor tag, the link shows up in Firefox's status bar). The method I came up with is to hide the value in a jQuery data cache once the DOM is ready and then pull it out when for SM when needed (like a click).

    For example, if using the inlineplayer.js file (for clickable links), we can hide the link like so:


    $(function() {
    $('ul.graphic a').each(function (i, el) {
    var data = jQuery(el).data('song_link') || jQuery(el).data('song_link', undefined);
    if (!data) {
    jQuery(el).data('song_link', el.href);
    }
    el.href = '#';
    });
    });


    And pull it out when the user clicks the link:


    o.href = jQuery(o).data('song_link');
    if (o.nodeName.toLowerCase() != 'a') {
    o = self.isChildOfNode(o,'a');
    if (!o) return true;
    }
    var sURL = o.getAttribute('href');
    if (!o.href || !o.href.match(/
    o.href = jQuery(o).data('song_link');
    if (o.nodeName.toLowerCase() != 'a') {
    o = self.isChildOfNode(o,'a');
    if (!o) return true;
    }
    var sURL = o.getAttribute('href');
    if (!o.href || !o.href.match(/\.mp3(\\?.*)$/i) || self.classContains(o,self.excludeClass)) {
    if (isIE && o.onclick) {
    return false; // IE will run this handler before .onclick(), everyone else is cool?
    }
    return true; // pass-thru for non-MP3/non-links
    }
    sm._writeDebug('handleClick()');
    var soundURL = (o.href);
    o.href = '#';
    #46;mp3(\?.*)$/i) || self.classContains(o,self.excludeClass)) {
    if (isIE && o.onclick) {
    return false; // IE will run this handler before .onclick(), everyone else is cool?
    }
    return true; // pass-thru for non-MP3/non-links
    }
    sm._writeDebug('handleClick()');
    var soundURL = (o.href);
    o.href = '#';


    This solution only modifies the DOM, so the user can still "View Source" and pull the MP3 from the static source.

    I like the "private key" method described above, but I believe an extra HTTP header would still be a nice addition when the Flash requests the MP3. Then your PHP/Django/etc. can check the headers when the request comes in. This way right-clicking the URL would fail anyways, because the browser wouldn't send the correct HTTP request header. I think this would deter most users, because changing HTTP request headers requires some basic knowledge of the protocol.

    Thanks!

    colin
    http://www.caktusgroup.com/services/
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited sad, anxious, confused, frustrated

  • Hahaha, I hadn't even considered that! My entire implementation is dynamic and we don't even use "A" tags. It's all divs and spans where the songs are concerned and it's not even in the source because it's all loaded via ajax. You can still get the keys out of say, firebug, but so many of our users don't even know what firebug is that it's safe enough for us.

    Having myself reconsidered the idea of the http headers, I expect that it would end up being convenient, but after a while if the user base for any website is to grow then it would have to be removed for compatibility with non-flash or non-js browsers.
    Example:
    iphone (rapidly growing popularity for browsing); no flash, therefore you should be able to click on the link to download it, however if we add a special http header then it would not be accessible via a regular "get" access. Of course you could check the special header AND the referrer, but after a while it ends up with really jumbled code when you need to hard code every single header that you may use.
    In essence, with the idea of backward AND forward compatibility on the web (html5) it's probably a bad idea to implement something that would be dependant on that, though for now and the next year or two it will probably be a perfectly acceptible form of security.

    Plus, the http headers are just as easy as post variables to fake with all the developer tools available these days. Let alone the thousands of hacking/pirating tools ;-)
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • I've considered the iPhone issue, but am a little stumped about how to offer any degree of protection to mp3s when playing them via the Quicktime plugin. Then again, there are probably few people capable of stealing music from Safari's cache on an iPhone. Do we need to serve the non-Flash version of the site only to mobile browsers? (And how easy is it to fake a mobile browser from a desktop machine?)

    I did have one far-fetched idea for protecting mp3s that are going to be played through a proprietary Flash player: corrupt them. If you wrote a bunch of nulls to the mp3 files at predefined places, you'd probably make them unplayable. Your Flash player would be programmed to remove the nulls before playing. If anyone stole the file (even out of the cache, I believe), they'd have something unusable.

    Of course:
    1) I don't know if putting strings of nulls inside of an mp3 file would actually render it useless.

    2) The logistics of removing specific bytes from a 10 mb buffered mp3 file might be daunting.

    N
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I’m diggin' it
    I'm implementing this now to work with SM, but I currently have my purchasable (i.e. protected) mp3's outside of the web root. As was mentioned earlier, the download link actually calls a php script that reads the file and streams it to the output buffer. Here's a basic implementation:


    $filepath = $basepath.$basename;
    $filesize = filesize($filepath);

    header("Pragma: no-cache");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

    // force download dialog
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");

    header('Content-Disposition: attachment;filename="'.$basename.'"');

    header("Content-Transfer-Encoding: binary");

    #header('Content-Type: audio/mpeg3');
    header('Content-Length: '.$filesize);

    @readfile($filepath);
    exit(0);
    ?>

    -Scott
    www.busitones.com
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • Thanks for that, Scott. I was just getting to the point of having to implement something similar but I'm server-side challenged and did not relish the though having to pull out the PHP manual.

    Now...would you happen to know of a good web article on setting up Apache file/directory/script permissions?

    Cheers,
    Nick
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • Not without some googling, but I've always just relied on inside the webroot or outside. You can pretty much always count on that to be secure. Not exactly the same subject, but there's some handy apache tips on my blog you might enjoy. Feel free to leave a comment or ask a question there as well.
    http://bethink.olioideas.com
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • OK, I got it working:
    Javascript (snippet):
    soundManager.createSound({
    id: 'foo',
    url: '/stream.php?name=foo',
    volume: 80
    });
    soundManager.play('foo');

    PHP (url SM calls) stream.php:

    $soundname =$_GET['name'];

    if ($soundname == 'tone') {
    // This path is OUTSIDE the webroot
    $filepath = "../sounds/".$soundname.".mp3";
    } else {
    $filepath = 0;
    }

    $filesize = filesize($filepath);

    header("Pragma: no-cache");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");

    // force download dialog
    header("Content-Type: application/force-download");
    header("Content-Type: application/octet-stream");
    header("Content-Type: application/download");

    header('Content-Disposition: attachment;filename="'.$filepath.'"');

    header("Content-Transfer-Encoding: binary");

    #header('Content-Type: audio/mpeg3');
    header('Content-Length: '.$filesize);

    @readfile($filepath);
    exit(0);
    ?>

    -Scott
    www.busitones.com
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • Hi Scott,

    i tried your method but the song is always comes in memory while playing, if we use the add on of Firefox cache viewer, it's show the bytes in memory and anyone easily download the song from it.

    is any solution you have for the same.

    sorry for the my language, hope you get what i am saying.

    thanks
    bechar
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • That's interesting Bechar, I can't see mine in the cache viewer... From what I posted earlier, I've redone it in Python (which is what I'm testing with), but the result should be the same. Here's what I'm doing now:

    filesize = os.path.getsize(filepath)

    print "Prama: no-cache\r"
    print "Expires: 0\r"
    print "Cache-Control: must-revalidate, post-check=0, pre-check=0\r"
    print "Content-Type: application/octet-stream\r"
    print "Content-Type: application/download\r"
    print 'Content-Disposition: attachment;filename="'+filename+'"\r'
    print "Content-Transfer-Encoding: binary\r"
    print "Content-Length: "+str(filesize)+"\r"
    print #required blank line

    sys.stdout.write(open(filepath,"rb").read())
    sys.stdout.flush()

    -Scott
    www.busitones.com
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • This reply was removed on 2009-11-19.
    see the change log
  • I’m mystified
    Hi,
    Tried you php solution to this, but the mp3 downloads as normal if you enter the address of the php file.

    I did not manage to modify the page-player so that uses the js i.e.:

    soundManager.createSound({
    id: 'foo',
    url: '/stream.php?name=foo',
    volume: 80
    });
    soundManager.play('foo');

    So I tried to make the
  • item point to a php file with a hardcoded name value, which of course just sends the mp3 if you type in the address of the php.

    Is there a guide anywhere to using the js calls in the page-player?

    Thanks for reading
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • That seems to be a simple way to do it! But now the file wont play, as it fails to load.. Do I have to edit anything in the php as well?

    ) check? What is tone?
    • You need to tweak that section to your needs I believe.


      if ($soundname == 'tone') {
      // This path is OUTSIDE the webroot
      $filepath = ""../../../../../mp3/".$soundname.".mp3";
      } else {
      $filepath = 0;
      }

      will actually only work if $soundname is "tone". otherwise it will get no sound file.
      I'm assuming that you want to use many files with this script so if you take out the section and use it with just the

      $filepath = ""../../../../../mp3/".$soundname.".mp3"

      part then you should be able to do what you are trying to do.
      To make it more secure you need to add the security in yourself, which will be dependent on the setup you're using.

      The if statement there, I believe, was just an example of how to implement the security, but unless you want to manually code in every file, then you should probably use a database with IDs of the files and their locations. Then instead of $soundname, you could use $soundID and then get the name/location out of the database. At very least this way the user needs to have the ID if they want to steal it.
      There are other precautions you can take to make sure that the user is logged in or other conditions, but I think starting with a database routine would be a good step for the moment.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • http://github.com/kjvarga/SoundManager2

    This version adds support for streaming using RTMP (and its variants) from a Flash Media Server (or similar)
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • I've modified the above snippet by copelco to make it possible to mark, on an mp3 tracklist, some tracks to not be downloadable (of course, considering all the limitations already stated on this thread). The marked mp3 are still playable, but the URL won't show on the browser's status bar, nor will let you save them when doing "right-click -> save link as...".

    First, the jQuery code:


    $(function() {
    $('div.tracklist a.no_dl').each(function (i, el) {
    var data = $(el).data('song_link') || $(el).data('song_link', undefined);
    if (!data) {
    $(el).data('song_link', el.href);
    }
    el.href = '#';

    // uncomment following 3 lines if you would also like to disable
    // right-click on those links.
    // $(el).bind("contextmenu", function(e) {
    // e.preventDefault();
    // });
    });
    });


    Then, on the inlineplayer.js code, you will have to replace lines 141 to 151 with:


    o.href = jQuery(o).data('song_link') ? jQuery(o).data('song_link') : o.href;
    if (o.nodeName.toLowerCase() != 'a') {
    o = self.isChildOfNode(o,'a');
    if (!o) return true;
    }
    //var sURL = o.getAttribute('href');
    if (!o.href || !o.href.match(/
    o.href = jQuery(o).data('song_link') ? jQuery(o).data('song_link') : o.href;
    if (o.nodeName.toLowerCase() != 'a') {
    o = self.isChildOfNode(o,'a');
    if (!o) return true;
    }
    //var sURL = o.getAttribute('href');
    if (!o.href || !o.href.match(/\.mp3(\\?.*)$/i) || self.classContains(o,self.excludeClass)) {
    // if (isIE && o.onclick) {
    // return false; // IE will run this handler before .onclick(), everyone else is cool?
    // }
    return true; // pass-thru for non-MP3/non-links
    }
    sm._writeDebug('handleClick()');
    var soundURL = (o.href);
    o.href = jQuery(o).data('song_link') ? '#' : o.href;
    #46;mp3(\?.*)$/i) || self.classContains(o,self.excludeClass)) {
    // if (isIE && o.onclick) {
    // return false; // IE will run this handler before .onclick(), everyone else is cool?
    // }
    return true; // pass-thru for non-MP3/non-links
    }
    sm._writeDebug('handleClick()');
    var soundURL = (o.href);
    o.href = jQuery(o).data('song_link') ? '#' : o.href;


    Then, just simple add the class "no_dl" to mp3 links that you would like to avoid users to easily download.
    That's all.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited sad, anxious, confused, frustrated

  • Where do you put the jQuery code? Sorry I'm a n00b. And Should the second snippet you've shown also work in the pageplayer.js code? Thanks
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited sad, anxious, confused, frustrated

  • First of all, this is a great product, and it loads quickly! However, when I've tried (slower) Flash buttons (like Wimpy button) the URL to the audiofile doesn't show up in FireFox at the lower left corner of the browser since the URL is sort of hidden in the Flash-application itself. In SM2 the URL shows up.

    I guess the < a href > makes the URL visible. Is there any way around this? Some simple change? For example the 360° Player UI doesn't seem to show the URL.

    Update: I've tried the 360°. How can I "get rid" of the 360° surrounding part and just have the Flash play button in the middle? If I leave the < a href >< /a> empty there's still a tiny invisible space that can be clicked where the URL is seen. How to get rid of?
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • How about generating a unique filename for each instance of a given audio file? Instead of always displaying "music.mp3," have PHP or your app make a unique string like "7HB9F.mp3" and save the string in a DB table with 3 fields "string","actual", and "played." The tag would look like this:

    Some Title

    Then you would use either Apache rewrite to fetch the real filename or write your app script to parse the URI and fetch the real file name that way. Of course, you must also program your app to increment the "played" field in the db table the first time. Then upon subsequent calls to the same file you would serve up a different file such as "no-stealing-my-audio.mp3" so they would get the clue.

    Drawback is that you would have to allow caching so they can at least replay the file a few times during the browser session.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited

  • This reply was removed.
    see the change log
  • I was having errors when using the methods described by Copelco and Julian since I'm not using the inlineplayer.js, but rather the mp3-player-button.js.

    But this process works perfectly when using mp3-player-button.js

    Add a new class of no_dl to each player that you want protected.

    a href="path/to/song.mp3" class="sm2_button no_dl"


    Insert this on your page before your player(s):

    a href="path/to/song.mp3" class="sm2_button no_dl"


    Insert this on your page before your player(s):

    $(function() {
    $('a.no_dl').each(function (i, el) {
    var data = jQuery(el).data('song_link') || jQuery(el).data('song_link', undefined);
    if (!data) {
    jQuery(el).data('song_link', el.href);
    }
    el.href = '#';

    $(el).bind("contextmenu", function(e) {
    e.preventDefault();
    });

    });
    });

    // This prevents soundmanager.js from breaking links
    $(function() {
    $('a').not('.sm2_button').each(function (i, el) {
    var data = jQuery(el).data('not_mp3') || jQuery(el).data('not_mp3', undefined);
    if (!data) {
    jQuery(el).data('not_mp3', el.href);
    }
    });
    });


    And in mp3-player-button.js, replace lines 146-158 with this:

    var o = self.getTheDamnLink(e);
    o.href = jQuery(o).data('song_link');
    if (o.nodeName.toLowerCase() != 'a') {
    var o = self.isChildOfNode(o,'a');
    if (!o) return true;
    }
    var sURL = o.getAttribute('href');
    if (!o.href || !o.href.match(/
    var o = self.getTheDamnLink(e);
    o.href = jQuery(o).data('song_link');
    if (o.nodeName.toLowerCase() != 'a') {
    var o = self.isChildOfNode(o,'a');
    if (!o) return true;
    }
    var sURL = o.getAttribute('href');
    if (!o.href || !o.href.match(/\.mp3(\\?.*)$/i) || self.classContains(o,self.excludeClass)) {
    o.href = jQuery(o).data('not_mp3'); // re-assign the non-mp3 link
    return true; // pass-thru for non-MP3/non-links
    }
    sm._writeDebug('handleClick()');
    var soundURL = (o.href);
    o.href = '#';
    var thisSound = self.getSoundByURL(soundURL);
    #46;mp3(\?.*)$/i) || self.classContains(o,self.excludeClass)) {
    o.href = jQuery(o).data('not_mp3'); // re-assign the non-mp3 link
    return true; // pass-thru for non-MP3/non-links
    }
    sm._writeDebug('handleClick()');
    var soundURL = (o.href);
    o.href = '#';
    var thisSound = self.getSoundByURL(soundURL);
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. indifferent, undecided, unconcerned happy, confident, thankful, excited kidding, amused, unsure, silly sad, anxious, confused, frustrated

  • I’m confident
    There's one thing that doesn't seem to have been mentioned in this thread; watermarking.

    Watermarking is a kind of "social DRM" which lets you play your files in any mp3-capable player, including SoundManager 2. But since the mp3 is watermarked, you won't be tempted to share it online, since the file would be tracable back to you.

    Decent watermarking solutions like the ones from MusicTrace and ActivatedContent will cost you though.
  • (some HTML allowed)
    How does this make you feel?
    Add Image
    I'm

    e.g. sad, anxious, confused, frustrated kidding, amused, unsure, silly indifferent, undecided, unconcerned happy, confident, thankful, excited