mediaelement_rails 0.8.1 → 0.8.2
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/app/assets/javascripts/mediaelement_rails/mediaelement.js +175 -72
- data/app/assets/javascripts/mediaelement_rails/mediaelementplayer.js +288 -131
- data/app/assets/plugins/mediaelement_rails/flashmediaelement-cdn.swf +0 -0
- data/app/assets/plugins/mediaelement_rails/flashmediaelement.swf +0 -0
- data/app/assets/stylesheets/mediaelement_rails/mediaelementplayer.css.erb +22 -2
- data/lib/mediaelement_rails/version.rb +1 -1
- metadata +3 -3
@@ -12,6 +12,19 @@
|
|
12
12
|
*/
|
13
13
|
if (typeof jQuery != 'undefined') {
|
14
14
|
mejs.$ = jQuery;
|
15
|
+
} else if (typeof Zepto != 'undefined') {
|
16
|
+
mejs.$ = Zepto;
|
17
|
+
|
18
|
+
// define `outerWidth` method which has not been realized in Zepto
|
19
|
+
Zepto.fn.outerWidth = function(includeMargin) {
|
20
|
+
var width = $(this).width();
|
21
|
+
if (includeMargin) {
|
22
|
+
width += parseInt($(this).css('margin-right'), 10);
|
23
|
+
width += parseInt($(this).css('margin-left'), 10);
|
24
|
+
}
|
25
|
+
return width
|
26
|
+
}
|
27
|
+
|
15
28
|
} else if (typeof ender != 'undefined') {
|
16
29
|
mejs.$ = ender;
|
17
30
|
}
|
@@ -60,9 +73,25 @@ if (typeof jQuery != 'undefined') {
|
|
60
73
|
autoRewind: true,
|
61
74
|
// resize to media dimensions
|
62
75
|
enableAutosize: true,
|
76
|
+
|
77
|
+
/*
|
78
|
+
* Time format to use. Default: 'mm:ss'
|
79
|
+
* Supported units:
|
80
|
+
* h: hour
|
81
|
+
* m: minute
|
82
|
+
* s: second
|
83
|
+
* f: frame count
|
84
|
+
* When using 'hh', 'mm', 'ss' or 'ff' we always display 2 digits.
|
85
|
+
* If you use 'h', 'm', 's' or 'f' we display 1 digit if possible.
|
86
|
+
*
|
87
|
+
* Example to display 75 seconds:
|
88
|
+
* Format 'mm:ss': 01:15
|
89
|
+
* Format 'm:ss': 1:15
|
90
|
+
* Format 'm:s': 1:15
|
91
|
+
*/
|
92
|
+
timeFormat: '',
|
63
93
|
// forces the hour marker (##:00:00)
|
64
94
|
alwaysShowHours: false,
|
65
|
-
|
66
95
|
// show framecount in timecode (##:00:00:00)
|
67
96
|
showTimecodeFrameCount: false,
|
68
97
|
// used when showTimecodeFrameCount is set to true
|
@@ -102,9 +131,9 @@ if (typeof jQuery != 'undefined') {
|
|
102
131
|
],
|
103
132
|
action: function(player, media) {
|
104
133
|
if (media.paused || media.ended) {
|
105
|
-
|
134
|
+
media.play();
|
106
135
|
} else {
|
107
|
-
|
136
|
+
media.pause();
|
108
137
|
}
|
109
138
|
}
|
110
139
|
},
|
@@ -217,12 +246,13 @@ if (typeof jQuery != 'undefined') {
|
|
217
246
|
t.$media = t.$node = $(node);
|
218
247
|
t.node = t.media = t.$media[0];
|
219
248
|
|
249
|
+
if(!t.node) {
|
250
|
+
return
|
251
|
+
}
|
252
|
+
|
220
253
|
// check for existing player
|
221
254
|
if (typeof t.node.player != 'undefined') {
|
222
255
|
return t.node.player;
|
223
|
-
} else {
|
224
|
-
// attach player to DOM node for reference
|
225
|
-
t.node.player = t;
|
226
256
|
}
|
227
257
|
|
228
258
|
|
@@ -234,6 +264,19 @@ if (typeof jQuery != 'undefined') {
|
|
234
264
|
// extend default options
|
235
265
|
t.options = $.extend({},mejs.MepDefaults,o);
|
236
266
|
|
267
|
+
if (!t.options.timeFormat) {
|
268
|
+
// Generate the time format according to options
|
269
|
+
t.options.timeFormat = 'mm:ss';
|
270
|
+
if (t.options.alwaysShowHours) {
|
271
|
+
t.options.timeFormat = 'hh:mm:ss';
|
272
|
+
}
|
273
|
+
if (t.options.showTimecodeFrameCount) {
|
274
|
+
t.options.timeFormat += ':ff';
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
mejs.Utility.calculateTimeFormat(0, t.options, t.options.framesPerSecond || 25);
|
279
|
+
|
237
280
|
// unique ID
|
238
281
|
t.id = 'mep_' + mejs.mepIndex++;
|
239
282
|
|
@@ -351,6 +394,9 @@ if (typeof jQuery != 'undefined') {
|
|
351
394
|
// normal way of moving it into place (doesn't work on iOS)
|
352
395
|
t.container.find('.mejs-mediaelement').append(t.$media);
|
353
396
|
}
|
397
|
+
|
398
|
+
// needs to be assigned here, after iOS remap
|
399
|
+
t.node.player = t;
|
354
400
|
|
355
401
|
// find parts
|
356
402
|
t.controls = t.container.find('.mejs-controls');
|
@@ -743,6 +789,15 @@ if (typeof jQuery != 'undefined') {
|
|
743
789
|
t.setControlsSize();
|
744
790
|
}
|
745
791
|
}, false);
|
792
|
+
|
793
|
+
// Only change the time format when necessary
|
794
|
+
var duration = null;
|
795
|
+
t.media.addEventListener('timeupdate',function() {
|
796
|
+
if (duration !== this.duration) {
|
797
|
+
duration = this.duration;
|
798
|
+
mejs.Utility.calculateTimeFormat(duration, t.options, t.options.framesPerSecond || 25);
|
799
|
+
}
|
800
|
+
}, false);
|
746
801
|
|
747
802
|
t.container.focusout(function (e) {
|
748
803
|
if( e.relatedTarget ) { //FF is working on supporting focusout https://bugzilla.mozilla.org/show_bug.cgi?id=687787
|
@@ -823,7 +878,7 @@ if (typeof jQuery != 'undefined') {
|
|
823
878
|
}
|
824
879
|
|
825
880
|
// detect 100% mode - use currentStyle for IE since css() doesn't return percentages
|
826
|
-
if (t.height.toString().indexOf('%') > 0 || t.$node.css('max-width')
|
881
|
+
if (t.height.toString().indexOf('%') > 0 || (t.$node.css('max-width') !== 'none' && t.$node.css('max-width') !== 't.width') || (t.$node[0].currentStyle && t.$node[0].currentStyle.maxWidth === '100%')) {
|
827
882
|
|
828
883
|
// do we have the native dimensions yet?
|
829
884
|
var nativeWidth = (function() {
|
@@ -864,7 +919,7 @@ if (typeof jQuery != 'undefined') {
|
|
864
919
|
newHeight = parentHeight;
|
865
920
|
}
|
866
921
|
|
867
|
-
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
922
|
+
if (t.container.parent().length > 0 && t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
868
923
|
parentWidth = $(window).width();
|
869
924
|
newHeight = $(window).height();
|
870
925
|
}
|
@@ -907,13 +962,6 @@ if (typeof jQuery != 'undefined') {
|
|
907
962
|
|
908
963
|
}
|
909
964
|
|
910
|
-
// special case for big play button so it doesn't go over the controls area
|
911
|
-
var playLayer = t.layers.find('.mejs-overlay-play'),
|
912
|
-
playButton = playLayer.find('.mejs-overlay-button');
|
913
|
-
|
914
|
-
playLayer.height(t.container.height() - t.controls.height());
|
915
|
-
playButton.css('margin-top', '-' + (playButton.height()/2 - t.controls.height()/2).toString() + 'px' );
|
916
|
-
|
917
965
|
},
|
918
966
|
|
919
967
|
setControlsSize: function() {
|
@@ -922,8 +970,6 @@ if (typeof jQuery != 'undefined') {
|
|
922
970
|
railWidth = 0,
|
923
971
|
rail = t.controls.find('.mejs-time-rail'),
|
924
972
|
total = t.controls.find('.mejs-time-total'),
|
925
|
-
current = t.controls.find('.mejs-time-current'),
|
926
|
-
loaded = t.controls.find('.mejs-time-loaded'),
|
927
973
|
others = rail.siblings(),
|
928
974
|
lastControl = others.last(),
|
929
975
|
lastControlPosition = null;
|
@@ -966,15 +1012,12 @@ if (typeof jQuery != 'undefined') {
|
|
966
1012
|
total.width(railWidth - (total.outerWidth(true) - total.width()));
|
967
1013
|
|
968
1014
|
if (lastControl.css('position') != 'absolute') {
|
969
|
-
lastControlPosition = lastControl.position();
|
1015
|
+
lastControlPosition = lastControl.length ? lastControl.position() : null;
|
970
1016
|
railWidth--;
|
971
1017
|
}
|
972
1018
|
} while (lastControlPosition !== null && lastControlPosition.top > 0 && railWidth > 0);
|
973
1019
|
|
974
|
-
|
975
|
-
t.setProgressRail();
|
976
|
-
if (t.setCurrentRail)
|
977
|
-
t.setCurrentRail();
|
1020
|
+
t.container.trigger('controlsresize');
|
978
1021
|
},
|
979
1022
|
|
980
1023
|
|
@@ -1015,7 +1058,7 @@ if (typeof jQuery != 'undefined') {
|
|
1015
1058
|
posterImg = posterDiv.find('img');
|
1016
1059
|
|
1017
1060
|
if (posterImg.length === 0) {
|
1018
|
-
posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
|
1061
|
+
posterImg = $('<img width="100%" height="100%" alt="" />').appendTo(posterDiv);
|
1019
1062
|
}
|
1020
1063
|
|
1021
1064
|
posterImg.attr('src', url);
|
@@ -1127,11 +1170,12 @@ if (typeof jQuery != 'undefined') {
|
|
1127
1170
|
}, false);
|
1128
1171
|
|
1129
1172
|
// error handling
|
1130
|
-
media.addEventListener('error',function() {
|
1173
|
+
media.addEventListener('error',function(e) {
|
1174
|
+
t.handleError(e);
|
1131
1175
|
loading.hide();
|
1132
|
-
|
1176
|
+
bigPlay.hide();
|
1133
1177
|
error.show();
|
1134
|
-
error.find('mejs-overlay-error').html("Error loading this resource");
|
1178
|
+
error.find('.mejs-overlay-error').html("Error loading this resource");
|
1135
1179
|
}, false);
|
1136
1180
|
|
1137
1181
|
media.addEventListener('keydown', function(e) {
|
@@ -1239,6 +1283,8 @@ if (typeof jQuery != 'undefined') {
|
|
1239
1283
|
},
|
1240
1284
|
remove: function() {
|
1241
1285
|
var t = this, featureIndex, feature;
|
1286
|
+
|
1287
|
+
t.container.prev('.mejs-offscreen').remove();
|
1242
1288
|
|
1243
1289
|
// invoke features cleanup
|
1244
1290
|
for (featureIndex in t.options.features) {
|
@@ -1284,6 +1330,15 @@ if (typeof jQuery != 'undefined') {
|
|
1284
1330
|
var t = this;
|
1285
1331
|
t.findTracks();
|
1286
1332
|
t.buildtracks(t, t.controls, t.layers, t.media);
|
1333
|
+
},
|
1334
|
+
resetSize: function(){
|
1335
|
+
var t = this;
|
1336
|
+
// webkit has trouble doing this without a delay
|
1337
|
+
setTimeout(function () {
|
1338
|
+
//
|
1339
|
+
t.setPlayerSize(t.width, t.height);
|
1340
|
+
t.setControlsSize();
|
1341
|
+
}, 50);
|
1287
1342
|
}
|
1288
1343
|
};
|
1289
1344
|
|
@@ -1433,9 +1488,9 @@ if (typeof jQuery != 'undefined') {
|
|
1433
1488
|
// STOP BUTTON
|
1434
1489
|
$.extend(MediaElementPlayer.prototype, {
|
1435
1490
|
buildstop: function(player, controls, layers, media) {
|
1436
|
-
var t = this
|
1437
|
-
|
1438
|
-
|
1491
|
+
var t = this;
|
1492
|
+
|
1493
|
+
$('<div class="mejs-button mejs-stop-button mejs-stop">' +
|
1439
1494
|
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.stopText + '" aria-label="' + t.options.stopText + '"></button>' +
|
1440
1495
|
'</div>')
|
1441
1496
|
.appendTo(controls)
|
@@ -1448,8 +1503,8 @@ if (typeof jQuery != 'undefined') {
|
|
1448
1503
|
media.pause();
|
1449
1504
|
controls.find('.mejs-time-current').width('0px');
|
1450
1505
|
controls.find('.mejs-time-handle').css('left', '0px');
|
1451
|
-
controls.find('.mejs-time-float-current').html( mejs.Utility.secondsToTimeCode(0
|
1452
|
-
controls.find('.mejs-currenttime').html( mejs.Utility.secondsToTimeCode(0
|
1506
|
+
controls.find('.mejs-time-float-current').html( mejs.Utility.secondsToTimeCode(0, player.options));
|
1507
|
+
controls.find('.mejs-currenttime').html( mejs.Utility.secondsToTimeCode(0, player.options));
|
1453
1508
|
layers.find('.mejs-poster').show();
|
1454
1509
|
}
|
1455
1510
|
});
|
@@ -1472,15 +1527,16 @@ if (typeof jQuery != 'undefined') {
|
|
1472
1527
|
$('<div class="mejs-time-rail">' +
|
1473
1528
|
'<span class="mejs-time-total mejs-time-slider">' +
|
1474
1529
|
//'<span class="mejs-offscreen">' + this.options.progessHelpText + '</span>' +
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1530
|
+
'<span class="mejs-time-buffering"></span>' +
|
1531
|
+
'<span class="mejs-time-loaded"></span>' +
|
1532
|
+
'<span class="mejs-time-current"></span>' +
|
1533
|
+
'<span class="mejs-time-handle"></span>' +
|
1534
|
+
'<span class="mejs-time-float">' +
|
1535
|
+
'<span class="mejs-time-float-current">00:00</span>' +
|
1536
|
+
'<span class="mejs-time-float-corner"></span>' +
|
1537
|
+
'</span>' +
|
1482
1538
|
'</span>' +
|
1483
|
-
|
1539
|
+
'</div>')
|
1484
1540
|
.appendTo(controls);
|
1485
1541
|
controls.find('.mejs-time-buffering').hide();
|
1486
1542
|
|
@@ -1503,9 +1559,11 @@ if (typeof jQuery != 'undefined') {
|
|
1503
1559
|
x;
|
1504
1560
|
|
1505
1561
|
// mouse or touch position relative to the object
|
1506
|
-
if (e.originalEvent.changedTouches) {
|
1562
|
+
if (e.originalEvent && e.originalEvent.changedTouches) {
|
1507
1563
|
x = e.originalEvent.changedTouches[0].pageX;
|
1508
|
-
}else{
|
1564
|
+
} else if (e.changedTouches) { // for Zepto
|
1565
|
+
x = e.changedTouches[0].pageX;
|
1566
|
+
} else {
|
1509
1567
|
x = e.pageX;
|
1510
1568
|
}
|
1511
1569
|
|
@@ -1528,7 +1586,7 @@ if (typeof jQuery != 'undefined') {
|
|
1528
1586
|
// position floating time box
|
1529
1587
|
if (!mejs.MediaFeatures.hasTouch) {
|
1530
1588
|
timefloat.css('left', pos);
|
1531
|
-
timefloatcurrent.html( mejs.Utility.secondsToTimeCode(newTime) );
|
1589
|
+
timefloatcurrent.html( mejs.Utility.secondsToTimeCode(newTime, player.options) );
|
1532
1590
|
timefloat.show();
|
1533
1591
|
}
|
1534
1592
|
}
|
@@ -1543,7 +1601,7 @@ if (typeof jQuery != 'undefined') {
|
|
1543
1601
|
|
1544
1602
|
var seconds = media.currentTime,
|
1545
1603
|
timeSliderText = mejs.i18n.t('Time Slider'),
|
1546
|
-
time = mejs.Utility.secondsToTimeCode(seconds),
|
1604
|
+
time = mejs.Utility.secondsToTimeCode(seconds, player.options),
|
1547
1605
|
duration = media.duration;
|
1548
1606
|
|
1549
1607
|
slider.attr({
|
@@ -1678,6 +1736,10 @@ if (typeof jQuery != 'undefined') {
|
|
1678
1736
|
updateSlider(e);
|
1679
1737
|
}, false);
|
1680
1738
|
|
1739
|
+
t.container.on('controlsresize', function() {
|
1740
|
+
player.setProgressRail();
|
1741
|
+
player.setCurrentRail();
|
1742
|
+
});
|
1681
1743
|
|
1682
1744
|
// store for later use
|
1683
1745
|
t.loaded = loaded;
|
@@ -1694,8 +1756,8 @@ if (typeof jQuery != 'undefined') {
|
|
1694
1756
|
|
1695
1757
|
// newest HTML5 spec has buffered array (FF4, Webkit)
|
1696
1758
|
if (target && target.buffered && target.buffered.length > 0 && target.buffered.end && target.duration) {
|
1697
|
-
//
|
1698
|
-
percent = target.buffered.end(
|
1759
|
+
// account for a real array with multiple values - always read the end of the last buffer
|
1760
|
+
percent = target.buffered.end(target.buffered.length - 1) / target.duration;
|
1699
1761
|
}
|
1700
1762
|
// Some browsers (e.g., FF3.6 and Safari 5) cannot calculate target.bufferered.end()
|
1701
1763
|
// to be anything other than 0. If the byte count is available we use this instead.
|
@@ -1738,6 +1800,7 @@ if (typeof jQuery != 'undefined') {
|
|
1738
1800
|
}
|
1739
1801
|
});
|
1740
1802
|
})(mejs.$);
|
1803
|
+
|
1741
1804
|
(function($) {
|
1742
1805
|
|
1743
1806
|
// options
|
@@ -1754,8 +1817,7 @@ if (typeof jQuery != 'undefined') {
|
|
1754
1817
|
|
1755
1818
|
$('<div class="mejs-time" role="timer" aria-live="off">' +
|
1756
1819
|
'<span class="mejs-currenttime">' +
|
1757
|
-
|
1758
|
-
(player.options.showTimecodeFrameCount? '00:00:00':'00:00') +
|
1820
|
+
mejs.Utility.secondsToTimeCode(0, player.options) +
|
1759
1821
|
'</span>'+
|
1760
1822
|
'</div>')
|
1761
1823
|
.appendTo(controls);
|
@@ -1774,10 +1836,7 @@ if (typeof jQuery != 'undefined') {
|
|
1774
1836
|
if (controls.children().last().find('.mejs-currenttime').length > 0) {
|
1775
1837
|
$(t.options.timeAndDurationSeparator +
|
1776
1838
|
'<span class="mejs-duration">' +
|
1777
|
-
(t.options.duration
|
1778
|
-
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1779
|
-
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1780
|
-
) +
|
1839
|
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options) +
|
1781
1840
|
'</span>')
|
1782
1841
|
.appendTo(controls.find('.mejs-time'));
|
1783
1842
|
} else {
|
@@ -1787,10 +1846,7 @@ if (typeof jQuery != 'undefined') {
|
|
1787
1846
|
|
1788
1847
|
$('<div class="mejs-time mejs-duration-container">'+
|
1789
1848
|
'<span class="mejs-duration">' +
|
1790
|
-
(t.options.duration
|
1791
|
-
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1792
|
-
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1793
|
-
) +
|
1849
|
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options) +
|
1794
1850
|
'</span>' +
|
1795
1851
|
'</div>')
|
1796
1852
|
.appendTo(controls);
|
@@ -1807,7 +1863,7 @@ if (typeof jQuery != 'undefined') {
|
|
1807
1863
|
var t = this;
|
1808
1864
|
|
1809
1865
|
if (t.currenttime) {
|
1810
|
-
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options
|
1866
|
+
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options));
|
1811
1867
|
}
|
1812
1868
|
},
|
1813
1869
|
|
@@ -1818,7 +1874,7 @@ if (typeof jQuery != 'undefined') {
|
|
1818
1874
|
t.container.toggleClass("mejs-long-video", t.media.duration > 3600);
|
1819
1875
|
|
1820
1876
|
if (t.durationD && (t.options.duration > 0 || t.media.duration)) {
|
1821
|
-
t.durationD.html(mejs.Utility.secondsToTimeCode(t.options.duration > 0 ? t.options.duration : t.media.duration, t.options
|
1877
|
+
t.durationD.html(mejs.Utility.secondsToTimeCode(t.options.duration > 0 ? t.options.duration : t.media.duration, t.options));
|
1822
1878
|
}
|
1823
1879
|
}
|
1824
1880
|
});
|
@@ -1898,8 +1954,10 @@ if (typeof jQuery != 'undefined') {
|
|
1898
1954
|
// ajust mute button style
|
1899
1955
|
if (volume === 0) {
|
1900
1956
|
mute.removeClass('mejs-mute').addClass('mejs-unmute');
|
1957
|
+
mute.children('button').attr('title', mejs.i18n.t('Unmute')).attr('aria-label', mejs.i18n.t('Unmute'));
|
1901
1958
|
} else {
|
1902
1959
|
mute.removeClass('mejs-unmute').addClass('mejs-mute');
|
1960
|
+
mute.children('button').attr('title', mejs.i18n.t('Mute')).attr('aria-label', mejs.i18n.t('Mute'));
|
1903
1961
|
}
|
1904
1962
|
|
1905
1963
|
// top/left of full size volume slider background
|
@@ -1945,7 +2003,6 @@ if (typeof jQuery != 'undefined') {
|
|
1945
2003
|
|
1946
2004
|
var
|
1947
2005
|
railHeight = volumeTotal.height(),
|
1948
|
-
totalTop = parseInt(volumeTotal.css('top').replace(/px/,''),10),
|
1949
2006
|
newY = e.pageY - totalOffset.top;
|
1950
2007
|
|
1951
2008
|
volume = (railHeight - newY) / railHeight;
|
@@ -2078,25 +2135,25 @@ if (typeof jQuery != 'undefined') {
|
|
2078
2135
|
}
|
2079
2136
|
updateVolumeSlider(e);
|
2080
2137
|
}, false);
|
2081
|
-
|
2082
|
-
if
|
2083
|
-
|
2084
|
-
|
2085
|
-
|
2086
|
-
// mutes the media and sets the volume icon muted if the initial volume is set to 0
|
2087
|
-
if (player.options.startVolume === 0) {
|
2088
|
-
media.setMuted(true);
|
2089
|
-
}
|
2090
|
-
|
2091
|
-
// shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
|
2092
|
-
if (media.pluginType === 'native') {
|
2093
|
-
media.setVolume(player.options.startVolume);
|
2094
|
-
}
|
2138
|
+
|
2139
|
+
// mutes the media and sets the volume icon muted if the initial volume is set to 0
|
2140
|
+
if (player.options.startVolume === 0) {
|
2141
|
+
media.setMuted(true);
|
2095
2142
|
}
|
2143
|
+
|
2144
|
+
// shim gets the startvolume as a parameter, but we have to set it on the native <video> and <audio> elements
|
2145
|
+
if (media.pluginType === 'native') {
|
2146
|
+
media.setVolume(player.options.startVolume);
|
2147
|
+
}
|
2148
|
+
|
2149
|
+
t.container.on('controlsresize', function() {
|
2150
|
+
positionVolumeHandle(media.volume);
|
2151
|
+
});
|
2096
2152
|
}
|
2097
2153
|
});
|
2098
2154
|
|
2099
2155
|
})(mejs.$);
|
2156
|
+
|
2100
2157
|
(function($) {
|
2101
2158
|
|
2102
2159
|
$.extend(mejs.MepDefaults, {
|
@@ -2143,9 +2200,6 @@ if (typeof jQuery != 'undefined') {
|
|
2143
2200
|
}
|
2144
2201
|
|
2145
2202
|
var t = this,
|
2146
|
-
normalHeight = 0,
|
2147
|
-
normalWidth = 0,
|
2148
|
-
container = player.container,
|
2149
2203
|
fullscreenBtn =
|
2150
2204
|
$('<div class="mejs-button mejs-fullscreen-button">' +
|
2151
2205
|
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '" aria-label="' + t.options.fullscreenText + '"></button>' +
|
@@ -2375,6 +2429,9 @@ if (typeof jQuery != 'undefined') {
|
|
2375
2429
|
player.exitFullScreen();
|
2376
2430
|
}
|
2377
2431
|
});
|
2432
|
+
|
2433
|
+
t.normalHeight = 0;
|
2434
|
+
t.normalWidth = 0;
|
2378
2435
|
|
2379
2436
|
},
|
2380
2437
|
|
@@ -2399,8 +2456,8 @@ if (typeof jQuery != 'undefined') {
|
|
2399
2456
|
$(document.documentElement).addClass('mejs-fullscreen');
|
2400
2457
|
|
2401
2458
|
// store sizing
|
2402
|
-
normalHeight = t.container.height();
|
2403
|
-
normalWidth = t.container.width();
|
2459
|
+
t.normalHeight = t.container.height();
|
2460
|
+
t.normalWidth = t.container.width();
|
2404
2461
|
|
2405
2462
|
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
2406
2463
|
if (t.media.pluginType === 'native') {
|
@@ -2415,13 +2472,25 @@ if (typeof jQuery != 'undefined') {
|
|
2415
2472
|
setTimeout(function checkFullscreen() {
|
2416
2473
|
|
2417
2474
|
if (t.isNativeFullScreen) {
|
2418
|
-
var zoomMultiplier = window["devicePixelRatio"] || 1
|
2475
|
+
var zoomMultiplier = window["devicePixelRatio"] || 1,
|
2419
2476
|
// Use a percent error margin since devicePixelRatio is a float and not exact.
|
2420
|
-
|
2421
|
-
|
2422
|
-
|
2423
|
-
|
2424
|
-
|
2477
|
+
percentErrorMargin = 0.002, // 0.2%
|
2478
|
+
windowWidth = zoomMultiplier * $(window).width(),
|
2479
|
+
screenWidth = screen.width,
|
2480
|
+
// ** 13twelve
|
2481
|
+
// Screen width is sort of useless: http://www.quirksmode.org/blog/archives/2013/11/screenwidth_is.html
|
2482
|
+
// My rMBP ignores devicePixelRatio when returning the values, so fullscreen would always fail the "suddenly not fullscreen" test
|
2483
|
+
// Theory: the gap between reported values should give us an indication of browser behavior with screen.width and devicePixelRatio
|
2484
|
+
zoomedWindowWidth = zoomMultiplier * windowWidth;
|
2485
|
+
|
2486
|
+
if (Math.abs(screenWidth-windowWidth) > Math.abs(screenWidth-zoomedWindowWidth)) {
|
2487
|
+
// screen.width is likely true pixels, not CSS pixels, so we need to use the zoomed window width for comparison
|
2488
|
+
windowWidth = zoomedWindowWidth;
|
2489
|
+
}
|
2490
|
+
// ** / 13twelve
|
2491
|
+
|
2492
|
+
var absDiff = Math.abs(screenWidth - windowWidth),
|
2493
|
+
marginError = screenWidth * percentErrorMargin;
|
2425
2494
|
|
2426
2495
|
// check if the video is suddenly not really fullscreen
|
2427
2496
|
if (absDiff > marginError) {
|
@@ -2432,9 +2501,8 @@ if (typeof jQuery != 'undefined') {
|
|
2432
2501
|
setTimeout(checkFullscreen, 500);
|
2433
2502
|
}
|
2434
2503
|
}
|
2435
|
-
|
2436
|
-
|
2437
|
-
}, 500);
|
2504
|
+
|
2505
|
+
}, 1000);
|
2438
2506
|
}
|
2439
2507
|
|
2440
2508
|
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
@@ -2516,6 +2584,8 @@ if (typeof jQuery != 'undefined') {
|
|
2516
2584
|
|
2517
2585
|
t.container.find('.mejs-captions-text').css('font-size', screen.width / t.width * 1.00 * 100 + '%');
|
2518
2586
|
t.container.find('.mejs-captions-position').css('bottom', '45px');
|
2587
|
+
|
2588
|
+
t.container.trigger('enteredfullscreen');
|
2519
2589
|
},
|
2520
2590
|
|
2521
2591
|
exitFullScreen: function() {
|
@@ -2542,25 +2612,24 @@ if (typeof jQuery != 'undefined') {
|
|
2542
2612
|
|
2543
2613
|
t.container
|
2544
2614
|
.removeClass('mejs-container-fullscreen')
|
2545
|
-
.width(normalWidth)
|
2546
|
-
.height(normalHeight);
|
2547
|
-
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
2615
|
+
.width(t.normalWidth)
|
2616
|
+
.height(t.normalHeight);
|
2548
2617
|
|
2549
2618
|
if (t.media.pluginType === 'native') {
|
2550
2619
|
t.$media
|
2551
|
-
.width(normalWidth)
|
2552
|
-
.height(normalHeight);
|
2620
|
+
.width(t.normalWidth)
|
2621
|
+
.height(t.normalHeight);
|
2553
2622
|
} else {
|
2554
2623
|
t.container.find('.mejs-shim')
|
2555
|
-
.width(normalWidth)
|
2556
|
-
.height(normalHeight);
|
2624
|
+
.width(t.normalWidth)
|
2625
|
+
.height(t.normalHeight);
|
2557
2626
|
|
2558
|
-
t.media.setVideoSize(normalWidth, normalHeight);
|
2627
|
+
t.media.setVideoSize(t.normalWidth, t.normalHeight);
|
2559
2628
|
}
|
2560
2629
|
|
2561
2630
|
t.layers.children('div')
|
2562
|
-
.width(normalWidth)
|
2563
|
-
.height(normalHeight);
|
2631
|
+
.width(t.normalWidth)
|
2632
|
+
.height(t.normalHeight);
|
2564
2633
|
|
2565
2634
|
t.fullscreenBtn
|
2566
2635
|
.removeClass('mejs-unfullscreen')
|
@@ -2571,6 +2640,8 @@ if (typeof jQuery != 'undefined') {
|
|
2571
2640
|
|
2572
2641
|
t.container.find('.mejs-captions-text').css('font-size','');
|
2573
2642
|
t.container.find('.mejs-captions-position').css('bottom', '');
|
2643
|
+
|
2644
|
+
t.container.trigger('exitedfullscreen');
|
2574
2645
|
}
|
2575
2646
|
});
|
2576
2647
|
|
@@ -2581,6 +2652,8 @@ if (typeof jQuery != 'undefined') {
|
|
2581
2652
|
// Speed
|
2582
2653
|
$.extend(mejs.MepDefaults, {
|
2583
2654
|
|
2655
|
+
// We also support to pass object like this:
|
2656
|
+
// [{name: 'Slow', value: '0.75'}, {name: 'Normal', value: '1.00'}, ...]
|
2584
2657
|
speeds: ['2.00', '1.50', '1.25', '1.00', '0.75'],
|
2585
2658
|
|
2586
2659
|
defaultSpeed: '1.00',
|
@@ -2599,53 +2672,90 @@ if (typeof jQuery != 'undefined') {
|
|
2599
2672
|
speedButton = null,
|
2600
2673
|
speedSelector = null,
|
2601
2674
|
playbackSpeed = null,
|
2602
|
-
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2675
|
+
inputId = null;
|
2676
|
+
|
2677
|
+
var speeds = [];
|
2678
|
+
var defaultInArray = false;
|
2679
|
+
for (var i=0, len=t.options.speeds.length; i < len; i++) {
|
2680
|
+
var s = t.options.speeds[i];
|
2681
|
+
if (typeof(s) === 'string'){
|
2682
|
+
speeds.push({
|
2683
|
+
name: s + t.options.speedChar,
|
2684
|
+
value: s
|
2685
|
+
});
|
2686
|
+
if(s === t.options.defaultSpeed) {
|
2687
|
+
defaultInArray = true;
|
2688
|
+
}
|
2689
|
+
}
|
2690
|
+
else {
|
2691
|
+
speeds.push(s);
|
2692
|
+
if(s.value === t.options.defaultSpeed) {
|
2693
|
+
defaultInArray = true;
|
2694
|
+
}
|
2695
|
+
}
|
2696
|
+
}
|
2697
|
+
|
2698
|
+
if (!defaultInArray) {
|
2699
|
+
speeds.push({
|
2700
|
+
name: t.options.defaultSpeed + t.options.speedChar,
|
2701
|
+
value: t.options.defaultSpeed
|
2702
|
+
});
|
2609
2703
|
}
|
2610
2704
|
|
2611
|
-
|
2612
|
-
return parseFloat(b) - parseFloat(a);
|
2705
|
+
speeds.sort(function(a, b) {
|
2706
|
+
return parseFloat(b.value) - parseFloat(a.value);
|
2613
2707
|
});
|
2614
2708
|
|
2615
|
-
|
2709
|
+
var getSpeedNameFromValue = function(value) {
|
2710
|
+
for(i=0,len=speeds.length; i <len; i++) {
|
2711
|
+
if (speeds[i].value === value) {
|
2712
|
+
return speeds[i].name;
|
2713
|
+
}
|
2714
|
+
}
|
2715
|
+
};
|
2716
|
+
|
2717
|
+
var html = '<div class="mejs-button mejs-speed-button">' +
|
2718
|
+
'<button type="button">' + getSpeedNameFromValue(t.options.defaultSpeed) + '</button>' +
|
2719
|
+
'<div class="mejs-speed-selector">' +
|
2720
|
+
'<ul>';
|
2721
|
+
|
2722
|
+
for (i = 0, il = speeds.length; i<il; i++) {
|
2723
|
+
inputId = t.id + '-speed-' + speeds[i].value;
|
2616
2724
|
html += '<li>' +
|
2617
2725
|
'<input type="radio" name="speed" ' +
|
2618
|
-
'value="' +
|
2619
|
-
'id="' +
|
2620
|
-
(
|
2726
|
+
'value="' + speeds[i].value + '" ' +
|
2727
|
+
'id="' + inputId + '" ' +
|
2728
|
+
(speeds[i].value === t.options.defaultSpeed ? ' checked' : '') +
|
2621
2729
|
' />' +
|
2622
|
-
'<label for="' +
|
2623
|
-
(
|
2624
|
-
'>' +
|
2730
|
+
'<label for="' + inputId + '" ' +
|
2731
|
+
(speeds[i].value === t.options.defaultSpeed ? ' class="mejs-speed-selected"' : '') +
|
2732
|
+
'>' + speeds[i].name + '</label>' +
|
2625
2733
|
'</li>';
|
2626
2734
|
}
|
2627
2735
|
html += '</ul></div></div>';
|
2628
2736
|
|
2629
2737
|
speedButton = $(html).appendTo(controls);
|
2630
|
-
speedSelector = speedButton.find('.mejs-speed-selector');
|
2738
|
+
speedSelector = speedButton.find('.mejs-speed-selector');
|
2631
2739
|
|
2632
|
-
|
2740
|
+
playbackSpeed = t.options.defaultSpeed;
|
2633
2741
|
|
2634
2742
|
speedSelector
|
2635
2743
|
.on('click', 'input[type="radio"]', function() {
|
2636
2744
|
var newSpeed = $(this).attr('value');
|
2637
|
-
|
2745
|
+
playbackSpeed = newSpeed;
|
2638
2746
|
media.playbackRate = parseFloat(newSpeed);
|
2639
|
-
speedButton.find('button').html(newSpeed
|
2747
|
+
speedButton.find('button').html(getSpeedNameFromValue(newSpeed));
|
2640
2748
|
speedButton.find('.mejs-speed-selected').removeClass('mejs-speed-selected');
|
2641
2749
|
speedButton.find('input[type="radio"]:checked').next().addClass('mejs-speed-selected');
|
2642
2750
|
});
|
2643
|
-
|
2644
|
-
|
2645
|
-
|
2646
|
-
|
2647
|
-
|
2648
|
-
|
2751
|
+
speedButton
|
2752
|
+
.one( 'mouseenter focusin', function() {
|
2753
|
+
speedSelector
|
2754
|
+
.height(
|
2755
|
+
speedButton.find('.mejs-speed-selector ul').outerHeight(true) +
|
2756
|
+
speedButton.find('.mejs-speed-translations').outerHeight(true))
|
2757
|
+
.css('top', (-1 * speedSelector.height()) + 'px');
|
2758
|
+
});
|
2649
2759
|
}
|
2650
2760
|
}
|
2651
2761
|
});
|
@@ -2661,6 +2771,10 @@ if (typeof jQuery != 'undefined') {
|
|
2661
2771
|
|
2662
2772
|
tracksText: mejs.i18n.t('Captions/Subtitles'),
|
2663
2773
|
|
2774
|
+
// By default, no WAI-ARIA live region - don't make a
|
2775
|
+
// screen reader speak captions over an audio track.
|
2776
|
+
tracksAriaLive: false,
|
2777
|
+
|
2664
2778
|
// option to remove the [cc] button when no <track kind="subtitles"> are present
|
2665
2779
|
hideCaptionsButtonWhenEmpty: true,
|
2666
2780
|
|
@@ -2688,8 +2802,9 @@ if (typeof jQuery != 'undefined') {
|
|
2688
2802
|
return;
|
2689
2803
|
|
2690
2804
|
var t = this,
|
2691
|
-
|
2692
|
-
|
2805
|
+
attr = t.options.tracksAriaLive ?
|
2806
|
+
'role="log" aria-live="assertive" aria-atomic="false"' : '',
|
2807
|
+
i;
|
2693
2808
|
|
2694
2809
|
if (t.domNode.textTracks) { // if browser will do native captions, prefer mejs captions, loop through tracks and hide
|
2695
2810
|
for (i = t.domNode.textTracks.length - 1; i >= 0; i--) {
|
@@ -2701,7 +2816,8 @@ if (typeof jQuery != 'undefined') {
|
|
2701
2816
|
$('<div class="mejs-chapters mejs-layer"></div>')
|
2702
2817
|
.prependTo(layers).hide();
|
2703
2818
|
player.captions =
|
2704
|
-
$('<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position mejs-captions-position-hover"
|
2819
|
+
$('<div class="mejs-captions-layer mejs-layer"><div class="mejs-captions-position mejs-captions-position-hover" ' +
|
2820
|
+
attr + '><span class="mejs-captions-text"></span></div></div>')
|
2705
2821
|
.prependTo(layers).hide();
|
2706
2822
|
player.captionsText = player.captions.find('.mejs-captions-text');
|
2707
2823
|
player.captionsButton =
|
@@ -2821,6 +2937,10 @@ if (typeof jQuery != 'undefined') {
|
|
2821
2937
|
}
|
2822
2938
|
});
|
2823
2939
|
|
2940
|
+
t.container.on('controlsresize', function() {
|
2941
|
+
t.adjustLanguageBox();
|
2942
|
+
});
|
2943
|
+
|
2824
2944
|
// check for autoplay
|
2825
2945
|
if (player.node.getAttribute('autoplay') !== null) {
|
2826
2946
|
player.chapters.css('visibility','hidden');
|
@@ -2872,8 +2992,6 @@ if (typeof jQuery != 'undefined') {
|
|
2872
2992
|
|
2873
2993
|
track.isLoaded = true;
|
2874
2994
|
|
2875
|
-
// create button
|
2876
|
-
//t.addTrackButton(track.srclang);
|
2877
2995
|
t.enableTrackButton(track.srclang, track.label);
|
2878
2996
|
|
2879
2997
|
t.loadNextTrack();
|
@@ -2908,6 +3026,7 @@ if (typeof jQuery != 'undefined') {
|
|
2908
3026
|
}
|
2909
3027
|
},
|
2910
3028
|
error: function() {
|
3029
|
+
t.removeTrackButton(track.srclang);
|
2911
3030
|
t.loadNextTrack();
|
2912
3031
|
}
|
2913
3032
|
});
|
@@ -2933,6 +3052,14 @@ if (typeof jQuery != 'undefined') {
|
|
2933
3052
|
|
2934
3053
|
t.adjustLanguageBox();
|
2935
3054
|
},
|
3055
|
+
|
3056
|
+
removeTrackButton: function(lang) {
|
3057
|
+
var t = this;
|
3058
|
+
|
3059
|
+
t.captionsButton.find('input[value=' + lang + ']').closest('li').remove();
|
3060
|
+
|
3061
|
+
t.adjustLanguageBox();
|
3062
|
+
},
|
2936
3063
|
|
2937
3064
|
addTrackButton: function(lang, label) {
|
2938
3065
|
var t = this;
|
@@ -2970,7 +3097,7 @@ if (typeof jQuery != 'undefined') {
|
|
2970
3097
|
// check if any subtitles
|
2971
3098
|
if (t.options.hideCaptionsButtonWhenEmpty) {
|
2972
3099
|
for (i=0; i<t.tracks.length; i++) {
|
2973
|
-
if (t.tracks[i].kind == 'subtitles') {
|
3100
|
+
if (t.tracks[i].kind == 'subtitles' && t.tracks[i].isLoaded) {
|
2974
3101
|
hasSubtitles = true;
|
2975
3102
|
break;
|
2976
3103
|
}
|
@@ -3116,7 +3243,7 @@ if (typeof jQuery != 'undefined') {
|
|
3116
3243
|
'<div class="mejs-chapter" rel="' + chapters.entries.times[i].start + '" style="left: ' + usedPercent.toString() + '%;width: ' + percent.toString() + '%;">' +
|
3117
3244
|
'<div class="mejs-chapter-block' + ((i==chapters.entries.times.length-1) ? ' mejs-chapter-block-last' : '') + '">' +
|
3118
3245
|
'<span class="ch-title">' + chapters.entries.text[i] + '</span>' +
|
3119
|
-
'<span class="ch-time">' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].start) + '–' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].stop) + '</span>' +
|
3246
|
+
'<span class="ch-time">' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].start, t.options) + '–' + mejs.Utility.secondsToTimeCode(chapters.entries.times[i].stop, t.options) + '</span>' +
|
3120
3247
|
'</div>' +
|
3121
3248
|
'</div>'));
|
3122
3249
|
usedPercent += percent;
|
@@ -3266,8 +3393,6 @@ if (typeof jQuery != 'undefined') {
|
|
3266
3393
|
lines = container.find("p"),
|
3267
3394
|
styleNode = trackText.find("#" + container.attr("style")),
|
3268
3395
|
styles,
|
3269
|
-
begin,
|
3270
|
-
end,
|
3271
3396
|
text,
|
3272
3397
|
entries = {text:[], times:[]};
|
3273
3398
|
|
@@ -3536,6 +3661,38 @@ $.extend(mejs.MepDefaults,
|
|
3536
3661
|
});
|
3537
3662
|
|
3538
3663
|
})(mejs.$);
|
3664
|
+
(function($) {
|
3665
|
+
// skip back button
|
3666
|
+
|
3667
|
+
$.extend(mejs.MepDefaults, {
|
3668
|
+
skipBackInterval: 30,
|
3669
|
+
// %1 will be replaced with skipBackInterval in this string
|
3670
|
+
skipBackText: mejs.i18n.t('Skip back %1 seconds')
|
3671
|
+
});
|
3672
|
+
|
3673
|
+
$.extend(MediaElementPlayer.prototype, {
|
3674
|
+
buildskipback: function(player, controls, layers, media) {
|
3675
|
+
var
|
3676
|
+
t = this,
|
3677
|
+
// Replace %1 with skip back interval
|
3678
|
+
backText = t.options.skipBackText.replace('%1', t.options.skipBackInterval),
|
3679
|
+
// create the loop button
|
3680
|
+
loop =
|
3681
|
+
$('<div class="mejs-button mejs-skip-back-button">' +
|
3682
|
+
'<button type="button" aria-controls="' + t.id + '" title="' + backText + '" aria-label="' + backText + '">' + t.options.skipBackInterval + '</button>' +
|
3683
|
+
'</div>')
|
3684
|
+
// append it to the toolbar
|
3685
|
+
.appendTo(controls)
|
3686
|
+
// add a click toggle event
|
3687
|
+
.click(function() {
|
3688
|
+
media.setCurrentTime(Math.max(media.currentTime - t.options.skipBackInterval, 0));
|
3689
|
+
$(this).find('button').blur();
|
3690
|
+
});
|
3691
|
+
}
|
3692
|
+
});
|
3693
|
+
|
3694
|
+
})(mejs.$);
|
3695
|
+
|
3539
3696
|
/**
|
3540
3697
|
* Postroll plugin
|
3541
3698
|
*/
|