I\'m initializing jplayer with the following parameters:
$jplayer.jPlayer(\'setMedia\',{
mp3: data.audioMP3,
oga: data.audioOGA
});
Assume
Since you are using javascript to get the file, others can do the same by reading the headers/file requests from the browser (firebug, Chrome's default tools, etc).
The best way to protect your files from being downloaded is to make a series of checks to get at the data. It's not perfect, but it will deter all but the most determined. For some ideas, check out this page on Grooveshark's API (This is a bit old and some info is missing, so it's the perfect reference), or just visit Grooveshark/Youtube and see how they protect their content.
It is possible to recreate this kind of security with some clever usage of sessions and a good database.
Thanks for everyone's answers.
I actually ended up solving the problem without revealing the path to the audio file to the user.
Because this is for an online voice messaging application, it was important to protect the path to the messages in order to protect the user's privacy.
The situation ended up being further complicated by the fact that the messages are stored on a remote server... found this out right after I posted this question.
So all in all the process was:
1) Curl the MP3 file from the remote server
2) Set some headers to force the download of the data, which you then echo to stdout
Because the data is being put on standard out and the headers are set to force a download, the effect for jPlayer is the same as if it had requested a file at /some/dir/message.mp3, except that the request goes to /some/dir/playmessage.php - thus the path is never revealed to the user.
EDIT** - Assume that I have access control, validation running before the snippit below, otherwise exposing the path to the script below is no different than just exposing the path to the mp3. (see comments between me and Lloyd)
Here's the code that ended up getting the job done:
$ch = curl_init($remoteFile);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
curl_close($ch);
if ($data === false) {
echo 'CURL Failed';
exit;
}
//Get file size
if (preg_match('/Content-Length: (\d+)/', $data, $matches)) {
$contentLength = (int)$matches[1];
}
//force user to download file contents
header('Content-Transfer-Encoding: binary');
header('Content-Type: audio/mpeg');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Content-Length: ' . $contentLength);
ob_clean();
flush();
echo $data;
exit;
?>
Assume that $remoteFile
is a path to the mp3 file that I want to play on the server where we are storing messages.
I found this resource on reading a remote file using PHP especially helpful. Here's some more information on modifying http headers.
NOTE I am essentially downloading the file twice, which slows the process down for the user. There is probably a better way to do this. :) If you kept the file locally, what I had initially in my question actually works (using readfile() to output the raw mp3 data).
i think you'll struggle to prevent users discovering your media content URL, i'd say it was pretty much impossible (a quick look at the 'Network' tab on Chrome would reveal your loaded track, regardless how you coded playaudio.php
).
I'd say you were better off sticking to publishing media you don't mind sharing with the world.. Or just publish
If you really wanted to protect your resources, you could use oAuth or Access Control at the server side.