2015-10-09 3 views
2

Mon but est de lire un flux audio HTTP MP3 à partir du navigateur et avoir accès aux données audio brutes.XMLHttpRequest et http streaming

  • HTML5 < audio> me permet de jouer facilement le flux, mais, autant que je sache, ne donne pas accès aux données audio brutes. Ça joue juste ça.

  • JS XMLHTTPRequest peut télécharger des fichiers via HTTP et traiter les données audio brutes. Il semble être un bon candidat, mais il souffre d'une limitation: il n'accorde pas l'accès aux données binaires tant que le téléchargement n'est pas terminé (readystate = 4). Dans mon cas, le flux est illimité, donc le readystate reste en permanence à 3 et la réponse XHR est nulle (ce comportement est détaillé dans la documentation de mozilla). Notez que la politique inter-origine du serveur que je me connecte à est l'accès-Control-Allow-origine: *

exemple de code qui fonctionne pour les fichiers locaux réguliers, mais pas pour les cours d'eau. Je reçois une exception de pointeur nul à request.response.length

request = new XMLHttpRequest(); 
//request.open('GET', 'test.mp3', true); 
request.open('GET', 'http://domain.com/stream.mp3', true); 
request.responseType = 'arraybuffer'; 
request.onload = function() { 
    console.log("request onload"); 
    var audioData = request.response; 
    audioCtx.decodeAudioData(audioData, 
    function(buffer) { myBuffer = buffer; source.buffer = myBuffer; }, 
    function(e){"Error with decoding audio data" + e.err} 
); 
} 
request.onreadystatechange = function() { 
    console.log("ready state = " + request.readyState); 
    console.log(request.response.length); 
} 
request.send(); 

Quelqu'un sait-il des alternatives ou des solutions de contournement à ces options, de sorte que les paquets binaires brutes peuvent être lus pendant le téléchargement du flux?

Notez que je n'ai aucun contrôle sur le serveur. C'est un flux http icecast. En outre, du côté du navigateur, j'aimerais éviter d'utiliser Flash. Merci

Modifier: pour clarifier d'éventuelles questions d'origine croisée, le JS est exécuté sur une page hébergée sur un serveur localhost.

+0

Pour être clair, vous voulez les données audio PCM décodées brutes, pas le flux binaire du serveur, oui? Si c'est le cas, l'API Web Audio est ce dont vous avez besoin. – Brad

+0

@Brad en effet j'utilise l'API Web Audio (comme un indice voir par exemple la méthode decodeAudioData ci-dessus, dans mon code partiel). J'ai juste eu du mal à obtenir un tampon du flux et à le mettre dans l'API. Je pense avoir trouvé une solution, voir ma solution ci-dessous. – astooooooo

Répondre

4

La solution suivante a fonctionné:

Comme indiqué dans MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data, il est possible de remplacer le type MIME de requête http , en le personnalisant et appelez responseText.

function load_binary_resource(url) { 
    var req = new XMLHttpRequest(); 
    req.open('GET', url, false); 
    //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com] 
    req.overrideMimeType('text\/plain; charset=x-user-defined'); 
    req.send(null); 
    if (req.status != 200) return ''; 
    return req.responseText; 
} 

Le point est que req.responseText ne souffre pas de la même limitation de req.response. Il n'est pas nul dans l'état readystate = 3. Ensuite, le responseText binaire est accessible avec

var filestream = load_binary_resource(url); 
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7) 

Un inconvénient important est que req.responseText ne cesse de croître comme le flux est téléchargé. La demande doit être réinitialisée de temps en temps pour éviter une consommation excessive de RAM.

+1

Y a-t-il des mises à jour jusqu'à aujourd'hui? –

-2

Vous devez avoir un serveur ou un script localhost sur l'hôte. Becouse lorsque vous exécutez le script en tant que fichier que vous obtenez l'erreur d'origine croisée, lorsque vous essayez demande sur un autre serveur

+1

merci pour votre contribution.Notez que la politique d'origine croisée du serveur auquel je me connecte est Access-Control-Allow-Origin: * – astooooooo

+0

yes mais, si vous n'utilisez que des fichiers locaux, à partir d'un serveur quelconque, le navigateur annule automatiquement toute requête de localhost – Sebastian

+0

J'ai vérifié deux fois avec un fichier mp3 aléatoire sur un serveur externe. Je reçois l'erreur d'origine croisée. Le flux que j'essaie de télécharger a une politique d'origine croisée ouverte. Je ne reçois aucune erreur CORS lorsque j'essaie de me connecter. Le problème est ailleurs. – astooooooo