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

IMSC.js Styling #95

Open
wants to merge 3 commits into
base: smp-v4.7
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 16 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"fast-deep-equal": "2.0.1",
"foodoc": "^0.0.9",
"html-entities": "^1.2.1",
"imsc": "^1.1.4",
"imsc": "github:bbc/imscJS#v1.0.11-2",
"localforage": "^1.7.1",
"path-browserify": "^1.0.1",
"ua-parser-js": "^1.0.2"
Expand Down
202 changes: 202 additions & 0 deletions samples/captioning/ttml-ebutt-styling.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>TTML Adjusting Text Size</title>
<script src="../../contrib/akamai/controlbar/ControlBar.js"></script>
<script src="../../dist/dash.all.debug.js"></script>

<!-- Bootstrap core CSS -->
<link href="../lib/bootstrap/bootstrap.min.css" rel="stylesheet">
<link href="../lib/main.css" rel="stylesheet">

<link rel="stylesheet" href="../../contrib/akamai/controlbar/controlbar.css">

<style>
video {
width: 100%;
}

.dash-video-player {
position: relative; /* This position relative is needed to position the menus */
margin: 0 auto;
line-height: 1.0;
}
</style>

<script>
let player;
const url = "https://rdmedia.bbc.co.uk/elephants_dream/1/client_manifest-all.mpd";

const config = {
"streaming": {
"text":{
"imsc":{
"enableRollUp": false,
"displayForcedOnlyMode": false,
"options":{
"sizeAdjust": 0,
"lineHeightAdjust":0,
"backgroundOpacityScale":0
},
},
},
},
};


const showConfig = () =>{
document.querySelector("#player-config").innerHTML = JSON.stringify(config, null, 2);
}

const updatePlayerSettings = () => {

config.streaming.text.imsc = {
enableRollUp: document.querySelector("#imsc-enableRollUp").checked ? true: false,
displayForcedOnlyMode: document.querySelector("#imsc-displayForcedOnlyMode").checked ? true: false,
options:{
sizeAdjust: parseFloat(document.querySelector("#imsc-option-sizeAdjust").value),
lineHeightAdjust: parseFloat(document.querySelector("#imsc-option-lineHeightAdjust").value),
backgroundOpacityScale: parseFloat(document.querySelector("#imsc-option-backgroundOpacityScale").value),
},
}

player.updateSettings(config);
showConfig()
}

const init = ()=> {
// Get required elements from the DOM
const video = document.querySelector('video');
const TTMLRenderingDiv = document.querySelector("#ttml-rendering-div");

// Create and initialise player
player = dashjs.MediaPlayer().create();
player.initialize(video, url, true);
player.attachTTMLRenderingDiv(TTMLRenderingDiv);
updatePlayerSettings();

// Add some UI
const controlbar = new ControlBar(player);
controlbar.initialize();
}

</script>
</head>
<body>

<main>
<div class="container py-4">
<header class="pb-3 mb-4 border-bottom">
<img class=""
src="../lib/img/dashjs-logo.png"
width="200">
</header>
<div class="row">
<div class="col-md-4">
<div class="h-100 p-4 bg-light border rounded-3">
<h3>TTML ENBUTT Styling</h3>
<p>Example showing content with TTML captions and the ability to adjust their styling.</p>

<div class="row">

<h6>IMSC Settings</h6>

<div class="input-group input-group-sm mt-1">
<div class="form-check mb-3">
<input onchange="updatePlayerSettings()" class="form-check-input" type="checkbox" id="imsc-enableRollUp">
<label class="form-check-label" for="imsc-enableRollUp">
Enable Rollup
</label>
</div>

<div class="form-check mb-3">
<input onchange="updatePlayerSettings()" class="form-check-input" type="checkbox" id="imsc-displayForcedOnlyMode">
<label class="form-check-label" for="imsc-displayForcedOnlyMode">
Display Forced Only Mode
</label>
</div>
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text"> Size Adjust</span>
<input onchange="updatePlayerSettings()" id="imsc-option-sizeAdjust" class="form-control" value="1"
step="0.1" min="0" type="number">
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text"> Line Height Adjust</span>
<input onchange="updatePlayerSettings()" id="imsc-option-lineHeightAdjust" class="form-control" value="1"
step="0.1" min="0" type="number">
</div>

<div class="input-group input-group-sm mb-3">
<span class="input-group-text"> Background Opacity Scale</span>
<input onchange="updatePlayerSettings()" id="imsc-option-backgroundOpacityScale" class="form-control" value="1"
step="0.1" min="0" max="1" type="number">
</div>


