Skip to content

Commit

Permalink
fix(FEC-10797): back-end bumper config is left from previous media pl…
Browse files Browse the repository at this point in the history
…ayed (#393)

Reset the provider plugins on reset but keep it on the playlist item for the next time the item will be played (use `setMedia`)

Solves FEC-10797
  • Loading branch information
yairans committed Dec 29, 2020
1 parent a062427 commit f3905e7
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 16 deletions.
22 changes: 22 additions & 0 deletions src/common/playlist/playlist-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const formats = ['hls', 'dash', 'progressive'];
class PlaylistItem {
_sources: ?PKSourcesConfigObject;
_config: ?KPPlaylistItemConfigObject;
_plugins: KPPluginsConfigObject;

constructor(sources: ?PKSourcesConfigObject, config: ?KPPlaylistItemConfigObject) {
this._sources = sources;
Expand All @@ -26,6 +27,17 @@ class PlaylistItem {
this._sources = Utils.Object.mergeDeep({}, sourcesObject);
}

/**
* Update the playlist item plugins (e.g. bumper from BE)
* @param {KPPluginsConfigObject} pluginsObject - The plugins
* @returns {void}
* @instance
* @memberof PlaylistItem
*/
updatePlugins(pluginsObject: KPPluginsConfigObject): void {
this._plugins = Utils.Object.copyDeep(pluginsObject);
}

/**
* Playlist item sources
* @type {?PKSourcesConfigObject}
Expand All @@ -51,6 +63,16 @@ class PlaylistItem {
return this._config;
}

/**
* Playlist item plugins
* @type {KPPluginsConfigObject}
* @instance
* @memberof PlaylistItem
*/
get plugins(): KPPluginsConfigObject {
return this._plugins;
}

/**
* @returns {boolean} = Whether the playlist item has sources to play
* @instance
Expand Down
17 changes: 16 additions & 1 deletion src/common/playlist/playlist-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {PlaylistEventType} from './playlist-event-type';
import {Playlist} from './playlist';
import {PlaylistItem} from './playlist-item';
import {addKalturaPoster} from 'poster';
import {mergeProviderPluginsConfig} from '../utils/setup-helpers';

/**
* @class PlaylistManager
Expand All @@ -20,6 +21,7 @@ class PlaylistManager {
_countdown: KPPlaylistCountdownOptions;
_playerOptions: KPOptionsObject;
_mediaInfoList: Array<ProviderMediaInfoObject>;
_appPluginConfig: KPPluginsConfigObject;

constructor(player: KalturaPlayer, options: KPOptionsObject) {
this._player = player;
Expand All @@ -29,6 +31,7 @@ class PlaylistManager {
this._countdown = {duration: 10, showing: true};
this._mediaInfoList = [];
this._playerOptions = options;
this._appPluginConfig = {};
}

/**
Expand Down Expand Up @@ -262,26 +265,38 @@ class PlaylistManager {
this._player.configure({playback});
this._playlist.activeItemIndex = index;
if (activeItem.isPlayable()) {
this._resetProviderPluginsConfig();
this._player.reset();
const mergedPluginsConfigAndFromApp = mergeProviderPluginsConfig(activeItem.plugins, this._player.config.plugins);
const providerPlugins = mergedPluginsConfigAndFromApp[0];
this._appPluginConfig = mergedPluginsConfigAndFromApp[1];
const media = {session: this._player.config.session, plugins: providerPlugins, sources: activeItem.sources};
// $FlowFixMe
this._player.setMedia({session: this._player.config.session, plugins: {}, sources: activeItem.sources});
this._player.setMedia(media);
this._player.dispatchEvent(new FakeEvent(PlaylistEventType.PLAYLIST_ITEM_CHANGED, {index, activeItem}));
return Promise.resolve();
} else {
if (this._mediaInfoList[index]) {
this._resetProviderPluginsConfig();
this._player.reset();
this._player.configure({
sources: activeItem.sources
});
return this._player.loadMedia(this._mediaInfoList[index]).then(() => {
this._playlist.updateItemSources(index, this._player.config.sources);
this._playlist.updateItemPlugins(index, this._player.config.plugins);
this._player.dispatchEvent(new FakeEvent(PlaylistEventType.PLAYLIST_ITEM_CHANGED, {index, activeItem}));
});
}
}
return Promise.reject();
}

_resetProviderPluginsConfig(): void {
this._player.configure({plugins: this._appPluginConfig});
this._appPluginConfig = {};
}

destroy(): void {
this._eventManager.destroy();
}
Expand Down
4 changes: 4 additions & 0 deletions src/common/playlist/playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class Playlist {
this._items[index].updateSources(sourcesObject);
}

updateItemPlugins(index: number, pluginsObject: KPPluginsConfigObject) {
this._items[index].updatePlugins(pluginsObject);
}

get id(): string {
return this._id;
}
Expand Down
28 changes: 27 additions & 1 deletion src/common/utils/setup-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,31 @@ function maybeSetCapabilitiesForIos(options: KPOptionsObject): void {
}
}

/**
* Merge the provider plugins config (e.g. bumper) into the app config and returns it and the respective app config to restore in change media
* @param {KPPluginsConfigObject} providerPluginsConfig - the provider plugins config
* @param {KPOptionsObject} appPluginsConfig - the entire app plugins config
* @returns {Array<KPPluginsConfigObject>} - the merged plugins config and the partial respective app plugins config
*/
function mergeProviderPluginsConfig(
providerPluginsConfig: KPPluginsConfigObject,
appPluginsConfig: KPPluginsConfigObject
): Array<KPPluginsConfigObject> {
const mergePluginConfig: KPPluginsConfigObject = {};
const respectiveAppPluginsConfig: KPPluginsConfigObject = {};
Utils.Object.isObject(providerPluginsConfig) &&
Object.entries(providerPluginsConfig).forEach(([pluginName, pluginConfig]: [string, Object]) => {
mergePluginConfig[pluginName] = {};
respectiveAppPluginsConfig[pluginName] = {};
Object.entries(pluginConfig).forEach(([key, providerValue]) => {
const appValue = Utils.Object.getPropertyPath(appPluginsConfig[pluginName], key);
mergePluginConfig[pluginName][key] = appValue || providerValue;
respectiveAppPluginsConfig[pluginName][key] = appValue;
});
});
return [mergePluginConfig, respectiveAppPluginsConfig];
}

export {
printSetupMessages,
supportLegacyOptions,
Expand All @@ -661,5 +686,6 @@ export {
checkNativeHlsSupport,
getDefaultOptions,
maybeSetStreamPriority,
hasYoutubeSource
hasYoutubeSource,
mergeProviderPluginsConfig
};
21 changes: 9 additions & 12 deletions src/kaltura-player.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import {EventType as UIEventType} from '@playkit-js/playkit-js-ui';
import {Provider} from 'playkit-js-providers';
import {supportLegacyOptions, maybeSetStreamPriority, hasYoutubeSource} from './common/utils/setup-helpers';
import {supportLegacyOptions, maybeSetStreamPriority, hasYoutubeSource, mergeProviderPluginsConfig} from './common/utils/setup-helpers';
import {addKalturaParams} from './common/utils/kaltura-params';
import {ConfigEvaluator} from './common/plugins';
import {addKalturaPoster} from 'poster';
Expand Down Expand Up @@ -52,6 +52,7 @@ class KalturaPlayer extends FakeEventTarget {
_sourceSelected: boolean = false;
_pluginReadinessMiddleware: PluginReadinessMiddleware;
_configEvaluator: ConfigEvaluator;
_appPluginConfig: KPPluginsConfigObject = {};

constructor(options: KPOptionsObject) {
super();
Expand Down Expand Up @@ -113,7 +114,9 @@ class KalturaPlayer extends FakeEventTarget {
}
mediaConfig.sources = Utils.Object.mergeDeep(mediaConfig.sources, mediaOptions);
}
mediaConfig.plugins = this._mergeProviderPluginsConfig(mediaConfig.plugins);
const mergedPluginsConfigAndFromApp = mergeProviderPluginsConfig(mediaConfig.plugins, this.config.plugins);
mediaConfig.plugins = mergedPluginsConfigAndFromApp[0];
this._appPluginConfig = mergedPluginsConfigAndFromApp[1];
this.configure(getDefaultRedirectOptions(this.config, mediaConfig));
this.setMedia(mediaConfig);
},
Expand Down Expand Up @@ -274,6 +277,7 @@ class KalturaPlayer extends FakeEventTarget {
this._reset = true;
this._firstPlay = true;
this._uiWrapper.reset();
this._resetProviderPluginsConfig();
this._pluginManager.reset();
this._localPlayer.reset();
}
Expand Down Expand Up @@ -774,16 +778,9 @@ class KalturaPlayer extends FakeEventTarget {
this._localPlayer.detachMediaSource();
}

_mergeProviderPluginsConfig(providerPluginsConfig: KPPluginsConfigObject): KPPluginsConfigObject {
const mergePluginConfig: KPPluginsConfigObject = {};
Object.entries(providerPluginsConfig).forEach(([pluginName, pluginConfig]: [string, Object]) => {
mergePluginConfig[pluginName] = {};
Object.entries(pluginConfig).forEach(([key, providerValue]) => {
const appValue = Utils.Object.getPropertyPath(this.config.plugins[pluginName], key);
mergePluginConfig[pluginName][key] = appValue || providerValue;
});
});
return mergePluginConfig;
_resetProviderPluginsConfig(): void {
this.configure({plugins: this._appPluginConfig});
this._appPluginConfig = {};
}

/**
Expand Down
93 changes: 92 additions & 1 deletion test/src/common/playlist/playlist-manager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import * as MediaMockData from '../../mock-data/media';
import * as PlaylistMockData from '../../mock-data/playlist';
import {FakeEvent} from '@playkit-js/playkit-js';
import {PlaylistEventType} from '../../../../src/common/playlist/playlist-event-type';
import {PluginManager} from '../../../../src/common/plugins';
import ColorsPlugin from '../plugin/test-plugins/colors-plugin';

describe('PlaylistManager', function () {
let kalturaPlayer, playlistManager, sandbox;
Expand Down Expand Up @@ -53,7 +55,11 @@ describe('PlaylistManager', function () {
});

it('should update config', function () {
playlistManager.configure({id: '1234', options: {autoContinue: false}, countdown: {duration: 20, showing: false, timeToShow: 50}});
playlistManager.configure({
id: '1234',
options: {autoContinue: false},
countdown: {duration: 20, showing: false, timeToShow: 50}
});
playlistManager._playlist.id.should.equal('1234');
playlistManager._options.autoContinue.should.be.false;
playlistManager._countdown.duration.should.equal(20);
Expand Down Expand Up @@ -397,6 +403,7 @@ describe('PlaylistManager', function () {

after(function () {
sandbox.restore();
kalturaPlayer.loadMedia.restore();
});

it('should call playNext automatically once the playlist loaded', function (done) {
Expand All @@ -416,4 +423,88 @@ describe('PlaylistManager', function () {
});
});
});

describe('provider plugins', function () {
before(function () {
PluginManager.register('colors', ColorsPlugin);
sinon.stub(kalturaPlayer._provider, 'getMediaConfig').callsFake(function (info) {
const mediaConfig = MediaMockData.MediaConfig[info.entryId];
return Promise.resolve(mediaConfig);
});
});

beforeEach(function () {
kalturaPlayer.configure({
plugins: {
colors: {
someProp1: 'app_prop1',
someProp2: ''
}
}
});
playlistManager.load(PlaylistMockData.playlistByEntryListWithPlugins);
});

after(function () {
sandbox.restore();
kalturaPlayer._provider.getMediaConfig.restore();
});

it("should apply the app's plugin config before the provider's and reset the provider's on change media", function (done) {
kalturaPlayer._eventManager.listenOnce(kalturaPlayer, PlaylistEventType.PLAYLIST_ITEM_CHANGED, () => {
try {
kalturaPlayer.config.plugins.colors.favouriteColor.should.equals('green');
kalturaPlayer.config.plugins.colors.someProp1.should.equals('app_prop1');
kalturaPlayer.config.plugins.colors.someProp2.should.equals('');
kalturaPlayer._eventManager.listenOnce(kalturaPlayer, PlaylistEventType.PLAYLIST_ITEM_CHANGED, () => {
try {
kalturaPlayer.config.plugins.colors.favouriteColor.should.equals('green');
kalturaPlayer.config.plugins.colors.someProp1.should.equals('app_prop1');
kalturaPlayer.config.plugins.colors.someProp2.should.equals('prop2');
kalturaPlayer._eventManager.listenOnce(kalturaPlayer, PlaylistEventType.PLAYLIST_ITEM_CHANGED, () => {
try {
kalturaPlayer.config.plugins.colors.favouriteColor.should.equals('green');
kalturaPlayer.config.plugins.colors.someProp1.should.equals('app_prop1');
kalturaPlayer.config.plugins.colors.someProp2.should.equals('');
kalturaPlayer._eventManager.listenOnce(kalturaPlayer, PlaylistEventType.PLAYLIST_ITEM_CHANGED, () => {
try {
kalturaPlayer.config.plugins.colors.favouriteColor.should.equals('green');
kalturaPlayer.config.plugins.colors.someProp1.should.equals('app_prop1');
kalturaPlayer.config.plugins.colors.someProp2.should.equals('prop2');
kalturaPlayer._eventManager.listenOnce(kalturaPlayer, PlaylistEventType.PLAYLIST_ITEM_CHANGED, () => {
try {
kalturaPlayer.config.plugins.colors.favouriteColor.should.equals('green');
kalturaPlayer.config.plugins.colors.someProp1.should.equals('app_prop1');
kalturaPlayer.config.plugins.colors.someProp2.should.equals('');
done();
} catch (e) {
done(e);
}
});
kalturaPlayer._reset = false;
playlistManager.playPrev();
} catch (e) {
done(e);
}
});
kalturaPlayer._reset = false;
playlistManager.playPrev();
} catch (e) {
done(e);
}
});
kalturaPlayer._reset = false;
playlistManager.playNext();
} catch (e) {
done(e);
}
});
kalturaPlayer._reset = false;
playlistManager.playNext();
} catch (e) {
done(e);
}
});
});
});
});
44 changes: 44 additions & 0 deletions test/src/mock-data/media.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,50 @@ const MediaConfig = {
},
plugins: {}
},
'0_nwkpghdf': {
session: {
isAnonymous: true,
partnerId: 1091,
ks: 'YTBmMmM2M2Y5ZWE1ZTU2ZjZmNjM0ZGUxMmY2MWU1YWRkNzYzOTVlMXwxMDkxOzEwOTE7MTU0ODA2NTI0MzswOzE1NDc5Nzg4NDMuNTcxOTswO3ZpZXc6Kix3aWRnZXQ6MTs7'
},
sources: {
hls: [
{
id: '0_nwkp7jtx_1033,applehttp',
url:
'http://qa-apache-php7.dev.kaltura.com/p/1091/sp/109100/playManifest/entryId/0_nwkp7jtx/protocol/http/format/applehttp/flavorIds/0_iju7j519,0_98mlrldo,0_5hts3h5r,0_n6n76xp9/a.m3u8',
mimetype: 'application/x-mpegURL'
}
],
dash: [
{
id: '0_nwkp7jtx_301,mpegdash',
url:
'http://qa-apache-php7.dev.kaltura.com/p/1091/sp/109100/playManifest/entryId/0_nwkp7jtx/protocol/http/format/mpegdash/flavorIds/0_iju7j519,0_98mlrldo,0_5hts3h5r,0_n6n76xp9/a.mpd',
mimetype: 'application/dash+xml'
}
],
progressive: [],
id: '0_nwkpghdf',
duration: 86089,
type: 'Live',
poster: 'http://cdntesting.qa.mkaltura.com/p/1091/sp/109100/thumbnail/entry_id/0_nwkp7jtx/version/0',
dvr: true,
vr: null,
metadata: {
name: 'Kaltura Live with DVR new - 08.17',
description: '',
tags: ''
}
},
plugins: {
colors: {
favouriteColor: 'red',
someProp1: 'prop1',
someProp2: 'prop2'
}
}
},
Youtube: {
session: {
isAnonymous: true,
Expand Down
Loading

0 comments on commit f3905e7

Please sign in to comment.