Stream an audio file into the HTML audio element via AJAX/PHP request with Blob?

I’m trying to create an HTML5 player with a minimum of protection to avoid music downloads.

To explain quickly :

  • I have a database containing the title, a hash to find my music.
  • In my HTML file I have buttons containing my hash in an attribute.
  • So I retrieve my hash via JS then I make an AJAX request and this request returns the MP3 file as a Blob.

The normal functioning of Audio via a direct URL of an audio file allows preloading but the playback can be done even if the buffer is not complete.
But here to prevent the download I have to use an AJAX request. And the problem is that it downloads the complete file and then create the Blob and start playback.

But the problem is that if my user is a poor connection and the file is about 10 MB (about 10-15 seconds to load)

So I would like my user to be able to start listening without having finished downloading the whole music but only need the first 20% to be able to start playing the audio file for example.

Here is the code that performs the AJAX query that will load the blog response in my player.

    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'blob';
    request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');

    // Decode asynchronously
    request.onload = function ()
    {
        if (request.readyState === 2)
        {
            const url = window.URL.createObjectURL(request.response);
            audio.src = url;
            audio.play();
            document.body.removeChild(div);
        }
        else
        {
            alert('Impossible de lire cet music.');
        }
    }
    request.send();

And here the code of the page called by AJAX

$res contains the music data. To be able to fetch the file from the server.

        if ($res)
        {
            // TODO auto extension
            $filename = '../mp3/' . $res['title'] . $res['track_extension'];
            $fsize    = filesize($filename);

            $handle   = fopen($filename, "rb", false, $context);
            $contents = fread($handle, $fsize);
            fclose($handle);

            header('content-type: audio/mpeg');
            header('Content-Length: ' . $fsize);


            echo readfile($filename);
        }
        else
        {
            header('HTTP/1.0 404 Not Found', 404);
            echo '0';
        }

16 thoughts on “Stream an audio file into the HTML audio element via AJAX/PHP request with Blob?”

  1. You can be sure that your solution isn’t preventing anyone from downloading anything. It’s trivial to just click the network tab and see the URL for the audio file (among other methods).

    What you’re proposing offers zero protection.

    Even if it did help you in some way, the only way forward for streaming is to implement code to use Media Source Extensions, which is an incredible hassle and offers no benefit to your users.

    If you want to protect your media, the best you can do is use DRM… but it is still trivial to copy audio to the point that most people don’t bother with the encryption.

    Reply

Leave a Comment