videojs_rails 4.3.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bcaa721474f6b37dd8044eb542bbbb356dfcb1e
|
4
|
+
data.tar.gz: a4fc6f926cfe0c58574f16c4b5bffb854cdbf768
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a8a31cf17dde4bc8586087ac3a693bf4a10f00cf646ef12400500c21dd3c24b501538720a13ba8f6d628e8d0eeead1a1b497d27cd7c1f36d2d3871702992e2f
|
7
|
+
data.tar.gz: 0bfe968aec754a1ff0ad0cdca0b05c13fe1c6853f8933c00d35f84bb6d2e09f9e15a2deaa9b9d4c79a352ef140d5725263f823768bc37058188561637117a2df
|
Binary file
|
@@ -64,7 +64,7 @@ var videojs = vjs;
|
|
64
64
|
window.videojs = window.vjs = vjs;
|
65
65
|
|
66
66
|
// CDN Version. Used to target right flash swf.
|
67
|
-
vjs.CDN_VERSION = '4.
|
67
|
+
vjs.CDN_VERSION = '4.4';
|
68
68
|
vjs.ACCESS_PROTOCOL = ('https:' == document.location.protocol ? 'https://' : 'http://');
|
69
69
|
|
70
70
|
/**
|
@@ -106,7 +106,7 @@ vjs.options = {
|
|
106
106
|
};
|
107
107
|
|
108
108
|
// Set CDN Version of swf
|
109
|
-
// The added (+) blocks the replace from changing this 4.
|
109
|
+
// The added (+) blocks the replace from changing this 4.4 string
|
110
110
|
if (vjs.CDN_VERSION !== 'GENERATED'+'_CDN_VSN') {
|
111
111
|
videojs.options['flash']['swf'] = vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+vjs.CDN_VERSION+'/video-js.swf';
|
112
112
|
}
|
@@ -116,6 +116,21 @@ if (vjs.CDN_VERSION !== 'GENERATED'+'_CDN_VSN') {
|
|
116
116
|
* @type {Object}
|
117
117
|
*/
|
118
118
|
vjs.players = {};
|
119
|
+
|
120
|
+
/*!
|
121
|
+
* Custom Universal Module Definition (UMD)
|
122
|
+
*
|
123
|
+
* Video.js will never be a non-browser lib so we can simplify UMD a bunch and
|
124
|
+
* still support requirejs and browserify. This also needs to be closure
|
125
|
+
* compiler compatible, so string keys are used.
|
126
|
+
*/
|
127
|
+
if (typeof define === 'function' && define['amd']) {
|
128
|
+
define([], function(){ return videojs; });
|
129
|
+
|
130
|
+
// checking that module is an object too because of umdjs/umd#35
|
131
|
+
} else if (typeof exports === 'object' && typeof module === 'object') {
|
132
|
+
module.exports = videojs;
|
133
|
+
}
|
119
134
|
/**
|
120
135
|
* Core Object/Class for objects that use inheritance + contstructors
|
121
136
|
*
|
@@ -426,8 +441,13 @@ vjs.fixEvent = function(event) {
|
|
426
441
|
// TODO: Probably best to create a whitelist of event props
|
427
442
|
for (var key in old) {
|
428
443
|
// Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
|
429
|
-
|
430
|
-
|
444
|
+
// Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
|
445
|
+
if (key !== 'layerX' && key !== 'layerY' && key !== 'keyboardEvent.keyLocation') {
|
446
|
+
// Chrome 32+ warns if you try to copy deprecated returnValue, but
|
447
|
+
// we still want to if preventDefault isn't supported (IE8).
|
448
|
+
if (!(key == 'returnValue' && old.preventDefault)) {
|
449
|
+
event[key] = old[key];
|
450
|
+
}
|
431
451
|
}
|
432
452
|
}
|
433
453
|
|
@@ -1289,6 +1309,46 @@ vjs.findPosition = function(el) {
|
|
1289
1309
|
top: top
|
1290
1310
|
};
|
1291
1311
|
};
|
1312
|
+
/**
|
1313
|
+
* Utility functions namespace
|
1314
|
+
* @namespace
|
1315
|
+
* @type {Object}
|
1316
|
+
*/
|
1317
|
+
vjs.util = {};
|
1318
|
+
|
1319
|
+
/**
|
1320
|
+
* Merge two options objects,
|
1321
|
+
* recursively merging any plain object properties as well.
|
1322
|
+
* Previously `deepMerge`
|
1323
|
+
*
|
1324
|
+
* @param {Object} obj1 Object to override values in
|
1325
|
+
* @param {Object} obj2 Overriding object
|
1326
|
+
* @return {Object} New object -- obj1 and obj2 will be untouched
|
1327
|
+
*/
|
1328
|
+
vjs.util.mergeOptions = function(obj1, obj2){
|
1329
|
+
var key, val1, val2;
|
1330
|
+
|
1331
|
+
// make a copy of obj1 so we're not ovewriting original values.
|
1332
|
+
// like prototype.options_ and all sub options objects
|
1333
|
+
obj1 = vjs.obj.copy(obj1);
|
1334
|
+
|
1335
|
+
for (key in obj2){
|
1336
|
+
if (obj2.hasOwnProperty(key)) {
|
1337
|
+
val1 = obj1[key];
|
1338
|
+
val2 = obj2[key];
|
1339
|
+
|
1340
|
+
// Check if both properties are pure objects and do a deep merge if so
|
1341
|
+
if (vjs.obj.isPlain(val1) && vjs.obj.isPlain(val2)) {
|
1342
|
+
obj1[key] = vjs.util.mergeOptions(val1, val2);
|
1343
|
+
} else {
|
1344
|
+
obj1[key] = obj2[key];
|
1345
|
+
}
|
1346
|
+
}
|
1347
|
+
}
|
1348
|
+
return obj1;
|
1349
|
+
};
|
1350
|
+
|
1351
|
+
|
1292
1352
|
/**
|
1293
1353
|
* @fileoverview Player Component - Base class for all UI objects
|
1294
1354
|
*
|
@@ -1325,7 +1385,7 @@ vjs.findPosition = function(el) {
|
|
1325
1385
|
*/
|
1326
1386
|
vjs.Component = vjs.CoreObject.extend({
|
1327
1387
|
/**
|
1328
|
-
* the constructor
|
1388
|
+
* the constructor function for the class
|
1329
1389
|
*
|
1330
1390
|
* @constructor
|
1331
1391
|
*/
|
@@ -1356,6 +1416,10 @@ vjs.Component = vjs.CoreObject.extend({
|
|
1356
1416
|
this.ready(ready);
|
1357
1417
|
// Don't want to trigger ready here or it will before init is actually
|
1358
1418
|
// finished for all children that run this constructor
|
1419
|
+
|
1420
|
+
if (options.reportTouchActivity !== false) {
|
1421
|
+
this.enableTouchActivity();
|
1422
|
+
}
|
1359
1423
|
}
|
1360
1424
|
});
|
1361
1425
|
|
@@ -1363,7 +1427,7 @@ vjs.Component = vjs.CoreObject.extend({
|
|
1363
1427
|
* Dispose of the component and all child components
|
1364
1428
|
*/
|
1365
1429
|
vjs.Component.prototype.dispose = function(){
|
1366
|
-
this.trigger('dispose');
|
1430
|
+
this.trigger({ type: 'dispose', 'bubbles': false });
|
1367
1431
|
|
1368
1432
|
// Dispose all children.
|
1369
1433
|
if (this.children_) {
|
@@ -1454,13 +1518,13 @@ vjs.Component.prototype.options_;
|
|
1454
1518
|
* }
|
1455
1519
|
* }
|
1456
1520
|
*
|
1457
|
-
* @param {Object} obj Object
|
1458
|
-
* @return {Object} NEW
|
1521
|
+
* @param {Object} obj Object of new option values
|
1522
|
+
* @return {Object} A NEW object of this.options_ and obj merged
|
1459
1523
|
*/
|
1460
1524
|
vjs.Component.prototype.options = function(obj){
|
1461
1525
|
if (obj === undefined) return this.options_;
|
1462
1526
|
|
1463
|
-
return this.options_ = vjs.
|
1527
|
+
return this.options_ = vjs.util.mergeOptions(this.options_, obj);
|
1464
1528
|
};
|
1465
1529
|
|
1466
1530
|
/**
|
@@ -1595,7 +1659,7 @@ vjs.Component.prototype.getChildById = function(id){
|
|
1595
1659
|
vjs.Component.prototype.childNameIndex_;
|
1596
1660
|
|
1597
1661
|
/**
|
1598
|
-
* Returns a child component with the provided
|
1662
|
+
* Returns a child component with the provided name
|
1599
1663
|
*
|
1600
1664
|
* @return {vjs.Component}
|
1601
1665
|
*/
|
@@ -1617,14 +1681,14 @@ vjs.Component.prototype.getChild = function(name){
|
|
1617
1681
|
*
|
1618
1682
|
* Pass in options for child constructors and options for children of the child
|
1619
1683
|
*
|
1620
|
-
*
|
1621
|
-
*
|
1622
|
-
*
|
1623
|
-
*
|
1624
|
-
*
|
1625
|
-
*
|
1626
|
-
*
|
1627
|
-
*
|
1684
|
+
* var myButton = myComponent.addChild('MyButton', {
|
1685
|
+
* text: 'Press Me',
|
1686
|
+
* children: {
|
1687
|
+
* buttonChildExample: {
|
1688
|
+
* buttonChildOption: true
|
1689
|
+
* }
|
1690
|
+
* }
|
1691
|
+
* });
|
1628
1692
|
*
|
1629
1693
|
* @param {String|vjs.Component} child The class name or instance of a child to add
|
1630
1694
|
* @param {Object=} options Options, including options to be passed to children of the child.
|
@@ -1943,7 +2007,7 @@ vjs.Component.prototype.show = function(){
|
|
1943
2007
|
};
|
1944
2008
|
|
1945
2009
|
/**
|
1946
|
-
* Hide the component element if
|
2010
|
+
* Hide the component element if currently showing
|
1947
2011
|
*
|
1948
2012
|
* @return {vjs.Component}
|
1949
2013
|
*/
|
@@ -1978,6 +2042,9 @@ vjs.Component.prototype.unlockShowing = function(){
|
|
1978
2042
|
|
1979
2043
|
/**
|
1980
2044
|
* Disable component by making it unshowable
|
2045
|
+
*
|
2046
|
+
* Currently private because we're movign towards more css-based states.
|
2047
|
+
* @private
|
1981
2048
|
*/
|
1982
2049
|
vjs.Component.prototype.disable = function(){
|
1983
2050
|
this.hide();
|
@@ -1987,13 +2054,15 @@ vjs.Component.prototype.disable = function(){
|
|
1987
2054
|
/**
|
1988
2055
|
* Set or get the width of the component (CSS values)
|
1989
2056
|
*
|
1990
|
-
*
|
1991
|
-
*
|
2057
|
+
* Setting the video tag dimension values only works with values in pixels.
|
2058
|
+
* Percent values will not work.
|
2059
|
+
* Some percents can be used, but width()/height() will return the number + %,
|
2060
|
+
* not the actual computed width/height.
|
1992
2061
|
*
|
1993
2062
|
* @param {Number|String=} num Optional width number
|
1994
2063
|
* @param {Boolean} skipListeners Skip the 'resize' event trigger
|
1995
|
-
* @return {vjs.Component}
|
1996
|
-
* @return {Number|String}
|
2064
|
+
* @return {vjs.Component} This component, when setting the width
|
2065
|
+
* @return {Number|String} The width, when getting
|
1997
2066
|
*/
|
1998
2067
|
vjs.Component.prototype.width = function(num, skipListeners){
|
1999
2068
|
return this.dimension('width', num, skipListeners);
|
@@ -2002,10 +2071,15 @@ vjs.Component.prototype.width = function(num, skipListeners){
|
|
2002
2071
|
/**
|
2003
2072
|
* Get or set the height of the component (CSS values)
|
2004
2073
|
*
|
2074
|
+
* Setting the video tag dimension values only works with values in pixels.
|
2075
|
+
* Percent values will not work.
|
2076
|
+
* Some percents can be used, but width()/height() will return the number + %,
|
2077
|
+
* not the actual computed width/height.
|
2078
|
+
*
|
2005
2079
|
* @param {Number|String=} num New component height
|
2006
2080
|
* @param {Boolean=} skipListeners Skip the resize event trigger
|
2007
|
-
* @return {vjs.Component}
|
2008
|
-
* @return {Number|String} The height
|
2081
|
+
* @return {vjs.Component} This component, when setting the height
|
2082
|
+
* @return {Number|String} The height, when getting
|
2009
2083
|
*/
|
2010
2084
|
vjs.Component.prototype.height = function(num, skipListeners){
|
2011
2085
|
return this.dimension('height', num, skipListeners);
|
@@ -2132,7 +2206,7 @@ vjs.Component.prototype.emitTapEvents = function(){
|
|
2132
2206
|
|
2133
2207
|
// When the touch ends, measure how long it took and trigger the appropriate
|
2134
2208
|
// event
|
2135
|
-
this.on('touchend', function() {
|
2209
|
+
this.on('touchend', function(event) {
|
2136
2210
|
// Proceed only if the touchmove/leave/cancel event didn't happen
|
2137
2211
|
if (couldBeTap === true) {
|
2138
2212
|
// Measure how long the touch lasted
|
@@ -2147,6 +2221,57 @@ vjs.Component.prototype.emitTapEvents = function(){
|
|
2147
2221
|
}
|
2148
2222
|
});
|
2149
2223
|
};
|
2224
|
+
|
2225
|
+
/**
|
2226
|
+
* Report user touch activity when touch events occur
|
2227
|
+
*
|
2228
|
+
* User activity is used to determine when controls should show/hide. It's
|
2229
|
+
* relatively simple when it comes to mouse events, because any mouse event
|
2230
|
+
* should show the controls. So we capture mouse events that bubble up to the
|
2231
|
+
* player and report activity when that happens.
|
2232
|
+
*
|
2233
|
+
* With touch events it isn't as easy. We can't rely on touch events at the
|
2234
|
+
* player level, because a tap (touchstart + touchend) on the video itself on
|
2235
|
+
* mobile devices is meant to turn controls off (and on). User activity is
|
2236
|
+
* checked asynchronously, so what could happen is a tap event on the video
|
2237
|
+
* turns the controls off, then the touchend event bubbles up to the player,
|
2238
|
+
* which if it reported user activity, would turn the controls right back on.
|
2239
|
+
* (We also don't want to completely block touch events from bubbling up)
|
2240
|
+
*
|
2241
|
+
* Also a touchmove, touch+hold, and anything other than a tap is not supposed
|
2242
|
+
* to turn the controls back on on a mobile device.
|
2243
|
+
*
|
2244
|
+
* Here we're setting the default component behavior to report user activity
|
2245
|
+
* whenever touch events happen, and this can be turned off by components that
|
2246
|
+
* want touch events to act differently.
|
2247
|
+
*/
|
2248
|
+
vjs.Component.prototype.enableTouchActivity = function() {
|
2249
|
+
var report, touchHolding, touchEnd;
|
2250
|
+
|
2251
|
+
// listener for reporting that the user is active
|
2252
|
+
report = vjs.bind(this.player(), this.player().reportUserActivity);
|
2253
|
+
|
2254
|
+
this.on('touchstart', function() {
|
2255
|
+
report();
|
2256
|
+
// For as long as the they are touching the device or have their mouse down,
|
2257
|
+
// we consider them active even if they're not moving their finger or mouse.
|
2258
|
+
// So we want to continue to update that they are active
|
2259
|
+
clearInterval(touchHolding);
|
2260
|
+
// report at the same interval as activityCheck
|
2261
|
+
touchHolding = setInterval(report, 250);
|
2262
|
+
});
|
2263
|
+
|
2264
|
+
touchEnd = function(event) {
|
2265
|
+
report();
|
2266
|
+
// stop the interval that maintains activity if the touch is holding
|
2267
|
+
clearInterval(touchHolding);
|
2268
|
+
};
|
2269
|
+
|
2270
|
+
this.on('touchmove', report);
|
2271
|
+
this.on('touchend', touchEnd);
|
2272
|
+
this.on('touchcancel', touchEnd);
|
2273
|
+
};
|
2274
|
+
|
2150
2275
|
/* Button - Base class for all buttons
|
2151
2276
|
================================================================================ */
|
2152
2277
|
/**
|
@@ -2192,7 +2317,7 @@ vjs.Button.prototype.createEl = function(type, props){
|
|
2192
2317
|
props = vjs.obj.merge({
|
2193
2318
|
className: this.buildCSSClass(),
|
2194
2319
|
innerHTML: '<div class="vjs-control-content"><span class="vjs-control-text">' + (this.buttonText || 'Need Text') + '</span></div>',
|
2195
|
-
role: 'button',
|
2320
|
+
'role': 'button',
|
2196
2321
|
'aria-live': 'polite', // let the screen reader user know that the text of the button may change
|
2197
2322
|
tabIndex: 0
|
2198
2323
|
}, props);
|
@@ -2268,7 +2393,7 @@ vjs.Slider.prototype.createEl = function(type, props) {
|
|
2268
2393
|
// Add the slider element class to all sub classes
|
2269
2394
|
props.className = props.className + ' vjs-slider';
|
2270
2395
|
props = vjs.obj.merge({
|
2271
|
-
role: 'slider',
|
2396
|
+
'role': 'slider',
|
2272
2397
|
'aria-valuenow': 0,
|
2273
2398
|
'aria-valuemin': 0,
|
2274
2399
|
'aria-valuemax': 100,
|
@@ -2708,6 +2833,9 @@ vjs.Player = vjs.Component.extend({
|
|
2708
2833
|
init: function(tag, options, ready){
|
2709
2834
|
this.tag = tag; // Store the original tag used to set options
|
2710
2835
|
|
2836
|
+
// Make sure tag ID exists
|
2837
|
+
tag.id = tag.id || 'vjs_video_' + vjs.guid++;
|
2838
|
+
|
2711
2839
|
// Set Options
|
2712
2840
|
// The options argument overrides options set in the video tag
|
2713
2841
|
// which overrides globally set options.
|
@@ -2727,6 +2855,10 @@ vjs.Player = vjs.Component.extend({
|
|
2727
2855
|
// May be turned back on by HTML5 tech if nativeControlsForTouch is true
|
2728
2856
|
tag.controls = false;
|
2729
2857
|
|
2858
|
+
// we don't want the player to report touch activity on itself
|
2859
|
+
// see enableTouchActivity in Component
|
2860
|
+
options.reportTouchActivity = false;
|
2861
|
+
|
2730
2862
|
// Run base component initializing with new options.
|
2731
2863
|
// Builds the element through createEl()
|
2732
2864
|
// Inits and embeds any child components in opts
|
@@ -2881,9 +3013,6 @@ vjs.Player.prototype.createEl = function(){
|
|
2881
3013
|
}
|
2882
3014
|
}
|
2883
3015
|
|
2884
|
-
// Make sure tag ID exists
|
2885
|
-
tag.id = tag.id || 'vjs_video_' + vjs.guid++;
|
2886
|
-
|
2887
3016
|
// Give video tag ID and class to player div
|
2888
3017
|
// ID will now reference player box, not the video tag
|
2889
3018
|
el.id = tag.id;
|
@@ -2923,10 +3052,10 @@ vjs.Player.prototype.loadTech = function(techName, source){
|
|
2923
3052
|
// Pause and remove current playback technology
|
2924
3053
|
if (this.tech) {
|
2925
3054
|
this.unloadTech();
|
3055
|
+
}
|
2926
3056
|
|
2927
|
-
//
|
2928
|
-
|
2929
|
-
} else if (techName !== 'Html5' && this.tag) {
|
3057
|
+
// get rid of the HTML5 video tag as soon as we are using another tech
|
3058
|
+
if (techName !== 'Html5' && this.tag) {
|
2930
3059
|
vjs.Html5.disposeMediaElement(this.tag);
|
2931
3060
|
this.tag = null;
|
2932
3061
|
}
|
@@ -3173,7 +3302,12 @@ vjs.Player.prototype.onEnded = function(){
|
|
3173
3302
|
*/
|
3174
3303
|
vjs.Player.prototype.onDurationChange = function(){
|
3175
3304
|
// Allows for cacheing value instead of asking player each time.
|
3176
|
-
|
3305
|
+
// We need to get the techGet response and check for a value so we don't
|
3306
|
+
// accidentally cause the stack to blow up.
|
3307
|
+
var duration = this.techGet('duration');
|
3308
|
+
if (duration) {
|
3309
|
+
this.duration(duration);
|
3310
|
+
}
|
3177
3311
|
};
|
3178
3312
|
|
3179
3313
|
/**
|
@@ -3187,7 +3321,7 @@ vjs.Player.prototype.onVolumeChange;
|
|
3187
3321
|
* @event fullscreenchange
|
3188
3322
|
*/
|
3189
3323
|
vjs.Player.prototype.onFullscreenChange = function() {
|
3190
|
-
if (this.isFullScreen) {
|
3324
|
+
if (this.isFullScreen()) {
|
3191
3325
|
this.addClass('vjs-fullscreen');
|
3192
3326
|
} else {
|
3193
3327
|
this.removeClass('vjs-fullscreen');
|
@@ -3317,9 +3451,6 @@ vjs.Player.prototype.paused = function(){
|
|
3317
3451
|
vjs.Player.prototype.currentTime = function(seconds){
|
3318
3452
|
if (seconds !== undefined) {
|
3319
3453
|
|
3320
|
-
// cache the last set value for smoother scrubbing
|
3321
|
-
this.cache_.lastSetCurrentTime = seconds;
|
3322
|
-
|
3323
3454
|
this.techCall('setCurrentTime', seconds);
|
3324
3455
|
|
3325
3456
|
// improve the accuracy of manual timeupdates
|
@@ -3328,8 +3459,12 @@ vjs.Player.prototype.currentTime = function(seconds){
|
|
3328
3459
|
return this;
|
3329
3460
|
}
|
3330
3461
|
|
3331
|
-
// cache last currentTime and return
|
3332
|
-
//
|
3462
|
+
// cache last currentTime and return. default to 0 seconds
|
3463
|
+
//
|
3464
|
+
// Caching the currentTime is meant to prevent a massive amount of reads on the tech's
|
3465
|
+
// currentTime when scrubbing, but may not provide much performace benefit afterall.
|
3466
|
+
// Should be tested. Also something has to read the actual current time or the cache will
|
3467
|
+
// never get updated.
|
3333
3468
|
return this.cache_.currentTime = (this.techGet('currentTime') || 0);
|
3334
3469
|
};
|
3335
3470
|
|
@@ -3357,7 +3492,7 @@ vjs.Player.prototype.duration = function(seconds){
|
|
3357
3492
|
this.onDurationChange();
|
3358
3493
|
}
|
3359
3494
|
|
3360
|
-
return this.cache_.duration;
|
3495
|
+
return this.cache_.duration || 0;
|
3361
3496
|
};
|
3362
3497
|
|
3363
3498
|
// Calculates how much time is left. Not in spec, but useful.
|
@@ -3473,8 +3608,43 @@ vjs.Player.prototype.muted = function(muted){
|
|
3473
3608
|
return this.techGet('muted') || false; // Default to false
|
3474
3609
|
};
|
3475
3610
|
|
3476
|
-
// Check if current tech can support native fullscreen
|
3477
|
-
|
3611
|
+
// Check if current tech can support native fullscreen
|
3612
|
+
// (e.g. with built in controls lik iOS, so not our flash swf)
|
3613
|
+
vjs.Player.prototype.supportsFullScreen = function(){
|
3614
|
+
return this.techGet('supportsFullScreen') || false;
|
3615
|
+
};
|
3616
|
+
|
3617
|
+
/**
|
3618
|
+
* is the player in fullscreen
|
3619
|
+
* @type {Boolean}
|
3620
|
+
* @private
|
3621
|
+
*/
|
3622
|
+
vjs.Player.prototype.isFullScreen_ = false;
|
3623
|
+
|
3624
|
+
/**
|
3625
|
+
* Check if the player is in fullscreen mode
|
3626
|
+
*
|
3627
|
+
* // get
|
3628
|
+
* var fullscreenOrNot = myPlayer.isFullScreen();
|
3629
|
+
*
|
3630
|
+
* // set
|
3631
|
+
* myPlayer.isFullScreen(true); // tell the player it's in fullscreen
|
3632
|
+
*
|
3633
|
+
* NOTE: As of the latest HTML5 spec, isFullScreen is no longer an official
|
3634
|
+
* property and instead document.fullscreenElement is used. But isFullScreen is
|
3635
|
+
* still a valuable property for internal player workings.
|
3636
|
+
*
|
3637
|
+
* @param {Boolean=} isFS Update the player's fullscreen state
|
3638
|
+
* @return {Boolean} true if fullscreen, false if not
|
3639
|
+
* @return {vjs.Player} self, when setting
|
3640
|
+
*/
|
3641
|
+
vjs.Player.prototype.isFullScreen = function(isFS){
|
3642
|
+
if (isFS !== undefined) {
|
3643
|
+
this.isFullScreen_ = isFS;
|
3644
|
+
return this;
|
3645
|
+
}
|
3646
|
+
return this.isFullScreen_;
|
3647
|
+
};
|
3478
3648
|
|
3479
3649
|
/**
|
3480
3650
|
* Increase the size of the video to full screen
|
@@ -3492,7 +3662,7 @@ vjs.Player.prototype.supportsFullScreen = function(){ return this.techGet('suppo
|
|
3492
3662
|
*/
|
3493
3663
|
vjs.Player.prototype.requestFullScreen = function(){
|
3494
3664
|
var requestFullScreen = vjs.support.requestFullScreen;
|
3495
|
-
this.isFullScreen
|
3665
|
+
this.isFullScreen(true);
|
3496
3666
|
|
3497
3667
|
if (requestFullScreen) {
|
3498
3668
|
// the browser supports going fullscreen at the element level so we can
|
@@ -3504,10 +3674,10 @@ vjs.Player.prototype.requestFullScreen = function(){
|
|
3504
3674
|
// players on a page, they would all be reacting to the same fullscreen
|
3505
3675
|
// events
|
3506
3676
|
vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(e){
|
3507
|
-
this.isFullScreen
|
3677
|
+
this.isFullScreen(document[requestFullScreen.isFullScreen]);
|
3508
3678
|
|
3509
3679
|
// If cancelling fullscreen, remove event listener.
|
3510
|
-
if (this.isFullScreen === false) {
|
3680
|
+
if (this.isFullScreen() === false) {
|
3511
3681
|
vjs.off(document, requestFullScreen.eventName, arguments.callee);
|
3512
3682
|
}
|
3513
3683
|
|
@@ -3539,7 +3709,7 @@ vjs.Player.prototype.requestFullScreen = function(){
|
|
3539
3709
|
*/
|
3540
3710
|
vjs.Player.prototype.cancelFullScreen = function(){
|
3541
3711
|
var requestFullScreen = vjs.support.requestFullScreen;
|
3542
|
-
this.isFullScreen
|
3712
|
+
this.isFullScreen(false);
|
3543
3713
|
|
3544
3714
|
// Check for browser element fullscreen support
|
3545
3715
|
if (requestFullScreen) {
|
@@ -3574,7 +3744,7 @@ vjs.Player.prototype.enterFullWindow = function(){
|
|
3574
3744
|
};
|
3575
3745
|
vjs.Player.prototype.fullWindowOnEscKey = function(event){
|
3576
3746
|
if (event.keyCode === 27) {
|
3577
|
-
if (this.isFullScreen === true) {
|
3747
|
+
if (this.isFullScreen() === true) {
|
3578
3748
|
this.cancelFullScreen();
|
3579
3749
|
} else {
|
3580
3750
|
this.exitFullWindow();
|
@@ -3769,11 +3939,18 @@ vjs.Player.prototype.poster_;
|
|
3769
3939
|
* @return {vjs.Player} self when setting
|
3770
3940
|
*/
|
3771
3941
|
vjs.Player.prototype.poster = function(src){
|
3772
|
-
if (src
|
3773
|
-
this.poster_
|
3774
|
-
return this;
|
3942
|
+
if (src === undefined) {
|
3943
|
+
return this.poster_;
|
3775
3944
|
}
|
3776
|
-
|
3945
|
+
|
3946
|
+
// update the internal poster variable
|
3947
|
+
this.poster_ = src;
|
3948
|
+
|
3949
|
+
// update the tech's poster
|
3950
|
+
this.techCall('setPoster', src);
|
3951
|
+
|
3952
|
+
// alert components that the poster has been set
|
3953
|
+
this.trigger('posterchange');
|
3777
3954
|
};
|
3778
3955
|
|
3779
3956
|
/**
|
@@ -3915,7 +4092,7 @@ vjs.Player.prototype.listenForUserActivity = function(){
|
|
3915
4092
|
var onMouseActivity, onMouseDown, mouseInProgress, onMouseUp,
|
3916
4093
|
activityCheck, inactivityTimeout;
|
3917
4094
|
|
3918
|
-
onMouseActivity = this.reportUserActivity;
|
4095
|
+
onMouseActivity = vjs.bind(this, this.reportUserActivity);
|
3919
4096
|
|
3920
4097
|
onMouseDown = function() {
|
3921
4098
|
onMouseActivity();
|
@@ -3926,7 +4103,7 @@ vjs.Player.prototype.listenForUserActivity = function(){
|
|
3926
4103
|
// Setting userActivity=true now and setting the interval to the same time
|
3927
4104
|
// as the activityCheck interval (250) should ensure we never miss the
|
3928
4105
|
// next activityCheck
|
3929
|
-
mouseInProgress = setInterval(
|
4106
|
+
mouseInProgress = setInterval(onMouseActivity, 250);
|
3930
4107
|
};
|
3931
4108
|
|
3932
4109
|
onMouseUp = function(event) {
|
@@ -3945,14 +4122,6 @@ vjs.Player.prototype.listenForUserActivity = function(){
|
|
3945
4122
|
this.on('keydown', onMouseActivity);
|
3946
4123
|
this.on('keyup', onMouseActivity);
|
3947
4124
|
|
3948
|
-
// Consider any touch events that bubble up to be activity
|
3949
|
-
// Certain touches on the tech will be blocked from bubbling because they
|
3950
|
-
// toggle controls
|
3951
|
-
this.on('touchstart', onMouseDown);
|
3952
|
-
this.on('touchmove', onMouseActivity);
|
3953
|
-
this.on('touchend', onMouseUp);
|
3954
|
-
this.on('touchcancel', onMouseUp);
|
3955
|
-
|
3956
4125
|
// Run an interval every 250 milliseconds instead of stuffing everything into
|
3957
4126
|
// the mousemove/touchmove function itself, to prevent performance degradation.
|
3958
4127
|
// `this.reportUserActivity` simply sets this.userActivity_ to true, which
|
@@ -3993,7 +4162,6 @@ vjs.Player.prototype.listenForUserActivity = function(){
|
|
3993
4162
|
// Methods to add support for
|
3994
4163
|
// networkState: function(){ return this.techCall('networkState'); },
|
3995
4164
|
// readyState: function(){ return this.techCall('readyState'); },
|
3996
|
-
// seeking: function(){ return this.techCall('seeking'); },
|
3997
4165
|
// initialTime: function(){ return this.techCall('initialTime'); },
|
3998
4166
|
// startOffsetTime: function(){ return this.techCall('startOffsetTime'); },
|
3999
4167
|
// played: function(){ return this.techCall('played'); },
|
@@ -4057,8 +4225,6 @@ vjs.Player.prototype.listenForUserActivity = function(){
|
|
4057
4225
|
}
|
4058
4226
|
|
4059
4227
|
})();
|
4060
|
-
|
4061
|
-
|
4062
4228
|
/**
|
4063
4229
|
* Container of main controls
|
4064
4230
|
* @param {vjs.Player|Object} player
|
@@ -4155,20 +4321,20 @@ vjs.CurrentTimeDisplay.prototype.createEl = function(){
|
|
4155
4321
|
className: 'vjs-current-time vjs-time-controls vjs-control'
|
4156
4322
|
});
|
4157
4323
|
|
4158
|
-
this.
|
4324
|
+
this.contentEl_ = vjs.createEl('div', {
|
4159
4325
|
className: 'vjs-current-time-display',
|
4160
4326
|
innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00', // label the current time for screen reader users
|
4161
4327
|
'aria-live': 'off' // tell screen readers not to automatically read the time as it changes
|
4162
4328
|
});
|
4163
4329
|
|
4164
|
-
el.appendChild(
|
4330
|
+
el.appendChild(this.contentEl_);
|
4165
4331
|
return el;
|
4166
4332
|
};
|
4167
4333
|
|
4168
4334
|
vjs.CurrentTimeDisplay.prototype.updateContent = function(){
|
4169
4335
|
// Allows for smooth scrubbing, when player can't keep up.
|
4170
4336
|
var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
|
4171
|
-
this.
|
4337
|
+
this.contentEl_.innerHTML = '<span class="vjs-control-text">Current Time </span>' + vjs.formatTime(time, this.player_.duration());
|
4172
4338
|
};
|
4173
4339
|
|
4174
4340
|
/**
|
@@ -4182,7 +4348,12 @@ vjs.DurationDisplay = vjs.Component.extend({
|
|
4182
4348
|
init: function(player, options){
|
4183
4349
|
vjs.Component.call(this, player, options);
|
4184
4350
|
|
4185
|
-
|
4351
|
+
// this might need to be changed to 'durationchange' instead of 'timeupdate' eventually,
|
4352
|
+
// however the durationchange event fires before this.player_.duration() is set,
|
4353
|
+
// so the value cannot be written out using this method.
|
4354
|
+
// Once the order of durationchange and this.player_.duration() being set is figured out,
|
4355
|
+
// this can be updated.
|
4356
|
+
player.on('timeupdate', vjs.bind(this, this.updateContent));
|
4186
4357
|
}
|
4187
4358
|
});
|
4188
4359
|
|
@@ -4191,20 +4362,20 @@ vjs.DurationDisplay.prototype.createEl = function(){
|
|
4191
4362
|
className: 'vjs-duration vjs-time-controls vjs-control'
|
4192
4363
|
});
|
4193
4364
|
|
4194
|
-
this.
|
4365
|
+
this.contentEl_ = vjs.createEl('div', {
|
4195
4366
|
className: 'vjs-duration-display',
|
4196
4367
|
innerHTML: '<span class="vjs-control-text">Duration Time </span>' + '0:00', // label the duration time for screen reader users
|
4197
4368
|
'aria-live': 'off' // tell screen readers not to automatically read the time as it changes
|
4198
4369
|
});
|
4199
4370
|
|
4200
|
-
el.appendChild(
|
4371
|
+
el.appendChild(this.contentEl_);
|
4201
4372
|
return el;
|
4202
4373
|
};
|
4203
4374
|
|
4204
4375
|
vjs.DurationDisplay.prototype.updateContent = function(){
|
4205
4376
|
var duration = this.player_.duration();
|
4206
4377
|
if (duration) {
|
4207
|
-
this.
|
4378
|
+
this.contentEl_.innerHTML = '<span class="vjs-control-text">Duration Time </span>' + vjs.formatTime(duration); // label the duration time for screen reader users
|
4208
4379
|
}
|
4209
4380
|
};
|
4210
4381
|
|
@@ -4251,24 +4422,24 @@ vjs.RemainingTimeDisplay.prototype.createEl = function(){
|
|
4251
4422
|
className: 'vjs-remaining-time vjs-time-controls vjs-control'
|
4252
4423
|
});
|
4253
4424
|
|
4254
|
-
this.
|
4425
|
+
this.contentEl_ = vjs.createEl('div', {
|
4255
4426
|
className: 'vjs-remaining-time-display',
|
4256
4427
|
innerHTML: '<span class="vjs-control-text">Remaining Time </span>' + '-0:00', // label the remaining time for screen reader users
|
4257
4428
|
'aria-live': 'off' // tell screen readers not to automatically read the time as it changes
|
4258
4429
|
});
|
4259
4430
|
|
4260
|
-
el.appendChild(
|
4431
|
+
el.appendChild(this.contentEl_);
|
4261
4432
|
return el;
|
4262
4433
|
};
|
4263
4434
|
|
4264
4435
|
vjs.RemainingTimeDisplay.prototype.updateContent = function(){
|
4265
4436
|
if (this.player_.duration()) {
|
4266
|
-
this.
|
4437
|
+
this.contentEl_.innerHTML = '<span class="vjs-control-text">Remaining Time </span>' + '-'+ vjs.formatTime(this.player_.remainingTime());
|
4267
4438
|
}
|
4268
4439
|
|
4269
4440
|
// Allows for smooth scrubbing, when player can't keep up.
|
4270
4441
|
// var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
|
4271
|
-
// this.
|
4442
|
+
// this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
|
4272
4443
|
};
|
4273
4444
|
/**
|
4274
4445
|
* Toggle fullscreen video
|
@@ -4295,7 +4466,7 @@ vjs.FullscreenToggle.prototype.buildCSSClass = function(){
|
|
4295
4466
|
};
|
4296
4467
|
|
4297
4468
|
vjs.FullscreenToggle.prototype.onClick = function(){
|
4298
|
-
if (!this.player_.isFullScreen) {
|
4469
|
+
if (!this.player_.isFullScreen()) {
|
4299
4470
|
this.player_.requestFullScreen();
|
4300
4471
|
this.el_.children[0].children[0].innerHTML = 'Non-Fullscreen'; // change the button text to "Non-Fullscreen"
|
4301
4472
|
} else {
|
@@ -4373,25 +4544,7 @@ vjs.SeekBar.prototype.updateARIAAttributes = function(){
|
|
4373
4544
|
};
|
4374
4545
|
|
4375
4546
|
vjs.SeekBar.prototype.getPercent = function(){
|
4376
|
-
|
4377
|
-
// Flash RTMP provider will not report the correct time
|
4378
|
-
// immediately after a seek. This isn't noticeable if you're
|
4379
|
-
// seeking while the video is playing, but it is if you seek
|
4380
|
-
// while the video is paused.
|
4381
|
-
if (this.player_.techName === 'Flash' && this.player_.seeking()) {
|
4382
|
-
var cache = this.player_.getCache();
|
4383
|
-
if (cache.lastSetCurrentTime) {
|
4384
|
-
currentTime = cache.lastSetCurrentTime;
|
4385
|
-
}
|
4386
|
-
else {
|
4387
|
-
currentTime = this.player_.currentTime();
|
4388
|
-
}
|
4389
|
-
}
|
4390
|
-
else {
|
4391
|
-
currentTime = this.player_.currentTime();
|
4392
|
-
}
|
4393
|
-
|
4394
|
-
return currentTime / this.player_.duration();
|
4547
|
+
return this.player_.currentTime() / this.player_.duration();
|
4395
4548
|
};
|
4396
4549
|
|
4397
4550
|
vjs.SeekBar.prototype.onMouseDown = function(event){
|
@@ -4487,7 +4640,12 @@ vjs.PlayProgressBar.prototype.createEl = function(){
|
|
4487
4640
|
* @param {Object=} options
|
4488
4641
|
* @constructor
|
4489
4642
|
*/
|
4490
|
-
vjs.SeekHandle = vjs.SliderHandle.extend(
|
4643
|
+
vjs.SeekHandle = vjs.SliderHandle.extend({
|
4644
|
+
init: function(player, options) {
|
4645
|
+
vjs.SliderHandle.call(this, player, options);
|
4646
|
+
player.on('timeupdate', vjs.bind(this, this.updateContent));
|
4647
|
+
}
|
4648
|
+
});
|
4491
4649
|
|
4492
4650
|
/**
|
4493
4651
|
* The default value for the handle content, which may be read by screen readers
|
@@ -4498,11 +4656,17 @@ vjs.SeekHandle = vjs.SliderHandle.extend();
|
|
4498
4656
|
vjs.SeekHandle.prototype.defaultValue = '00:00';
|
4499
4657
|
|
4500
4658
|
/** @inheritDoc */
|
4501
|
-
vjs.SeekHandle.prototype.createEl = function(){
|
4659
|
+
vjs.SeekHandle.prototype.createEl = function() {
|
4502
4660
|
return vjs.SliderHandle.prototype.createEl.call(this, 'div', {
|
4503
|
-
className: 'vjs-seek-handle'
|
4661
|
+
className: 'vjs-seek-handle',
|
4662
|
+
'aria-live': 'off'
|
4504
4663
|
});
|
4505
4664
|
};
|
4665
|
+
|
4666
|
+
vjs.SeekHandle.prototype.updateContent = function() {
|
4667
|
+
var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();
|
4668
|
+
this.el_.innerHTML = '<span class="vjs-control-text">' + vjs.formatTime(time, this.player_.duration()) + '</span>';
|
4669
|
+
};
|
4506
4670
|
/**
|
4507
4671
|
* The component for controlling the volume level
|
4508
4672
|
*
|
@@ -4776,34 +4940,64 @@ vjs.PosterImage = vjs.Button.extend({
|
|
4776
4940
|
init: function(player, options){
|
4777
4941
|
vjs.Button.call(this, player, options);
|
4778
4942
|
|
4943
|
+
if (player.poster()) {
|
4944
|
+
this.src(player.poster());
|
4945
|
+
}
|
4946
|
+
|
4779
4947
|
if (!player.poster() || !player.controls()) {
|
4780
4948
|
this.hide();
|
4781
4949
|
}
|
4782
4950
|
|
4951
|
+
player.on('posterchange', vjs.bind(this, function(){
|
4952
|
+
this.src(player.poster());
|
4953
|
+
}));
|
4954
|
+
|
4783
4955
|
player.on('play', vjs.bind(this, this.hide));
|
4784
4956
|
}
|
4785
4957
|
});
|
4786
4958
|
|
4959
|
+
// use the test el to check for backgroundSize style support
|
4960
|
+
var _backgroundSizeSupported = 'backgroundSize' in vjs.TEST_VID.style;
|
4961
|
+
|
4787
4962
|
vjs.PosterImage.prototype.createEl = function(){
|
4788
4963
|
var el = vjs.createEl('div', {
|
4789
|
-
|
4964
|
+
className: 'vjs-poster',
|
4790
4965
|
|
4791
|
-
|
4792
|
-
|
4793
|
-
|
4794
|
-
poster = this.player_.poster();
|
4966
|
+
// Don't want poster to be tabbable.
|
4967
|
+
tabIndex: -1
|
4968
|
+
});
|
4795
4969
|
|
4796
|
-
if (
|
4797
|
-
|
4798
|
-
|
4799
|
-
} else {
|
4800
|
-
el.appendChild(vjs.createEl('img', { src: poster }));
|
4801
|
-
}
|
4970
|
+
if (!_backgroundSizeSupported) {
|
4971
|
+
// setup an img element as a fallback for IE8
|
4972
|
+
el.appendChild(vjs.createEl('img'));
|
4802
4973
|
}
|
4803
4974
|
|
4804
4975
|
return el;
|
4805
4976
|
};
|
4806
4977
|
|
4978
|
+
vjs.PosterImage.prototype.src = function(url){
|
4979
|
+
var el = this.el();
|
4980
|
+
|
4981
|
+
// getter
|
4982
|
+
// can't think of a need for a getter here
|
4983
|
+
// see #838 if on is needed in the future
|
4984
|
+
// still don't want a getter to set src as undefined
|
4985
|
+
if (url === undefined) {
|
4986
|
+
return;
|
4987
|
+
}
|
4988
|
+
|
4989
|
+
// setter
|
4990
|
+
// To ensure the poster image resizes while maintaining its original aspect
|
4991
|
+
// ratio, use a div with `background-size` when available. For browsers that
|
4992
|
+
// do not support `background-size` (e.g. IE8), fall back on using a regular
|
4993
|
+
// img element.
|
4994
|
+
if (_backgroundSizeSupported) {
|
4995
|
+
el.style.backgroundImage = 'url("' + url + '")';
|
4996
|
+
} else {
|
4997
|
+
el.firstChild.src = url;
|
4998
|
+
}
|
4999
|
+
};
|
5000
|
+
|
4807
5001
|
vjs.PosterImage.prototype.onClick = function(){
|
4808
5002
|
// Only accept clicks when controls are enabled
|
4809
5003
|
if (this.player().controls()) {
|
@@ -4888,6 +5082,10 @@ vjs.BigPlayButton.prototype.onClick = function(){
|
|
4888
5082
|
vjs.MediaTechController = vjs.Component.extend({
|
4889
5083
|
/** @constructor */
|
4890
5084
|
init: function(player, options, ready){
|
5085
|
+
options = options || {};
|
5086
|
+
// we don't want the tech to report user activity automatically.
|
5087
|
+
// This is done manually in addControlsListeners
|
5088
|
+
options.reportTouchActivity = false;
|
4891
5089
|
vjs.Component.call(this, player, options, ready);
|
4892
5090
|
|
4893
5091
|
this.initControlsListeners();
|
@@ -4936,7 +5134,7 @@ vjs.MediaTechController.prototype.initControlsListeners = function(){
|
|
4936
5134
|
};
|
4937
5135
|
|
4938
5136
|
vjs.MediaTechController.prototype.addControlsListeners = function(){
|
4939
|
-
var
|
5137
|
+
var userWasActive;
|
4940
5138
|
|
4941
5139
|
// Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
|
4942
5140
|
// trigger mousedown/up.
|
@@ -4944,37 +5142,20 @@ vjs.MediaTechController.prototype.addControlsListeners = function(){
|
|
4944
5142
|
// Any touch events are set to block the mousedown event from happening
|
4945
5143
|
this.on('mousedown', this.onClick);
|
4946
5144
|
|
4947
|
-
//
|
4948
|
-
//
|
4949
|
-
//
|
4950
|
-
// only a tap (fast touch) should toggle the user active state and turn the
|
4951
|
-
// controls back on. A touch and move or touch and hold should not trigger
|
4952
|
-
// the controls (per iOS as an example at least)
|
4953
|
-
//
|
4954
|
-
// We always want to stop propagation on touchstart because touchstart
|
4955
|
-
// at the player level starts the touchInProgress interval. We can still
|
4956
|
-
// report activity on the other events, but won't let them bubble for
|
4957
|
-
// consistency. We don't want to bubble a touchend without a touchstart.
|
5145
|
+
// If the controls were hidden we don't want that to change without a tap event
|
5146
|
+
// so we'll check if the controls were already showing before reporting user
|
5147
|
+
// activity
|
4958
5148
|
this.on('touchstart', function(event) {
|
4959
5149
|
// Stop the mouse events from also happening
|
4960
5150
|
event.preventDefault();
|
4961
|
-
event.stopPropagation();
|
4962
|
-
// Record if the user was active now so we don't have to keep polling it
|
4963
5151
|
userWasActive = this.player_.userActive();
|
4964
5152
|
});
|
4965
5153
|
|
4966
|
-
|
4967
|
-
|
4968
|
-
|
4969
|
-
this.player_.reportUserActivity();
|
5154
|
+
this.on('touchmove', function(event) {
|
5155
|
+
if (userWasActive){
|
5156
|
+
this.player().reportUserActivity();
|
4970
5157
|
}
|
4971
|
-
};
|
4972
|
-
|
4973
|
-
// Treat all touch events the same for consistency
|
4974
|
-
this.on('touchmove', preventBubble);
|
4975
|
-
this.on('touchleave', preventBubble);
|
4976
|
-
this.on('touchcancel', preventBubble);
|
4977
|
-
this.on('touchend', preventBubble);
|
5158
|
+
});
|
4978
5159
|
|
4979
5160
|
// Turn on component tap events
|
4980
5161
|
this.emitTapEvents();
|
@@ -5024,7 +5205,6 @@ vjs.MediaTechController.prototype.onClick = function(event){
|
|
5024
5205
|
* Handle a tap on the media element. By default it will toggle the user
|
5025
5206
|
* activity state, which hides and shows the controls.
|
5026
5207
|
*/
|
5027
|
-
|
5028
5208
|
vjs.MediaTechController.prototype.onTap = function(){
|
5029
5209
|
this.player().userActive(!this.player().userActive());
|
5030
5210
|
};
|
@@ -5084,6 +5264,7 @@ vjs.Html5 = vjs.MediaTechController.extend({
|
|
5084
5264
|
this.features['fullscreenResize'] = true;
|
5085
5265
|
|
5086
5266
|
vjs.MediaTechController.call(this, player, options, ready);
|
5267
|
+
this.setupTriggers();
|
5087
5268
|
|
5088
5269
|
var source = options['source'];
|
5089
5270
|
|
@@ -5116,7 +5297,6 @@ vjs.Html5 = vjs.MediaTechController.extend({
|
|
5116
5297
|
}
|
5117
5298
|
});
|
5118
5299
|
|
5119
|
-
this.setupTriggers();
|
5120
5300
|
this.triggerReady();
|
5121
5301
|
}
|
5122
5302
|
});
|
@@ -5276,6 +5456,9 @@ vjs.Html5.prototype.src = function(src){ this.el_.src = src; };
|
|
5276
5456
|
vjs.Html5.prototype.load = function(){ this.el_.load(); };
|
5277
5457
|
vjs.Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; };
|
5278
5458
|
|
5459
|
+
vjs.Html5.prototype.poster = function(){ return this.el_.poster; };
|
5460
|
+
vjs.Html5.prototype.setPoster = function(val){ this.el_.poster = val; };
|
5461
|
+
|
5279
5462
|
vjs.Html5.prototype.preload = function(){ return this.el_.preload; };
|
5280
5463
|
vjs.Html5.prototype.setPreload = function(val){ this.el_.preload = val; };
|
5281
5464
|
|
@@ -5415,7 +5598,9 @@ vjs.Flash = vjs.MediaTechController.extend({
|
|
5415
5598
|
'id': objId,
|
5416
5599
|
'name': objId, // Both ID and Name needed or swf to identifty itself
|
5417
5600
|
'class': 'vjs-tech'
|
5418
|
-
}, options['attributes'])
|
5601
|
+
}, options['attributes']),
|
5602
|
+
|
5603
|
+
lastSeekTarget
|
5419
5604
|
;
|
5420
5605
|
|
5421
5606
|
// If source was supplied pass as a flash var.
|
@@ -5430,6 +5615,19 @@ vjs.Flash = vjs.MediaTechController.extend({
|
|
5430
5615
|
}
|
5431
5616
|
}
|
5432
5617
|
|
5618
|
+
this['setCurrentTime'] = function(time){
|
5619
|
+
lastSeekTarget = time;
|
5620
|
+
this.el_.vjs_setProperty('currentTime', time);
|
5621
|
+
};
|
5622
|
+
this['currentTime'] = function(time){
|
5623
|
+
// when seeking make the reported time keep up with the requested time
|
5624
|
+
// by reading the time we're seeking to
|
5625
|
+
if (this.seeking()) {
|
5626
|
+
return lastSeekTarget;
|
5627
|
+
}
|
5628
|
+
return this.el_.vjs_getProperty('currentTime');
|
5629
|
+
};
|
5630
|
+
|
5433
5631
|
// Add placeholder to player div
|
5434
5632
|
vjs.insertFirst(placeHolder, parentEl);
|
5435
5633
|
|
@@ -5443,6 +5641,17 @@ vjs.Flash = vjs.MediaTechController.extend({
|
|
5443
5641
|
});
|
5444
5642
|
}
|
5445
5643
|
|
5644
|
+
// firefox doesn't bubble mousemove events to parent. videojs/video-js-swf#37
|
5645
|
+
// bugzilla bug: https://bugzilla.mozilla.org/show_bug.cgi?id=836786
|
5646
|
+
if (vjs.IS_FIREFOX) {
|
5647
|
+
this.ready(function(){
|
5648
|
+
vjs.on(this.el(), 'mousemove', vjs.bind(this, function(){
|
5649
|
+
// since it's a custom event, don't bubble higher than the player
|
5650
|
+
this.player().trigger({ 'type':'mousemove', 'bubbles': false });
|
5651
|
+
}));
|
5652
|
+
});
|
5653
|
+
}
|
5654
|
+
|
5446
5655
|
// Flash iFrame Mode
|
5447
5656
|
// In web browsers there are multiple instances where changing the parent element or visibility of a plugin causes the plugin to reload.
|
5448
5657
|
// - Firefox just about always. https://bugzilla.mozilla.org/show_bug.cgi?id=90268 (might be fixed by version 13)
|
@@ -5627,6 +5836,9 @@ vjs.Flash.prototype.load = function(){
|
|
5627
5836
|
vjs.Flash.prototype.poster = function(){
|
5628
5837
|
this.el_.vjs_getProperty('poster');
|
5629
5838
|
};
|
5839
|
+
vjs.Flash.prototype.setPoster = function(){
|
5840
|
+
// poster images are not handled by the Flash tech so make this a no-op
|
5841
|
+
};
|
5630
5842
|
|
5631
5843
|
vjs.Flash.prototype.buffered = function(){
|
5632
5844
|
return vjs.createTimeRange(0, this.el_.vjs_getProperty('buffered'));
|
@@ -5643,9 +5855,9 @@ vjs.Flash.prototype.enterFullScreen = function(){
|
|
5643
5855
|
|
5644
5856
|
// Create setters and getters for attributes
|
5645
5857
|
var api = vjs.Flash.prototype,
|
5646
|
-
readWrite = 'rtmpConnection,rtmpStream,preload,
|
5858
|
+
readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','),
|
5647
5859
|
readOnly = 'error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks'.split(',');
|
5648
|
-
// Overridden: buffered
|
5860
|
+
// Overridden: buffered, currentTime
|
5649
5861
|
|
5650
5862
|
/**
|
5651
5863
|
* @this {*}
|
@@ -6236,7 +6448,7 @@ vjs.TextTrack.prototype.mode = function(){
|
|
6236
6448
|
* and restore it to its normal size when not in fullscreen mode.
|
6237
6449
|
*/
|
6238
6450
|
vjs.TextTrack.prototype.adjustFontSize = function(){
|
6239
|
-
if (this.player_.isFullScreen) {
|
6451
|
+
if (this.player_.isFullScreen()) {
|
6240
6452
|
// Scale the font by the same factor as increasing the video width to the full screen window width.
|
6241
6453
|
// Additionally, multiply that factor by 1.4, which is the default font size for
|
6242
6454
|
// the caption track (from the CSS)
|
@@ -6985,6 +7197,8 @@ if (typeof window.JSON !== 'undefined' && window.JSON.parse === 'function') {
|
|
6985
7197
|
* parse the json
|
6986
7198
|
*
|
6987
7199
|
* @memberof vjs.JSON
|
7200
|
+
* @param {String} text The JSON string to parse
|
7201
|
+
* @param {Function=} [reviver] Optional function that can transform the results
|
6988
7202
|
* @return {Object|Array} The parsed JSON
|
6989
7203
|
*/
|
6990
7204
|
vjs.JSON.parse = function (text, reviver) {
|