• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

XHR3 und mehr

xorg1990

New member
Hi, es gibt eine neue API, mit der man Daten vom Server holen kann die fetch API.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

man dann damit auch audio daten zerteilen:
Code:
//
// loads remote file using fetch() streams and "pipe" it to webaudio API
// remote file must have CORS enabled if on another domain
//
// mostly from http://stackoverflow.com/questions/20475982/choppy-inaudible-playback-with-chunked-audio-through-web-audio-api
// 

function play(url) {
  var context = new (window.AudioContext || window.webkitAudioContext)();
  var audioStack = [];
  var nextTime = 0;

  fetch(url).then(function(response) {
    var reader = response.body.getReader();
    function read() {
      return reader.read().then(({ value, done })=> {
        context.decodeAudioData(value.buffer, function(buffer) {
          audioStack.push(buffer);
          if (audioStack.length) {
              scheduleBuffers();
          }
        }, function(err) {
          console.log("err(decodeAudioData): "+err);
        });
        if (done) {
          console.log('done');
          return;
        }
        read()
      });
    }
    read();
  })

  function scheduleBuffers() {
      while ( audioStack.length) {
          var buffer    = audioStack.shift();
          var source    = context.createBufferSource();
          source.buffer = buffer;
          source.connect(context.destination);
          if (nextTime == 0)
              nextTime = context.currentTime + 0.01;  /// add 50ms latency to work well across systems - tune this if you like
          source.start(nextTime);
          nextTime += source.buffer.duration; // Make the next buffer wait the length of the last buffer before being played
      };
  }
}

var url = 'http://www.metadecks.org/software/sweep/audio/demos/beats1.wav?adazdaz'
play(url);

Mit nen normalem xhr klappt das nicht, da müsste man das komplette file in den Browser laden und dann dekodieren.

Dann auch im kommen die OffscreenCanvas API,

https://developer.mozilla.org/de/docs/Web/API/OffscreenCanvas
Leider:
This API is currently implemented for WebGL1 and WebGL2 contexts only. See bug 801176 for Canvas 2D API support from workers.
Aber in chrome scheint die 2d api zu funktionieren.
 
Bist du dir da absolut sicher?

.decodeAudioData möchte ja immer einen Datei Kopf sonst kommt ein Fehler. Im ersten chunk hast du noch den Kopf mit bei, aber im 2ten chunk irgendwas.

Das mit den zerstückeln von wav Dateien ist aber sowieso so eine Sache. Bei mono wav ist das alles kein ding. Aber bei Mehrkanal muss man aufpassen wo man den Zeiger hinsetzt sonst sind die Kanäle verschoben.
 
Bist du dir da absolut sicher?
ja

.decodeAudioData möchte ja immer einen Datei Kopf sonst kommt ein Fehler.
ich meine ganz normale text-daten - xhr.responseText. mit was anderem geht das mit xhr leider nicht - mies spezifiziert.

Im ersten chunk hast du noch den Kopf mit bei, aber im 2ten chunk irgendwas.
im 2. chunk hast du bei fetch auch keinen kopf dabei.
bei xhr steht im responseText leider chunk1 + chunk2

index.html
Code:
<!DOCTYPE html>
<html>
  <head>
    <title></title>
  </head>
  <body>
    <div id="xhr"></div>
    <script>
      var pos = 0;
      var xxx = document.getElementById("xhr");
      var xhr = new XMLHttpRequest();
      xhr.addEventListener("readystatechange", function()
      {
        if (xhr.readyState == 3)
        {
          console.log("xhr: new " + (xhr.responseText.length - pos) + "chars");
          xxx.textContent = xhr.responseText.substring(pos);
          pos = xhr.responseText.length;
        }
        if (xhr.readyState == 4)
        {
          console.log("xhr done");
        }
      });
      xhr.open("GET", "/xxx");
      xhr.send();
    </script>
    <div id="fetch"></div>
    <script>
      fetch("/xxx").then(function(response)
      {
        var xxx = document.getElementById("fetch");
        var reader = response.body.getReader();
        function read()
        {
          return reader.read().then(function(result)
          {
            if (result.value)
            {
              console.log("fetch: new " + result.value.byteLength + "byte");
              xxx.textContent = new TextDecoder("utf-8").decode(result.value);
            }
            if (result.done)
            {
              console.log("fetch done");
              return;
            }
            read()
          });
        }
        read();
      });
    </script>
  </body>
</html>

fetch geht ja leider nicht mit file://
hier mal für node
Code:
var express = require('express');

var app = express();

app.get('/', function(req, res)
{
  res.sendFile(__dirname + '/index.html');
});

app.get('/xxx', function(req, res)
{
  res.sendFile(__dirname + '/xxx');
});

app.listen(3000);

und hinter xxx legst du eine große datei, ich hab die zahlen 0 bis 9 solange hinternander kopiert, bis ich 54 mb hatte ;)
 
Zuletzt bearbeitet:
Zurück
Oben