Skip to content
This repository was archived by the owner on Oct 20, 2022. It is now read-only.

Commit 3a8c632

Browse files
committed
Merge branch 'release/1.7.0'
2 parents 4fb7720 + d007910 commit 3a8c632

20 files changed

+515
-471
lines changed

RELEASES NOTES.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
### Release Notes v1.7.0 (2016/11/28)
2+
* Add support for TTML origin defined with field 'c'
3+
* Bugs fixing:
4+
* - Fix compatibility issue with Smooth streaming Streams in CENC/PIFF1.3 format
5+
* - Fix subtitles being displayed by Firefox when using external display mode
6+
* - Fix issue on image subtitles display
7+
* - Fix namespace resolution for subtitles XML files
8+
* - Remove subtitles external <div> size setting (to be set by webapp)
9+
* - Workaround for missing 'cueExit' event not sent by Firefox when seeking
10+
* - Fix issue on track selection among tracks with identical language
11+
* - Correct FragmentInfo requests scheduling in Smooth Streaming DVR mode
12+
* - Stops Smooth Streaming DVR FragmentInfo requests in case of session reloading
13+
* - Fix TTML origin management if set on main div
14+
* - Correct TTML showbackground management to keep text alignment value
15+
116
### Release Notes v1.6.0 (2016/10/04)
217
* Handle Firefox's MSE and <video> timestamping based on CTS/PTS (and not DTS like on other browsers)
318
* Add 'subType' information for tracks (MediaPlayer.getTracks()) to differentiate HoH subtitles

app/js/mss/MssFragmentController.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ Mss.dependencies.MssFragmentController = function() {
297297
}
298298
}
299299

