Skip to content

Commit

Permalink
allow setInitialMediaSettingsFor with fragmentedText media type (#3245)
Browse files Browse the repository at this point in the history
* MediaPlayer.setInitialMediaSettingsFor compatible with fragmentedText media type

* disable text by default

* setTextDefaultLanguage and getTextDefaultLanguage are now deprecated and will be removed in version 3.2.0

* add an example of setInitialMediaSettingsFor

* update unit tests as subtitles are now disabled by default
  • Loading branch information
jeffcunat committed Jun 9, 2020
1 parent c4b6f11 commit f29346d
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 26 deletions.
3 changes: 3 additions & 0 deletions samples/captioning/multi-track-captions.html
Expand Up @@ -28,6 +28,9 @@

player = dashjs.MediaPlayer().create();
player.initialize(videoElement, url, true);
player.setInitialMediaSettingsFor('fragmentedText', {
lang: 'swe'
});
player.attachTTMLRenderingDiv(TTMLRenderingDiv);
controlbar = new ControlBar(player); // Checkout ControlBar.js for more info on how to target/add text tracks to UI
controlbar.initialize();
Expand Down
11 changes: 10 additions & 1 deletion samples/dash-if-reference-player/app/main.js
Expand Up @@ -619,7 +619,16 @@ app.controller('DashController', function ($scope, sources, contributors, dashif
});
}
if ($scope.initialSettings.text) {
$scope.player.setTextDefaultLanguage($scope.initialSettings.text);
if ($scope.initialSettings.textRole) {
$scope.player.setInitialMediaSettingsFor('fragmentedText', {
role: $scope.initialSettings.textRole,
lang: $scope.initialSettings.text
});
} else {
$scope.player.setInitialMediaSettingsFor('fragmentedText', {
lang: $scope.initialSettings.text
});
}
}
$scope.player.setTextDefaultEnabled($scope.initialSettings.textEnabled);
$scope.player.enableForcedTextStreaming($scope.initialSettings.forceTextStreaming);
Expand Down
4 changes: 3 additions & 1 deletion samples/dash-if-reference-player/index.html
Expand Up @@ -239,8 +239,10 @@
<label class="options-label">Audio:</label>
<input type="text" class="form-control" placeholder="audio initial lang, e.g. 'en'" ng-model="initialSettings.audio">
<label class="options-label">Video:</label>
<input type="text" class="form-control" placeholder="initial role, e.g. 'alternate'" ng-model="initialSettings.video"> <label class="options-label">Text:</label>
<input type="text" class="form-control" placeholder="initial role, e.g. 'alternate'" ng-model="initialSettings.video">
<label class="options-label">Text:</label>
<input type="text" class="form-control" placeholder="text initial lang, e.g. 'en'" ng-model="initialSettings.text">
<input type="text" class="form-control" placeholder="text initial role, e.g. 'caption'" ng-model="initialSettings.textRole">
<label class="topcoat-checkbox" data-toggle="tooltip" data-placement="right"
title="Enable subtitle on loading text">
<input type="checkbox" id="enableTextAtLoading" ng-model="initialSettings.textEnabled">
Expand Down
12 changes: 9 additions & 3 deletions src/streaming/MediaPlayer.js
Expand Up @@ -1142,12 +1142,13 @@ function MediaPlayer() {
* @param {string} lang - default language
* @memberof module:MediaPlayer
* @instance
* @deprecated will be removed in version 3.2.0. Please use setInitialMediaSettingsFor("fragmentedText", { lang: lang }) instead
*/
function setTextDefaultLanguage(lang) {
logger.warn('setTextDefaultLanguage is deprecated and will be removed in version 3.2.0. Please use setInitialMediaSettingsFor("fragmentedText", { lang: lang }) instead');
if (textController === undefined) {
textController = TextController(context).getInstance();
}

textController.setTextDefaultLanguage(lang);
}

Expand All @@ -1157,8 +1158,10 @@ function MediaPlayer() {
* @return {string} the default language if it has been set using setTextDefaultLanguage
* @memberof module:MediaPlayer
* @instance
* @deprecated will be removed in version 3.2.0. Please use getInitialMediaSettingsFor("fragmentedText").lang instead
*/
function getTextDefaultLanguage() {
logger.warn('getTextDefaultLanguage is deprecated and will be removed in version 3.2.0. Please use getInitialMediaSettingsFor("fragmentedText").lang instead');
if (textController === undefined) {
textController = TextController(context).getInstance();
}
Expand Down Expand Up @@ -1473,11 +1476,14 @@ function MediaPlayer() {
* @throws {@link module:MediaPlayer~MEDIA_PLAYER_NOT_INITIALIZED_ERROR MEDIA_PLAYER_NOT_INITIALIZED_ERROR} if called before initialize function
* @instance
*/
function setQualityForSettingsFor(type, value) {
function setInitialMediaSettingsFor(type, value) {
if (!mediaPlayerInitialized) {
throw MEDIA_PLAYER_NOT_INITIALIZED_ERROR;
}
mediaController.setInitialSettings(type, value);
if (type === Constants.FRAGMENTED_TEXT) {
textController.setInitialSettings(value);
}
}

/**
Expand Down Expand Up @@ -2241,7 +2247,7 @@ function MediaPlayer() {
getTracksFor: getTracksFor,
getTracksForTypeFromManifest: getTracksForTypeFromManifest,
getCurrentTrackFor: getCurrentTrackFor,
setInitialMediaSettingsFor: setQualityForSettingsFor,
setInitialMediaSettingsFor: setInitialMediaSettingsFor,
getInitialMediaSettingsFor: getInitialMediaSettingsFor,
setCurrentTrack: setCurrentTrack,
getTrackSwitchModeFor: getTrackSwitchModeFor,
Expand Down
1 change: 1 addition & 0 deletions src/streaming/controllers/MediaController.js
Expand Up @@ -496,6 +496,7 @@ function MediaController() {
getSelectionModeForInitialTrack: getSelectionModeForInitialTrack,
isMultiTrackSupportedByType: isMultiTrackSupportedByType,
isTracksEqual: isTracksEqual,
matchSettings: matchSettings,
setConfig: setConfig,
reset: reset
};
Expand Down
34 changes: 21 additions & 13 deletions src/streaming/text/TextController.js
Expand Up @@ -54,7 +54,7 @@ function TextController() {
vttParser,
ttmlParser,
eventBus,
defaultLanguage,
defaultSettings,
lastEnabledIndex,
textDefaultEnabled, // this is used for default settings (each time a file is loaded, we check value of this settings )
allTracksAreDisabled, // this is used for one session (when a file has been loaded, we use this settings to enable/disable text)
Expand All @@ -63,9 +63,9 @@ function TextController() {

function setup() {

defaultLanguage = '';
defaultSettings = {};
lastEnabledIndex = -1;
textDefaultEnabled = true;
textDefaultEnabled = false;
forceTextStreaming = false;
textTracks = TextTracks(context).getInstance();
vttParser = VTTParser(context).getInstance();
Expand Down Expand Up @@ -170,24 +170,31 @@ function TextController() {

function setTextDefaultLanguage(lang) {
checkParameterType(lang, 'string');
defaultLanguage = lang;
defaultSettings.lang = lang;
}

function setInitialSettings(settings) {
defaultSettings = settings;
}

function getTextDefaultLanguage() {
return defaultLanguage;
return defaultSettings.lang || '';
}

function onTextTracksAdded(e) {
let tracks = e.tracks;
let index = e.index;

tracks.some((item, idx) => {
if (item.lang === defaultLanguage) {
this.setTextTrack(idx);
index = idx;
return true;
}
});
if (defaultSettings) {
tracks.some((item, idx) => {
// matchSettings is compatible with setTextDefaultLanguage and setInitialSettings
if (mediaController.matchSettings(defaultSettings, item)) {
this.setTextTrack(idx);
index = idx;
return true;
}
});
}

if (!textDefaultEnabled) {
// disable text at startup
Expand Down Expand Up @@ -249,7 +256,7 @@ function TextController() {
}

function setTextTrack(idx) {
//For external time text file, the only action needed to change a track is marking the track mode to showing.
//For external time text file, the only action needed to change a track is marking the track mode to showing.
// Fragmented text tracks need the additional step of calling TextController.setTextTrack();
let config = textSourceBuffer.getConfig();
let fragmentModel = config.fragmentModel;
Expand Down Expand Up @@ -342,6 +349,7 @@ function TextController() {
setTextDefaultLanguage: setTextDefaultLanguage,
setTextDefaultEnabled: setTextDefaultEnabled,
getTextDefaultEnabled: getTextDefaultEnabled,
setInitialSettings: setInitialSettings,
enableText: enableText,
isTextEnabled: isTextEnabled,
setTextTrack: setTextTrack,
Expand Down
7 changes: 7 additions & 0 deletions test/unit/mocks/MediaControllerMock.js
Expand Up @@ -104,6 +104,13 @@ class MediaControllerMock {
return (mediaInfoForType.lang === 'deu');
}

matchSettings(settings, track) {
const matchRole = !settings.role || !!track.roles.filter(function (item) {
return item === settings.role;
})[0];
return settings.lang === track.lang && matchRole;
}

setConfig() {}

reset() {
Expand Down
11 changes: 9 additions & 2 deletions test/unit/streaming.MediaPlayer.js
Expand Up @@ -873,8 +873,8 @@ describe('MediaPlayer', function () {
expect(player.setTextDefaultEnabled).to.throw(Constants.BAD_ARGUMENT_ERROR);
});

it('Method getTextDefaultEnabled should return true', function () {
expect(player.getTextDefaultEnabled()).to.be.true; // jshint ignore:line
it('Method getTextDefaultEnabled should return false', function () {
expect(player.getTextDefaultEnabled()).to.be.false; // jshint ignore:line
});
});
});
Expand Down Expand Up @@ -1040,6 +1040,13 @@ describe('MediaPlayer', function () {

initialSettings = player.getInitialMediaSettingsFor('audio');
expect(initialSettings).to.equal('settings');

player.setInitialMediaSettingsFor('fragmentedText', { lang: 'en', role: 'caption'});
initialSettings = player.getInitialMediaSettingsFor('fragmentedText');
expect(initialSettings).to.exist; ; // jshint ignore:line
expect(initialSettings.lang).to.equal('en');
expect(initialSettings.role).to.equal('caption');

});

it('should set current track', function () {
Expand Down
43 changes: 37 additions & 6 deletions test/unit/streaming.text.TextController.js
Expand Up @@ -8,6 +8,8 @@ import Constants from '../../src/streaming/constants/Constants';

import VideoModelMock from './mocks/VideoModelMock';
import StreamControllerMock from './mocks/StreamControllerMock';
import MediaControllerMock from './mocks/MediaControllerMock';


const expect = require('chai').expect;
const context = {};
Expand All @@ -19,6 +21,7 @@ describe('TextController', function () {

let videoModelMock = new VideoModelMock();
let streamControllerMock = new StreamControllerMock();
let mediaControllerMock = new MediaControllerMock();
let textTracks;
let textController;

Expand Down Expand Up @@ -49,7 +52,8 @@ describe('TextController', function () {
textController = TextController(context).getInstance();
textController.setConfig({
videoModel: videoModelMock,
streamController: streamControllerMock
streamController: streamControllerMock,
mediaController: mediaControllerMock
});
});

Expand Down Expand Up @@ -84,10 +88,10 @@ describe('TextController', function () {
describe('Method setTextDefaultEnabled', function () {
it('should not set text default enabled if enable is not a boolean', function () {
expect(textController.setTextDefaultEnabled.bind(textController, -1)).to.throw(Constants.BAD_ARGUMENT_ERROR);
expect(textController.getTextDefaultEnabled()).to.equal(true); // jshint ignore:line
expect(textController.getTextDefaultEnabled()).to.equal(false); // jshint ignore:line

expect(textController.setTextDefaultEnabled.bind(textController)).to.throw(Constants.BAD_ARGUMENT_ERROR);
expect(textController.getTextDefaultEnabled()).to.equal(true); // jshint ignore:line
expect(textController.getTextDefaultEnabled()).to.equal(false); // jshint ignore:line
});

it('should set text default enabled if enable is a boolean', function () {
Expand Down Expand Up @@ -208,17 +212,24 @@ describe('TextController', function () {

textTracksQueue.push({
index: 0,
kind: 'subtitles',
roles: ['subtitles'],
label: 'sub_en',
lang: 'eng'
});

textTracksQueue.push({
index: 1,
kind: 'subtitles',
roles: ['subtitles'],
label: 'sub_fr',
lang: 'fr'
});

textTracksQueue.push({
index: 2,
roles: ['captions'],
label: 'sub_fr_hoh',
lang: 'fr'
});
});

it('should send TEXT_TRACKS_ADDED event', function (done) {
Expand All @@ -242,7 +253,7 @@ describe('TextController', function () {
eventBus.trigger(Events.TEXT_TRACKS_QUEUE_INITIALIZED, event);
});

it('should choose langauge according to default language', function (done) {
it('should choose language according to default language', function (done) {
// init test
textController.setTextDefaultLanguage('fr');

Expand Down Expand Up @@ -282,6 +293,26 @@ describe('TextController', function () {
// send event
eventBus.trigger(Events.TEXT_TRACKS_QUEUE_INITIALIZED, event);
});

it('should choose track according to default settings', function (done) {
// init test
textController.setInitialSettings({ lang: 'fr', role: 'captions' });

const event = {
index: initialIndex,
tracks: textTracksQueue
};
const onTracksAdded = function (e) {
expect(e.index).to.equal(2); // jshint ignore:line
expect(e.tracks.length).to.equal(textTracksQueue.length); // jshint ignore:line
eventBus.off(Events.TEXT_TRACKS_ADDED, onTracksAdded, this);
done();
};
eventBus.on(Events.TEXT_TRACKS_ADDED, onTracksAdded, this);

// send event
eventBus.trigger(Events.TEXT_TRACKS_QUEUE_INITIALIZED, event);
});
});

});

0 comments on commit f29346d

Please sign in to comment.