The audio element is a fantastic part of HTML 5 that give you a ton of control over the UI and functionality of media on a page. However, it is far too easy to open up Dev Tools, find the absolute file path to a media file on a server and download it for free. Obviously, this isn’t great for site owners who’d like to give users a way to stream music while preserving the ability to sell that media (aka – not have it stolen from them). So the question becomes, “how do you hide file paths?”

I ran into this issue while building a custom audio player for mattlitzingermusic.com. Although I choose to give my music away for free through certain outlets, I want the ability to be strategic about how it is available on the web. While I was thinking through this issue, a few solutions came to mind.

Method 1: No Worries Man!

You could trust people and hope they won’t try to steal your files. At the time of writing, this is the case for sites like Squarespace and BandCamp, which have become popular tools for music artists. The audio player for these sites loads the file from a CDN (which is great for speed), but it fails to obfuscate the file path in any way. You can simply find the audio tag in the HTML, copy the source link and now you have free music. What’s worse is I don’t even think this is illegal because the file wasn’t obtained through any nefarious method. It’s just a public link to a file living on the internet. Needless to say, I didn’t settle for this option. Here’s what that would have looked like:

<audio src="/audio/file_0.mp3"></audio>

Method 2: Look I’m Wearing A Mask

The audio element can accept a data URI as a source, so you could Base64 encode the files before they are sent to the browser. Unfortunately, anything that is Base64 encoded can be decoded. However, this would deter many users that might otherwise grab a plain text URL to your file. Here’s what this method could look like:

<?php 
    $file = file_get_contents('/audio/file_0.mp3'); 
?>
<audio src="data:audio/mp3;base64,<?php echo base64_encode($file); ?>"></audio>

Method 3: The Black Box

You could use a PHP file as a proxy layer. This file would use a GET variable to reference a list of audio files stored in an array (or database for larger lists). The PHP file would then return the media associated with that ID to the browser. Note that the file returns a response of 403 Forbidden if the file is accessed anywhere other than the specified URL. Here is what that looks like:

<audio src="/mp3.php?file_id=0"></audio>
<?php
  if (strstr($_SERVER['HTTP_REFERER'], 'mattlitzingermusic.com/music') !== false) {
    $track_id = $_GET['file_id'];
    $tracks = array(
      '/audio/file_0.mp3',
      '/audio/file_1.mp3',
      '/audio/file_2.mp3',
      '/audio/file_3.mp3'
    );
    header('Location: ' . $tracks[$track_id]);
  } else {
    header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden', true, 403);
    echo '<h1>Forbidden</h1><p>You don\'t have permission to access this file. </p><hr>';
  }

As you can see, there is a lot to think about when it comes to playing audio securely on the web. None of these methods are close foolproof. They are just my thoughts on how we can address this problem with the tools available. If you can think of a better way, let me know on Twitter.