300-
// If protected content (sepiff box = Sample Encryption PIFF)
301-
// => convert it into a senc box
300+
// If protected content in PIFF1.1 format (sepiff box = Sample Encryption PIFF)
301+
// => convert sepiff box it into a senc box
302302
// => create saio and saiz boxes (if not already present)
303303
sepiff = traf.getBoxByType("sepiff");
304304
if (sepiff !== null) {
@@ -353,7 +353,8 @@ Mss.dependencies.MssFragmentController = function() {
353353
trun.data_offset = fragment_size - mdat.size + 8; // 8 = 'size' + 'type' mdat fields length
354354

355355
// Update saio box offset field according to new senc box offset
356-
if (sepiff !== null) {
356+
saio = traf.getBoxByType("saio");
357+
if (saio !== null) {
357358
moofPosInFragment = fragment.getBoxOffsetByType("moof");
358359
trafPosInMoof = moof.getBoxOffsetByType("traf");
359360
sencPosInTraf = traf.getBoxOffsetByType("senc");

app/js/streaming/BufferController.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ MediaPlayer.dependencies.BufferController = function() {
286286
initializationData[quality] = data;
287287

288288
self.debug.info("[BufferController][" + type + "] Buffer initialization segment ", (request.url !== null) ? request.url : request.quality);
289+
//console.saveBinArray(data, type + "_init_" + request.quality + ".mp4");
289290
appendToBuffer.call(self, data, request.quality).then(
290291
function() {
291292
// Load next media segment
@@ -355,7 +356,7 @@ MediaPlayer.dependencies.BufferController = function() {
355356
}
356357
}*/
357358

358-
//console.saveBinArray(data, type + "_" + request.index + "_" + request.quality + ".mp4");
359+
//console.saveBinArray(data, request.url.substring(request.url.lastIndexOf('/') + 1));
359360
data = deleteInbandEvents.call(self, data);
360361

361362
// Check if we need to override the current buffered segments (in case of language switch for example)
@@ -1406,16 +1407,13 @@ MediaPlayer.dependencies.BufferController = function() {
14061407
this.debug.log("[BufferController][" + type + "] Update data");
14071408

14081409
// Check if track has changed (in case of language switch for example)
1409-
//trackChanged = data === null ? true : (((data.lang !== null ? data.lang : data.id) !== ((newData.lang !== null ? newData.lang : newData.id))) ? true : false);
1410-
trackChanged = data === null ? false : (((data.lang !== null ? data.lang : data.id) !== ((newData.lang !== null ? newData.lang : newData.id))) ? true : false);
1410+
trackChanged = (data === null) ? false : ((data.id !== newData.id) || (data.lang !== newData.lang) || (data.subType !== newData.subType));
14111411

14121412
// Set the new data
14131413
data = newData;
14141414
periodInfo = newPeriodInfo;
14151415
dataChanged = true;
14161416

1417-
// Check if track has changed (in case of language switch for example)
1418-
//if (data === null ? true : (((data.lang !== null ? data.lang : data.id) !== ((newData.lang !== null ? newData.lang : newData.id))) ? true : false);
14191417
if (trackChanged) {
14201418
this.debug.log("[BufferController][" + type + "] Track changed");
14211419

app/js/streaming/FragmentInfoController.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ MediaPlayer.dependencies.FragmentInfoController = function() {
2929
segmentDownloadFailed = false,
3030
segmentDownloadErrorCount = 0,
3131
reloadTimeout = null,
32-
startLoadingDate = null,
32+
startFragmentInfoDate = null,
33+
startTimeStampValue = null,
3334
deltaTime = 0,
3435

3536
segmentDuration = NaN,
@@ -51,6 +52,9 @@ MediaPlayer.dependencies.FragmentInfoController = function() {
5152
return;
5253
}
5354

55+
startFragmentInfoDate = new Date().getTime();
56+
startTimeStampValue = _fragmentInfoTime;
57+
5458
this.debug.info("[FragmentInfoController][" + type + "] startPlayback");
5559

5660
// Start buffering process
@@ -94,6 +98,9 @@ MediaPlayer.dependencies.FragmentInfoController = function() {
9498
clearTimeout(bufferTimeout);
9599
started = false;
96100

101+
startFragmentInfoDate = null;
102+
startTimeStampValue = null;
103+
97104
// Stop reload timeout
98105
clearTimeout(reloadTimeout);
99106
reloadTimeout = null;
@@ -106,7 +113,9 @@ MediaPlayer.dependencies.FragmentInfoController = function() {
106113
},
107114

108115
onBytesLoaded = function(request, response) {
109-
var data;
116+
var data,
117+
deltaDate,
118+
deltaTimeStamp;
110119

111120
segmentDuration = request.duration;
112121

@@ -120,9 +129,13 @@ MediaPlayer.dependencies.FragmentInfoController = function() {
120129
data = this.fragmentController.process(response.data, request, _bufferController.getAvailableRepresentations());
121130
this.debug.info("[FragmentInfoController][" + type + "] Buffer segment from url ", request.url);
122131

123-
deltaTime = new Date().getTime() - startLoadingDate;
132+
deltaDate = (new Date().getTime() - startFragmentInfoDate) / 1000;
133+
134+
deltaTimeStamp = (_fragmentInfoTime + segmentDuration) - startTimeStampValue;
124135

125-
delayLoadNextFragmentInfo.call(this, (segmentDuration - (deltaTime / 1000)));
136+
deltaTime = (deltaTimeStamp - deltaDate) > 0 ? (deltaTimeStamp - deltaDate) : 0;
137+
138+
delayLoadNextFragmentInfo.call(this, deltaTime);
126139
} catch (e) {
127140
this.errHandler.sendError(MediaPlayer.dependencies.ErrorHandler.prototype.INTERNAL_ERROR, "Internal error while processing fragment info segment", e.message);
128141
}
@@ -216,8 +229,6 @@ MediaPlayer.dependencies.FragmentInfoController = function() {
216229

217230
self.debug.log("[FragmentInfoController][" + type + "] Start buffering process...");
218231

219-
startLoadingDate = new Date().getTime();
220-
221232
// Get next segment time
222233
segmentTime = _fragmentInfoTime;
223234

app/js/streaming/MediaPlayer.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,9 @@ MediaPlayer = function () {
341341
return null;
342342
};
343343

344+
var _isSameTrack = function (track1, track2) {
345+
return (track1.id === track2.id) && (track1.lang === track2.lang) && (track1.subType === track2.subType);
346+
};
344347

345348
// parse the arguments of load function to make an object
346349
var _parseLoadArguments = function () {
@@ -1206,7 +1209,7 @@ MediaPlayer = function () {
12061209
* @memberof MediaPlayer#
12071210
* @see [getTracks]{@link MediaPlayer#getTracks}
12081211
* @param {String} type - the stream type according to MediaPlayer.TRACKS_TYPE (see @link MediaPlayer#TRACKS_TYPE)
1209-
* @param {Track} track - the track to select
1212+
* @param {Track} track - the track to select, as returned by the [getTracks]{@link MediaPlayer#getTracks} method
12101213
*
12111214
*/
12121215
selectTrack: function (type, track) {
@@ -1217,8 +1220,8 @@ MediaPlayer = function () {
12171220
throw new Error('MediaPlayer Invalid Argument - "type" should be defined and shoud be kind of MediaPlayer.TRACKS_TYPE');
12181221
}
12191222

1220-
if (!track || !(track.id || track.lang)) {
1221-
throw new Error('MediaPlayer.selectTrack(): track parameter is unknown');
1223+
if (!track || !(track.id || track.lang || track.subType)) {
1224+
throw new Error('MediaPlayer.selectTrack(): track parameter is not in valid');
12221225
}
12231226

12241227
var _tracks = _getTracksFromType(type);
@@ -1227,19 +1230,15 @@ MediaPlayer = function () {
12271230
this.debug.error("[MediaPlayer] No available track for type " + type);
12281231
return;
12291232
}
1230-
12311233
var selectedTrack = _getSelectedTrackFromType(type);
12321234

1233-
if (selectedTrack &&
1234-
((track.id && track.id === selectedTrack.id) ||
1235-
(track.lang && track.lang === selectedTrack.lang))) {
1235+
if (selectedTrack && _isSameTrack(selectedTrack, track)) {
12361236
this.debug.log("[MediaPlayer] " + type + " track [" + track.id + " - " + track.lang + "] is already selected");
12371237
return;
12381238
}
12391239

12401240
for (var i = 0; i < _tracks.length; i += 1) {
1241-
if ((track.id && track.id === _tracks[i].id) ||
1242-
(track.lang && track.lang === _tracks[i].lang)) {
1241+
if (_isSameTrack(_tracks[i], track)) {
12431242
_selectTrackFromType(type, _tracks[i]);
12441243
return;
12451244
}
@@ -1269,7 +1268,8 @@ MediaPlayer = function () {
12691268

12701269
return {
12711270
id: _track.id,
1272-
lang: _track.lang
1271+
lang: _track.lang,
1272+
subType: _track.subType
12731273
};
12741274
},
12751275
//#endregion

app/js/streaming/Mp4Processor.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,12 @@ MediaPlayer.dependencies.Mp4Processor = function() {
396396
}
397397

398398
avc1.data_reference_index = 1; //To DO... ??
399-
avc1.compressorname = "AVC Coding"; //is a name, for informative purposes. It is formatted in a fixed 32-byte field, with the first
399+
avc1.compressorname = [0x0A, 0x41, 0x56, 0x43, 0x20, 0x43, 0x6F, 0x64,
400+
0x69, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00,
401+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
403+
// = "AVC Coding";
404+
//is a name, for informative purposes. It is formatted in a fixed 32-byte field, with the first
400405
//byte set to the number of bytes to be displayed, followed by that number of bytes of displayable data,
401406
//and then padding to complete 32 bytes total (including the size byte). The field may be set to 0.
402407
avc1.depth = 0x0018; //takes one of the following values 0x0018 – images are in colour with no alpha.

app/js/streaming/SourceBufferExtensions.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,15 @@ MediaPlayer.dependencies.SourceBufferExtensions.prototype = {
223223
if ((start >= 0) && (start < duration) && (end > start) && (mediaSource.readyState !== "ended")) {
224224
buffer.remove(start, end);
225225
}
226+
227+
//workaround in order to remove all the cues in the textTrack from the video element.
228+
//end parameter equals the video.duration. The use case of a dash stream with a full TTML subtitles file has an issue because video duration could be NaN. It occurs
229+
//after the manifest has been parsed, a call to MediaSource.setDuration is made but after a few ms, a duration change event occurs with a value of NaN. The origin of this issue may be
230+
//that no media segments have been pushed.
231+
//So, all the buffer is removed.
232+
if (isNaN(end) && (mediaSource.readyState !== "ended")) {
233+
buffer.remove(start);
234+
}
226235

227236
if (sync) {
228237
deferred.resolve();

app/js/streaming/Stream.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,7 @@ MediaPlayer.dependencies.Stream = function() {
955955
reloadTimeout = null;
956956
//pause.call(self);
957957
self.system.notify("manifestUpdate", true);
958+
stopFragmentInfoControllers.call(self);
958959
}, delay * 1000);
959960
} else {
960961
// For VOD streams, we seek at recovery time
@@ -1249,8 +1250,10 @@ MediaPlayer.dependencies.Stream = function() {
12491250
streamsComposed.call(this);
12501251
}
12511252
// show subtitle here => useful for full TTML file
1252-
if (track && track.mode !== 'showing') {
1253+
if (track && track.kind !== 'metadata' && track.mode !== 'showing') {
12531254
track.mode = "showing";
1255+
}else if (track) {
1256+
track.mode = "hidden";
12541257
}
12551258
} else {
12561259
if (fragmentInfoTextController) {

app/js/streaming/VideoModel.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,6 @@ MediaPlayer.models.VideoModel = function () {
152152
TTMLRenderingDiv.style.pointerEvents = 'none';
153153
TTMLRenderingDiv.style.top = 0;
154154
TTMLRenderingDiv.style.left = 0;
155-
TTMLRenderingDiv.style.width = '100%';
156-
TTMLRenderingDiv.style.height = '100%';
157155
},
158156

159157
stallStream: stallStream

0 commit comments

Comments
 (0)