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

Store and use fragmentedText settings in localStorage #3293

2 changes: 2 additions & 0 deletions contrib/akamai/controlbar/ControlBar.js
Expand Up @@ -489,6 +489,8 @@ var ControlBar = function (dashjsMediaPlayer, displayUTCTimeCodes) {
menuHandlersList.push(func);
captionBtn.addEventListener('click', func);
captionBtn.classList.remove('hide');
} else {
setMenuItemsState(e.index + 1, 'caption-list');
}
};

Expand Down
118 changes: 103 additions & 15 deletions samples/captioning/multi-track-captions.html
Expand Up @@ -13,28 +13,75 @@
<!--<script src="../../dist/dash.all.min.js"></script>-->

<script class="code">
var EXTERNAL_CAPTION_URL = "https://dash.akamaized.net/dash264/TestCases/4b/qualcomm/1/ED_OnDemand_5SecSeg_Subtitles.mpd", // need to manually seek to get stream to start... issue with MPD but only sample with multi adaptations for external sidecar caption text xml
var EXTERNAL_CAPTION_URL = "https://dash.akamaized.net/dash264/TestCases/4b/qualcomm/1/ED_OnDemand_5SecSeg_Subtitles.mpd", /* need to manually seek to get stream to start... issue with MPD but only sample with multi adaptations for external sidecar caption text xml */
FRAGMENTED_CAPTION_URL = "https://vm2.dashif.org/dash/vod/testpic_2s/multi_subs.mpd",
videoElement,
controlbar,
player;

