Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/development'
Browse files Browse the repository at this point in the history
  • Loading branch information
dsilhavy committed Dec 14, 2022
2 parents df045d6 + 357bbfc commit 00a172d
Show file tree
Hide file tree
Showing 26 changed files with 2,548 additions and 464 deletions.
1,956 changes: 1,956 additions & 0 deletions contrib/videojs-vtt.js/vtt.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions contrib/videojs-vtt.js/vtt.min.js

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ declare namespace dashjs {
scheduleWhilePaused?: boolean
},
text?: {
defaultEnabled?: boolean
defaultEnabled?: boolean,
webvtt?: {
customRenderingEnabled?: number
}
},
liveCatchup?: {
maxDrift?: number;
Expand Down
2 changes: 1 addition & 1 deletion 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
@@ -1,6 +1,6 @@
{
"name": "dashjs",
"version": "4.5.1",
"version": "4.5.2",
"description": "A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.",
"author": "Dash Industry Forum",
"license": "BSD-3-Clause",
Expand Down
134 changes: 134 additions & 0 deletions samples/captioning/vttjs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>WebVTT Custom Rendering</title>
<script src="../../contrib/videojs-vtt.js/vtt.min.js"></script>
<script class="code" 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 class="code">
function init() {
var url = 'https://dash.akamaized.net/akamai/test/caption_test/ElephantsDream/elephants_dream_480p_heaac5_1_https.mpd',
video = document.querySelector('video'),
vttRenderingDiv,
player;

vttRenderingDiv = document.querySelector("#vtt-rendering-div");
player = dashjs.MediaPlayer({}).create();
player.updateSettings({
debug: {
logLevel: 5
},
streaming: {
text: {
webvtt: {
customRenderingEnabled: true
}
}
}
})
player.initialize(video, url, true);
player.attachVttRenderingDiv(vttRenderingDiv)
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-5 bg-light border rounded-3">
<h3>WebVTT Custom Rendering Demo</h3>
<p>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. <p>The first
captions appear at the 15s mark.</p>
<p>Note: This sample will only work when using http as the subtitles are not hosted via https.</p>
</div>
</div>
<div class="col-md-8">
<div class="dash-video-player code">
<div class="videoContainer" id="videoContainer">
<video preload="auto" muted></video>
<div style="position: relative">
<div id="vtt-rendering-div" style="min-width: 600px; min-height: 100px;"></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="col-md-12">
<div id="code-output"></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>
12 changes: 12 additions & 0 deletions samples/samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,18 @@
"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.",
"href": "captioning/vttjs.html",
"image": "lib/img/sintel-1.jpg",
"labels": [
"VoD",
"External caption",
"Video",
"Audio"
]
}
]
},
Expand Down
13 changes: 11 additions & 2 deletions src/core/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ import Events from './events/Events';
* scheduleWhilePaused: true
* },
* text: {
* defaultEnabled: true
* defaultEnabled: true,
* webvtt: {
* customRenderingEnabled: false
* }
* },
* liveCatchup: {
* maxDrift: NaN,
Expand Down Expand Up @@ -448,6 +451,9 @@ import Events from './events/Events';
* @typedef {Object} Text
* @property {number} [defaultEnabled=true]
* Enable/disable subtitle rendering by default.
* @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 @@ -854,7 +860,10 @@ function Settings() {
scheduleWhilePaused: true
},
text: {
defaultEnabled: true
defaultEnabled: true,
webvtt: {
customRenderingEnabled: false
}
},
liveCatchup: {
maxDrift: NaN,
Expand Down
88 changes: 2 additions & 86 deletions src/dash/DashHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,89 +300,6 @@ function DashHandler(config) {
return request;
}

/**
* This function returns a time for which we can generate a request. It is supposed to be as close as possible to the target time.
* This is useful in scenarios in which the user seeks into a gap. We will not find a valid request then and need to adjust the seektime.
* @param {number} time
* @param {object} mediaInfo
* @param {object} representation
* @param {number} targetThreshold
*/
function getValidTimeCloseToTargetTime(time, mediaInfo, representation, targetThreshold) {
try {

if (isNaN(time) || !mediaInfo || !representation) {
return NaN;
}

if (time < 0) {
time = 0;
}

if (isNaN(targetThreshold)) {
targetThreshold = DEFAULT_ADJUST_SEEK_TIME_THRESHOLD;
}

if (getSegmentRequestForTime(mediaInfo, representation, time)) {
return time;
}

const start = representation.adaptation.period.start;
const end = representation.adaptation.period.start + representation.adaptation.period.duration;
let currentUpperTime = Math.min(time + targetThreshold, end);
let currentLowerTime = Math.max(time - targetThreshold, start);
let adjustedTime = NaN;
let targetRequest = null;

while (currentUpperTime <= end || currentLowerTime >= start) {
let upperRequest = null;
let lowerRequest = null;
if (currentUpperTime <= end) {
upperRequest = getSegmentRequestForTime(mediaInfo, representation, currentUpperTime);
}
if (currentLowerTime >= start) {
lowerRequest = getSegmentRequestForTime(mediaInfo, representation, currentLowerTime);
}

if (lowerRequest) {
adjustedTime = currentLowerTime;
targetRequest = lowerRequest;
break;
} else if (upperRequest) {
adjustedTime = currentUpperTime;
targetRequest = upperRequest;
break;
}

currentUpperTime += targetThreshold;
currentLowerTime -= targetThreshold;
}

if (targetRequest) {
const requestEndTime = targetRequest.startTime + targetRequest.duration;

// Keep the original start time in case it is covered by a segment
if (time >= targetRequest.startTime && requestEndTime - time > targetThreshold) {
return time;
}

// If target time is before the start of the request use request starttime
if (time < targetRequest.startTime) {
// Apply delta to segment start time to get around rounding issues
return targetRequest.startTime + SEGMENT_START_TIME_DELTA;
}

return Math.min(requestEndTime - targetThreshold, adjustedTime);
}

return adjustedTime;


} catch (e) {
return NaN;
}
}

/**
* This function returns a time larger than the current time for which we can generate a request.
* This is useful in scenarios in which the user seeks into a gap in a dynamic Timeline manifest. We will not find a valid request then and need to adjust the seektime.
Expand Down Expand Up @@ -414,8 +331,8 @@ function DashHandler(config) {
return NaN;
}

// Only look 30 seconds ahead
const end = Math.min(representation.adaptation.period.start + representation.adaptation.period.duration, time + 30);
// If we have a duration look until the end of the duration, otherwise maximum 30 seconds
const end = isFinite(representation.adaptation.period.duration) ? representation.adaptation.period.start + representation.adaptation.period.duration : time + 30;
let currentUpperTime = Math.min(time + targetThreshold, end);
let adjustedTime = NaN;
let targetRequest = null;
Expand Down Expand Up @@ -481,7 +398,6 @@ function DashHandler(config) {
isLastSegmentRequested,
reset,
getNextSegmentRequestIdempotent,
getValidTimeCloseToTargetTime,
getValidTimeAheadOfTargetTime
};

Expand Down
23 changes: 19 additions & 4 deletions src/streaming/MediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,7 @@ import Events from './../core/events/Events';
import MediaPlayerEvents from './MediaPlayerEvents';
import FactoryMaker from '../core/FactoryMaker';
import Settings from '../core/Settings';
import {
getVersionString
}
from '../core/Version';
import {getVersionString} from '../core/Version';

//Dash
import SegmentBaseController from '../dash/controllers/SegmentBaseController';
Expand Down Expand Up @@ -593,6 +590,10 @@ function MediaPlayer() {
throw Constants.BAD_ARGUMENT_ERROR;
}

if (value < 0) {
value = 0;
}

let s = playbackController.getIsDynamic() ? getDVRSeekOffset(value) : value;

// For VoD limit the seek to the duration of the content
Expand Down Expand Up @@ -1425,6 +1426,13 @@ function MediaPlayer() {
videoModel.setTTMLRenderingDiv(div);
}

function attachVttRenderingDiv(div) {
if (!videoModel.getElement()) {
throw ELEMENT_NOT_ATTACHED_ERROR;
}
videoModel.setVttRenderingDiv(div);
}

/*
---------------------------------------------------------------------------
Expand Down Expand Up @@ -1840,6 +1848,12 @@ function MediaPlayer() {
uriFragmentModel.initialize(urlOrManifest);
}

if (startTime == null || isNaN(startTime)) {
startTime = NaN;
}

startTime = Math.max(0, startTime);

source = urlOrManifest;

if (streamingInitialized || playbackInitialized) {
Expand Down Expand Up @@ -2441,6 +2455,7 @@ function MediaPlayer() {
setCustomInitialTrackSelectionFunction,
resetCustomInitialTrackSelectionFunction,
attachTTMLRenderingDiv,
attachVttRenderingDiv,
getCurrentTextTrackIndex,
provideThumbnail,
getDashAdapter,
Expand Down

0 comments on commit 00a172d

Please sign in to comment.