Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(FEC-10980): Enable setting ABR settings on-the-fly #134

Merged
merged 29 commits into from
May 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
16b7f55
feat(FEC-10980): Enable setting ABR settings on-the-fly
Yuvalke Mar 3, 2021
7024abf
set only when it passed
Yuvalke Mar 3, 2021
d27fb7d
fix logic
Yuvalke Mar 3, 2021
7edae30
Update dash-adapter.js
Yuvalke Mar 3, 2021
5ff115b
add width and height to restriction
Yuvalke Mar 15, 2021
0e1c58f
Merge branch 'master' into FEC-10980
Yuvalke Mar 16, 2021
b4f40b9
fix flow
Yuvalke Mar 16, 2021
322e002
Merge branch 'FEC-10980' of https://github.com/kaltura/playkit-js-das…
Yuvalke Mar 16, 2021
6de0296
update logic
Yuvalke Mar 17, 2021
4260e3a
fix condition
Yuvalke Mar 22, 2021
300814a
Update dash-adapter.js
Yuvalke Mar 24, 2021
06ff619
Update dash-adapter.js
Yuvalke Mar 24, 2021
cc5953b
Update dash-adapter.js
Yuvalke Mar 24, 2021
fb9116f
Update dash-adapter.js
Yuvalke Mar 24, 2021
adfafcf
update PR
Yuvalke Mar 25, 2021
4884a17
Update dash-adapter.js
Yuvalke Mar 25, 2021
bf7ba2a
Update dash-adapter.js
Yuvalke Mar 25, 2021
1bfd6ae
update config
Yuvalke Mar 25, 2021
7e9e708
fix tests
Yuvalke Mar 25, 2021
48650ac
Update dash-adapter.js
Yuvalke Apr 26, 2021
031d102
Update dash-adapter.js
Yuvalke Apr 26, 2021
17b2d25
Merge branch 'master' into FEC-10980
Yuvalke May 10, 2021
3e4576e
player restrictions from player level
Yuvalke May 11, 2021
f201640
Merge branch 'FEC-10980' of https://github.com/kaltura/playkit-js-das…
Yuvalke May 11, 2021
5cff4a2
fix PR
Yuvalke May 12, 2021
ca99b1d
add fix for not adaptive
Yuvalke May 13, 2021
11e382e
Update dash-adapter.js
Yuvalke May 13, 2021
023c700
update dev dependencies to master
Yuvalke May 13, 2021
395bdf1
update dev dependencies to master
Yuvalke May 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"@babel/preset-env": "^7.10.4",
"@babel/preset-flow": "^7.10.4",
"@babel/register": "^7.10.5",
"@playkit-js/playkit-js": "0.68.0-canary.3b1d78e",
"@playkit-js/playkit-js": "0.71.0-canary.a8a3e9f",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"babel-plugin-istanbul": "^6.0.0",
Expand Down
154 changes: 98 additions & 56 deletions src/dash-adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
Utils,
VideoTrack,
ImageTrack,
ThumbnailInfo
ThumbnailInfo,
PKABRRestrictionObject,
filterTracksByRestriction
} from '@playkit-js/playkit-js';
import {Widevine} from './drm/widevine';
import {PlayReady} from './drm/playready';
Expand Down Expand Up @@ -254,14 +256,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter {
adapterConfig.shakaConfig.abr.defaultBandwidthEstimate = abr.defaultBandwidthEstimate;
}
if (abr.restrictions) {
if (abr.restrictions.minBitrate > 0) {
adapterConfig.shakaConfig.abr.restrictions.minBandwidth = abr.restrictions.minBitrate;
}
if (abr.restrictions.maxBitrate < Infinity) {
//You can either set capping by size or bitrate, if bitrate is set then disable size capping
adapterConfig.capLevelToPlayerSize = false;
adapterConfig.shakaConfig.abr.restrictions.maxBandwidth = abr.restrictions.maxBitrate;
}
Utils.Object.createPropertyPath(adapterConfig, 'abr.restrictions', abr.restrictions);
}
}

