Skip to content

Commit

Permalink
Feature/v5 adaptation set switching (#4276)
Browse files Browse the repository at this point in the history
* Refactor variable names

* Remove RepresentationInfo.js

* Add JSDoc for function in AbrController.js

* WiP: Enable adaptation-set-switching-2016

* Fix some bugs when enabling Adaptation Set Switching

* Adjust AS switching implementation

* Add skeleton for PeriodTransitionStateModel.js

* Fix various bugs around texttracks and SegmentBase addressing

* Fix bug for non-segmented subtitles

* Save last selected track to maintain same text and audio language when transitioning to a new period

* For multiperiod content use bitrate from previous period for track selection

* Fix race condition when MPD is updated

* Start adjusting the ABR rules

* Fix ABR rules to match the new structure

* Fix a bug when identifying the possible compatible AdaptationSets

* Fix a bug when reading the value of a role

* WiP: Fix DroppedFramesRule.js

* Fix dropped frames rule

* Fix BOLA rule to be compliant with new endpoints in AbrController.js

* Additional fixes to the rules to support dynamic filtering

* Additional fixes for Bola and L2A rule

* Additional fixes for Bola and L2A rule

* Additional fixes for LolP rule

* Fix segment abandon

* Fixed some of the unit tests

* Additional changes to fix the unit tests

* fix unit tests

* getAverageThroughput allows calculationmode and samplesize to be passed as input

* Fix minor bugs

* Add depliy script for v5

* Fix unit test

* Fix bug in CmcdModel.js
  • Loading branch information
dsilhavy committed Nov 9, 2023
1 parent 241cb2f commit 295c666
Show file tree
Hide file tree
Showing 106 changed files with 3,248 additions and 3,346 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
@@ -1,6 +1,6 @@
version: 2.1
orbs:
browser-tools: circleci/browser-tools@1.4.2
browser-tools: circleci/browser-tools@1.4.6

executors:
dashjs-executor:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy_latest.yml
@@ -1,4 +1,4 @@
name: deploy
name: deploy_latest

on:
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy_nightly.yml
@@ -1,4 +1,4 @@
name: deploy
name: deploy_nightly

on:
push:
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/deploy_v5.yml
@@ -0,0 +1,18 @@
name: deploy_v5

on:
push:
branches:
- 'v5.0.0'

jobs:
deploy_staging:
if: github.repository == 'Dash-Industry-Forum/dash.js'
uses: ./.github/workflows/deploy.yml
with:
envname: v5
deploy_path: '/377335/dash.js'
secrets:
host: ${{secrets.HOST}}
user: ${{secrets.USER}}
private_key: ${{secrets.PRIVATE_KEY}}
14 changes: 7 additions & 7 deletions contrib/akamai/controlbar/ControlBar.js
Expand Up @@ -528,13 +528,13 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
destroyMenu(bitrateListMenu, bitrateListBtn, menuHandlersList.bitrate);
bitrateListMenu = null;
var availableBitrates = { menuType: 'bitrate' };
availableBitrates.audio = self.player.getBitrateInfoListFor && self.player.getBitrateInfoListFor('audio') || [];
availableBitrates.video = self.player.getBitrateInfoListFor && self.player.getBitrateInfoListFor('video') || [];
availableBitrates.images = self.player.getBitrateInfoListFor && self.player.getBitrateInfoListFor('image') || [];
availableBitrates.audio = self.player.getRepresentationsByType && self.player.getRepresentationsByType('audio') || [];
availableBitrates.video = self.player.getRepresentationsByType && self.player.getRepresentationsByType('video') || [];
availableBitrates.images = self.player.getRepresentationsByType && self.player.getRepresentationsByType('image') || [];

if (availableBitrates.audio.length >= 1 || availableBitrates.video.length >= 1 || availableBitrates.images.length >= 1) {
contentFunc = function (element, index) {
var result = isNaN(index) ? ' Auto Switch' : Math.floor(element.bitrate / 1000) + ' kbps';
var result = isNaN(index) ? ' Auto Switch' : Math.floor(element.bitrateInKbit) + ' kbps';
result += element && element.width && element.height ? ' (' + element.width + 'x' + element.height + ')' : '';
return result;
};
Expand Down Expand Up @@ -575,7 +575,7 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
}

if (element.roles[0]) {
info += '- Role: ' + element.roles[0] + ' ';
info += '- Role: ' + element.roles[0].value + ' ';
}

if (element.codec) {
Expand Down Expand Up @@ -852,14 +852,14 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
if (item.index > 0) {
cfg.streaming.abr.autoSwitchBitrate[item.mediaType] = false;
self.player.updateSettings(cfg);
self.player.setQualityFor(item.mediaType, item.index - 1, forceQuality);
self.player.setRepresentationForTypeByIndex(item.mediaType, item.index - 1, forceQuality);
} else {
cfg.streaming.abr.autoSwitchBitrate[item.mediaType] = true;
self.player.updateSettings(cfg);
}
break;
case 'image-bitrate-list':
player.setQualityFor(item.mediaType, item.index);
player.setRepresentationForTypeByIndex(item.mediaType, item.index);
break;
case 'caption-list':
self.player.setTextTrack(item.index - 1);
Expand Down
109 changes: 48 additions & 61 deletions index.d.ts
Expand Up @@ -122,11 +122,11 @@ declare namespace dashjs {

getZlema(dict: ThroughputDictEntry[], sampleSize: number): number

getAverageThroughput(mediaType: MediaType, calculationMode: Constants["THROUGHPUT_CALCULATION_MODES"], sampleSize: number): number
getAverageThroughput(mediaType: MediaType, calculationMode: string, sampleSize: number): number

getSafeAverageThroughput(mediaType: MediaType, calculationMode: Constants["THROUGHPUT_CALCULATION_MODES"], sampleSize: number): number
getSafeAverageThroughput(mediaType: MediaType, calculationMode: string, sampleSize: number): number

getAverageLatency(mediaType: MediaType, calculationMode: Constants["THROUGHPUT_CALCULATION_MODES"], sampleSize: number): number
getAverageLatency(mediaType: MediaType, calculationMode: string, sampleSize: number): number

getRawThroughputData(mediaType: MediaType): number

Expand All @@ -148,7 +148,7 @@ declare namespace dashjs {

getCurrentRepresentation(): object;

getCurrentRepresentationInfo(): RepresentationInfo;
getCurrentRepresentation(): Representation;

getRepresentationForQuality(quality: number): object | null;

Expand Down Expand Up @@ -572,41 +572,34 @@ declare namespace dashjs {
}

export interface Representation {
adaptation: AdaptationSet | null;
availabilityTimeComplete: boolean;
availabilityTimeOffset: number;
availableSegmentsNumber: number;
bandwidth: number;
codecPrivateData: string | null;
codecs: string | null;
fragmentDuration: number | null;
frameRate: number;
height: number;
id: string;
index: number;
//adaptation needs checking
adaptation: AdaptationSet | null;
segmentInfoType: string | null;
indexRange: string | null;
initialization: object | null;
codecs: string | null;
maxPlayoutRate: number;
mediaFinishedInformation: MediaFinishedInformation;
mediaInfo: MediaInfo | null;
mimeType: string | null;
codecPrivateData: string | null;
segmentDuration: number;
timescale: number;
startNumber: number;
indexRange: string | null;
range: Range | null;
mseTimeOffset: number;
presentationTimeOffset: number;
MSETimeOffset: number;
mediaFinishedInformation: MediaFinishedInformation;
availableSegmentsNumber: number;
bandwidth: number;
width: number;
height: number;
range: Range | null;
scanType: string;
maxPlayoutRate: number;
availabilityTimeOffset: number;
availabilityTimeComplete: boolean;
segmentDuration: number;
segmentInfoType: string | null;
segments: any[];
frameRate: number;
}

export interface RepresentationInfo {
id: string | null;
quality: number | null;
fragmentDuration: number | null;
mediaInfo: MediaInfo | null;
MSETimeOffset: number | null;
startNumber: number;
timescale: number;
width: number;
}

export interface Segment {
Expand Down Expand Up @@ -1225,18 +1218,10 @@ declare namespace dashjs {
audio?: number;
video?: number;
};
maxRepresentationRatio?: {
audio?: number;
video?: number;
};
initialBitrate?: {
audio?: number;
video?: number;
};
initialRepresentationRatio?: {
audio?: number;
video?: number;
};
autoSwitchBitrate?: {
audio?: boolean;
video?: boolean;
Expand Down Expand Up @@ -1454,7 +1439,7 @@ declare namespace dashjs {

setTextTrack(idx: number): void;

getBitrateInfoListFor(type: MediaType): BitrateInfo[];
getRepresentationsFor(type: MediaType): Representation[];

getStreamsFromManifest(manifest: object): StreamInfo[];

Expand Down Expand Up @@ -2105,7 +2090,7 @@ declare namespace dashjs {

getTopBitrateInfoFor(type: string, streamId?: string): BitrateInfo | null;

getInitialBitrateFor(type: string, streamId: string): number;
getInitialBitrateFor(type: string): number;

checkPlaybackQuality(type: string, streamId: string): boolean;

Expand Down Expand Up @@ -2169,7 +2154,7 @@ declare namespace dashjs {

prepareForReplacementTrackSwitch(codec: string): Promise<any>;

prepareForForceReplacementQualitySwitch(representationInfo: RepresentationInfo): Promise<any>;
prepareForForceReplacementQualitySwitch(voRepresentation: Representation): Promise<any>;

prepareForNonReplacementTrackSwitch(codec: string): Promise<any>;

Expand All @@ -2181,7 +2166,7 @@ declare namespace dashjs {

clearBuffers(ranges: Range[]): Promise<any>;

updateBufferTimestampOffset(representationInfo: RepresentationInfo): Promise<any>;
updateBufferTimestampOffset(voRepresentation: Representation): Promise<any>;

updateAppendWindow(): Promise<any>;

Expand Down Expand Up @@ -2255,7 +2240,7 @@ declare namespace dashjs {

saveTextSettingsDisabled(): void;

isTracksEqual(t1: MediaInfo, t2: MediaInfo): boolean;
areTracksEqual(t1: MediaInfo, t2: MediaInfo): boolean;

setConfig(config: object): void;

Expand Down Expand Up @@ -2345,8 +2330,6 @@ declare namespace dashjs {

getStreamId(): string;

setCurrentRepresentation(representationInfo: RepresentationInfo): void;

startScheduleTimer(value: object): void;

clearScheduleTimer(): void;
Expand Down Expand Up @@ -2674,8 +2657,6 @@ declare namespace dashjs {
reset(): void;

resetInitialSettings(): void;

addExecutedRequest(request: HTTPRequest): void;
}

export interface AastLowLatencyThroughputModel {
Expand All @@ -2685,7 +2666,7 @@ declare namespace dashjs {

getThroughputCapacityDelayMS(request: HTTPRequest, currentBufferLevel: number): number;

getEstimaredDownloadDurationMS(request: HTTPRequest): number;
getEstimatedDownloadDurationMS(request: HTTPRequest): number;
}

export interface ThroughputModel {
Expand All @@ -2694,7 +2675,7 @@ declare namespace dashjs {
getThroughputDict(mediaType: MediaType): ThroughputDictEntry;

getEwmaThroughputDict(mediaType: MediaType): ThroughputEwmaDictEntry;

getEwmaLatencyDict(mediaType: MediaType): ThroughputEwmaDictEntry;

getEwmaHalfLife(mediaType: MediaType): object;
Expand Down Expand Up @@ -2771,13 +2752,13 @@ declare namespace dashjs {

addRequestsQueue(mediaType: MediaType, loadingRequests: any[], executedRequests: any[]): void;

addManifestUpdate(mediaType: MediaType, type: string, requestTime: number, fetchTime: number, availabilityStartTime: number, presentationStartTime: number, clientTimeOffset: number, currentTime: number, buffered: RepresentationInfo, latency: number): void;
addManifestUpdate(mediaType: MediaType, type: string, requestTime: number, fetchTime: number): void;

updateManifestUpdateInfo(manifestUpdate: ManifestUpdate, updatedFields: any[]): void;

addManifestUpdateStreamInfo(manifestUpdate: ManifestUpdate, id: string, index: number, start: number, duration: number): void;

addManifestUpdateRepresentationInfo(manifestUpdate: ManifestUpdate, id: string, index: number, streamIndex: number, mediaType: MediaType, presentationTimeOffset: number, startNumber: number, fragmentInfoType: string): void;
addManifestUpdateRepresentationInfo(manifestUpdate: ManifestUpdate, representation: Representation, mediaType: MediaType): void;

addPlayList(vo: any): void;

Expand Down Expand Up @@ -3592,7 +3573,7 @@ declare namespace dashjs {
getCurrentRequest(): SwitchRequest;

getSwitchHistory(): SwitchRequestHistory; //pot. just Switch History

getStreamInfo(): StreamInfo;

getScheduleController(): ScheduleController;
Expand All @@ -3601,7 +3582,7 @@ declare namespace dashjs {

getAbrController(): AbrController;

getRepresentationInfo(): RepresentationInfo
getVoRepresentation(): Representation;

getVideoModel(): VideoModel;
}
Expand Down Expand Up @@ -4085,13 +4066,21 @@ declare namespace dashjs {
presentationStartTime: number;
clientTimeOffset: number;
currentTime: number | null;
buffered: RepresentationInfo;
buffered: object | null;
latency: number;
streamInfo: StreamInfo[];
representationInfo: RepresentationInfo;
representationInfo: ManifestUpdateRepresentationInfo[];

}

export interface ManifestUpdateRepresentationInfo {
id: string | null;
index: number | null;
mediaType: MediaType | null;
presentationTimeOffset: number | null;
startNumber: number | null;
}

export interface PlayList {
start: number | null;
mstart: number | null;
Expand Down Expand Up @@ -4464,7 +4453,7 @@ declare namespace dashjs {

reset(): void;

updateTimestampOffset(MSETimeOffset: number): void;
updateTimestampOffset(mseTimeOffset: number): void;

initializeForStreamSwitch(mInfo: MediaInfo, selectedRepresentation: Representation, oldSourceBufferSink: SourceBufferSink): Promise<any>;

Expand Down Expand Up @@ -4506,8 +4495,6 @@ declare namespace dashjs {

getThumbnailController(): object;

getBitrateListFor(type: MediaType): BitrateInfo[];

updateData(updatedStreamInfo: StreamInfo): void;

reset(): void;
Expand Down Expand Up @@ -4556,7 +4543,7 @@ declare namespace dashjs {

getRepresentationController(): RepresentationController;

getRepresentationInfo(quality: number): RepresentationInfo;
getVoRepresentation(quality: number): Representation;

getBufferLevel(): number;

Expand Down
2 changes: 1 addition & 1 deletion karma.unit.conf.cjs
Expand Up @@ -90,7 +90,7 @@ module.exports = function (config) {

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['ChromeHeadless', 'FirefoxHeadless'],
browsers: ['ChromeHeadless'],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
Expand Down
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -12,7 +12,6 @@
"start": "webpack serve --config build/webpack.dev.cjs",
"lint": "eslint \"src/**/*.js\" test/unit/mocks/*.js test/unit/*.js ",
"build": "tsc && rimraf dist && webpack --config build/webpack.prod.cjs",
"postbuild": "cp index.d.ts dash.d.ts",
"doc": "jsdoc -c build/jsdoc/jsdoc_conf.json -d docs/jsdoc",
"test": "karma start karma.unit.conf.cjs",
"test-browserunit": "karma start build/karma.conf.cjs",
Expand Down
4 changes: 2 additions & 2 deletions samples/abr/LowestBitrateRule.js
Expand Up @@ -45,7 +45,7 @@ function LowestBitrateRuleClass() {
}

// Always use lowest bitrate
function getMaxIndex(rulesContext) {
function getSwitchRequest(rulesContext) {
// here you can get some informations aboit metrics for example, to implement the rule
let metricsModel = MetricsModel(context).getInstance();
var mediaType = rulesContext.getMediaInfo().type;
Expand Down Expand Up @@ -74,7 +74,7 @@ function LowestBitrateRuleClass() {
}

instance = {
getMaxIndex: getMaxIndex
getSwitchRequest
};

setup();
Expand Down

0 comments on commit 295c666

Please sign in to comment.