</div>
</div>
</div>
<div class="col-md-8">
<div class="dash-video-player">
<div class="videoContainer" id="videoContainer">
<video preload="auto" autoplay></video>
<div id="ttml-rendering-div"></div>
<div id="videoController" class="video-controller unselectable">
<div id="playPauseBtn" class="btn-play-pause" title="Play/Pause">
<span id="iconPlayPause" class="icon-play"></span>
</div>
<span id="videoTime" class="time-display">00:00:00</span>
<div id="fullscreenBtn" class="btn-fullscreen control-icon-layout" title="Fullscreen">
<span class="icon-fullscreen-enter"></span>
</div>
<div id="bitrateListBtn" class="control-icon-layout" title="Bitrate List">
<span class="icon-bitrate"></span>
</div>
<input type="range" id="volumebar" class="volumebar" value="1" min="0" max="1" step=".01"/>
<div id="muteBtn" class="btn-mute control-icon-layout" title="Mute">
<span id="iconMute" class="icon-mute-off"></span>
</div>
<div id="trackSwitchBtn" class="control-icon-layout" title="A/V Tracks">
<span class="icon-tracks"></span>
</div>
<div id="captionBtn" class="btn-caption control-icon-layout" title="Closed Caption">
<span class="icon-caption"></span>
</div>
<span id="videoDuration" class="duration-display">00:00:00</span>
<div class="seekContainer">
<div id="seekbar" class="seekbar seekbar-complete">
<div id="seekbar-buffer" class="seekbar seekbar-buffer"></div>
<div id="seekbar-play" class="seekbar seekbar-play"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="pt-4 col-md-12">
<div class="p-4 bg-light border rounded-3">
<h6>Player Config</h6>
<br>
<pre><code class="text-monospace" id="player-config" data-lang="json"></code></pre>
</div>
</div>
</div>
<footer class="pt-3 mt-4 text-muted border-top">
&copy; DASH-IF
</footer>
</div>
</main>
<script>
document.addEventListener('DOMContentLoaded', function () {
init();
});
</script>
<script src="../highlighter.js"></script>
</body>
</html>
14 changes: 13 additions & 1 deletion samples/samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,18 @@
"Audio"
]
},
{
"title": "TTML EBU caption styling",
"description": "Example showing content with TTML captions and the ability to adjust their style.",
"href": "captioning/ttml-ebutt-styling.html",
"image": "lib/img/elephant-1.jpg",
"labels": [
"VoD",
"Fragmented text",
"Video",
"Audio"
]
},
{
"title": "WebVTT Custom Rendering",
"description": "This example shows how content with VTT captions can be played back by the dash.js player using the external vtt.js library. This enables VTT support on devices that do not provide native VTT support.",
Expand Down Expand Up @@ -802,4 +814,4 @@
}
]
}
]
]
22 changes: 21 additions & 1 deletion src/core/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,18 @@ import Events from './events/Events';
* Enable/disable subtitle rendering by default.
* @property {boolean} [extendSegmentedCues=true]
* Enable/disable patching of segmented cues in order to merge as a single cue by extending cue end time.
* @property {object} [webvtt={customRenderingEnabled=false}]
* @property {boolean} [imsc.displayForcedOnlyMode=false]
* Enable/disable forced only mode in IMSC captions.
* When true, only those captions where itts:forcedDisplay="true" will be displayed.
* @property {boolean} [imsc.enableRollUp=true]
* Enable/disable rollUp style display of IMSC captions.
* @property {number} [imsc.options.sizeAdjust=1]
* IMSC styling options - adjust text size, scales the text size and line padding
* @property {number} [imsc.options.lineHeightAdjust=1]
* IMSC styling options - scales the line height
* @property {number} [imsc.options.backgroundOpacityScale=1]
* IMSC styling options - scales the backgroundColor opacity
* @property {object} [webvtt.customRenderingEnabled=false]
* Enables the custom rendering for WebVTT captions. For details refer to the "Subtitles and Captions" sample section of dash.js.
* Custom WebVTT rendering requires the external library vtt.js that can be found in the contrib folder.
*/
Expand Down Expand Up @@ -982,6 +993,15 @@ function Settings() {
text: {
defaultEnabled: true,
extendSegmentedCues: true,
imsc: {
displayForcedOnlyMode: false,
enableRollUp: true,
options: {
sizeAdjust: 1,
lineHeightAdjust: 1,
backgroundOpacityScale: 1
},
},
webvtt: {
customRenderingEnabled: false
}
Expand Down
22 changes: 16 additions & 6 deletions src/streaming/text/TextTracks.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,12 +411,22 @@ function TextTracks(config) {
if (captionContainer) {
const finalCue = document.createElement('div');
captionContainer.appendChild(finalCue);
previousISDState = renderHTML(cue.isd, finalCue, function (src) {
return _resolveImageSrc(cue, src);
}, captionContainer.clientHeight, captionContainer.clientWidth, false/*displayForcedOnlyMode*/, function (err) {
logger.info('renderCaption :', err);
//TODO add ErrorHandler management
}, previousISDState, true /*enableRollUp*/);
previousISDState = renderHTML(
cue.isd,
finalCue,
function (src) {
return _resolveImageSrc(cue, src)
},
captionContainer.clientHeight,
captionContainer.clientWidth,
settings.get().streaming.text.imsc.displayForcedOnlyMode,
function (err) {
logger.info('renderCaption :', err) /*TODO: add ErrorHandler management*/
},
previousISDState,
settings.get().streaming.text.imsc.enableRollUp,
settings.get().streaming.text.imsc.options
);
finalCue.id = cue.cueID;
eventBus.trigger(MediaPlayerEvents.CAPTION_RENDERED, { captionDiv: finalCue, currentTrackIdx });
}
Expand Down