videojs_rails 4.3.0 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
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) {
|