UNPKG

@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.

95 lines (76 loc) 2.78 kB
import { expect } from '@bundled-es-modules/chai'; import sinon from 'sinon'; import ManifestLoader from '../../../src/io/ManifestLoader.js'; describe('ManifestLoader', () => { let loader; let fetchMock; const MOCK_MANIFEST = `#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXTINF:10.0, segment1.ts #EXTINF:15.0, segment2.ts`; beforeEach(() => { fetchMock = sinon.stub().resolves({ ok: true, text: sinon.stub().resolves(MOCK_MANIFEST), }); loader = new ManifestLoader(fetchMock); }); describe('#constructor', () => { it('sets a custom fetch function if provided', () => { expect(loader.fetchFn).to.equal(fetchMock); }); it('defaults to window.fetch if no custom fetch function is provided', () => { const defaultLoader = new ManifestLoader(); expect(typeof defaultLoader.fetchFn).to.equal('function'); }); }); describe('#load', () => { it('returns a promise with parsed segments and a cancel function', async () => { const handle = loader.load('http://example.com/playlist.m3u8', { headers: { Auth: 'Token' }, }); expect(handle).to.have.property('promise'); expect(handle).to.have.property('cancel'); const result = await handle.promise; expect(fetchMock.calledOnce).to.be.true; const [url, options] = fetchMock.firstCall.args; expect(url).to.equal('http://example.com/playlist.m3u8'); expect(options.headers.Auth).to.equal('Token'); expect(options.signal).to.be.instanceOf(AbortSignal); expect(result).to.deep.equal([ { src: 'http://example.com/segment1.ts', duration: 10 }, { src: 'http://example.com/segment2.ts', duration: 15 }, ]); }); it('throws if response is not ok', async () => { fetchMock.resolves({ ok: false, status: 404, }); try { await loader.load('http://example.com/playlist.m3u8').promise; expect.fail('Should have thrown'); } catch (err) { expect(err.message).to.equal('Network response was not ok'); } }); it('should abort fetch when cancel is called', () => { const handle = loader.load('http://example.com/playlist.m3u8'); const abortSpy = sinon.spy(loader.abortController, 'abort'); handle.cancel(); expect(abortSpy.calledOnce).to.be.true; }); }); describe('#parse', () => { it('statically parses a manifest string into segment descriptors', () => { const result = ManifestLoader.parse(MOCK_MANIFEST, 'http://example.com/playlist.m3u8'); expect(result).to.deep.equal([ { src: 'http://example.com/segment1.ts', duration: 10 }, { src: 'http://example.com/segment2.ts', duration: 15 }, ]); }); }); });