Expand Down Expand Up @@ -552,48 +547,89 @@ export default class DashAdapter extends BaseMediaSourceAdapter {
*/
_maybeApplyAbrRestrictions(): void {
if (this._config.capLevelToPlayerSize) {
const videoTracks = this._getVideoTracks();
const getMinDimensions = (dim): number =>
Math.min.apply(
null,
videoTracks.map(variant => variant[dim])
);
//Get minimal allowed dimensions
const minWidth = getMinDimensions('width');
const minHeight = getMinDimensions('height');
const updateAbrRestrictions = () => {
const curHeight = this._videoHeight;
const curWidth = this._videoWidth;
if (typeof curWidth === 'number' && typeof curHeight === 'number') {
//check if current player size is smaller than smallest rendition
//setting restriction below smallest rendition size will result in shaka emitting restriction unmet error
if (curHeight >= minHeight && curWidth >= minWidth) {
DashAdapter._logger.debug(`applying dimension restriction: width < ${curWidth}, height < ${curHeight}`);
this._shaka.configure({
abr: {
restrictions: {
maxHeight: curHeight,
maxWidth: curWidth
}
}
});
} else {
DashAdapter._logger.debug(`applying dimension restriction: width < ${minHeight}, height < ${minWidth}`);
this._shaka.configure({
abr: {
restrictions: {
maxHeight: minHeight,
maxWidth: minWidth
}
}
});
}
}
const getRestrictions = () => {
return {
minHeight: 0,
maxHeight: this._videoHeight,
minWidth: 0,
maxWidth: this._videoWidth,
minBitrate: 0,
maxBitrate: Infinity
};
};
this._clearVideoUpdateTimer();
this._videoSizeUpdateTimer = setInterval(updateAbrRestrictions, ABR_RESTRICTION_UPDATE_INTERVAL);
updateAbrRestrictions();
this._videoSizeUpdateTimer = setInterval(() => this._updateRestriction(getRestrictions()), ABR_RESTRICTION_UPDATE_INTERVAL);
this._updateRestriction(getRestrictions());
} else {
this._clearVideoUpdateTimer();
if (Utils.Object.hasPropertyPath(this._config, 'abr.restrictions')) {
this._updateRestriction(this._config.abr.restrictions);
if (!this.isAdaptiveBitrateEnabled()) {
const videoTracks = this._getParsedVideoTracks();
const availableTracks = filterTracksByRestriction(videoTracks, this._config.abr.restrictions);
if (availableTracks.length) {
const activeTrackInRange = availableTracks.find(track => track.active);
if (!activeTrackInRange) {
this.selectVideoTrack(availableTracks[0]);
}
}
}
}
}
}

/**
* apply ABR restrictions by size
* @private
* @param {PKABRRestrictionObject} restrictions - abr restrictions config
* @returns {void}
*/
_updateRestriction(restrictions: PKABRRestrictionObject): void {
const shakaRestrictionsConfig = this._getRestrictionShakaConfig(restrictions);
this._shaka.configure({
abr: {
restrictions: shakaRestrictionsConfig
}
});
}

_getRestrictionShakaConfig(restrictions: PKABRRestrictionObject): Object {
const getMinDimensions = (dim): number => {
const videoTracks = this._getVideoTracks();
return Math.min.apply(
null,
videoTracks.map(variant => variant[dim])
);
};
let restrictionsShakaConfig = {};
if (restrictions) {
let {maxHeight, maxWidth, maxBitrate, minHeight, minWidth, minBitrate} = restrictions;
const minHeightValue = Math.max(minHeight, 0);
const maxHeightValue = Math.max(maxHeight, getMinDimensions('height'));
if (maxHeightValue >= minHeightValue) {
restrictionsShakaConfig.minHeight = minHeightValue;
restrictionsShakaConfig.maxHeight = maxHeightValue;
} else {
DashAdapter._logger.warn('Invalid maxHeight restriction, maxHeight must be greater than minHeight', minHeight, maxHeight);
}
const minWidthValue = Math.max(minWidth, 0);
const maxWidthValue = Math.max(maxWidth, getMinDimensions('width'));
if (maxWidthValue >= minWidthValue) {
restrictionsShakaConfig.minWidth = minWidthValue;
restrictionsShakaConfig.maxWidth = maxWidthValue;
} else {
DashAdapter._logger.warn('Invalid maxWidth restriction, maxWidth must be greater than minWidth', minWidth, maxWidth);
}
const minBitrateValue = Math.max(minBitrate, 0);
const maxBitrateValue = Math.max(maxBitrate, getMinDimensions('bandwidth'));
if (maxBitrateValue >= minBitrateValue) {
restrictionsShakaConfig.minBandwidth = minBitrateValue;
restrictionsShakaConfig.maxBandwidth = maxBitrateValue;
} else {
DashAdapter._logger.warn('Invalid maxBitrate restriction, maxBitrate must be greater than minBitrate', minBitrate, maxBitrate);
}
}
return restrictionsShakaConfig;
}

/**
Expand Down Expand Up @@ -743,7 +779,6 @@ export default class DashAdapter extends BaseMediaSourceAdapter {
})
.then(() => {
const data = {tracks: this._getParsedTracks()};
this._maybeApplyAbrRestrictions();
DashAdapter._logger.debug('The source has been loaded successfully');
resolve(data);
})
Expand Down Expand Up @@ -835,9 +870,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter {
}

_getActiveTrack(): Object {
return this._shaka.getVariantTracks().filter(variantTrack => {
return variantTrack.active;
})[0];
return this._shaka.getVariantTracks().find(variantTrack => variantTrack.active);
}

/**
Expand Down Expand Up @@ -1070,6 +1103,18 @@ export default class DashAdapter extends BaseMediaSourceAdapter {
return false;
}

/**
* Apply ABR restriction.
* @function applyABRRestriction
* @param {PKABRRestrictionObject} restrictions - abr restrictions config
* @returns {void}
* @public
*/
applyABRRestriction(restrictions: PKABRRestrictionObject): void {
Utils.Object.createPropertyPath(this._config, 'abr.restrictions', restrictions);
this._maybeApplyAbrRestrictions();
}

/**
* Returns the live edge
* @returns {number} - live edge
Expand Down Expand Up @@ -1111,10 +1156,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter {
* @private
*/
_onAdaptation(): void {
let selectedVideoTrack = this._getParsedVideoTracks().filter(function (videoTrack) {
return videoTrack.active;
})[0];
DashAdapter._logger.debug('Video track changed', selectedVideoTrack);
let selectedVideoTrack = this._getParsedVideoTracks().find(videoTrack => videoTrack.active);
this._onTrackChanged(selectedVideoTrack);
}

Expand Down
2 changes: 1 addition & 1 deletion test/src/dash-adapter.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ describe('DashAdapter: _getLiveEdge', () => {
.load()
.then(() => {
try {
dashInstance._getLiveEdge().should.equal(dashInstance._shaka.seekRange().end);
Math.floor(Math.abs(dashInstance._getLiveEdge() - dashInstance._shaka.seekRange().end)).should.equal(0);
done();
} catch (e) {
done(e);
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -853,10 +853,10 @@
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd"
integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==

"@playkit-js/playkit-js@0.68.0-canary.3b1d78e":
version "0.68.0-canary.3b1d78e"
resolved "https://registry.yarnpkg.com/@playkit-js/playkit-js/-/playkit-js-0.68.0-canary.3b1d78e.tgz#1a28e435742e3f2aeca40a724b69cec0b9d015cb"
integrity sha512-u5rkeodIhhNWw145BTyppydEiMAl3rVDF4GUMV7z2eGKwwUNqM11bgVfB6gkam5RwvMUyoA5Hsy71mWOt1wuIA==
"@playkit-js/playkit-js@0.71.0-canary.a8a3e9f":
version "0.71.0-canary.a8a3e9f"
resolved "https://registry.yarnpkg.com/@playkit-js/playkit-js/-/playkit-js-0.71.0-canary.a8a3e9f.tgz#067d7b53ed39fcb6fd20d25f530759e61fafd56f"
integrity sha512-wyaS7+hsfclNgnVLEPsdKe2yldpsIFc8cjZQz5QFFxgOp7zMawYlaf+rx3XGaEHrI/BrJy+XoxMNrtLJ7SO8zQ==
dependencies:
js-logger "^1.6.0"
ua-parser-js "^0.7.21"
Expand Down