function startVideo() {
var url = FRAGMENTED_CAPTION_URL,
TTMLRenderingDiv;

function init() {
var TTMLRenderingDiv = document.querySelector("#ttml-rendering-div");
videoElement = document.querySelector(".videoContainer video");
TTMLRenderingDiv = document.querySelector("#ttml-rendering-div");

player = dashjs.MediaPlayer().create();
player.initialize(videoElement, url, true);
player.setTextDefaultEnabled(true);
player.setInitialMediaSettingsFor('fragmentedText', {
lang: 'swe'
});
player.initialize(videoElement);
player.attachTTMLRenderingDiv(TTMLRenderingDiv);
controlbar = new ControlBar(player); // Checkout ControlBar.js for more info on how to target/add text tracks to UI
player.on('currentTrackChanged', function(e) {
if (e.newMediaInfo.type === 'fragmentedText') {
setTimeout(showDomStorage, 0);
}
});
controlbar = new ControlBar(player); /* Checkout ControlBar.js for more info on how to target/add text tracks to UI */
controlbar.initialize();
document.getElementById("lastMediaSettingsCachingInfoEnabled").checked = player.getSettings().streaming.lastMediaSettingsCachingInfo.enabled;
showDomStorage();
}

function showDomStorage() {
document.getElementById("domStorage").innerHTML = localStorage.getItem('dashjs_fragmentedText_settings');
}

function play() {
var url = FRAGMENTED_CAPTION_URL;
player.attachSource(url);
setTextDefaultEnabled();
setLang();
player.play();
showDomStorage();
}

function setTextDefaultEnabled() {
var checkbox = document.getElementById("textDefaultEnabled");
player.setTextDefaultEnabled(checkbox.checked);
}

function setLang() {
var lang = document.getElementById("textSettings").value;
var role = null;
if (lang) {
if (lang.indexOf('-') != -1) {
var values = lang.split('-');
lang = values[0];
role = values[1];
}
player.setInitialMediaSettingsFor('fragmentedText', {
lang: lang,
role: role
});
}
}

function setLastMediaSettingsCachingInfoEnabled() {
var checkbox = document.getElementById("lastMediaSettingsCachingInfoEnabled");
player.updateSettings({
streaming: {
lastMediaSettingsCachingInfo: { enabled: checkbox.checked }
}
})
}

function clearDomStorage() {
localStorage.removeItem('dashjs_fragmentedText_settings');
showDomStorage();
}

</script>
Expand All @@ -47,12 +94,24 @@
.dash-video-player {
width: 640px;
}

.settings {
clear: both;
}
.settings>div {
padding: 5px 0;
}

label {
font-size: 1.1em;
}

</style>

<body onload="startVideo()">
<body onload="init()">
<div class="dash-video-player code">
<div class="videoContainer" id="videoContainer">
<video preload="auto" autoplay="true" > </video>
<video preload="auto"> </video>
<div id="ttml-rendering-div"></div>

<div id="videoController" class="video-controller unselectable">
Expand Down Expand Up @@ -85,6 +144,35 @@
</div>
</div>
</div>
<div class="settings">
<div>
<button onclick="play()">play</button>
</div>
<div>
<input type="checkbox" id="textDefaultEnabled" onchange="setTextDefaultEnabled()" checked>
<label>textDefaultEnabled</label>
</div>
<div>
<label>initial settings Language/Role </label>
<select onchange="setLang()" id="textSettings">
<option value="">-- unset initial lang and role --</option>
<option value="eng-subtitle">eng - subtitles</option>
<option value="eng-caption">eng - captions</option>
<option value="swe">swe - subtitles</option>
<option value="qbb">qbb - subtitles</option>
<option value="nor">nor - subtitles</option>
</select>
</div>
<div>
<input type="checkbox" id="lastMediaSettingsCachingInfoEnabled" onchange="setLastMediaSettingsCachingInfoEnabled()"/>
dsilhavy marked this conversation as resolved.
Show resolved Hide resolved
<label>streaming.lastMediaSettingsCachingInfo.enabled</label>
</div>
<div>
<label>localStorage content</label>
<div id="domStorage"></div>
<button onclick="clearDomStorage()">Clear localStorage</button>
</div>
</div>
</div>
<script src="../highlighter.js"></script>
</body>
Expand Down
9 changes: 2 additions & 7 deletions src/streaming/Stream.js
Expand Up @@ -474,14 +474,9 @@ function Stream(config) {
return;
}

if (type !== Constants.FRAGMENTED_TEXT || (type === Constants.FRAGMENTED_TEXT && textController.getTextDefaultEnabled())) {
mediaController.checkInitialMediaSettingsForType(type, streamInfo);
initialMediaInfo = mediaController.getCurrentTrackFor(type, streamInfo);
}

if (type === Constants.FRAGMENTED_TEXT && !textController.getTextDefaultEnabled()) {
initialMediaInfo = mediaController.getTracksFor(type, streamInfo)[0];
}
mediaController.checkInitialMediaSettingsForType(type, streamInfo);
initialMediaInfo = mediaController.getCurrentTrackFor(type, streamInfo);

eventBus.trigger(Events.STREAM_INITIALIZING, {
streamInfo: streamInfo,
Expand Down
60 changes: 35 additions & 25 deletions src/streaming/controllers/MediaController.js
Expand Up @@ -78,12 +78,6 @@ function MediaController() {
const tracksForType = getTracksFor(type, streamInfo);
const tracks = [];

if (type === Constants.FRAGMENTED_TEXT) {
// Choose the first track
setTrack(tracksForType[0]);
return;
}

if (!settings) {
settings = domStorage.getSavedMediaSettings(type);
setInitialSettings(type, settings);
Expand All @@ -100,10 +94,10 @@ function MediaController() {
}

if (tracks.length === 0) {
setTrack(selectInitialTrack(tracksForType));
setTrack(selectInitialTrack(type, tracksForType), true);
} else {
if (tracks.length > 1) {
setTrack(selectInitialTrack(tracks));
setTrack(selectInitialTrack(type, tracks));
} else {
setTrack(tracks[0]);
}
Expand Down Expand Up @@ -185,9 +179,10 @@ function MediaController() {

/**
* @param {MediaInfo} track
* @param {boolean} noSettingsSave specify if settings must be not be saved
* @memberof MediaController#
*/
function setTrack(track) {
function setTrack(track, noSettingsSave) {
if (!track || !track.streamInfo) return;

const type = track.type;
Expand All @@ -199,28 +194,31 @@ function MediaController() {

tracks[id][type].current = track;

if (tracks[id][type].current) {
if (tracks[id][type].current && !(noSettingsSave && type === Constants.FRAGMENTED_TEXT)) {
eventBus.trigger(Events.CURRENT_TRACK_CHANGED, {oldMediaInfo: current, newMediaInfo: track, switchMode: switchMode[type]});
}

let settings = extractSettings(track);
if (!noSettingsSave) {

if (!settings || !tracks[id][type].storeLastSettings) return;
let settings = extractSettings(track);

if (settings.roles) {
settings.role = settings.roles[0];
delete settings.roles;
}
if (!settings || !tracks[id][type].storeLastSettings) return;

if (settings.accessibility) {
settings.accessibility = settings.accessibility[0];
}
if (settings.roles) {
settings.role = settings.roles[0];
delete settings.roles;
}

if (settings.audioChannelConfiguration) {
settings.audioChannelConfiguration = settings.audioChannelConfiguration[0];
}
if (settings.accessibility) {
settings.accessibility = settings.accessibility[0];
}

if (settings.audioChannelConfiguration) {
settings.audioChannelConfiguration = settings.audioChannelConfiguration[0];
}

domStorage.setSavedMediaSettings(type, settings);
domStorage.setSavedMediaSettings(type, settings);
}
}

/**
Expand All @@ -245,6 +243,13 @@ function MediaController() {
return initialSettings[type];
}

/**
* @memberof MediaController#
*/
function saveTextSettingsDisabled() {
domStorage.setSavedMediaSettings(Constants.FRAGMENTED_TEXT, null);
}

/**
* @param {string} type
* @param {string} mode
Expand Down Expand Up @@ -384,13 +389,17 @@ function MediaController() {
function resetInitialSettings() {
initialSettings = {
audio: null,
video: null
video: null,
fragmentedText: null
};
}

function selectInitialTrack(tracks) {
function selectInitialTrack(type, tracks) {
if (type === Constants.FRAGMENTED_TEXT) return tracks[0];

let mode = getSelectionModeForInitialTrack();
let tmpArr = [];

const getTracksWithHighestBitrate = function (trackArr) {
let max = 0;
let result = [];
Expand Down Expand Up @@ -497,6 +506,7 @@ function MediaController() {
isMultiTrackSupportedByType: isMultiTrackSupportedByType,
isTracksEqual: isTracksEqual,
matchSettings: matchSettings,
saveTextSettingsDisabled: saveTextSettingsDisabled,
setConfig: setConfig,
reset: reset
};
Expand Down