Skip to content

Instantly share code, notes, and snippets.

@Minigugus
Last active April 3, 2019 21:20
Show Gist options
  • Save Minigugus/531b4bf6345cefb4a8ff145df9506a8c to your computer and use it in GitHub Desktop.
Save Minigugus/531b4bf6345cefb4a8ff145df9506a8c to your computer and use it in GitHub Desktop.
/*
* A HTTP Source for Aurora.JS (https://github.com/audiocogs/aurora.js) allowing real-time decoding and playing.
* Use fetch & Streams API in order to process the response in real-time.
*
* Example :
*
* var player = new AV.Player(new AV.Asset(new HTTPLiveSource('http://example.com/live.aac')))
* player.play();
*
*/
var HTTPLiveSource = (function(){
var fetchSupport = (typeof fetch !== 'undefined');
var writableStreamSupport = (typeof WritableStream !== 'undefined');
var readableStreamSupport = (typeof ReadableStream !== 'undefined');
function write(buf) {
var buffer = new AV.Buffer(buf);
this.length = (this.offset += buffer.length);
this.emit('data', buffer);
}
function end() {
if (this.controller)
{
this.emit('end');
this.controller = null;
}
}
function abort(err) {
if (this.controller)
{
this.emit('error', err);
this.emit('end');
this.controller = null;
}
}
function HTTPLiveSource(url) {
AV.EventEmitter.call(this);
if (!fetchSupport || !(writableStreamSupport || readableStreamSupport)) {
return this.emit('error', 'This browser does not have Fetch and Steams API support.');
}
this.url = url;
}
HTTPLiveSource.prototype = AV.EventEmitter.prototype;
if (writableStreamSupport)
HTTPLiveSource.prototype.start = function() {
if (this.controller)
this.pause();
var stream = new WritableStream({
write: write.bind(this),
close: end.bind(this),
abort: abort.bind(this)
}, new ByteLengthQueuingStrategy({ highWaterMark: 8192 }));
this.controller = new AbortController();
return fetch(this.url, { signal: this.controller.signal })
.then(function(res) {
return res.body.pipeTo(stream);
});
};
else
HTTPLiveSource.prototype.start = function() {
if (this.controller)
this.pause();
this.controller = new AbortController();
var source = this;
return fetch(this.url, { signal: this.controller.signal })
.then(function(res) {
return res.body.getReader();
})
.then(function(reader) {
var _abort = abort.bind(source);
function consume() {
reader.read()
.then(function(res) {
if (res.done)
return end.call(source);
write.call(source, res.value);
consume();
})
.catch(_abort);
}
consume();
});
};
HTTPLiveSource.prototype.pause = function pause() {
var controller = this.controller;
this.controller = null;
this.emit('end');
controller.abort();
};
HTTPLiveSource.prototype.reset = HTTPLiveSource.prototype.pause;
return HTTPLiveSource;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment