My Experience
There is nothing wrong with your code. I had this issue once and .. And it was a simple cache issue on Firefox
and Content-Length
which you have discovered
c.php
<audio controls="controls" id="audio-sample" preload="auto">
<source src="a.php?type=ogg&id=0" type="audio/ogg" />
<source src="a.php?type=mp3&id=1" type="audio/mp3" />
</audio>
a.php
$id = intval($_GET['id']);
$files = array(0 => "audio.ogg",1 => "audio.mp3");
$filename = $files[$id];
header('Content-Type: ' . mime_content_type($filename));
header("Content-transfer-encoding: binary");
header("Content-Length: " . filesize($filename));
ob_clean();
flush();
readfile($filename);
exit();
This worked 100%
in Firefox but when i changed readfile($filename)
to
readfile("SIMPLE ERROR ERROR");
Firefox sill pays the audio for me instead of not paying any file the only way to make it realize the mistake was to add a random string to the src
file
<source src="a.php?type=ogg&id=0&<?php echo mt_rand(); ?>" type="audio/ogg" />
^---- rand string
This way the URL was requested Firefox stooped playing the audio instantly
The Problem
Because you have tried to stream the content before with Zero Content-Length
that is sill the reason your audio is not paying ..... Firefox has cached the initial invalid content
Solution
Clear all your cache .. with the following code above your code should work fine or just add the rand parameter in your code for testing

Invalid Relative Position
Permanently using mt_rand()
would make it difficult for Firefox
to cache the audio file which results in Invalid Relative solution.
Remove the mt_rand
after the cleaning of cache and this would be fixed