Files
hls.js/tests/unit/controller/audio-stream-controller.ts
2024-02-21 11:02:40 -08:00

203 lines
5.4 KiB
TypeScript

import Hls from '../../../src/hls';
import { hlsDefaultConfig } from '../../../src/config';
import AudioStreamController from '../../../src/controller/audio-stream-controller';
import { Events } from '../../../src/events';
import { FragmentTracker } from '../../../src/controller/fragment-tracker';
import KeyLoader from '../../../src/loader/key-loader';
import { LoadStats } from '../../../src/loader/load-stats';
import { AttrList } from '../../../src/utils/attr-list';
import {
MediaAttributes,
MediaPlaylist,
} from '../../../src/types/media-playlist';
import { Level } from '../../../src/types/level';
import type {
AudioTrackSwitchingData,
AudioTrackLoadedData,
TrackLoadedData,
} from '../../../src/types/events';
import type { LevelDetails } from '../../../src/loader/level-details';
import type { Fragment } from '../../../src/loader/fragment';
import chai from 'chai';
import sinonChai from 'sinon-chai';
import { State } from '../../../src/controller/base-stream-controller';
chai.use(sinonChai);
const expect = chai.expect;
type AudioStreamControllerTestable = Omit<
AudioStreamController,
'levels' | 'mainDetails' | 'onAudioTrackSwitching' | 'onAudioTrackLoaded'
> & {
levels: Level[] | null;
mainDetails: LevelDetails;
onAudioTrackSwitching: (
event: Events.AUDIO_TRACK_SWITCHING,
data: AudioTrackSwitchingData,
) => void;
onAudioTrackLoaded: (
event: Events.AUDIO_TRACK_LOADED,
data: TrackLoadedData,
) => void;
};
describe('AudioStreamController', function () {
const audioTracks: MediaPlaylist[] = [
{
attrs: new AttrList({}) as MediaAttributes,
autoselect: true,
bitrate: 0,
forced: false,
type: 'AUDIO',
url: 'data://',
groupId: '1',
id: 0,
default: true,
name: 'A',
},
{
attrs: new AttrList({}) as MediaAttributes,
autoselect: true,
bitrate: 0,
forced: false,
type: 'AUDIO',
url: 'data://',
groupId: '1',
id: 1,
default: false,
name: 'B',
},
{
attrs: new AttrList({}) as MediaAttributes,
autoselect: true,
bitrate: 0,
forced: false,
type: 'AUDIO',
url: 'data://',
groupId: '1',
id: 2,
default: false,
name: 'C',
},
{
attrs: new AttrList({}) as MediaAttributes,
autoselect: true,
bitrate: 0,
forced: false,
type: 'AUDIO',
url: 'data://',
groupId: '2',
id: 0,
default: true,
name: 'A',
},
{
attrs: new AttrList({}) as MediaAttributes,
autoselect: true,
bitrate: 0,
forced: false,
type: 'AUDIO',
url: 'data://',
groupId: '2',
id: 1,
default: false,
name: 'B',
},
{
attrs: new AttrList({}) as MediaAttributes,
autoselect: true,
bitrate: 0,
forced: false,
type: 'AUDIO',
url: 'data://',
groupId: '3',
id: 2,
default: false,
name: 'C',
},
];
const tracks: Level[] = audioTracks.map((parsedLevel) => {
const level = new Level(parsedLevel);
return level;
});
let hls: Hls;
let fragmentTracker: FragmentTracker;
let keyLoader: KeyLoader;
let audioStreamController: AudioStreamControllerTestable;
beforeEach(function () {
hls = new Hls();
fragmentTracker = new FragmentTracker(hls);
keyLoader = new KeyLoader(hlsDefaultConfig);
audioStreamController = new AudioStreamController(
hls,
fragmentTracker,
keyLoader,
) as unknown as AudioStreamControllerTestable;
});
afterEach(function () {
hls.destroy();
});
describe('onAudioTrackSwitching', function () {
it('reset the controller state to IDLE when WAITING_TRACK', function () {
audioStreamController.state = State.WAITING_TRACK;
audioStreamController.onAudioTrackSwitching(
Events.AUDIO_TRACK_SWITCHING,
audioTracks[0],
);
expect(audioStreamController.state).to.equal(State.IDLE);
expect(audioStreamController.hasInterval()).to.be.true;
});
it('leaved the controller in the STOPPED state', function () {
audioStreamController.state = State.STOPPED;
audioStreamController.onAudioTrackSwitching(
Events.AUDIO_TRACK_SWITCHING,
audioTracks[0],
);
expect(audioStreamController.state).to.equal(State.STOPPED);
expect(audioStreamController.hasInterval()).to.be.false;
});
});
describe('onAudioTrackLoaded', function () {
it('should update the level details from the event data', function () {
const trackLoadedData: AudioTrackLoadedData = {
id: 0,
groupId: 'audio',
stats: new LoadStats(),
deliveryDirectives: null,
networkDetails: {},
details: {
live: false,
get fragments() {
const frags: Fragment[] = [];
for (let i = 0; i < this.endSN; i++) {
frags.push({ sn: i, type: 'main' } as unknown as Fragment);
}
return frags;
},
targetduration: 100,
} as unknown as LevelDetails,
};
audioStreamController.levels = tracks;
audioStreamController.mainDetails = trackLoadedData.details;
audioStreamController.tick = () => {};
audioStreamController.onAudioTrackLoaded(
Events.AUDIO_TRACK_LOADED,
trackLoadedData,
);
expect(audioStreamController.levels[0].details).to.equal(
trackLoadedData.details,
);
});
});
});