@firstcoders/hls-web-audio
Version:
`@firstcoders/hls-web-audio` plays multiple streamed audio tracks in sync using the Web Audio API. It is designed for stem-like playback where each track can be independently loaded, buffered, scheduled, and mixed.
92 lines (82 loc) • 2.74 kB
JavaScript
/**
* Stores a normalized snapshot of playback timing data and exposes scheduling helpers.
*/
export default class Timeframe {
/**
* @param {Object} [options]
* @param {number} [options.anchor]
* @param {number} [options.realEnd]
* @param {number} [options.currentTime]
* @param {number} [options.playDuration]
* @param {number} [options.offset]
*/
constructor({ anchor, realEnd, currentTime, playDuration, offset } = {}) {
this.update({ anchor, realEnd, currentTime, playDuration, offset });
}
/**
* Updates the snapshot values in place.
*
* @param {Object} options
* @param {number} [options.anchor]
* @param {number} [options.realEnd]
* @param {number} [options.currentTime]
* @param {number} [options.playDuration]
* @param {number} [options.offset]
* @returns {Timeframe}
*/
update({ anchor, realEnd, currentTime, playDuration, offset }) {
if (anchor !== undefined) this.anchor = anchor;
this.realEnd = realEnd;
this.currentTime = currentTime;
this.playDuration = playDuration;
this.offset = offset;
return this;
}
/**
* Recalculates the internal anchor base time using a given context time and target track time
*/
setAnchor(contextTime, trackTime) {
this.anchor = contextTime - trackTime;
return this.anchor;
}
/**
* Calculate start relative to now.
* Normally the start time is just this.start. However due to seeking this can vary. It will help to understand the workings of the audiocontext timeline.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/currentTime
* @see https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start
*
* @param {Integer} segment - The segment
* @param {Integer} segment.start - The start time in seconds
*
* @returns {Integer|undefined}
*/
calculateRealStart({ start }) {
let realStart = this.anchor + start;
if (realStart < 0) realStart = 0;
return realStart;
}
/**
* Calculate offset by taking into consideration the start time.
* Normally the offset is 0. If the user seeks halfway into a 10 second segment, the offset is 5.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode/start
*
* @param {Integer} t
* @returns {Integer|undefined}
*/
calculateOffset({ start }) {
let offset = this.currentTime - start;
// offset is < 0 when start is in the future, so offset should be 0 in that case
if (offset < 0) offset = 0;
return offset;
}
/**
* Returns the absolute track-time end bound for this timeframe.
*
* @returns {number}
*/
get end() {
return this.offset + this.playDuration;
}
}