pageflow 12.0.1 → 12.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pageflow might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/app/assets/javascripts/pageflow/dist/react.js +5 -1
- data/app/assets/javascripts/pageflow/editor/initializers/setup_file_types.js +1 -1
- data/app/assets/javascripts/pageflow/video_player/cue_settings_methods.js +2 -1
- data/db/migrate/20170913105048_fix_hls_output_presences_for_legacy_video_files.rb +12 -0
- data/lib/pageflow/version.rb +1 -1
- data/vendor/assets/javascripts/jquery.fullscreen.js +5 -63
- data/vendor/assets/javascripts/videojs-dash.js +457 -123
- data/vendor/assets/javascripts/videojs.js +19568 -21534
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56358a772f2ffd39c8ff1e923381474a84e7479d
|
4
|
+
data.tar.gz: 24450abb51ff9fda63c25df4e1a1886bf015636c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ba66d120beb537080abf0eb7ad8e9d6c8ac623de3f215a41d2796ba58d70aae9c611666458c5666d2da36df7146dc6df03edf5c17b82b4b509782ac4f657835
|
7
|
+
data.tar.gz: 1dad4196be1ce9d5f2fd5cdc9e2d90462193503277377408d2d48772fe73ec40235f24a9e1ad752ef96c41ce1e291d9f25e9eaf7d6bf79985b7c47fc834ac89a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
### Version 12.0.2
|
4
|
+
|
5
|
+
2017-09-13
|
6
|
+
|
7
|
+
[Compare changes](https://github.com/codevise/pageflow/compare/v12.0.1...v12.0.2)
|
8
|
+
|
9
|
+
#### Manual Update Step
|
10
|
+
|
11
|
+
The database migration for Pageflow 12.0 which updates output
|
12
|
+
presences of existing video files is missing the HLS variant. This
|
13
|
+
causes HLS urls of existing video files to be rendered as `undefined`.
|
14
|
+
([#870](https://github.com/codevise/pageflow/pull/870))
|
15
|
+
|
16
|
+
To apply the fix, install migrations and migrate your database.
|
17
|
+
|
18
|
+
#### Bug Fixes
|
19
|
+
|
20
|
+
- Update videojs and videojs-dash to improve Dash playback
|
21
|
+
([#843](https://github.com/codevise/pageflow/pull/843))
|
22
|
+
- Bug fix: Prevent calling `localeCompare` of null.
|
23
|
+
([#865](https://github.com/codevise/pageflow/pull/865))
|
24
|
+
- Bug fix: Prevent background videos from stopping on fullscreen toggle
|
25
|
+
([#864](https://github.com/codevise/pageflow/pull/864))
|
26
|
+
- Bug fix: Activate text track after it has been added
|
27
|
+
([#859](https://github.com/codevise/pageflow/pull/859))
|
28
|
+
- Bug fix: Fix file type detection for vtt uploads on safari
|
29
|
+
([#851](https://github.com/codevise/pageflow/pull/851))
|
30
|
+
|
3
31
|
### Version 12.0.1
|
4
32
|
|
5
33
|
2017-08-25
|
@@ -23081,7 +23081,7 @@ pageflow = typeof pageflow === "object" ? pageflow : {}; pageflow["react"] =
|
|
23081
23081
|
|
23082
23082
|
return {
|
23083
23083
|
files: files.sort(function (file1, file2) {
|
23084
|
-
return file1.displayLabel.localeCompare(file2.displayLabel);
|
23084
|
+
return (file1.displayLabel || '').localeCompare(file2.displayLabel || '');
|
23085
23085
|
}),
|
23086
23086
|
autoFile: autoFile,
|
23087
23087
|
activeFileId: getActiveTextTrackFileId(files, autoFile, textTrackSettings),
|
@@ -24102,6 +24102,10 @@ pageflow = typeof pageflow === "object" ? pageflow : {}; pageflow["react"] =
|
|
24102
24102
|
updateOnNextPlay(player, getActiveTexTrackFileId, getPosition);
|
24103
24103
|
});
|
24104
24104
|
|
24105
|
+
player.textTracks().on('addtrack', function () {
|
24106
|
+
updateTextTracks(player, null, getActiveTexTrackFileId(), getPosition());
|
24107
|
+
});
|
24108
|
+
|
24105
24109
|
updateTextTracks(player, null, getActiveTexTrackFileId(), getPosition());
|
24106
24110
|
updateOnNextPlay(player, getActiveTexTrackFileId, getPosition);
|
24107
24111
|
}
|
@@ -85,7 +85,7 @@ pageflow.app.addInitializer(function(options) {
|
|
85
85
|
pageflow.editor.fileTypes.register('text_track_files', {
|
86
86
|
model: pageflow.TextTrackFile,
|
87
87
|
matchUpload: function(upload) {
|
88
|
-
return upload.
|
88
|
+
return upload.name.match(/\.vtt$/) ||
|
89
89
|
upload.name.match(/\.srt$/);
|
90
90
|
},
|
91
91
|
skipUploadConfirmation: true,
|
@@ -50,7 +50,8 @@ pageflow.VideoPlayer.cueSettingsMethods = function(player) {
|
|
50
50
|
// for a cue even though the previous call had the same
|
51
51
|
// parameters.
|
52
52
|
if ((this.prevLine !== line || changed) && (command != 'lazy')) {
|
53
|
-
player.tech({IWillNotUseThisInPlugins: true})
|
53
|
+
var tech = player.tech({IWillNotUseThisInPlugins: true});
|
54
|
+
tech && tech.trigger('texttrackchange');
|
54
55
|
}
|
55
56
|
|
56
57
|
this.prevLine = line;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class FixHlsOutputPresencesForLegacyVideoFiles < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
execute(<<-SQL)
|
4
|
+
UPDATE pageflow_video_files
|
5
|
+
SET output_presences = '{"high":true,"medium":true,"low":true,"hls-playlist":true}'
|
6
|
+
WHERE output_presences = '{"high":true,"medium":true,"low":true}';
|
7
|
+
SQL
|
8
|
+
end
|
9
|
+
|
10
|
+
def down
|
11
|
+
end
|
12
|
+
end
|
data/lib/pageflow/version.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
*/
|
8
8
|
|
9
9
|
/*jshint browser: true, jquery: true */
|
10
|
+
// We shrank the plugin so that it contains only what Pageflow needs.
|
10
11
|
(function($){
|
11
12
|
"use strict";
|
12
13
|
|
@@ -50,17 +51,6 @@
|
|
50
51
|
$(document).on("fullscreenchange mozfullscreenchange webkitfullscreenchange", function(){
|
51
52
|
// The full screen status is automatically
|
52
53
|
// passed to our callback as an argument.
|
53
|
-
|
54
|
-
|
55
|
-
// Customized for Pageflow-Background-Audio
|
56
|
-
|
57
|
-
if(pageflow.activeBackgroundVideo) {
|
58
|
-
setTimeout(function() {
|
59
|
-
if(pageflow.activeBackgroundVideo.paused() && !pageflow.features.has('mobile platform')) {
|
60
|
-
pageflow.activeBackgroundVideo.play();
|
61
|
-
}
|
62
|
-
}, 300);
|
63
|
-
}
|
64
54
|
callback(fullScreenStatus());
|
65
55
|
});
|
66
56
|
}
|
@@ -69,7 +59,7 @@
|
|
69
59
|
$.support.fullscreen = supportFullScreen();
|
70
60
|
|
71
61
|
// Creating the plugin
|
72
|
-
$.fn.fullScreen = function(
|
62
|
+
$.fn.fullScreen = function(options){
|
73
63
|
if(!$.support.fullscreen || this.length !== 1) {
|
74
64
|
// The plugin can be called only
|
75
65
|
// on one element at a time
|
@@ -83,46 +73,9 @@
|
|
83
73
|
return this;
|
84
74
|
}
|
85
75
|
|
86
|
-
|
87
|
-
// for the background and a callback function
|
88
|
-
|
89
|
-
var options = $.extend({
|
90
|
-
'background' : '#111',
|
91
|
-
'callback' : $.noop( ),
|
92
|
-
'fullscreenClass' : 'fullScreen'
|
93
|
-
}, props),
|
94
|
-
|
95
|
-
elem = this,
|
96
|
-
|
97
|
-
// This temporary div is the element that is
|
98
|
-
// actually going to be enlarged in full screen
|
99
|
-
|
100
|
-
fs = $('<div>', {
|
101
|
-
'css' : {
|
102
|
-
'overflow-y' : 'auto',
|
103
|
-
'background' : options.background,
|
104
|
-
'width' : '100%',
|
105
|
-
'height' : '100%'
|
106
|
-
}
|
107
|
-
})
|
108
|
-
.insertBefore(elem)
|
109
|
-
.append(elem);
|
110
|
-
|
111
|
-
// You can use the .fullScreen class to
|
112
|
-
// apply styling to your element
|
113
|
-
elem.addClass( options.fullscreenClass );
|
76
|
+
var elem = this;
|
114
77
|
|
115
|
-
|
116
|
-
// div, after which we zoom it in fullscreen
|
117
|
-
|
118
|
-
requestFullScreen(fs.get(0));
|
119
|
-
|
120
|
-
fs.click(function(e){
|
121
|
-
if(e.target == this){
|
122
|
-
// If the black bar was clicked
|
123
|
-
cancelFullScreen();
|
124
|
-
}
|
125
|
-
});
|
78
|
+
requestFullScreen(elem.get(0));
|
126
79
|
|
127
80
|
elem.cancel = function(){
|
128
81
|
cancelFullScreen();
|
@@ -134,14 +87,9 @@
|
|
134
87
|
// We have exited full screen.
|
135
88
|
// Detach event listener
|
136
89
|
$(document).off( 'fullscreenchange mozfullscreenchange webkitfullscreenchange' );
|
137
|
-
// Remove the class and destroy
|
138
|
-
// the temporary div
|
139
|
-
|
140
|
-
elem.removeClass( options.fullscreenClass ).insertBefore(fs);
|
141
|
-
fs.remove();
|
142
90
|
}
|
143
91
|
|
144
|
-
// Calling
|
92
|
+
// Calling callback if user provided it
|
145
93
|
if(options.callback) {
|
146
94
|
options.callback(fullScreen);
|
147
95
|
}
|
@@ -149,10 +97,4 @@
|
|
149
97
|
|
150
98
|
return elem;
|
151
99
|
};
|
152
|
-
|
153
|
-
$.fn.cancelFullScreen = function( ) {
|
154
|
-
cancelFullScreen();
|
155
|
-
|
156
|
-
return this;
|
157
|
-
};
|
158
100
|
}(jQuery));
|
@@ -1,14 +1,318 @@
|
|
1
|
-
|
2
|
-
*
|
3
|
-
|
1
|
+
/**
|
2
|
+
* videojs-contrib-dash
|
3
|
+
* @version 2.9.1
|
4
|
+
* @copyright 2017 Brightcove, Inc
|
5
|
+
* @license Apache-2.0
|
6
|
+
*/
|
7
|
+
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojsDash = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
4
8
|
(function (global){
|
5
9
|
'use strict';
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
11
|
+
exports.__esModule = true;
|
12
|
+
exports['default'] = setupAudioTracks;
|
13
|
+
|
14
|
+
var _dashjs = (typeof window !== "undefined" ? window['dashjs'] : typeof global !== "undefined" ? global['dashjs'] : null);
|
15
|
+
|
16
|
+
var _dashjs2 = _interopRequireDefault(_dashjs);
|
17
|
+
|
18
|
+
var _video = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null);
|
19
|
+
|
20
|
+
var _video2 = _interopRequireDefault(_video);
|
10
21
|
|
11
|
-
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
23
|
+
|
24
|
+
/**
|
25
|
+
* Setup audio tracks. Take the tracks from dash and add the tracks to videojs. Listen for when
|
26
|
+
* videojs changes tracks and apply that to the dash player because videojs doesn't do this
|
27
|
+
* natively.
|
28
|
+
*
|
29
|
+
* @private
|
30
|
+
* @param {videojs} player the videojs player instance
|
31
|
+
* @param {videojs.tech} tech the videojs tech being used
|
32
|
+
*/
|
33
|
+
function handlePlaybackMetadataLoaded(player, tech) {
|
34
|
+
var mediaPlayer = player.dash.mediaPlayer;
|
35
|
+
|
36
|
+
var dashAudioTracks = mediaPlayer.getTracksFor('audio');
|
37
|
+
var videojsAudioTracks = player.audioTracks();
|
38
|
+
|
39
|
+
function generateIdFromTrackIndex(index) {
|
40
|
+
return 'dash-audio-' + index;
|
41
|
+
}
|
42
|
+
|
43
|
+
function findDashAudioTrack(dashAudioTracks, videojsAudioTrack) {
|
44
|
+
return dashAudioTracks.find(function (_ref) {
|
45
|
+
var index = _ref.index;
|
46
|
+
return generateIdFromTrackIndex(index) === videojsAudioTrack.id;
|
47
|
+
});
|
48
|
+
}
|
49
|
+
|
50
|
+
// Safari creates a single native `AudioTrack` (not `videojs.AudioTrack`) when loading. Clear all
|
51
|
+
// automatically generated audio tracks so we can create them all ourself.
|
52
|
+
if (videojsAudioTracks.length) {
|
53
|
+
tech.clearTracks(['audio']);
|
54
|
+
}
|
55
|
+
|
56
|
+
var currentAudioTrack = mediaPlayer.getCurrentTrackFor('audio');
|
57
|
+
|
58
|
+
dashAudioTracks.forEach(function (dashTrack) {
|
59
|
+
var label = dashTrack.lang;
|
60
|
+
|
61
|
+
if (dashTrack.roles && dashTrack.roles.length) {
|
62
|
+
label += ' (' + dashTrack.roles.join(', ') + ')';
|
63
|
+
}
|
64
|
+
|
65
|
+
// Add the track to the player's audio track list.
|
66
|
+
videojsAudioTracks.addTrack(new _video2['default'].AudioTrack({
|
67
|
+
enabled: dashTrack === currentAudioTrack,
|
68
|
+
id: generateIdFromTrackIndex(dashTrack.index),
|
69
|
+
kind: dashTrack.kind || 'main',
|
70
|
+
label: label,
|
71
|
+
language: dashTrack.lang
|
72
|
+
}));
|
73
|
+
});
|
74
|
+
|
75
|
+
videojsAudioTracks.addEventListener('change', function () {
|
76
|
+
for (var i = 0; i < videojsAudioTracks.length; i++) {
|
77
|
+
var track = videojsAudioTracks[i];
|
78
|
+
|
79
|
+
if (track.enabled) {
|
80
|
+
// Find the audio track we just selected by the id
|
81
|
+
var dashAudioTrack = findDashAudioTrack(dashAudioTracks, track);
|
82
|
+
|
83
|
+
// Set is as the current track
|
84
|
+
mediaPlayer.setCurrentTrack(dashAudioTrack);
|
85
|
+
|
86
|
+
// Stop looping
|
87
|
+
continue;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
});
|
91
|
+
}
|
92
|
+
|
93
|
+
/*
|
94
|
+
* Call `handlePlaybackMetadataLoaded` when `mediaPlayer` emits
|
95
|
+
* `dashjs.MediaPlayer.events.PLAYBACK_METADATA_LOADED`.
|
96
|
+
*/
|
97
|
+
function setupAudioTracks(player, tech) {
|
98
|
+
// When `dashjs` finishes loading metadata, create audio tracks for `video.js`.
|
99
|
+
player.dash.mediaPlayer.on(_dashjs2['default'].MediaPlayer.events.PLAYBACK_METADATA_LOADED, handlePlaybackMetadataLoaded.bind(null, player, tech));
|
100
|
+
}
|
101
|
+
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
102
|
+
},{}],2:[function(require,module,exports){
|
103
|
+
(function (global){
|
104
|
+
'use strict';
|
105
|
+
|
106
|
+
exports.__esModule = true;
|
107
|
+
exports['default'] = setupTextTracks;
|
108
|
+
|
109
|
+
var _dashjs = (typeof window !== "undefined" ? window['dashjs'] : typeof global !== "undefined" ? global['dashjs'] : null);
|
110
|
+
|
111
|
+
var _dashjs2 = _interopRequireDefault(_dashjs);
|
112
|
+
|
113
|
+
var _video = (typeof window !== "undefined" ? window['videojs'] : typeof global !== "undefined" ? global['videojs'] : null);
|
114
|
+
|
115
|
+
var _video2 = _interopRequireDefault(_video);
|
116
|
+
|
117
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
118
|
+
|
119
|
+
function find(l, f) {
|
120
|
+
for (var i = 0; i < l.length; i++) {
|
121
|
+
if (f(l[i])) {
|
122
|
+
return l[i];
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
/*
|
128
|
+
* Attach text tracks from dash.js to videojs
|
129
|
+
*
|
130
|
+
* @param {videojs} player the videojs player instance
|
131
|
+
* @param {array} tracks the tracks loaded by dash.js to attach to videojs
|
132
|
+
*
|
133
|
+
* @private
|
134
|
+
*/
|
135
|
+
function attachDashTextTracksToVideojs(player, tech, tracks) {
|
136
|
+
var trackDictionary = [];
|
137
|
+
|
138
|
+
// Add remote tracks
|
139
|
+
var tracksAttached = tracks
|
140
|
+
// Map input data to match HTMLTrackElement spec
|
141
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLTrackElement
|
142
|
+
.map(function (track) {
|
143
|
+
return {
|
144
|
+
dashTrack: track,
|
145
|
+
trackConfig: {
|
146
|
+
label: track.lang,
|
147
|
+
language: track.lang,
|
148
|
+
srclang: track.lang
|
149
|
+
}
|
150
|
+
};
|
151
|
+
}
|
152
|
+
|
153
|
+
// Add track to videojs track list
|
154
|
+
).map(function (_ref) {
|
155
|
+
var trackConfig = _ref.trackConfig,
|
156
|
+
dashTrack = _ref.dashTrack;
|
157
|
+
|
158
|
+
var remoteTextTrack = player.addRemoteTextTrack(trackConfig, true);
|
159
|
+
trackDictionary.push({ textTrack: remoteTextTrack.track, dashTrack: dashTrack });
|
160
|
+
|
161
|
+
// Don't add the cues becuase we're going to let dash handle it natively. This will ensure
|
162
|
+
// that dash handle external time text files and fragmented text tracks.
|
163
|
+
//
|
164
|
+
// Example file with external time text files:
|
165
|
+
// https://storage.googleapis.com/shaka-demo-assets/sintel-mp4-wvtt/dash.mpd
|
166
|
+
|
167
|
+
return remoteTextTrack;
|
168
|
+
});
|
169
|
+
|
170
|
+
/*
|
171
|
+
* Scan `videojs.textTracks()` to find one that is showing. Set the dash text track.
|
172
|
+
*/
|
173
|
+
function updateActiveDashTextTrack() {
|
174
|
+
var dashMediaPlayer = player.dash.mediaPlayer;
|
175
|
+
var textTracks = player.textTracks();
|
176
|
+
var activeTextTrackIndex = -1;
|
177
|
+
|
178
|
+
// Iterate through the tracks and find the one marked as showing. If none are showing,
|
179
|
+
// `activeTextTrackIndex` will be set to `-1`, disabling text tracks.
|
180
|
+
|
181
|
+
var _loop = function _loop(i) {
|
182
|
+
var textTrack = textTracks[i];
|
183
|
+
|
184
|
+
if (textTrack.mode === 'showing') {
|
185
|
+
// Find the dash track we want to use
|
186
|
+
|
187
|
+
/* jshint loopfunc: true */
|
188
|
+
var dictionaryLookupResult = find(trackDictionary, function (track) {
|
189
|
+
return track.textTrack === textTrack;
|
190
|
+
});
|
191
|
+
/* jshint loopfunc: false */
|
192
|
+
|
193
|
+
var dashTrackToActivate = dictionaryLookupResult ? dictionaryLookupResult.dashTrack : null;
|
194
|
+
|
195
|
+
// If we found a track, get it's index.
|
196
|
+
if (dashTrackToActivate) {
|
197
|
+
activeTextTrackIndex = tracks.indexOf(dashTrackToActivate);
|
198
|
+
}
|
199
|
+
}
|
200
|
+
};
|
201
|
+
|
202
|
+
for (var i = 0; i < textTracks.length; i += 1) {
|
203
|
+
_loop(i);
|
204
|
+
}
|
205
|
+
|
206
|
+
// If the text track has changed, then set it in dash
|
207
|
+
if (activeTextTrackIndex !== dashMediaPlayer.getCurrentTextTrackIndex()) {
|
208
|
+
dashMediaPlayer.setTextTrack(activeTextTrackIndex);
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
// Update dash when videojs's selected text track changes.
|
213
|
+
player.textTracks().on('change', updateActiveDashTextTrack);
|
214
|
+
|
215
|
+
// Cleanup event listeners whenever we start loading a new source
|
216
|
+
player.one('loadstart', function () {
|
217
|
+
player.textTracks().off('change', updateActiveDashTextTrack);
|
218
|
+
});
|
219
|
+
|
220
|
+
// Initialize the text track on our first run-through
|
221
|
+
updateActiveDashTextTrack();
|
222
|
+
|
223
|
+
return tracksAttached;
|
224
|
+
}
|
225
|
+
|
226
|
+
/*
|
227
|
+
* Wait for dash to emit `TEXT_TRACKS_ADDED` and then attach the text tracks loaded by dash if
|
228
|
+
* we're not using native text tracks.
|
229
|
+
*
|
230
|
+
* @param {videojs} player the videojs player instance
|
231
|
+
* @private
|
232
|
+
*/
|
233
|
+
function setupTextTracks(player, tech, options) {
|
234
|
+
// Clear VTTCue if it was shimmed by vttjs and let dash.js use TextTrackCue.
|
235
|
+
// This is necessary because dash.js creates text tracks
|
236
|
+
// using addTextTrack which is incompatible with vttjs.VTTCue in IE11
|
237
|
+
if (window.VTTCue && !/\[native code\]/.test(window.VTTCue.toString())) {
|
238
|
+
window.VTTCue = false;
|
239
|
+
}
|
240
|
+
|
241
|
+
// Store the tracks that we've added so we can remove them later.
|
242
|
+
var dashTracksAttachedToVideoJs = [];
|
243
|
+
|
244
|
+
// We're relying on the user to disable native captions. Show an error if they didn't do so.
|
245
|
+
if (tech.featuresNativeTextTracks) {
|
246
|
+
_video2['default'].log.error('You must pass {html: {nativeCaptions: false}} in the videojs constructor ' + 'to use text tracks in videojs-contrib-dash');
|
247
|
+
return;
|
248
|
+
}
|
249
|
+
|
250
|
+
var mediaPlayer = player.dash.mediaPlayer;
|
251
|
+
|
252
|
+
// Clear the tracks that we added. We don't clear them all because someone else can add tracks.
|
253
|
+
function clearDashTracks() {
|
254
|
+
dashTracksAttachedToVideoJs.forEach(player.removeRemoteTextTrack.bind(player));
|
255
|
+
|
256
|
+
dashTracksAttachedToVideoJs = [];
|
257
|
+
}
|
258
|
+
|
259
|
+
function handleTextTracksAdded(_ref2) {
|
260
|
+
var index = _ref2.index,
|
261
|
+
tracks = _ref2.tracks;
|
262
|
+
|
263
|
+
// Stop listening for this event. We only want to hear it once.
|
264
|
+
mediaPlayer.off(_dashjs2['default'].MediaPlayer.events.TEXT_TRACKS_ADDED, handleTextTracksAdded);
|
265
|
+
|
266
|
+
// Cleanup old tracks
|
267
|
+
clearDashTracks();
|
268
|
+
|
269
|
+
if (!tracks.length) {
|
270
|
+
// Don't try to add text tracks if there aren't any
|
271
|
+
return;
|
272
|
+
}
|
273
|
+
|
274
|
+
// Save the tracks so we can remove them later
|
275
|
+
dashTracksAttachedToVideoJs = attachDashTextTracksToVideojs(player, tech, tracks, options);
|
276
|
+
}
|
277
|
+
|
278
|
+
// Attach dash text tracks whenever we dash emits `TEXT_TRACKS_ADDED`.
|
279
|
+
mediaPlayer.on(_dashjs2['default'].MediaPlayer.events.TEXT_TRACKS_ADDED, handleTextTracksAdded);
|
280
|
+
|
281
|
+
function cleanup() {
|
282
|
+
mediaPlayer.off(_dashjs2['default'].MediaPlayer.events.TEXT_TRACKS_ADDED, handleTextTracksAdded);
|
283
|
+
|
284
|
+
player.one('loadstart', clearDashTracks);
|
285
|
+
}
|
286
|
+
|
287
|
+
// When the player can play, remove the initialization events. We might not have received
|
288
|
+
// TEXT_TRACKS_ADDED` so we have to stop listening for it or we'll get errors when we load new
|
289
|
+
// videos and are listening for the same event in multiple places, including cleaned up
|
290
|
+
// mediaPlayers.
|
291
|
+
mediaPlayer.on(_dashjs2['default'].MediaPlayer.events.CAN_PLAY, cleanup);
|
292
|
+
}
|
293
|
+
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
294
|
+
},{}],3:[function(require,module,exports){
|
295
|
+
(function (global){
|
296
|
+
var win;
|
297
|
+
|
298
|
+
if (typeof window !== "undefined") {
|
299
|
+
win = window;
|
300
|
+
} else if (typeof global !== "undefined") {
|
301
|
+
win = global;
|
302
|
+
} else if (typeof self !== "undefined"){
|
303
|
+
win = self;
|
304
|
+
} else {
|
305
|
+
win = {};
|
306
|
+
}
|
307
|
+
|
308
|
+
module.exports = win;
|
309
|
+
|
310
|
+
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
311
|
+
},{}],4:[function(require,module,exports){
|
312
|
+
(function (global){
|
313
|
+
'use strict';
|
314
|
+
|
315
|
+
exports.__esModule = true;
|
12
316
|
|
13
317
|
var _window = require('global/window');
|
14
318
|
|
@@ -22,20 +326,23 @@ var _dashjs = (typeof window !== "undefined" ? window['dashjs'] : typeof global
|
|
22
326
|
|
23
327
|
var _dashjs2 = _interopRequireDefault(_dashjs);
|
24
328
|
|
25
|
-
|
329
|
+
var _setupAudioTracks = require('./setup-audio-tracks');
|
26
330
|
|
27
|
-
|
331
|
+
var _setupAudioTracks2 = _interopRequireDefault(_setupAudioTracks);
|
28
332
|
|
29
|
-
var
|
30
|
-
|
31
|
-
|
333
|
+
var _setupTextTracks = require('./setup-text-tracks');
|
334
|
+
|
335
|
+
var _setupTextTracks2 = _interopRequireDefault(_setupTextTracks);
|
336
|
+
|
337
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
338
|
+
|
339
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
32
340
|
|
33
341
|
/**
|
34
342
|
* videojs-contrib-dash
|
35
343
|
*
|
36
344
|
* Use Dash.js to playback DASH content inside of Video.js via a SourceHandler
|
37
345
|
*/
|
38
|
-
|
39
346
|
var Html5DashJS = function () {
|
40
347
|
function Html5DashJS(source, tech, options) {
|
41
348
|
var _this = this;
|
@@ -45,7 +352,7 @@ var Html5DashJS = function () {
|
|
45
352
|
// Get options from tech if not provided for backwards compatibility
|
46
353
|
options = options || tech.options_;
|
47
354
|
|
48
|
-
this.player = (0, _video2
|
355
|
+
this.player = (0, _video2['default'])(options.playerId);
|
49
356
|
this.player.dash = this.player.dash || {};
|
50
357
|
|
51
358
|
this.tech_ = tech;
|
@@ -63,7 +370,7 @@ var Html5DashJS = function () {
|
|
63
370
|
tech.isReady_ = false;
|
64
371
|
|
65
372
|
if (Html5DashJS.updateSourceData) {
|
66
|
-
_video2
|
373
|
+
_video2['default'].log.warn('updateSourceData has been deprecated.' + ' Please switch to using hook("updatesource", callback).');
|
67
374
|
source = Html5DashJS.updateSourceData(source);
|
68
375
|
}
|
69
376
|
|
@@ -75,18 +382,18 @@ var Html5DashJS = function () {
|
|
75
382
|
var manifestSource = source.src;
|
76
383
|
this.keySystemOptions_ = Html5DashJS.buildDashJSProtData(source.keySystemOptions);
|
77
384
|
|
78
|
-
this.player.dash.mediaPlayer = _dashjs2
|
385
|
+
this.player.dash.mediaPlayer = _dashjs2['default'].MediaPlayer().create();
|
79
386
|
|
80
387
|
this.mediaPlayer_ = this.player.dash.mediaPlayer;
|
81
388
|
|
82
389
|
// Log MedaPlayer messages through video.js
|
83
390
|
if (Html5DashJS.useVideoJSDebug) {
|
84
|
-
_video2
|
391
|
+
_video2['default'].log.warn('useVideoJSDebug has been deprecated.' + ' Please switch to using hook("beforeinitialize", callback).');
|
85
392
|
Html5DashJS.useVideoJSDebug(this.mediaPlayer_);
|
86
393
|
}
|
87
394
|
|
88
395
|
if (Html5DashJS.beforeInitialize) {
|
89
|
-
_video2
|
396
|
+
_video2['default'].log.warn('beforeInitialize has been deprecated.' + ' Please switch to using hook("beforeinitialize", callback).');
|
90
397
|
Html5DashJS.beforeInitialize(this.player, this.mediaPlayer_);
|
91
398
|
}
|
92
399
|
|
@@ -98,11 +405,35 @@ var Html5DashJS = function () {
|
|
98
405
|
// element to bind to.
|
99
406
|
this.mediaPlayer_.initialize();
|
100
407
|
|
101
|
-
// Apply
|
102
|
-
if (options.dash
|
103
|
-
|
104
|
-
|
105
|
-
|
408
|
+
// Apply all dash options that are set
|
409
|
+
if (options.dash) {
|
410
|
+
Object.keys(options.dash).forEach(function (key) {
|
411
|
+
var _mediaPlayer_;
|
412
|
+
|
413
|
+
var dashOptionsKey = 'set' + key.charAt(0).toUpperCase() + key.slice(1);
|
414
|
+
var value = options.dash[key];
|
415
|
+
|
416
|
+
if (_this.mediaPlayer_.hasOwnProperty(dashOptionsKey)) {
|
417
|
+
// Providing a key without `set` prefix is now deprecated.
|
418
|
+
_video2['default'].log.warn('Using dash options in videojs-contrib-dash without the set prefix ' + ('has been deprecated. Change \'' + key + '\' to \'' + dashOptionsKey + '\''));
|
419
|
+
|
420
|
+
// Set key so it will still work
|
421
|
+
key = dashOptionsKey;
|
422
|
+
}
|
423
|
+
|
424
|
+
if (!_this.mediaPlayer_.hasOwnProperty(key)) {
|
425
|
+
_video2['default'].log.warn('Warning: dash configuration option unrecognized: ' + key);
|
426
|
+
|
427
|
+
return;
|
428
|
+
}
|
429
|
+
|
430
|
+
// Guarantee `value` is an array
|
431
|
+
if (!Array.isArray(value)) {
|
432
|
+
value = [value];
|
433
|
+
}
|
434
|
+
|
435
|
+
(_mediaPlayer_ = _this.mediaPlayer_)[key].apply(_mediaPlayer_, value);
|
436
|
+
});
|
106
437
|
}
|
107
438
|
|
108
439
|
this.mediaPlayer_.attachView(this.el_);
|
@@ -110,6 +441,12 @@ var Html5DashJS = function () {
|
|
110
441
|
// Dash.js autoplays by default, video.js will handle autoplay
|
111
442
|
this.mediaPlayer_.setAutoPlay(false);
|
112
443
|
|
444
|
+
// Setup audio tracks
|
445
|
+
_setupAudioTracks2['default'].call(null, this.player, tech);
|
446
|
+
|
447
|
+
// Setup text tracks
|
448
|
+
_setupTextTracks2['default'].call(null, this.player, tech, options);
|
449
|
+
|
113
450
|
// Attach the source with any protection data
|
114
451
|
this.mediaPlayer_.setProtectionData(this.keySystemOptions_);
|
115
452
|
this.mediaPlayer_.attachSource(manifestSource);
|
@@ -125,100 +462,101 @@ var Html5DashJS = function () {
|
|
125
462
|
*/
|
126
463
|
|
127
464
|
|
128
|
-
|
129
|
-
|
130
|
-
value: function dispose() {
|
131
|
-
if (this.mediaPlayer_) {
|
132
|
-
this.mediaPlayer_.reset();
|
133
|
-
}
|
465
|
+
Html5DashJS.buildDashJSProtData = function buildDashJSProtData(keySystemOptions) {
|
466
|
+
var output = {};
|
134
467
|
|
135
|
-
|
136
|
-
|
137
|
-
}
|
468
|
+
if (!keySystemOptions || !Array.isArray(keySystemOptions)) {
|
469
|
+
return null;
|
138
470
|
}
|
139
471
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
* @param {string} type the lifecycle to get hooks from
|
144
|
-
* @param {Function=|Function[]=} hook Optionally add a hook tothe lifecycle
|
145
|
-
* @return {Array} an array of hooks or epty if none
|
146
|
-
* @method hooks
|
147
|
-
*/
|
148
|
-
|
149
|
-
}], [{
|
150
|
-
key: 'buildDashJSProtData',
|
151
|
-
value: function buildDashJSProtData(keySystemOptions) {
|
152
|
-
var output = {};
|
153
|
-
|
154
|
-
if (!keySystemOptions || !isArray(keySystemOptions)) {
|
155
|
-
return null;
|
156
|
-
}
|
472
|
+
for (var i = 0; i < keySystemOptions.length; i++) {
|
473
|
+
var keySystem = keySystemOptions[i];
|
474
|
+
var options = _video2['default'].mergeOptions({}, keySystem.options);
|
157
475
|
|
158
|
-
|
159
|
-
|
160
|
-
|
476
|
+
if (options.licenseUrl) {
|
477
|
+
options.serverURL = options.licenseUrl;
|
478
|
+
delete options.licenseUrl;
|
479
|
+
}
|
161
480
|
|
162
|
-
|
163
|
-
|
164
|
-
delete options.licenseUrl;
|
165
|
-
}
|
481
|
+
output[keySystem.name] = options;
|
482
|
+
}
|
166
483
|
|
167
|
-
|
168
|
-
|
484
|
+
return output;
|
485
|
+
};
|
169
486
|
|
170
|
-
|
487
|
+
Html5DashJS.prototype.dispose = function dispose() {
|
488
|
+
if (this.mediaPlayer_) {
|
489
|
+
this.mediaPlayer_.reset();
|
171
490
|
}
|
172
|
-
}, {
|
173
|
-
key: 'hooks',
|
174
|
-
value: function hooks(type, hook) {
|
175
|
-
Html5DashJS.hooks_[type] = Html5DashJS.hooks_[type] || [];
|
176
491
|
|
177
|
-
|
178
|
-
|
179
|
-
|
492
|
+
if (this.player.dash) {
|
493
|
+
delete this.player.dash;
|
494
|
+
}
|
495
|
+
};
|
180
496
|
|
181
|
-
|
497
|
+
Html5DashJS.prototype.duration = function duration() {
|
498
|
+
var duration = this.el_.duration;
|
499
|
+
if (duration === Number.MAX_VALUE) {
|
500
|
+
return Infinity;
|
182
501
|
}
|
502
|
+
return duration;
|
503
|
+
};
|
504
|
+
|
505
|
+
/**
|
506
|
+
* Get a list of hooks for a specific lifecycle
|
507
|
+
*
|
508
|
+
* @param {string} type the lifecycle to get hooks from
|
509
|
+
* @param {Function=|Function[]=} hook Optionally add a hook tothe lifecycle
|
510
|
+
* @return {Array} an array of hooks or epty if none
|
511
|
+
* @method hooks
|
512
|
+
*/
|
513
|
+
|
183
514
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
* @method hook
|
190
|
-
*/
|
191
|
-
|
192
|
-
}, {
|
193
|
-
key: 'hook',
|
194
|
-
value: function hook(type, _hook) {
|
195
|
-
Html5DashJS.hooks(type, _hook);
|
515
|
+
Html5DashJS.hooks = function hooks(type, hook) {
|
516
|
+
Html5DashJS.hooks_[type] = Html5DashJS.hooks_[type] || [];
|
517
|
+
|
518
|
+
if (hook) {
|
519
|
+
Html5DashJS.hooks_[type] = Html5DashJS.hooks_[type].concat(hook);
|
196
520
|
}
|
197
521
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
522
|
+
return Html5DashJS.hooks_[type];
|
523
|
+
};
|
524
|
+
|
525
|
+
/**
|
526
|
+
* Add a function hook to a specific dash lifecycle
|
527
|
+
*
|
528
|
+
* @param {string} type the lifecycle to hook the function to
|
529
|
+
* @param {Function|Function[]} hook the function or array of functions to attach
|
530
|
+
* @method hook
|
531
|
+
*/
|
532
|
+
|
533
|
+
|
534
|
+
Html5DashJS.hook = function hook(type, _hook) {
|
535
|
+
Html5DashJS.hooks(type, _hook);
|
536
|
+
};
|
537
|
+
|
538
|
+
/**
|
539
|
+
* Remove a hook from a specific dash lifecycle.
|
540
|
+
*
|
541
|
+
* @param {string} type the lifecycle that the function hooked to
|
542
|
+
* @param {Function} hook The hooked function to remove
|
543
|
+
* @return {boolean} True if the function was removed, false if not found
|
544
|
+
* @method removeHook
|
545
|
+
*/
|
546
|
+
|
215
547
|
|
216
|
-
|
217
|
-
|
548
|
+
Html5DashJS.removeHook = function removeHook(type, hook) {
|
549
|
+
var index = Html5DashJS.hooks(type).indexOf(hook);
|
218
550
|
|
219
|
-
|
551
|
+
if (index === -1) {
|
552
|
+
return false;
|
220
553
|
}
|
221
|
-
|
554
|
+
|
555
|
+
Html5DashJS.hooks_[type] = Html5DashJS.hooks_[type].slice();
|
556
|
+
Html5DashJS.hooks_[type].splice(index, 1);
|
557
|
+
|
558
|
+
return true;
|
559
|
+
};
|
222
560
|
|
223
561
|
return Html5DashJS;
|
224
562
|
}();
|
@@ -226,10 +564,19 @@ var Html5DashJS = function () {
|
|
226
564
|
Html5DashJS.hooks_ = {};
|
227
565
|
|
228
566
|
var canHandleKeySystems = function canHandleKeySystems(source) {
|
567
|
+
// copy the source
|
568
|
+
source = JSON.parse(JSON.stringify(source));
|
569
|
+
|
229
570
|
if (Html5DashJS.updateSourceData) {
|
571
|
+
_video2['default'].log.warn('updateSourceData has been deprecated.' + ' Please switch to using hook("updatesource", callback).');
|
230
572
|
source = Html5DashJS.updateSourceData(source);
|
231
573
|
}
|
232
574
|
|
575
|
+
// call updatesource hooks
|
576
|
+
Html5DashJS.hooks('updatesource').forEach(function (hook) {
|
577
|
+
source = hook(source);
|
578
|
+
});
|
579
|
+
|
233
580
|
var videoEl = document.createElement('video');
|
234
581
|
if (source.keySystemOptions && !(navigator.requestMediaKeySystemAccess ||
|
235
582
|
// IE11 Win 8.1
|
@@ -240,7 +587,7 @@ var canHandleKeySystems = function canHandleKeySystems(source) {
|
|
240
587
|
return true;
|
241
588
|
};
|
242
589
|
|
243
|
-
_video2
|
590
|
+
_video2['default'].DashSourceHandler = function () {
|
244
591
|
return {
|
245
592
|
canHandleSource: function canHandleSource(source) {
|
246
593
|
var dashExtRE = /\.mpd/i;
|
@@ -249,7 +596,7 @@ _video2.default.DashSourceHandler = function () {
|
|
249
596
|
return '';
|
250
597
|
}
|
251
598
|
|
252
|
-
if (_video2
|
599
|
+
if (_video2['default'].DashSourceHandler.canPlayType(source.type)) {
|
253
600
|
return 'probably';
|
254
601
|
} else if (dashExtRE.test(source.src)) {
|
255
602
|
return 'maybe';
|
@@ -263,12 +610,12 @@ _video2.default.DashSourceHandler = function () {
|
|
263
610
|
},
|
264
611
|
|
265
612
|
canPlayType: function canPlayType(type) {
|
266
|
-
return _video2
|
613
|
+
return _video2['default'].DashSourceHandler.canPlayType(type);
|
267
614
|
}
|
268
615
|
};
|
269
616
|
};
|
270
617
|
|
271
|
-
_video2
|
618
|
+
_video2['default'].DashSourceHandler.canPlayType = function (type) {
|
272
619
|
var dashTypeRE = /^application\/dash\+xml/i;
|
273
620
|
if (dashTypeRE.test(type)) {
|
274
621
|
return 'probably';
|
@@ -278,25 +625,12 @@ _video2.default.DashSourceHandler.canPlayType = function (type) {
|
|
278
625
|
};
|
279
626
|
|
280
627
|
// Only add the SourceHandler if the browser supports MediaSourceExtensions
|
281
|
-
if (!!_window2
|
282
|
-
_video2
|
628
|
+
if (!!_window2['default'].MediaSource) {
|
629
|
+
_video2['default'].getTech('Html5').registerSourceHandler(_video2['default'].DashSourceHandler(), 0);
|
283
630
|
}
|
284
631
|
|
285
|
-
_video2
|
286
|
-
exports
|
287
|
-
|
632
|
+
_video2['default'].Html5DashJS = Html5DashJS;
|
633
|
+
exports['default'] = Html5DashJS;
|
288
634
|
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
289
|
-
},{"global/window":
|
290
|
-
|
291
|
-
if (typeof window !== "undefined") {
|
292
|
-
module.exports = window;
|
293
|
-
} else if (typeof global !== "undefined") {
|
294
|
-
module.exports = global;
|
295
|
-
} else if (typeof self !== "undefined"){
|
296
|
-
module.exports = self;
|
297
|
-
} else {
|
298
|
-
module.exports = {};
|
299
|
-
}
|
300
|
-
|
301
|
-
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
302
|
-
},{}]},{},[1]);
|
635
|
+
},{"./setup-audio-tracks":1,"./setup-text-tracks":2,"global/window":3}]},{},[4])(4)
|
636
|
+
});
|