This was initially a project I had started to get better acquainted with the Web Audio API. I had done some preliminary work with the Media Source Extensions API and piping output via to the Web Audio API, but I wanted to see how well the scheduling capabilities were. Throughout the effort, I learned quite a bit about signal processing and FFT.
The current process is rather simple: I utilize M3U8 for storing segment information, and manually parse the file when a play request is received. I grab the first few (Opus-encoded) segments, pass them through an OfflineContext to maintain a specific sample rate, and store the resulting buffer in a wrapper object. Each object is stored in an array, and is responsible for re-creating the AudioNode when stopping or starting.
The hardest part about this (for me at least) was fetching and scheduling accurately while the player is running. I group segments requests together, and schedule after each group has finished downloading. It's not perfect, as I occasionally get pops between each segment: Chrome seems to be less noticeable than Firefox in this regard. I schedule based on the buffer duration, but there seems to be subtle differences between browsers.
In any case, I've had quite a bit of fun working on this project.
The current process is rather simple: I utilize M3U8 for storing segment information, and manually parse the file when a play request is received. I grab the first few (Opus-encoded) segments, pass them through an OfflineContext to maintain a specific sample rate, and store the resulting buffer in a wrapper object. Each object is stored in an array, and is responsible for re-creating the AudioNode when stopping or starting.
The hardest part about this (for me at least) was fetching and scheduling accurately while the player is running. I group segments requests together, and schedule after each group has finished downloading. It's not perfect, as I occasionally get pops between each segment: Chrome seems to be less noticeable than Firefox in this regard. I schedule based on the buffer duration, but there seems to be subtle differences between browsers.
In any case, I've had quite a bit of fun working on this project.