Version Description
- Changed some default values and normalized all files with end of file as line feed only
Download this release
Release Info
Developer | rtcamp |
Plugin | rtMedia for WordPress, BuddyPress and bbPress |
Version | 2.1.2 |
Comparing to | |
See all releases |
Code changes from version 2.1.1 to 2.1.2
- includes/bp-media-actions.php +1 -1
- includes/bp-media-admin.php +8 -7
- includes/bp-media-functions.php +1 -1
- includes/bp-media-loader.php +2 -1
- includes/media-element/mediaelement-and-player.js +2023 -2023
- includes/media-element/mediaelement.js +140 -140
- includes/media-element/mediaelementplayer.js +1771 -1771
- loader.php +3 -4
- readme.txt +93 -90
includes/bp-media-actions.php
CHANGED
@@ -224,7 +224,7 @@ add_action('init', 'bp_media_init_count');
|
|
224 |
* @since BP Media 2.0
|
225 |
*/
|
226 |
function bp_media_footer() { ?>
|
227 |
-
<div id="bp-media-footer"><p>
|
228 |
<?php
|
229 |
}
|
230 |
if(get_option('bp_media_remove_linkback')!='1')
|
224 |
* @since BP Media 2.0
|
225 |
*/
|
226 |
function bp_media_footer() { ?>
|
227 |
+
<div id="bp-media-footer"><p>Using <a title="BuddyPress Media adds photos, video and audio upload/management feature" href="http://rtcamp.com/buddypress-media/">BuddyPress Media</a>.</p></div>
|
228 |
<?php
|
229 |
}
|
230 |
if(get_option('bp_media_remove_linkback')!='1')
|
includes/bp-media-admin.php
CHANGED
@@ -40,13 +40,11 @@ function bp_media_admin_menu() {
|
|
40 |
}
|
41 |
if(array_key_exists('submit', $_POST)){
|
42 |
|
43 |
-
if(array_key_exists('remove_linkback', $_POST)
|
44 |
-
if(update_option('bp_media_remove_linkback', '
|
45 |
$bp_media_messages[0]="<b>Settings saved.</b>";
|
46 |
}
|
47 |
-
|
48 |
-
else{
|
49 |
-
if(update_option('bp_media_remove_linkback', '1')){
|
50 |
$bp_media_messages[0]="<b>Settings saved.</b>";
|
51 |
}
|
52 |
}
|
@@ -135,8 +133,11 @@ function bp_media_admin_menu() {
|
|
135 |
<th scope="row"><label for="remove_linkback">Spread the word</label></th>
|
136 |
<td>
|
137 |
<fieldset>
|
138 |
-
<legend class="screen-reader-text"><span>
|
139 |
-
<label for="
|
|
|
|
|
|
|
140 |
</fieldset>
|
141 |
</td>
|
142 |
</tr>
|
40 |
}
|
41 |
if(array_key_exists('submit', $_POST)){
|
42 |
|
43 |
+
if(array_key_exists('remove_linkback', $_POST)){
|
44 |
+
if($_POST['remove_linkback']=='2'&&update_option('bp_media_remove_linkback', '2')){
|
45 |
$bp_media_messages[0]="<b>Settings saved.</b>";
|
46 |
}
|
47 |
+
else if(update_option('bp_media_remove_linkback', '1')){
|
|
|
|
|
48 |
$bp_media_messages[0]="<b>Settings saved.</b>";
|
49 |
}
|
50 |
}
|
133 |
<th scope="row"><label for="remove_linkback">Spread the word</label></th>
|
134 |
<td>
|
135 |
<fieldset>
|
136 |
+
<legend class="screen-reader-text"><span>Yes, we support BuddyPress Media</span></legend>
|
137 |
+
<label for="remove_linkback_yes"><input name="remove_linkback" type="radio" id="remove_linkback_yes" value="2" <?php if(get_option('bp_media_remove_linkback')=='2') echo 'checked="checked"' ?>> Yes, we support BuddyPress Media</label>
|
138 |
+
<br/>
|
139 |
+
<legend class="screen-reader-text"><span>No, we don't support BuddyPress Media</span></legend>
|
140 |
+
<label for="remove_linkback_no"><input name="remove_linkback" type="radio" id="remove_linkback_no" value="1" <?php if(get_option('bp_media_remove_linkback')=='1') echo 'checked="checked"' ?>> No, we don't support BuddyPress Media</label>
|
141 |
</fieldset>
|
142 |
</td>
|
143 |
</tr>
|
includes/bp-media-functions.php
CHANGED
@@ -157,7 +157,7 @@ function bp_media_page_not_exist() {
|
|
157 |
*
|
158 |
* @since BP Media 2.0
|
159 |
*/
|
160 |
-
function bp_media_get_feeds($feed_url = 'http://rtcamp.com/
|
161 |
// Get RSS Feed(s)
|
162 |
require_once( ABSPATH . WPINC . '/feed.php' );
|
163 |
$maxitems = 0;
|
157 |
*
|
158 |
* @since BP Media 2.0
|
159 |
*/
|
160 |
+
function bp_media_get_feeds($feed_url = 'http://rtcamp.com/tag/buddypress/feed/') {
|
161 |
// Get RSS Feed(s)
|
162 |
require_once( ABSPATH . WPINC . '/feed.php' );
|
163 |
$maxitems = 0;
|
includes/bp-media-loader.php
CHANGED
@@ -145,6 +145,7 @@ class BP_Media_Component extends BP_Component {
|
|
145 |
$includes[] = 'includes/bp-media-admin.php';
|
146 |
}
|
147 |
parent::includes($includes);
|
|
|
148 |
}
|
149 |
|
150 |
/**
|
@@ -393,4 +394,4 @@ function bp_media_fetch_feeds() {
|
|
393 |
}
|
394 |
}
|
395 |
add_action('init','bp_media_fetch_feeds');
|
396 |
-
?>
|
145 |
$includes[] = 'includes/bp-media-admin.php';
|
146 |
}
|
147 |
parent::includes($includes);
|
148 |
+
do_action('bp_media_init');
|
149 |
}
|
150 |
|
151 |
/**
|
394 |
}
|
395 |
}
|
396 |
add_action('init','bp_media_fetch_feeds');
|
397 |
+
?>
|
includes/media-element/mediaelement-and-player.js
CHANGED
@@ -11,147 +11,147 @@
|
|
11 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
12 |
*
|
13 |
*/
|
14 |
-
// Namespace
|
15 |
-
var mejs = mejs || {};
|
16 |
-
|
17 |
-
// version number
|
18 |
-
mejs.version = '2.9.1';
|
19 |
-
|
20 |
-
// player number (for missing, same id attr)
|
21 |
-
mejs.meIndex = 0;
|
22 |
-
|
23 |
-
// media types accepted by plugins
|
24 |
-
mejs.plugins = {
|
25 |
-
silverlight: [
|
26 |
-
{version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
|
27 |
-
],
|
28 |
-
flash: [
|
29 |
-
{version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
|
30 |
-
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
|
31 |
-
],
|
32 |
-
youtube: [
|
33 |
-
{version: null, types: ['video/youtube', 'video/x-youtube']}
|
34 |
-
],
|
35 |
-
vimeo: [
|
36 |
-
{version: null, types: ['video/vimeo']}
|
37 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
};
|
39 |
-
|
40 |
-
/*
|
41 |
-
Utility methods
|
42 |
-
*/
|
43 |
-
mejs.Utility = {
|
44 |
-
encodeUrl: function(url) {
|
45 |
-
return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
|
46 |
-
},
|
47 |
-
escapeHTML: function(s) {
|
48 |
-
return s.toString().split('&').join('&').split('<').join('<').split('"').join('"');
|
49 |
-
},
|
50 |
-
absolutizeUrl: function(url) {
|
51 |
-
var el = document.createElement('div');
|
52 |
-
el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
|
53 |
-
return el.firstChild.href;
|
54 |
-
},
|
55 |
-
getScriptPath: function(scriptNames) {
|
56 |
-
var
|
57 |
-
i = 0,
|
58 |
-
j,
|
59 |
-
path = '',
|
60 |
-
name = '',
|
61 |
-
script,
|
62 |
-
scripts = document.getElementsByTagName('script'),
|
63 |
-
il = scripts.length,
|
64 |
-
jl = scriptNames.length;
|
65 |
-
|
66 |
-
for (; i < il; i++) {
|
67 |
-
script = scripts[i].src;
|
68 |
-
for (j = 0; j < jl; j++) {
|
69 |
-
name = scriptNames[j];
|
70 |
-
if (script.indexOf(name) > -1) {
|
71 |
-
path = script.substring(0, script.indexOf(name));
|
72 |
-
break;
|
73 |
-
}
|
74 |
-
}
|
75 |
-
if (path !== '') {
|
76 |
-
break;
|
77 |
-
}
|
78 |
-
}
|
79 |
-
return path;
|
80 |
-
},
|
81 |
-
secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
|
82 |
-
//add framecount
|
83 |
-
if (typeof showFrameCount == 'undefined') {
|
84 |
-
showFrameCount=false;
|
85 |
-
} else if(typeof fps == 'undefined') {
|
86 |
-
fps = 25;
|
87 |
-
}
|
88 |
-
|
89 |
-
var hours = Math.floor(time / 3600) % 24,
|
90 |
-
minutes = Math.floor(time / 60) % 60,
|
91 |
-
seconds = Math.floor(time % 60),
|
92 |
-
frames = Math.floor(((time % 1)*fps).toFixed(3)),
|
93 |
-
result =
|
94 |
-
( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
|
95 |
-
+ (minutes < 10 ? '0' + minutes : minutes) + ':'
|
96 |
-
+ (seconds < 10 ? '0' + seconds : seconds)
|
97 |
-
+ ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
|
98 |
-
|
99 |
-
return result;
|
100 |
-
},
|
101 |
-
|
102 |
-
timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
|
103 |
-
if (typeof showFrameCount == 'undefined') {
|
104 |
-
showFrameCount=false;
|
105 |
-
} else if(typeof fps == 'undefined') {
|
106 |
-
fps = 25;
|
107 |
-
}
|
108 |
-
|
109 |
-
var tc_array = hh_mm_ss_ff.split(":"),
|
110 |
-
tc_hh = parseInt(tc_array[0], 10),
|
111 |
-
tc_mm = parseInt(tc_array[1], 10),
|
112 |
-
tc_ss = parseInt(tc_array[2], 10),
|
113 |
-
tc_ff = 0,
|
114 |
-
tc_in_seconds = 0;
|
115 |
-
|
116 |
-
if (showFrameCount) {
|
117 |
-
tc_ff = parseInt(tc_array[3])/fps;
|
118 |
-
}
|
119 |
-
|
120 |
-
tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
|
121 |
-
|
122 |
-
return tc_in_seconds;
|
123 |
-
},
|
124 |
-
|
125 |
-
/* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
|
126 |
-
removeSwf: function(id) {
|
127 |
-
var obj = document.getElementById(id);
|
128 |
-
if (obj && obj.nodeName == "OBJECT") {
|
129 |
-
if (mejs.MediaFeatures.isIE) {
|
130 |
-
obj.style.display = "none";
|
131 |
-
(function(){
|
132 |
-
if (obj.readyState == 4) {
|
133 |
-
mejs.Utility.removeObjectInIE(id);
|
134 |
-
} else {
|
135 |
-
setTimeout(arguments.callee, 10);
|
136 |
-
}
|
137 |
-
})();
|
138 |
-
} else {
|
139 |
-
obj.parentNode.removeChild(obj);
|
140 |
-
}
|
141 |
-
}
|
142 |
-
},
|
143 |
-
removeObjectInIE: function(id) {
|
144 |
-
var obj = document.getElementById(id);
|
145 |
-
if (obj) {
|
146 |
-
for (var i in obj) {
|
147 |
-
if (typeof obj[i] == "function") {
|
148 |
-
obj[i] = null;
|
149 |
-
}
|
150 |
-
}
|
151 |
-
obj.parentNode.removeChild(obj);
|
152 |
-
}
|
153 |
-
}
|
154 |
-
};
|
155 |
|
156 |
|
157 |
// Core detector, plugins are added below
|
@@ -1532,1196 +1532,1196 @@ if (typeof jQuery != 'undefined') {
|
|
1532 |
} else if (typeof ender != 'undefined') {
|
1533 |
mejs.$ = ender;
|
1534 |
}
|
1535 |
-
(function ($) {
|
1536 |
-
|
1537 |
-
// default player values
|
1538 |
-
mejs.MepDefaults = {
|
1539 |
-
// url to poster (to fix iOS 3.x)
|
1540 |
-
poster: '',
|
1541 |
-
// default if the <video width> is not specified
|
1542 |
-
defaultVideoWidth: 480,
|
1543 |
-
// default if the <video height> is not specified
|
1544 |
-
defaultVideoHeight: 270,
|
1545 |
-
// if set, overrides <video width>
|
1546 |
-
videoWidth: -1,
|
1547 |
-
// if set, overrides <video height>
|
1548 |
-
videoHeight: -1,
|
1549 |
-
// default if the user doesn't specify
|
1550 |
-
defaultAudioWidth: 400,
|
1551 |
-
// default if the user doesn't specify
|
1552 |
-
defaultAudioHeight: 30,
|
1553 |
-
// width of audio player
|
1554 |
-
audioWidth: -1,
|
1555 |
-
// height of audio player
|
1556 |
-
audioHeight: -1,
|
1557 |
-
// initial volume when the player starts (overrided by user cookie)
|
1558 |
-
startVolume: 0.8,
|
1559 |
-
// useful for <audio> player loops
|
1560 |
-
loop: false,
|
1561 |
-
// resize to media dimensions
|
1562 |
-
enableAutosize: true,
|
1563 |
-
// forces the hour marker (##:00:00)
|
1564 |
-
alwaysShowHours: false,
|
1565 |
-
|
1566 |
-
// show framecount in timecode (##:00:00:00)
|
1567 |
-
showTimecodeFrameCount: false,
|
1568 |
-
// used when showTimecodeFrameCount is set to true
|
1569 |
-
framesPerSecond: 25,
|
1570 |
-
|
1571 |
-
// automatically calculate the width of the progress bar based on the sizes of other elements
|
1572 |
-
autosizeProgress : true,
|
1573 |
-
// Hide controls when playing and mouse is not over the video
|
1574 |
-
alwaysShowControls: false,
|
1575 |
-
// force iPad's native controls
|
1576 |
-
iPadUseNativeControls: false,
|
1577 |
-
// force iPhone's native controls
|
1578 |
-
iPhoneUseNativeControls: false,
|
1579 |
-
// force Android's native controls
|
1580 |
-
AndroidUseNativeControls: false,
|
1581 |
-
// features to show
|
1582 |
-
features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
|
1583 |
-
// only for dynamic
|
1584 |
-
isVideo: true,
|
1585 |
-
|
1586 |
-
// turns keyboard support on and off for this instance
|
1587 |
-
enableKeyboard: true,
|
1588 |
-
|
1589 |
-
// whenthis player starts, it will pause other players
|
1590 |
-
pauseOtherPlayers: true,
|
1591 |
-
|
1592 |
-
// array of keyboard actions such as play pause
|
1593 |
-
keyActions: [
|
1594 |
-
{
|
1595 |
-
keys: [
|
1596 |
-
32, // SPACE
|
1597 |
-
179 // GOOGLE play/pause button
|
1598 |
-
],
|
1599 |
-
action: function(player, media) {
|
1600 |
-
if (media.paused || media.ended) {
|
1601 |
-
media.play();
|
1602 |
-
} else {
|
1603 |
-
media.pause();
|
1604 |
-
}
|
1605 |
-
}
|
1606 |
-
},
|
1607 |
-
{
|
1608 |
-
keys: [38], // UP
|
1609 |
-
action: function(player, media) {
|
1610 |
-
var newVolume = Math.min(media.volume + 0.1, 1);
|
1611 |
-
media.setVolume(newVolume);
|
1612 |
-
}
|
1613 |
-
},
|
1614 |
-
{
|
1615 |
-
keys: [40], // DOWN
|
1616 |
-
action: function(player, media) {
|
1617 |
-
var newVolume = Math.max(media.volume - 0.1, 0);
|
1618 |
-
media.setVolume(newVolume);
|
1619 |
-
}
|
1620 |
-
},
|
1621 |
-
{
|
1622 |
-
keys: [
|
1623 |
-
37, // LEFT
|
1624 |
-
227 // Google TV rewind
|
1625 |
-
],
|
1626 |
-
action: function(player, media) {
|
1627 |
-
if (!isNaN(media.duration) && media.duration > 0) {
|
1628 |
-
if (player.isVideo) {
|
1629 |
-
player.showControls();
|
1630 |
-
player.startControlsTimer();
|
1631 |
-
}
|
1632 |
-
|
1633 |
-
// 5%
|
1634 |
-
var newTime = Math.max(media.currentTime - (media.duration * 0.05), 0);
|
1635 |
-
media.setCurrentTime(newTime);
|
1636 |
-
}
|
1637 |
-
}
|
1638 |
-
},
|
1639 |
-
{
|
1640 |
-
keys: [
|
1641 |
-
39, // RIGHT
|
1642 |
-
228 // Google TV forward
|
1643 |
-
],
|
1644 |
-
action: function(player, media) {
|
1645 |
-
if (!isNaN(media.duration) && media.duration > 0) {
|
1646 |
-
if (player.isVideo) {
|
1647 |
-
player.showControls();
|
1648 |
-
player.startControlsTimer();
|
1649 |
-
}
|
1650 |
-
|
1651 |
-
// 5%
|
1652 |
-
var newTime = Math.min(media.currentTime + (media.duration * 0.05), media.duration);
|
1653 |
-
media.setCurrentTime(newTime);
|
1654 |
-
}
|
1655 |
-
}
|
1656 |
-
},
|
1657 |
-
{
|
1658 |
-
keys: [70], // f
|
1659 |
-
action: function(player, media) {
|
1660 |
-
if (typeof player.enterFullScreen != 'undefined') {
|
1661 |
-
if (player.isFullScreen) {
|
1662 |
-
player.exitFullScreen();
|
1663 |
-
} else {
|
1664 |
-
player.enterFullScreen();
|
1665 |
-
}
|
1666 |
-
}
|
1667 |
-
}
|
1668 |
-
}
|
1669 |
-
]
|
1670 |
-
};
|
1671 |
-
|
1672 |
-
mejs.mepIndex = 0;
|
1673 |
-
|
1674 |
-
mejs.players = [];
|
1675 |
-
|
1676 |
-
// wraps a MediaElement object in player controls
|
1677 |
-
mejs.MediaElementPlayer = function(node, o) {
|
1678 |
-
// enforce object, even without "new" (via John Resig)
|
1679 |
-
if ( !(this instanceof mejs.MediaElementPlayer) ) {
|
1680 |
-
return new mejs.MediaElementPlayer(node, o);
|
1681 |
-
}
|
1682 |
-
|
1683 |
-
var t = this;
|
1684 |
-
|
1685 |
-
// these will be reset after the MediaElement.success fires
|
1686 |
-
t.$media = t.$node = $(node);
|
1687 |
-
t.node = t.media = t.$media[0];
|
1688 |
-
|
1689 |
-
// check for existing player
|
1690 |
-
if (typeof t.node.player != 'undefined') {
|
1691 |
-
return t.node.player;
|
1692 |
-
} else {
|
1693 |
-
// attach player to DOM node for reference
|
1694 |
-
t.node.player = t;
|
1695 |
-
}
|
1696 |
-
|
1697 |
-
|
1698 |
-
// try to get options from data-mejsoptions
|
1699 |
-
if (typeof o == 'undefined') {
|
1700 |
-
o = t.$node.data('mejsoptions');
|
1701 |
-
}
|
1702 |
-
|
1703 |
-
// extend default options
|
1704 |
-
t.options = $.extend({},mejs.MepDefaults,o);
|
1705 |
-
|
1706 |
-
// add to player array (for focus events)
|
1707 |
-
mejs.players.push(t);
|
1708 |
-
|
1709 |
-
// start up
|
1710 |
-
t.init();
|
1711 |
-
|
1712 |
-
return t;
|
1713 |
-
};
|
1714 |
-
|
1715 |
-
// actual player
|
1716 |
-
mejs.MediaElementPlayer.prototype = {
|
1717 |
-
|
1718 |
-
hasFocus: false,
|
1719 |
-
|
1720 |
-
controlsAreVisible: true,
|
1721 |
-
|
1722 |
-
init: function() {
|
1723 |
-
|
1724 |
-
var
|
1725 |
-
t = this,
|
1726 |
-
mf = mejs.MediaFeatures,
|
1727 |
-
// options for MediaElement (shim)
|
1728 |
-
meOptions = $.extend(true, {}, t.options, {
|
1729 |
-
success: function(media, domNode) { t.meReady(media, domNode); },
|
1730 |
-
error: function(e) { t.handleError(e);}
|
1731 |
-
}),
|
1732 |
-
tagName = t.media.tagName.toLowerCase();
|
1733 |
-
|
1734 |
-
t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
|
1735 |
-
|
1736 |
-
if (t.isDynamic) {
|
1737 |
-
// get video from src or href?
|
1738 |
-
t.isVideo = t.options.isVideo;
|
1739 |
-
} else {
|
1740 |
-
t.isVideo = (tagName !== 'audio' && t.options.isVideo);
|
1741 |
-
}
|
1742 |
-
|
1743 |
-
// use native controls in iPad, iPhone, and Android
|
1744 |
-
if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
1745 |
-
|
1746 |
-
// add controls and stop
|
1747 |
-
t.$media.attr('controls', 'controls');
|
1748 |
-
|
1749 |
-
// attempt to fix iOS 3 bug
|
1750 |
-
//t.$media.removeAttr('poster');
|
1751 |
-
// no Issue found on iOS3 -ttroxell
|
1752 |
-
|
1753 |
-
// override Apple's autoplay override for iPads
|
1754 |
-
if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
|
1755 |
-
t.media.load();
|
1756 |
-
t.media.play();
|
1757 |
-
}
|
1758 |
-
|
1759 |
-
} else if (mf.isAndroid && t.AndroidUseNativeControls) {
|
1760 |
-
|
1761 |
-
// leave default player
|
1762 |
-
|
1763 |
-
} else {
|
1764 |
-
|
1765 |
-
// DESKTOP: use MediaElementPlayer controls
|
1766 |
-
|
1767 |
-
// remove native controls
|
1768 |
-
t.$media.removeAttr('controls');
|
1769 |
-
|
1770 |
-
// unique ID
|
1771 |
-
t.id = 'mep_' + mejs.mepIndex++;
|
1772 |
-
|
1773 |
-
// build container
|
1774 |
-
t.container =
|
1775 |
-
$('<div id="' + t.id + '" class="mejs-container">'+
|
1776 |
-
'<div class="mejs-inner">'+
|
1777 |
-
'<div class="mejs-mediaelement"></div>'+
|
1778 |
-
'<div class="mejs-layers"></div>'+
|
1779 |
-
'<div class="mejs-controls"></div>'+
|
1780 |
-
'<div class="mejs-clear"></div>'+
|
1781 |
-
'</div>' +
|
1782 |
-
'</div>')
|
1783 |
-
.addClass(t.$media[0].className)
|
1784 |
-
.insertBefore(t.$media);
|
1785 |
-
|
1786 |
-
// add classes for user and content
|
1787 |
-
t.container.addClass(
|
1788 |
-
(mf.isAndroid ? 'mejs-android ' : '') +
|
1789 |
-
(mf.isiOS ? 'mejs-ios ' : '') +
|
1790 |
-
(mf.isiPad ? 'mejs-ipad ' : '') +
|
1791 |
-
(mf.isiPhone ? 'mejs-iphone ' : '') +
|
1792 |
-
(t.isVideo ? 'mejs-video ' : 'mejs-audio ')
|
1793 |
-
);
|
1794 |
-
|
1795 |
-
|
1796 |
-
// move the <video/video> tag into the right spot
|
1797 |
-
if (mf.isiOS) {
|
1798 |
-
|
1799 |
-
// sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
|
1800 |
-
var $newMedia = t.$media.clone();
|
1801 |
-
|
1802 |
-
t.container.find('.mejs-mediaelement').append($newMedia);
|
1803 |
-
|
1804 |
-
t.$media.remove();
|
1805 |
-
t.$node = t.$media = $newMedia;
|
1806 |
-
t.node = t.media = $newMedia[0]
|
1807 |
-
|
1808 |
-
} else {
|
1809 |
-
|
1810 |
-
// normal way of moving it into place (doesn't work on iOS)
|
1811 |
-
t.container.find('.mejs-mediaelement').append(t.$media);
|
1812 |
-
}
|
1813 |
-
|
1814 |
-
// find parts
|
1815 |
-
t.controls = t.container.find('.mejs-controls');
|
1816 |
-
t.layers = t.container.find('.mejs-layers');
|
1817 |
-
|
1818 |
-
// determine the size
|
1819 |
-
|
1820 |
-
/* size priority:
|
1821 |
-
(1) videoWidth (forced),
|
1822 |
-
(2) style="width;height;"
|
1823 |
-
(3) width attribute,
|
1824 |
-
(4) defaultVideoWidth (for unspecified cases)
|
1825 |
-
*/
|
1826 |
-
|
1827 |
-
var capsTagName = tagName.substring(0,1).toUpperCase() + tagName.substring(1);
|
1828 |
-
|
1829 |
-
if (t.options[tagName + 'Width'] > 0 || t.options[tagName + 'Width'].toString().indexOf('%') > -1) {
|
1830 |
-
t.width = t.options[tagName + 'Width'];
|
1831 |
-
} else if (t.media.style.width !== '' && t.media.style.width !== null) {
|
1832 |
-
t.width = t.media.style.width;
|
1833 |
-
} else if (t.media.getAttribute('width') !== null) {
|
1834 |
-
t.width = t.$media.attr('width');
|
1835 |
-
} else {
|
1836 |
-
t.width = t.options['default' + capsTagName + 'Width'];
|
1837 |
-
}
|
1838 |
-
|
1839 |
-
if (t.options[tagName + 'Height'] > 0 || t.options[tagName + 'Height'].toString().indexOf('%') > -1) {
|
1840 |
-
t.height = t.options[tagName + 'Height'];
|
1841 |
-
} else if (t.media.style.height !== '' && t.media.style.height !== null) {
|
1842 |
-
t.height = t.media.style.height;
|
1843 |
-
} else if (t.$media[0].getAttribute('height') !== null) {
|
1844 |
-
t.height = t.$media.attr('height');
|
1845 |
-
} else {
|
1846 |
-
t.height = t.options['default' + capsTagName + 'Height'];
|
1847 |
-
}
|
1848 |
-
|
1849 |
-
// set the size, while we wait for the plugins to load below
|
1850 |
-
t.setPlayerSize(t.width, t.height);
|
1851 |
-
|
1852 |
-
// create MediaElementShim
|
1853 |
-
meOptions.pluginWidth = t.height;
|
1854 |
-
meOptions.pluginHeight = t.width;
|
1855 |
-
}
|
1856 |
-
|
1857 |
-
|
1858 |
-
|
1859 |
-
// create MediaElement shim
|
1860 |
-
mejs.MediaElement(t.$media[0], meOptions);
|
1861 |
-
},
|
1862 |
-
|
1863 |
-
showControls: function(doAnimation) {
|
1864 |
-
var t = this;
|
1865 |
-
|
1866 |
-
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
1867 |
-
|
1868 |
-
if (t.controlsAreVisible)
|
1869 |
-
return;
|
1870 |
-
|
1871 |
-
if (doAnimation) {
|
1872 |
-
t.controls
|
1873 |
-
.css('visibility','visible')
|
1874 |
-
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
1875 |
-
|
1876 |
-
// any additional controls people might add and want to hide
|
1877 |
-
t.container.find('.mejs-control')
|
1878 |
-
.css('visibility','visible')
|
1879 |
-
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
1880 |
-
|
1881 |
-
} else {
|
1882 |
-
t.controls
|
1883 |
-
.css('visibility','visible')
|
1884 |
-
.css('display','block');
|
1885 |
-
|
1886 |
-
// any additional controls people might add and want to hide
|
1887 |
-
t.container.find('.mejs-control')
|
1888 |
-
.css('visibility','visible')
|
1889 |
-
.css('display','block');
|
1890 |
-
|
1891 |
-
t.controlsAreVisible = true;
|
1892 |
-
}
|
1893 |
-
|
1894 |
-
t.setControlsSize();
|
1895 |
-
|
1896 |
-
},
|
1897 |
-
|
1898 |
-
hideControls: function(doAnimation) {
|
1899 |
-
var t = this;
|
1900 |
-
|
1901 |
-
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
1902 |
-
|
1903 |
-
if (!t.controlsAreVisible)
|
1904 |
-
return;
|
1905 |
-
|
1906 |
-
if (doAnimation) {
|
1907 |
-
// fade out main controls
|
1908 |
-
t.controls.stop(true, true).fadeOut(200, function() {
|
1909 |
-
$(this)
|
1910 |
-
.css('visibility','hidden')
|
1911 |
-
.css('display','block');
|
1912 |
-
|
1913 |
-
t.controlsAreVisible = false;
|
1914 |
-
});
|
1915 |
-
|
1916 |
-
// any additional controls people might add and want to hide
|
1917 |
-
t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
|
1918 |
-
$(this)
|
1919 |
-
.css('visibility','hidden')
|
1920 |
-
.css('display','block');
|
1921 |
-
});
|
1922 |
-
} else {
|
1923 |
-
|
1924 |
-
// hide main controls
|
1925 |
-
t.controls
|
1926 |
-
.css('visibility','hidden')
|
1927 |
-
.css('display','block');
|
1928 |
-
|
1929 |
-
// hide others
|
1930 |
-
t.container.find('.mejs-control')
|
1931 |
-
.css('visibility','hidden')
|
1932 |
-
.css('display','block');
|
1933 |
-
|
1934 |
-
t.controlsAreVisible = false;
|
1935 |
-
}
|
1936 |
-
},
|
1937 |
-
|
1938 |
-
controlsTimer: null,
|
1939 |
-
|
1940 |
-
startControlsTimer: function(timeout) {
|
1941 |
-
|
1942 |
-
var t = this;
|
1943 |
-
|
1944 |
-
timeout = typeof timeout != 'undefined' ? timeout : 1500;
|
1945 |
-
|
1946 |
-
t.killControlsTimer('start');
|
1947 |
-
|
1948 |
-
t.controlsTimer = setTimeout(function() {
|
1949 |
-
//console.log('timer fired');
|
1950 |
-
t.hideControls();
|
1951 |
-
t.killControlsTimer('hide');
|
1952 |
-
}, timeout);
|
1953 |
-
},
|
1954 |
-
|
1955 |
-
killControlsTimer: function(src) {
|
1956 |
-
|
1957 |
-
var t = this;
|
1958 |
-
|
1959 |
-
if (t.controlsTimer !== null) {
|
1960 |
-
clearTimeout(t.controlsTimer);
|
1961 |
-
delete t.controlsTimer;
|
1962 |
-
t.controlsTimer = null;
|
1963 |
-
}
|
1964 |
-
},
|
1965 |
-
|
1966 |
-
controlsEnabled: true,
|
1967 |
-
|
1968 |
-
disableControls: function() {
|
1969 |
-
var t= this;
|
1970 |
-
|
1971 |
-
t.killControlsTimer();
|
1972 |
-
t.hideControls(false);
|
1973 |
-
this.controlsEnabled = false;
|
1974 |
-
},
|
1975 |
-
|
1976 |
-
enableControls: function() {
|
1977 |
-
var t= this;
|
1978 |
-
|
1979 |
-
t.showControls(false);
|
1980 |
-
|
1981 |
-
t.controlsEnabled = true;
|
1982 |
-
},
|
1983 |
-
|
1984 |
-
|
1985 |
-
// Sets up all controls and events
|
1986 |
-
meReady: function(media, domNode) {
|
1987 |
-
|
1988 |
-
|
1989 |
-
var t = this,
|
1990 |
-
mf = mejs.MediaFeatures,
|
1991 |
-
autoplayAttr = domNode.getAttribute('autoplay'),
|
1992 |
-
autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
|
1993 |
-
featureIndex,
|
1994 |
-
feature;
|
1995 |
-
|
1996 |
-
// make sure it can't create itself again if a plugin reloads
|
1997 |
-
if (t.created)
|
1998 |
-
return;
|
1999 |
-
else
|
2000 |
-
t.created = true;
|
2001 |
-
|
2002 |
-
t.media = media;
|
2003 |
-
t.domNode = domNode;
|
2004 |
-
|
2005 |
-
if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
2006 |
-
|
2007 |
-
// two built in features
|
2008 |
-
t.buildposter(t, t.controls, t.layers, t.media);
|
2009 |
-
t.buildkeyboard(t, t.controls, t.layers, t.media);
|
2010 |
-
t.buildoverlays(t, t.controls, t.layers, t.media);
|
2011 |
-
|
2012 |
-
// grab for use by features
|
2013 |
-
t.findTracks();
|
2014 |
-
|
2015 |
-
// add user-defined features/controls
|
2016 |
-
for (featureIndex in t.options.features) {
|
2017 |
-
feature = t.options.features[featureIndex];
|
2018 |
-
if (t['build' + feature]) {
|
2019 |
-
try {
|
2020 |
-
t['build' + feature](t, t.controls, t.layers, t.media);
|
2021 |
-
} catch (e) {
|
2022 |
-
// TODO: report control error
|
2023 |
-
//throw e;
|
2024 |
-
//console.log('error building ' + feature);
|
2025 |
-
//console.log(e);
|
2026 |
-
}
|
2027 |
-
}
|
2028 |
-
}
|
2029 |
-
|
2030 |
-
t.container.trigger('controlsready');
|
2031 |
-
|
2032 |
-
// reset all layers and controls
|
2033 |
-
t.setPlayerSize(t.width, t.height);
|
2034 |
-
t.setControlsSize();
|
2035 |
-
|
2036 |
-
|
2037 |
-
// controls fade
|
2038 |
-
if (t.isVideo) {
|
2039 |
-
|
2040 |
-
if (mejs.MediaFeatures.hasTouch) {
|
2041 |
-
|
2042 |
-
// for touch devices (iOS, Android)
|
2043 |
-
// show/hide without animation on touch
|
2044 |
-
|
2045 |
-
t.$media.bind('touchstart', function() {
|
2046 |
-
|
2047 |
-
|
2048 |
-
// toggle controls
|
2049 |
-
if (t.controlsAreVisible) {
|
2050 |
-
t.hideControls(false);
|
2051 |
-
} else {
|
2052 |
-
if (t.controlsEnabled) {
|
2053 |
-
t.showControls(false);
|
2054 |
-
}
|
2055 |
-
}
|
2056 |
-
});
|
2057 |
-
|
2058 |
-
} else {
|
2059 |
-
// click controls
|
2060 |
-
var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
|
2061 |
-
|
2062 |
-
// click to play/pause
|
2063 |
-
clickElement.click(function() {
|
2064 |
-
if (media.paused) {
|
2065 |
-
media.play();
|
2066 |
-
} else {
|
2067 |
-
media.pause();
|
2068 |
-
}
|
2069 |
-
});
|
2070 |
-
|
2071 |
-
|
2072 |
-
// show/hide controls
|
2073 |
-
t.container
|
2074 |
-
.bind('mouseenter mouseover', function () {
|
2075 |
-
if (t.controlsEnabled) {
|
2076 |
-
if (!t.options.alwaysShowControls) {
|
2077 |
-
t.killControlsTimer('enter');
|
2078 |
-
t.showControls();
|
2079 |
-
t.startControlsTimer(2500);
|
2080 |
-
}
|
2081 |
-
}
|
2082 |
-
})
|
2083 |
-
.bind('mousemove', function() {
|
2084 |
-
if (t.controlsEnabled) {
|
2085 |
-
if (!t.controlsAreVisible) {
|
2086 |
-
t.showControls();
|
2087 |
-
}
|
2088 |
-
//t.killControlsTimer('move');
|
2089 |
-
if (!t.options.alwaysShowControls) {
|
2090 |
-
t.startControlsTimer(2500);
|
2091 |
-
}
|
2092 |
-
}
|
2093 |
-
})
|
2094 |
-
.bind('mouseleave', function () {
|
2095 |
-
if (t.controlsEnabled) {
|
2096 |
-
if (!t.media.paused && !t.options.alwaysShowControls) {
|
2097 |
-
t.startControlsTimer(1000);
|
2098 |
-
}
|
2099 |
-
}
|
2100 |
-
});
|
2101 |
-
}
|
2102 |
-
|
2103 |
-
// check for autoplay
|
2104 |
-
if (autoplay && !t.options.alwaysShowControls) {
|
2105 |
-
t.hideControls();
|
2106 |
-
}
|
2107 |
-
|
2108 |
-
// resizer
|
2109 |
-
if (t.options.enableAutosize) {
|
2110 |
-
t.media.addEventListener('loadedmetadata', function(e) {
|
2111 |
-
// if the <video height> was not set and the options.videoHeight was not set
|
2112 |
-
// then resize to the real dimensions
|
2113 |
-
if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
|
2114 |
-
t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
|
2115 |
-
t.setControlsSize();
|
2116 |
-
t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
|
2117 |
-
}
|
2118 |
-
}, false);
|
2119 |
-
}
|
2120 |
-
}
|
2121 |
-
|
2122 |
-
// EVENTS
|
2123 |
-
|
2124 |
-
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
|
2125 |
-
media.addEventListener('play', function() {
|
2126 |
-
|
2127 |
-
// go through all other players
|
2128 |
-
for (var i=0, il=mejs.players.length; i<il; i++) {
|
2129 |
-
var p = mejs.players[i];
|
2130 |
-
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
|
2131 |
-
p.pause();
|
2132 |
-
}
|
2133 |
-
p.hasFocus = false;
|
2134 |
-
}
|
2135 |
-
|
2136 |
-
t.hasFocus = true;
|
2137 |
-
},false);
|
2138 |
-
|
2139 |
-
|
2140 |
-
// ended for all
|
2141 |
-
t.media.addEventListener('ended', function (e) {
|
2142 |
-
try{
|
2143 |
-
t.media.setCurrentTime(0);
|
2144 |
-
} catch (exp) {
|
2145 |
-
|
2146 |
-
}
|
2147 |
-
t.media.pause();
|
2148 |
-
|
2149 |
-
if (t.setProgressRail)
|
2150 |
-
t.setProgressRail();
|
2151 |
-
if (t.setCurrentRail)
|
2152 |
-
t.setCurrentRail();
|
2153 |
-
|
2154 |
-
if (t.options.loop) {
|
2155 |
-
t.media.play();
|
2156 |
-
} else if (!t.options.alwaysShowControls && t.controlsEnabled) {
|
2157 |
-
t.showControls();
|
2158 |
-
}
|
2159 |
-
}, false);
|
2160 |
-
|
2161 |
-
// resize on the first play
|
2162 |
-
t.media.addEventListener('loadedmetadata', function(e) {
|
2163 |
-
if (t.updateDuration) {
|
2164 |
-
t.updateDuration();
|
2165 |
-
}
|
2166 |
-
if (t.updateCurrent) {
|
2167 |
-
t.updateCurrent();
|
2168 |
-
}
|
2169 |
-
|
2170 |
-
if (!t.isFullScreen) {
|
2171 |
-
t.setPlayerSize(t.width, t.height);
|
2172 |
-
t.setControlsSize();
|
2173 |
-
}
|
2174 |
-
}, false);
|
2175 |
-
|
2176 |
-
|
2177 |
-
// webkit has trouble doing this without a delay
|
2178 |
-
setTimeout(function () {
|
2179 |
-
t.setPlayerSize(t.width, t.height);
|
2180 |
-
t.setControlsSize();
|
2181 |
-
}, 50);
|
2182 |
-
|
2183 |
-
// adjust controls whenever window sizes (used to be in fullscreen only)
|
2184 |
-
$(window).resize(function() {
|
2185 |
-
|
2186 |
-
// don't resize for fullscreen mode
|
2187 |
-
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
|
2188 |
-
t.setPlayerSize(t.width, t.height);
|
2189 |
-
}
|
2190 |
-
|
2191 |
-
// always adjust controls
|
2192 |
-
t.setControlsSize();
|
2193 |
-
});
|
2194 |
-
|
2195 |
-
// TEMP: needs to be moved somewhere else
|
2196 |
-
if (t.media.pluginType == 'youtube') {
|
2197 |
-
t.container.find('.mejs-overlay-play').hide();
|
2198 |
-
}
|
2199 |
-
}
|
2200 |
-
|
2201 |
-
// force autoplay for HTML5
|
2202 |
-
if (autoplay && media.pluginType == 'native') {
|
2203 |
-
media.load();
|
2204 |
-
media.play();
|
2205 |
-
}
|
2206 |
-
|
2207 |
-
|
2208 |
-
if (t.options.success) {
|
2209 |
-
|
2210 |
-
if (typeof t.options.success == 'string') {
|
2211 |
-
window[t.options.success](t.media, t.domNode, t);
|
2212 |
-
} else {
|
2213 |
-
t.options.success(t.media, t.domNode, t);
|
2214 |
-
}
|
2215 |
-
}
|
2216 |
-
},
|
2217 |
-
|
2218 |
-
handleError: function(e) {
|
2219 |
-
var t = this;
|
2220 |
-
|
2221 |
-
t.controls.hide();
|
2222 |
-
|
2223 |
-
// Tell user that the file cannot be played
|
2224 |
-
if (t.options.error) {
|
2225 |
-
t.options.error(e);
|
2226 |
-
}
|
2227 |
-
},
|
2228 |
-
|
2229 |
-
setPlayerSize: function(width,height) {
|
2230 |
-
var t = this;
|
2231 |
-
|
2232 |
-
if (typeof width != 'undefined')
|
2233 |
-
t.width = width;
|
2234 |
-
|
2235 |
-
if (typeof height != 'undefined')
|
2236 |
-
t.height = height;
|
2237 |
-
|
2238 |
-
// detect 100% mode
|
2239 |
-
if (t.height.toString().indexOf('%') > 0) {
|
2240 |
-
|
2241 |
-
// do we have the native dimensions yet?
|
2242 |
-
var
|
2243 |
-
nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
|
2244 |
-
nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
|
2245 |
-
parentWidth = t.container.parent().width(),
|
2246 |
-
newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
|
2247 |
-
|
2248 |
-
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
2249 |
-
parentWidth = $(window).width();
|
2250 |
-
newHeight = $(window).height();
|
2251 |
-
}
|
2252 |
-
|
2253 |
-
|
2254 |
-
// set outer container size
|
2255 |
-
t.container
|
2256 |
-
.width(parentWidth)
|
2257 |
-
.height(newHeight);
|
2258 |
-
|
2259 |
-
// set native <video>
|
2260 |
-
t.$media
|
2261 |
-
.width('100%')
|
2262 |
-
.height('100%');
|
2263 |
-
|
2264 |
-
// set shims
|
2265 |
-
t.container.find('object, embed, iframe')
|
2266 |
-
.width('100%')
|
2267 |
-
.height('100%');
|
2268 |
-
|
2269 |
-
// if shim is ready, send the size to the embeded plugin
|
2270 |
-
if (t.media.setVideoSize)
|
2271 |
-
t.media.setVideoSize(parentWidth, newHeight);
|
2272 |
-
|
2273 |
-
// set the layers
|
2274 |
-
t.layers.children('.mejs-layer')
|
2275 |
-
.width('100%')
|
2276 |
-
.height('100%');
|
2277 |
-
|
2278 |
-
|
2279 |
-
} else {
|
2280 |
-
|
2281 |
-
t.container
|
2282 |
-
.width(t.width)
|
2283 |
-
.height(t.height);
|
2284 |
-
|
2285 |
-
t.layers.children('.mejs-layer')
|
2286 |
-
.width(t.width)
|
2287 |
-
.height(t.height);
|
2288 |
-
|
2289 |
-
}
|
2290 |
-
},
|
2291 |
-
|
2292 |
-
setControlsSize: function() {
|
2293 |
-
var t = this,
|
2294 |
-
usedWidth = 0,
|
2295 |
-
railWidth = 0,
|
2296 |
-
rail = t.controls.find('.mejs-time-rail'),
|
2297 |
-
total = t.controls.find('.mejs-time-total'),
|
2298 |
-
current = t.controls.find('.mejs-time-current'),
|
2299 |
-
loaded = t.controls.find('.mejs-time-loaded'),
|
2300 |
-
others = rail.siblings();
|
2301 |
-
|
2302 |
-
|
2303 |
-
// allow the size to come from custom CSS
|
2304 |
-
if (t.options && !t.options.autosizeProgress) {
|
2305 |
-
// Also, frontends devs can be more flexible
|
2306 |
-
// due the opportunity of absolute positioning.
|
2307 |
-
railWidth = parseInt(rail.css('width'));
|
2308 |
-
}
|
2309 |
-
|
2310 |
-
// attempt to autosize
|
2311 |
-
if (railWidth === 0 || !railWidth) {
|
2312 |
-
|
2313 |
-
// find the size of all the other controls besides the rail
|
2314 |
-
others.each(function() {
|
2315 |
-
if ($(this).css('position') != 'absolute') {
|
2316 |
-
usedWidth += $(this).outerWidth(true);
|
2317 |
-
}
|
2318 |
-
});
|
2319 |
-
|
2320 |
-
// fit the rail into the remaining space
|
2321 |
-
railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
|
2322 |
-
}
|
2323 |
-
|
2324 |
-
// outer area
|
2325 |
-
rail.width(railWidth);
|
2326 |
-
// dark space
|
2327 |
-
total.width(railWidth - (total.outerWidth(true) - total.width()));
|
2328 |
-
|
2329 |
-
if (t.setProgressRail)
|
2330 |
-
t.setProgressRail();
|
2331 |
-
if (t.setCurrentRail)
|
2332 |
-
t.setCurrentRail();
|
2333 |
-
},
|
2334 |
-
|
2335 |
-
|
2336 |
-
buildposter: function(player, controls, layers, media) {
|
2337 |
-
var t = this,
|
2338 |
-
poster =
|
2339 |
-
$('<div class="mejs-poster mejs-layer">' +
|
2340 |
-
'</div>')
|
2341 |
-
.appendTo(layers),
|
2342 |
-
posterUrl = player.$media.attr('poster');
|
2343 |
-
|
2344 |
-
// prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
|
2345 |
-
if (player.options.poster !== '') {
|
2346 |
-
posterUrl = player.options.poster;
|
2347 |
-
}
|
2348 |
-
|
2349 |
-
// second, try the real poster
|
2350 |
-
if (posterUrl !== '' && posterUrl != null) {
|
2351 |
-
t.setPoster(posterUrl);
|
2352 |
-
} else {
|
2353 |
-
poster.hide();
|
2354 |
-
}
|
2355 |
-
|
2356 |
-
media.addEventListener('play',function() {
|
2357 |
-
poster.hide();
|
2358 |
-
}, false);
|
2359 |
-
},
|
2360 |
-
|
2361 |
-
setPoster: function(url) {
|
2362 |
-
var t = this,
|
2363 |
-
posterDiv = t.container.find('.mejs-poster'),
|
2364 |
-
posterImg = posterDiv.find('img');
|
2365 |
-
|
2366 |
-
if (posterImg.length == 0) {
|
2367 |
-
posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
|
2368 |
-
}
|
2369 |
-
|
2370 |
-
posterImg.attr('src', url);
|
2371 |
-
},
|
2372 |
-
|
2373 |
-
buildoverlays: function(player, controls, layers, media) {
|
2374 |
-
if (!player.isVideo)
|
2375 |
-
return;
|
2376 |
-
|
2377 |
-
var
|
2378 |
-
loading =
|
2379 |
-
$('<div class="mejs-overlay mejs-layer">'+
|
2380 |
-
'<div class="mejs-overlay-loading"><span></span></div>'+
|
2381 |
-
'</div>')
|
2382 |
-
.hide() // start out hidden
|
2383 |
-
.appendTo(layers),
|
2384 |
-
error =
|
2385 |
-
$('<div class="mejs-overlay mejs-layer">'+
|
2386 |
-
'<div class="mejs-overlay-error"></div>'+
|
2387 |
-
'</div>')
|
2388 |
-
.hide() // start out hidden
|
2389 |
-
.appendTo(layers),
|
2390 |
-
// this needs to come last so it's on top
|
2391 |
-
bigPlay =
|
2392 |
-
$('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
|
2393 |
-
'<div class="mejs-overlay-button"></div>'+
|
2394 |
-
'</div>')
|
2395 |
-
.appendTo(layers)
|
2396 |
-
.click(function() {
|
2397 |
-
if (media.paused) {
|
2398 |
-
media.play();
|
2399 |
-
} else {
|
2400 |
-
media.pause();
|
2401 |
-
}
|
2402 |
-
});
|
2403 |
-
|
2404 |
-
/*
|
2405 |
-
if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
|
2406 |
-
bigPlay.remove();
|
2407 |
-
loading.remove();
|
2408 |
-
}
|
2409 |
-
*/
|
2410 |
-
|
2411 |
-
|
2412 |
-
// show/hide big play button
|
2413 |
-
media.addEventListener('play',function() {
|
2414 |
-
bigPlay.hide();
|
2415 |
-
loading.hide();
|
2416 |
-
controls.find('.mejs-time-buffering').hide();
|
2417 |
-
error.hide();
|
2418 |
-
}, false);
|
2419 |
-
|
2420 |
-
media.addEventListener('playing', function() {
|
2421 |
-
bigPlay.hide();
|
2422 |
-
loading.hide();
|
2423 |
-
controls.find('.mejs-time-buffering').hide();
|
2424 |
-
error.hide();
|
2425 |
-
}, false);
|
2426 |
-
|
2427 |
-
media.addEventListener('seeking', function() {
|
2428 |
-
loading.show();
|
2429 |
-
controls.find('.mejs-time-buffering').show();
|
2430 |
-
}, false);
|
2431 |
-
|
2432 |
-
media.addEventListener('seeked', function() {
|
2433 |
-
loading.hide();
|
2434 |
-
controls.find('.mejs-time-buffering').hide();
|
2435 |
-
}, false);
|
2436 |
-
|
2437 |
-
media.addEventListener('pause',function() {
|
2438 |
-
if (!mejs.MediaFeatures.isiPhone) {
|
2439 |
-
bigPlay.show();
|
2440 |
-
}
|
2441 |
-
}, false);
|
2442 |
-
|
2443 |
-
media.addEventListener('waiting', function() {
|
2444 |
-
loading.show();
|
2445 |
-
controls.find('.mejs-time-buffering').show();
|
2446 |
-
}, false);
|
2447 |
-
|
2448 |
-
|
2449 |
-
// show/hide loading
|
2450 |
-
media.addEventListener('loadeddata',function() {
|
2451 |
-
// for some reason Chrome is firing this event
|
2452 |
-
//if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
|
2453 |
-
// return;
|
2454 |
-
|
2455 |
-
loading.show();
|
2456 |
-
controls.find('.mejs-time-buffering').show();
|
2457 |
-
}, false);
|
2458 |
-
media.addEventListener('canplay',function() {
|
2459 |
-
loading.hide();
|
2460 |
-
controls.find('.mejs-time-buffering').hide();
|
2461 |
-
}, false);
|
2462 |
-
|
2463 |
-
// error handling
|
2464 |
-
media.addEventListener('error',function() {
|
2465 |
-
loading.hide();
|
2466 |
-
controls.find('.mejs-time-buffering').hide();
|
2467 |
-
error.show();
|
2468 |
-
error.find('mejs-overlay-error').html("Error loading this resource");
|
2469 |
-
}, false);
|
2470 |
-
},
|
2471 |
-
|
2472 |
-
buildkeyboard: function(player, controls, layers, media) {
|
2473 |
-
|
2474 |
-
var t = this;
|
2475 |
-
|
2476 |
-
// listen for key presses
|
2477 |
-
$(document).keydown(function(e) {
|
2478 |
-
|
2479 |
-
if (player.hasFocus && player.options.enableKeyboard) {
|
2480 |
-
|
2481 |
-
// find a matching key
|
2482 |
-
for (var i=0, il=player.options.keyActions.length; i<il; i++) {
|
2483 |
-
var keyAction = player.options.keyActions[i];
|
2484 |
-
|
2485 |
-
for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
|
2486 |
-
if (e.keyCode == keyAction.keys[j]) {
|
2487 |
-
e.preventDefault();
|
2488 |
-
keyAction.action(player, media);
|
2489 |
-
return false;
|
2490 |
-
}
|
2491 |
-
}
|
2492 |
-
}
|
2493 |
-
}
|
2494 |
-
|
2495 |
-
return true;
|
2496 |
-
});
|
2497 |
-
|
2498 |
-
// check if someone clicked outside a player region, then kill its focus
|
2499 |
-
$(document).click(function(event) {
|
2500 |
-
if ($(event.target).closest('.mejs-container').length == 0) {
|
2501 |
-
player.hasFocus = false;
|
2502 |
-
}
|
2503 |
-
});
|
2504 |
-
|
2505 |
-
},
|
2506 |
-
|
2507 |
-
findTracks: function() {
|
2508 |
-
var t = this,
|
2509 |
-
tracktags = t.$media.find('track');
|
2510 |
-
|
2511 |
-
// store for use by plugins
|
2512 |
-
t.tracks = [];
|
2513 |
-
tracktags.each(function(index, track) {
|
2514 |
-
|
2515 |
-
track = $(track);
|
2516 |
-
|
2517 |
-
t.tracks.push({
|
2518 |
-
srclang: track.attr('srclang').toLowerCase(),
|
2519 |
-
src: track.attr('src'),
|
2520 |
-
kind: track.attr('kind'),
|
2521 |
-
label: track.attr('label') || '',
|
2522 |
-
entries: [],
|
2523 |
-
isLoaded: false
|
2524 |
-
});
|
2525 |
-
});
|
2526 |
-
},
|
2527 |
-
changeSkin: function(className) {
|
2528 |
-
this.container[0].className = 'mejs-container ' + className;
|
2529 |
-
this.setPlayerSize(this.width, this.height);
|
2530 |
-
this.setControlsSize();
|
2531 |
-
},
|
2532 |
-
play: function() {
|
2533 |
-
this.media.play();
|
2534 |
-
},
|
2535 |
-
pause: function() {
|
2536 |
-
this.media.pause();
|
2537 |
-
},
|
2538 |
-
load: function() {
|
2539 |
-
this.media.load();
|
2540 |
-
},
|
2541 |
-
setMuted: function(muted) {
|
2542 |
-
this.media.setMuted(muted);
|
2543 |
-
},
|
2544 |
-
setCurrentTime: function(time) {
|
2545 |
-
this.media.setCurrentTime(time);
|
2546 |
-
},
|
2547 |
-
getCurrentTime: function() {
|
2548 |
-
return this.media.currentTime;
|
2549 |
-
},
|
2550 |
-
setVolume: function(volume) {
|
2551 |
-
this.media.setVolume(volume);
|
2552 |
-
},
|
2553 |
-
getVolume: function() {
|
2554 |
-
return this.media.volume;
|
2555 |
-
},
|
2556 |
-
setSrc: function(src) {
|
2557 |
-
this.media.setSrc(src);
|
2558 |
-
},
|
2559 |
-
remove: function() {
|
2560 |
-
var t = this;
|
2561 |
-
|
2562 |
-
if (t.media.pluginType == 'flash') {
|
2563 |
-
t.media.remove();
|
2564 |
-
} else if (t.media.pluginType == 'native') {
|
2565 |
-
t.media.prop('controls', true);
|
2566 |
-
}
|
2567 |
-
|
2568 |
-
// grab video and put it back in place
|
2569 |
-
if (!t.isDynamic) {
|
2570 |
-
t.$node.insertBefore(t.container)
|
2571 |
-
}
|
2572 |
-
|
2573 |
-
t.container.remove();
|
2574 |
-
}
|
2575 |
-
};
|
2576 |
-
|
2577 |
-
// turn into jQuery plugin
|
2578 |
-
if (typeof jQuery != 'undefined') {
|
2579 |
-
jQuery.fn.mediaelementplayer = function (options) {
|
2580 |
-
return this.each(function () {
|
2581 |
-
new mejs.MediaElementPlayer(this, options);
|
2582 |
-
});
|
2583 |
-
};
|
2584 |
-
}
|
2585 |
-
|
2586 |
-
$(document).ready(function() {
|
2587 |
-
// auto enable using JSON attribute
|
2588 |
-
$('.mejs-player').mediaelementplayer();
|
2589 |
-
});
|
2590 |
-
|
2591 |
-
// push out to window
|
2592 |
-
window.MediaElementPlayer = mejs.MediaElementPlayer;
|
2593 |
-
|
2594 |
-
})(mejs.$);
|
2595 |
|
2596 |
-
|
|
|
|
|
2597 |
|
2598 |
-
|
2599 |
-
|
2600 |
-
|
|
|
|
|
|
|
2601 |
|
2602 |
-
|
2603 |
-
|
2604 |
-
|
2605 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2606 |
t = this,
|
2607 |
-
|
2608 |
-
|
2609 |
-
|
2610 |
-
|
2611 |
-
|
2612 |
-
|
2613 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2614 |
|
2615 |
-
|
2616 |
-
|
2617 |
-
|
2618 |
-
|
2619 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2620 |
|
2621 |
-
|
2622 |
-
|
|
|
2623 |
|
2624 |
-
|
2625 |
-
play.removeClass('mejs-play').addClass('mejs-pause');
|
2626 |
-
}, false);
|
2627 |
-
media.addEventListener('playing',function() {
|
2628 |
-
play.removeClass('mejs-play').addClass('mejs-pause');
|
2629 |
-
}, false);
|
2630 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2631 |
|
2632 |
-
|
2633 |
-
|
2634 |
-
|
2635 |
-
|
2636 |
-
|
2637 |
-
|
2638 |
-
|
2639 |
-
|
2640 |
-
|
2641 |
-
|
2642 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2643 |
|
2644 |
-
|
2645 |
-
|
2646 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2647 |
|
2648 |
-
|
2649 |
-
|
2650 |
-
|
2651 |
-
|
2652 |
-
|
2653 |
-
|
2654 |
-
|
2655 |
-
|
2656 |
-
|
2657 |
-
|
2658 |
-
|
2659 |
-
|
2660 |
-
|
2661 |
-
|
2662 |
-
|
2663 |
-
|
2664 |
-
|
2665 |
-
|
2666 |
-
|
2667 |
-
|
2668 |
-
|
2669 |
-
|
2670 |
-
|
2671 |
-
|
|
|
|
|
2672 |
|
2673 |
-
|
2674 |
-
(
|
2675 |
-
|
2676 |
-
|
2677 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2678 |
|
2679 |
-
|
2680 |
-
|
2681 |
-
|
2682 |
-
|
2683 |
-
|
2684 |
-
|
2685 |
-
|
2686 |
-
|
2687 |
-
|
2688 |
-
|
2689 |
-
|
2690 |
-
|
2691 |
-
|
2692 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2693 |
|
2694 |
-
|
2695 |
-
t = this,
|
2696 |
-
total = controls.find('.mejs-time-total'),
|
2697 |
-
loaded = controls.find('.mejs-time-loaded'),
|
2698 |
-
current = controls.find('.mejs-time-current'),
|
2699 |
-
handle = controls.find('.mejs-time-handle'),
|
2700 |
-
timefloat = controls.find('.mejs-time-float'),
|
2701 |
-
timefloatcurrent = controls.find('.mejs-time-float-current'),
|
2702 |
-
handleMouseMove = function (e) {
|
2703 |
-
// mouse position relative to the object
|
2704 |
-
var x = e.pageX,
|
2705 |
-
offset = total.offset(),
|
2706 |
-
width = total.outerWidth(),
|
2707 |
-
percentage = 0,
|
2708 |
-
newTime = 0,
|
2709 |
-
pos = x - offset.left;
|
2710 |
|
|
|
2711 |
|
2712 |
-
|
2713 |
-
|
2714 |
-
|
2715 |
|
2716 |
-
|
2717 |
-
if (mouseIsDown) {
|
2718 |
-
media.setCurrentTime(newTime);
|
2719 |
-
}
|
2720 |
|
2721 |
-
|
2722 |
-
|
2723 |
-
|
2724 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2725 |
timefloat.show();
|
2726 |
}
|
2727 |
}
|
@@ -2838,86 +2838,86 @@ if (typeof jQuery != 'undefined') {
|
|
2838 |
}
|
2839 |
});
|
2840 |
})(mejs.$);
|
2841 |
-
(function($) {
|
2842 |
-
|
2843 |
-
// options
|
2844 |
-
$.extend(mejs.MepDefaults, {
|
2845 |
-
duration: -1,
|
2846 |
-
timeAndDurationSeparator: ' <span> | </span> '
|
2847 |
-
});
|
2848 |
-
|
2849 |
-
|
2850 |
-
// current and duration 00:00 / 00:00
|
2851 |
-
$.extend(MediaElementPlayer.prototype, {
|
2852 |
-
buildcurrent: function(player, controls, layers, media) {
|
2853 |
-
var t = this;
|
2854 |
-
|
2855 |
-
$('<div class="mejs-time">'+
|
2856 |
-
'<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
|
2857 |
-
+ (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
|
2858 |
-
'</div>')
|
2859 |
-
.appendTo(controls);
|
2860 |
-
|
2861 |
-
t.currenttime = t.controls.find('.mejs-currenttime');
|
2862 |
-
|
2863 |
-
media.addEventListener('timeupdate',function() {
|
2864 |
-
player.updateCurrent();
|
2865 |
-
}, false);
|
2866 |
-
},
|
2867 |
-
|
2868 |
-
|
2869 |
-
buildduration: function(player, controls, layers, media) {
|
2870 |
-
var t = this;
|
2871 |
-
|
2872 |
-
if (controls.children().last().find('.mejs-currenttime').length > 0) {
|
2873 |
-
$(t.options.timeAndDurationSeparator +
|
2874 |
-
'<span class="mejs-duration">' +
|
2875 |
-
(t.options.duration > 0 ?
|
2876 |
-
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
2877 |
-
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
2878 |
-
) +
|
2879 |
-
'</span>')
|
2880 |
-
.appendTo(controls.find('.mejs-time'));
|
2881 |
-
} else {
|
2882 |
-
|
2883 |
-
// add class to current time
|
2884 |
-
controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
|
2885 |
-
|
2886 |
-
$('<div class="mejs-time mejs-duration-container">'+
|
2887 |
-
'<span class="mejs-duration">' +
|
2888 |
-
(t.options.duration > 0 ?
|
2889 |
-
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
2890 |
-
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
2891 |
-
) +
|
2892 |
-
'</span>' +
|
2893 |
-
'</div>')
|
2894 |
-
.appendTo(controls);
|
2895 |
-
}
|
2896 |
-
|
2897 |
-
t.durationD = t.controls.find('.mejs-duration');
|
2898 |
-
|
2899 |
-
media.addEventListener('timeupdate',function() {
|
2900 |
-
player.updateDuration();
|
2901 |
-
}, false);
|
2902 |
-
},
|
2903 |
-
|
2904 |
-
updateCurrent: function() {
|
2905 |
-
var t = this;
|
2906 |
-
|
2907 |
-
if (t.currenttime) {
|
2908 |
-
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
2909 |
-
}
|
2910 |
-
},
|
2911 |
-
|
2912 |
-
updateDuration: function() {
|
2913 |
-
var t = this;
|
2914 |
-
|
2915 |
-
if (t.media.duration && t.durationD) {
|
2916 |
-
t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
2917 |
-
}
|
2918 |
-
}
|
2919 |
-
});
|
2920 |
-
|
2921 |
})(mejs.$);
|
2922 |
(function($) {
|
2923 |
|
@@ -3141,445 +3141,445 @@ if (typeof jQuery != 'undefined') {
|
|
3141 |
|
3142 |
})(mejs.$);
|
3143 |
|
3144 |
-
(function($) {
|
3145 |
-
|
3146 |
-
$.extend(mejs.MepDefaults, {
|
3147 |
-
usePluginFullScreen: true,
|
3148 |
-
newWindowCallback: function() { return '';},
|
3149 |
-
fullscreenText: 'Fullscreen'
|
3150 |
-
});
|
3151 |
-
|
3152 |
-
$.extend(MediaElementPlayer.prototype, {
|
3153 |
-
|
3154 |
-
isFullScreen: false,
|
3155 |
-
|
3156 |
-
isNativeFullScreen: false,
|
3157 |
-
|
3158 |
-
docStyleOverflow: null,
|
3159 |
-
|
3160 |
-
isInIframe: false,
|
3161 |
-
|
3162 |
-
buildfullscreen: function(player, controls, layers, media) {
|
3163 |
-
|
3164 |
-
if (!player.isVideo)
|
3165 |
-
return;
|
3166 |
-
|
3167 |
-
player.isInIframe = (window.location != window.parent.location);
|
3168 |
-
|
3169 |
-
// native events
|
3170 |
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3171 |
-
|
3172 |
-
// chrome doesn't alays fire this in an iframe
|
3173 |
-
var target = null;
|
3174 |
-
|
3175 |
-
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
|
3176 |
-
target = $(document);
|
3177 |
-
} else {
|
3178 |
-
target = player.container;
|
3179 |
-
}
|
3180 |
-
|
3181 |
-
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
|
3182 |
-
//player.container.bind('webkitfullscreenchange', function(e) {
|
3183 |
-
|
3184 |
-
|
3185 |
-
if (mejs.MediaFeatures.isFullScreen()) {
|
3186 |
-
player.isNativeFullScreen = true;
|
3187 |
-
// reset the controls once we are fully in full screen
|
3188 |
-
player.setControlsSize();
|
3189 |
-
} else {
|
3190 |
-
player.isNativeFullScreen = false;
|
3191 |
-
// when a user presses ESC
|
3192 |
-
// make sure to put the player back into place
|
3193 |
-
player.exitFullScreen();
|
3194 |
-
}
|
3195 |
-
});
|
3196 |
-
}
|
3197 |
-
|
3198 |
-
var t = this,
|
3199 |
-
normalHeight = 0,
|
3200 |
-
normalWidth = 0,
|
3201 |
-
container = player.container,
|
3202 |
-
fullscreenBtn =
|
3203 |
-
$('<div class="mejs-button mejs-fullscreen-button">' +
|
3204 |
-
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
|
3205 |
-
'</div>')
|
3206 |
-
.appendTo(controls);
|
3207 |
-
|
3208 |
-
if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
|
3209 |
-
|
3210 |
-
fullscreenBtn.click(function() {
|
3211 |
-
var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
|
3212 |
-
|
3213 |
-
if (isFullScreen) {
|
3214 |
-
player.exitFullScreen();
|
3215 |
-
} else {
|
3216 |
-
player.enterFullScreen();
|
3217 |
-
}
|
3218 |
-
});
|
3219 |
-
|
3220 |
-
} else {
|
3221 |
-
|
3222 |
-
var hideTimeout = null,
|
3223 |
-
supportsPointerEvents = (function() {
|
3224 |
-
// TAKEN FROM MODERNIZR
|
3225 |
-
var element = document.createElement('x'),
|
3226 |
-
documentElement = document.documentElement,
|
3227 |
-
getComputedStyle = window.getComputedStyle,
|
3228 |
-
supports;
|
3229 |
-
if(!('pointerEvents' in element.style)){
|
3230 |
-
return false;
|
3231 |
-
}
|
3232 |
-
element.style.pointerEvents = 'auto';
|
3233 |
-
element.style.pointerEvents = 'x';
|
3234 |
-
documentElement.appendChild(element);
|
3235 |
-
supports = getComputedStyle &&
|
3236 |
-
getComputedStyle(element, '').pointerEvents === 'auto';
|
3237 |
-
documentElement.removeChild(element);
|
3238 |
-
return !!supports;
|
3239 |
-
})();
|
3240 |
-
|
3241 |
-
console.log('supportsPointerEvents', supportsPointerEvents);
|
3242 |
-
|
3243 |
-
if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
|
3244 |
-
|
3245 |
-
// allows clicking through the fullscreen button and controls down directly to Flash
|
3246 |
-
|
3247 |
-
/*
|
3248 |
-
When a user puts his mouse over the fullscreen button, the controls are disabled
|
3249 |
-
So we put a div over the video and another one on iether side of the fullscreen button
|
3250 |
-
that caputre mouse movement
|
3251 |
-
and restore the controls once the mouse moves outside of the fullscreen button
|
3252 |
-
*/
|
3253 |
-
|
3254 |
-
var fullscreenIsDisabled = false,
|
3255 |
-
restoreControls = function() {
|
3256 |
-
if (fullscreenIsDisabled) {
|
3257 |
-
// hide the hovers
|
3258 |
-
videoHoverDiv.hide();
|
3259 |
-
controlsLeftHoverDiv.hide();
|
3260 |
-
controlsRightHoverDiv.hide();
|
3261 |
-
|
3262 |
-
// restore the control bar
|
3263 |
-
fullscreenBtn.css('pointer-events', '');
|
3264 |
-
t.controls.css('pointer-events', '');
|
3265 |
-
|
3266 |
-
// store for later
|
3267 |
-
fullscreenIsDisabled = false;
|
3268 |
-
}
|
3269 |
-
},
|
3270 |
-
videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
3271 |
-
controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
3272 |
-
controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
3273 |
-
positionHoverDivs = function() {
|
3274 |
-
var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
|
3275 |
-
videoHoverDiv.css(style);
|
3276 |
-
controlsLeftHoverDiv.css(style);
|
3277 |
-
controlsRightHoverDiv.css(style);
|
3278 |
-
|
3279 |
-
// over video, but not controls
|
3280 |
-
videoHoverDiv
|
3281 |
-
.width( t.container.width() )
|
3282 |
-
.height( t.container.height() - t.controls.height() );
|
3283 |
-
|
3284 |
-
// over controls, but not the fullscreen button
|
3285 |
-
var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
|
3286 |
-
fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
|
3287 |
-
|
3288 |
-
controlsLeftHoverDiv
|
3289 |
-
.width( fullScreenBtnOffset )
|
3290 |
-
.height( t.controls.height() )
|
3291 |
-
.css({top: t.container.height() - t.controls.height()});
|
3292 |
-
|
3293 |
-
// after the fullscreen button
|
3294 |
-
controlsRightHoverDiv
|
3295 |
-
.width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
|
3296 |
-
.height( t.controls.height() )
|
3297 |
-
.css({top: t.container.height() - t.controls.height(),
|
3298 |
-
left: fullScreenBtnOffset + fullScreenBtnWidth});
|
3299 |
-
};
|
3300 |
-
|
3301 |
-
$(document).resize(function() {
|
3302 |
-
positionHoverDivs();
|
3303 |
-
});
|
3304 |
-
|
3305 |
-
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
|
3306 |
-
fullscreenBtn
|
3307 |
-
.mouseover(function() {
|
3308 |
-
|
3309 |
-
if (!t.isFullScreen) {
|
3310 |
-
|
3311 |
-
var buttonPos = fullscreenBtn.offset(),
|
3312 |
-
containerPos = player.container.offset();
|
3313 |
-
|
3314 |
-
// move the button in Flash into place
|
3315 |
-
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
|
3316 |
-
|
3317 |
-
// allows click through
|
3318 |
-
fullscreenBtn.css('pointer-events', 'none');
|
3319 |
-
t.controls.css('pointer-events', 'none');
|
3320 |
-
|
3321 |
-
// show the divs that will restore things
|
3322 |
-
videoHoverDiv.show();
|
3323 |
-
controlsRightHoverDiv.show();
|
3324 |
-
controlsLeftHoverDiv.show();
|
3325 |
-
positionHoverDivs();
|
3326 |
-
|
3327 |
-
fullscreenIsDisabled = true;
|
3328 |
-
}
|
3329 |
-
|
3330 |
-
});
|
3331 |
-
|
3332 |
-
// restore controls anytime the user enters or leaves fullscreen
|
3333 |
-
media.addEventListener('fullscreenchange', function(e) {
|
3334 |
-
restoreControls();
|
3335 |
-
});
|
3336 |
-
|
3337 |
-
|
3338 |
-
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
|
3339 |
-
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
|
3340 |
-
/*
|
3341 |
-
$(document).mousemove(function(e) {
|
3342 |
-
|
3343 |
-
// if the mouse is anywhere but the fullsceen button, then restore it all
|
3344 |
-
if (fullscreenIsDisabled) {
|
3345 |
-
|
3346 |
-
var fullscreenBtnPos = fullscreenBtn.offset();
|
3347 |
-
|
3348 |
-
|
3349 |
-
if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
|
3350 |
-
e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
|
3351 |
-
) {
|
3352 |
-
|
3353 |
-
fullscreenBtn.css('pointer-events', '');
|
3354 |
-
t.controls.css('pointer-events', '');
|
3355 |
-
|
3356 |
-
fullscreenIsDisabled = false;
|
3357 |
-
}
|
3358 |
-
}
|
3359 |
-
});
|
3360 |
-
*/
|
3361 |
-
|
3362 |
-
|
3363 |
-
} else {
|
3364 |
-
|
3365 |
-
// the hover state will show the fullscreen button in Flash to hover up and click
|
3366 |
-
|
3367 |
-
fullscreenBtn
|
3368 |
-
.mouseover(function() {
|
3369 |
-
|
3370 |
-
if (hideTimeout !== null) {
|
3371 |
-
clearTimeout(hideTimeout);
|
3372 |
-
delete hideTimeout;
|
3373 |
-
}
|
3374 |
-
|
3375 |
-
var buttonPos = fullscreenBtn.offset(),
|
3376 |
-
containerPos = player.container.offset();
|
3377 |
-
|
3378 |
-
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
|
3379 |
-
|
3380 |
-
})
|
3381 |
-
.mouseout(function() {
|
3382 |
-
|
3383 |
-
if (hideTimeout !== null) {
|
3384 |
-
clearTimeout(hideTimeout);
|
3385 |
-
delete hideTimeout;
|
3386 |
-
}
|
3387 |
-
|
3388 |
-
hideTimeout = setTimeout(function() {
|
3389 |
-
media.hideFullscreenButton();
|
3390 |
-
}, 1500);
|
3391 |
-
|
3392 |
-
|
3393 |
-
});
|
3394 |
-
}
|
3395 |
-
}
|
3396 |
-
|
3397 |
-
player.fullscreenBtn = fullscreenBtn;
|
3398 |
-
|
3399 |
-
$(document).bind('keydown',function (e) {
|
3400 |
-
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
|
3401 |
-
player.exitFullScreen();
|
3402 |
-
}
|
3403 |
-
});
|
3404 |
-
|
3405 |
-
},
|
3406 |
-
enterFullScreen: function() {
|
3407 |
-
|
3408 |
-
var t = this;
|
3409 |
-
|
3410 |
-
// firefox+flash can't adjust plugin sizes without resetting :(
|
3411 |
-
if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
|
3412 |
-
//t.media.setFullscreen(true);
|
3413 |
-
//player.isFullScreen = true;
|
3414 |
-
return;
|
3415 |
-
}
|
3416 |
-
|
3417 |
-
// store overflow
|
3418 |
-
docStyleOverflow = document.documentElement.style.overflow;
|
3419 |
-
// set it to not show scroll bars so 100% will work
|
3420 |
-
document.documentElement.style.overflow = 'hidden';
|
3421 |
-
|
3422 |
-
// store sizing
|
3423 |
-
normalHeight = t.container.height();
|
3424 |
-
normalWidth = t.container.width();
|
3425 |
-
|
3426 |
-
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
3427 |
-
if (t.media.pluginType === 'native') {
|
3428 |
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3429 |
-
|
3430 |
-
mejs.MediaFeatures.requestFullScreen(t.container[0]);
|
3431 |
-
//return;
|
3432 |
-
|
3433 |
-
if (t.isInIframe) {
|
3434 |
-
// sometimes exiting from fullscreen doesn't work
|
3435 |
-
// notably in Chrome <iframe>. Fixed in version 17
|
3436 |
-
setTimeout(function checkFullscreen() {
|
3437 |
-
|
3438 |
-
if (t.isNativeFullScreen) {
|
3439 |
-
|
3440 |
-
// check if the video is suddenly not really fullscreen
|
3441 |
-
if ($(window).width() !== screen.width) {
|
3442 |
-
// manually exit
|
3443 |
-
t.exitFullScreen();
|
3444 |
-
} else {
|
3445 |
-
// test again
|
3446 |
-
setTimeout(checkFullscreen, 500);
|
3447 |
-
}
|
3448 |
-
}
|
3449 |
-
|
3450 |
-
|
3451 |
-
}, 500);
|
3452 |
-
}
|
3453 |
-
|
3454 |
-
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
3455 |
-
t.media.webkitEnterFullscreen();
|
3456 |
-
return;
|
3457 |
-
}
|
3458 |
-
}
|
3459 |
-
|
3460 |
-
// check for iframe launch
|
3461 |
-
if (t.isInIframe) {
|
3462 |
-
var url = t.options.newWindowCallback(this);
|
3463 |
-
|
3464 |
-
|
3465 |
-
if (url !== '') {
|
3466 |
-
|
3467 |
-
// launch immediately
|
3468 |
-
if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3469 |
-
t.pause();
|
3470 |
-
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
3471 |
-
return;
|
3472 |
-
} else {
|
3473 |
-
setTimeout(function() {
|
3474 |
-
if (!t.isNativeFullScreen) {
|
3475 |
-
t.pause();
|
3476 |
-
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
3477 |
-
}
|
3478 |
-
}, 250);
|
3479 |
-
}
|
3480 |
-
}
|
3481 |
-
|
3482 |
-
}
|
3483 |
-
|
3484 |
-
// full window code
|
3485 |
-
|
3486 |
-
|
3487 |
-
|
3488 |
-
// make full size
|
3489 |
-
t.container
|
3490 |
-
.addClass('mejs-container-fullscreen')
|
3491 |
-
.width('100%')
|
3492 |
-
.height('100%');
|
3493 |
-
//.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
|
3494 |
-
|
3495 |
-
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
|
3496 |
-
// Actually, it seems to be needed for IE8, too
|
3497 |
-
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3498 |
-
setTimeout(function() {
|
3499 |
-
t.container.css({width: '100%', height: '100%'});
|
3500 |
-
t.setControlsSize();
|
3501 |
-
}, 500);
|
3502 |
-
//}
|
3503 |
-
|
3504 |
-
if (t.pluginType === 'native') {
|
3505 |
-
t.$media
|
3506 |
-
.width('100%')
|
3507 |
-
.height('100%');
|
3508 |
-
} else {
|
3509 |
-
t.container.find('object, embed, iframe')
|
3510 |
-
.width('100%')
|
3511 |
-
.height('100%');
|
3512 |
-
|
3513 |
-
//if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3514 |
-
t.media.setVideoSize($(window).width(),$(window).height());
|
3515 |
-
//}
|
3516 |
-
}
|
3517 |
-
|
3518 |
-
t.layers.children('div')
|
3519 |
-
.width('100%')
|
3520 |
-
.height('100%');
|
3521 |
-
|
3522 |
-
if (t.fullscreenBtn) {
|
3523 |
-
t.fullscreenBtn
|
3524 |
-
.removeClass('mejs-fullscreen')
|
3525 |
-
.addClass('mejs-unfullscreen');
|
3526 |
-
}
|
3527 |
-
|
3528 |
-
t.setControlsSize();
|
3529 |
-
t.isFullScreen = true;
|
3530 |
-
},
|
3531 |
-
|
3532 |
-
exitFullScreen: function() {
|
3533 |
-
|
3534 |
-
var t = this;
|
3535 |
-
|
3536 |
-
// firefox can't adjust plugins
|
3537 |
-
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
|
3538 |
-
t.media.setFullscreen(false);
|
3539 |
-
//player.isFullScreen = false;
|
3540 |
-
return;
|
3541 |
-
}
|
3542 |
-
|
3543 |
-
// come outo of native fullscreen
|
3544 |
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
|
3545 |
-
mejs.MediaFeatures.cancelFullScreen();
|
3546 |
-
}
|
3547 |
-
|
3548 |
-
// restore scroll bars to document
|
3549 |
-
document.documentElement.style.overflow = docStyleOverflow;
|
3550 |
-
|
3551 |
-
t.container
|
3552 |
-
.removeClass('mejs-container-fullscreen')
|
3553 |
-
.width(normalWidth)
|
3554 |
-
.height(normalHeight);
|
3555 |
-
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
3556 |
-
|
3557 |
-
if (t.pluginType === 'native') {
|
3558 |
-
t.$media
|
3559 |
-
.width(normalWidth)
|
3560 |
-
.height(normalHeight);
|
3561 |
-
} else {
|
3562 |
-
t.container.find('object embed')
|
3563 |
-
.width(normalWidth)
|
3564 |
-
.height(normalHeight);
|
3565 |
-
|
3566 |
-
t.media.setVideoSize(normalWidth, normalHeight);
|
3567 |
-
}
|
3568 |
-
|
3569 |
-
t.layers.children('div')
|
3570 |
-
.width(normalWidth)
|
3571 |
-
.height(normalHeight);
|
3572 |
-
|
3573 |
-
t.fullscreenBtn
|
3574 |
-
.removeClass('mejs-unfullscreen')
|
3575 |
-
.addClass('mejs-fullscreen');
|
3576 |
-
|
3577 |
-
t.setControlsSize();
|
3578 |
-
t.isFullScreen = false;
|
3579 |
-
}
|
3580 |
-
});
|
3581 |
-
|
3582 |
-
})(mejs.$);
|
3583 |
|
3584 |
(function($) {
|
3585 |
|
@@ -4066,197 +4066,197 @@ if (typeof jQuery != 'undefined') {
|
|
4066 |
|
4067 |
})(mejs.$);
|
4068 |
|
4069 |
-
/*
|
4070 |
-
* ContextMenu Plugin
|
4071 |
-
*
|
4072 |
-
*
|
4073 |
-
*/
|
4074 |
-
|
4075 |
-
(function($) {
|
4076 |
-
|
4077 |
-
$.extend(mejs.MepDefaults,
|
4078 |
-
{ 'contextMenuItems': [
|
4079 |
-
// demo of a fullscreen option
|
4080 |
-
{
|
4081 |
-
render: function(player) {
|
4082 |
-
|
4083 |
-
// check for fullscreen plugin
|
4084 |
-
if (typeof player.enterFullScreen == 'undefined')
|
4085 |
-
return null;
|
4086 |
-
|
4087 |
-
if (player.isFullScreen) {
|
4088 |
-
return "Turn off Fullscreen";
|
4089 |
-
} else {
|
4090 |
-
return "Go Fullscreen";
|
4091 |
-
}
|
4092 |
-
},
|
4093 |
-
click: function(player) {
|
4094 |
-
if (player.isFullScreen) {
|
4095 |
-
player.exitFullScreen();
|
4096 |
-
} else {
|
4097 |
-
player.enterFullScreen();
|
4098 |
-
}
|
4099 |
-
}
|
4100 |
-
}
|
4101 |
-
,
|
4102 |
-
// demo of a mute/unmute button
|
4103 |
-
{
|
4104 |
-
render: function(player) {
|
4105 |
-
if (player.media.muted) {
|
4106 |
-
return "Unmute";
|
4107 |
-
} else {
|
4108 |
-
return "Mute";
|
4109 |
-
}
|
4110 |
-
},
|
4111 |
-
click: function(player) {
|
4112 |
-
if (player.media.muted) {
|
4113 |
-
player.setMuted(false);
|
4114 |
-
} else {
|
4115 |
-
player.setMuted(true);
|
4116 |
-
}
|
4117 |
-
}
|
4118 |
-
},
|
4119 |
-
// separator
|
4120 |
-
{
|
4121 |
-
isSeparator: true
|
4122 |
-
}
|
4123 |
-
,
|
4124 |
-
// demo of simple download video
|
4125 |
-
{
|
4126 |
-
render: function(player) {
|
4127 |
-
return "Download Video";
|
4128 |
-
},
|
4129 |
-
click: function(player) {
|
4130 |
-
window.location.href = player.media.currentSrc;
|
4131 |
-
}
|
4132 |
-
}
|
4133 |
-
]}
|
4134 |
-
);
|
4135 |
-
|
4136 |
-
|
4137 |
-
$.extend(MediaElementPlayer.prototype, {
|
4138 |
-
buildcontextmenu: function(player, controls, layers, media) {
|
4139 |
-
|
4140 |
-
// create context menu
|
4141 |
-
player.contextMenu = $('<div class="mejs-contextmenu"></div>')
|
4142 |
-
.appendTo($('body'))
|
4143 |
-
.hide();
|
4144 |
-
|
4145 |
-
// create events for showing context menu
|
4146 |
-
player.container.bind('contextmenu', function(e) {
|
4147 |
-
if (player.isContextMenuEnabled) {
|
4148 |
-
e.preventDefault();
|
4149 |
-
player.renderContextMenu(e.clientX-1, e.clientY-1);
|
4150 |
-
return false;
|
4151 |
-
}
|
4152 |
-
});
|
4153 |
-
player.container.bind('click', function() {
|
4154 |
-
player.contextMenu.hide();
|
4155 |
-
});
|
4156 |
-
player.contextMenu.bind('mouseleave', function() {
|
4157 |
-
|
4158 |
-
//console.log('context hover out');
|
4159 |
-
player.startContextMenuTimer();
|
4160 |
-
|
4161 |
-
});
|
4162 |
-
},
|
4163 |
-
|
4164 |
-
isContextMenuEnabled: true,
|
4165 |
-
enableContextMenu: function() {
|
4166 |
-
this.isContextMenuEnabled = true;
|
4167 |
-
},
|
4168 |
-
disableContextMenu: function() {
|
4169 |
-
this.isContextMenuEnabled = false;
|
4170 |
-
},
|
4171 |
-
|
4172 |
-
contextMenuTimeout: null,
|
4173 |
-
startContextMenuTimer: function() {
|
4174 |
-
//console.log('startContextMenuTimer');
|
4175 |
-
|
4176 |
-
var t = this;
|
4177 |
-
|
4178 |
-
t.killContextMenuTimer();
|
4179 |
-
|
4180 |
-
t.contextMenuTimer = setTimeout(function() {
|
4181 |
-
t.hideContextMenu();
|
4182 |
-
t.killContextMenuTimer();
|
4183 |
-
}, 750);
|
4184 |
-
},
|
4185 |
-
killContextMenuTimer: function() {
|
4186 |
-
var timer = this.contextMenuTimer;
|
4187 |
-
|
4188 |
-
//console.log('killContextMenuTimer', timer);
|
4189 |
-
|
4190 |
-
if (timer != null) {
|
4191 |
-
clearTimeout(timer);
|
4192 |
-
delete timer;
|
4193 |
-
timer = null;
|
4194 |
-
}
|
4195 |
-
},
|
4196 |
-
|
4197 |
-
hideContextMenu: function() {
|
4198 |
-
this.contextMenu.hide();
|
4199 |
-
},
|
4200 |
-
|
4201 |
-
renderContextMenu: function(x,y) {
|
4202 |
-
|
4203 |
-
// alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
|
4204 |
-
var t = this,
|
4205 |
-
html = '',
|
4206 |
-
items = t.options.contextMenuItems;
|
4207 |
-
|
4208 |
-
for (var i=0, il=items.length; i<il; i++) {
|
4209 |
-
|
4210 |
-
if (items[i].isSeparator) {
|
4211 |
-
html += '<div class="mejs-contextmenu-separator"></div>';
|
4212 |
-
} else {
|
4213 |
-
|
4214 |
-
var rendered = items[i].render(t);
|
4215 |
-
|
4216 |
-
// render can return null if the item doesn't need to be used at the moment
|
4217 |
-
if (rendered != null) {
|
4218 |
-
html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
|
4219 |
-
}
|
4220 |
-
}
|
4221 |
-
}
|
4222 |
-
|
4223 |
-
// position and show the context menu
|
4224 |
-
t.contextMenu
|
4225 |
-
.empty()
|
4226 |
-
.append($(html))
|
4227 |
-
.css({top:y, left:x})
|
4228 |
-
.show();
|
4229 |
-
|
4230 |
-
// bind events
|
4231 |
-
t.contextMenu.find('.mejs-contextmenu-item').each(function() {
|
4232 |
-
|
4233 |
-
// which one is this?
|
4234 |
-
var $dom = $(this),
|
4235 |
-
itemIndex = parseInt( $dom.data('itemindex'), 10 ),
|
4236 |
-
item = t.options.contextMenuItems[itemIndex];
|
4237 |
-
|
4238 |
-
// bind extra functionality?
|
4239 |
-
if (typeof item.show != 'undefined')
|
4240 |
-
item.show( $dom , t);
|
4241 |
-
|
4242 |
-
// bind click action
|
4243 |
-
$dom.click(function() {
|
4244 |
-
// perform click action
|
4245 |
-
if (typeof item.click != 'undefined')
|
4246 |
-
item.click(t);
|
4247 |
-
|
4248 |
-
// close
|
4249 |
-
t.contextMenu.hide();
|
4250 |
-
});
|
4251 |
-
});
|
4252 |
-
|
4253 |
-
// stop the controls from hiding
|
4254 |
-
setTimeout(function() {
|
4255 |
-
t.killControlsTimer('rev3');
|
4256 |
-
}, 100);
|
4257 |
-
|
4258 |
-
}
|
4259 |
-
});
|
4260 |
-
|
4261 |
})(mejs.$);
|
4262 |
|
11 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
12 |
*
|
13 |
*/
|
14 |
+
// Namespace
|
15 |
+
var mejs = mejs || {};
|
16 |
+
|
17 |
+
// version number
|
18 |
+
mejs.version = '2.9.1';
|
19 |
+
|
20 |
+
// player number (for missing, same id attr)
|
21 |
+
mejs.meIndex = 0;
|
22 |
+
|
23 |
+
// media types accepted by plugins
|
24 |
+
mejs.plugins = {
|
25 |
+
silverlight: [
|
26 |
+
{version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
|
27 |
+
],
|
28 |
+
flash: [
|
29 |
+
{version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
|
30 |
+
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
|
31 |
+
],
|
32 |
+
youtube: [
|
33 |
+
{version: null, types: ['video/youtube', 'video/x-youtube']}
|
34 |
+
],
|
35 |
+
vimeo: [
|
36 |
+
{version: null, types: ['video/vimeo']}
|
37 |
+
]
|
38 |
+
};
|
39 |
+
|
40 |
+
/*
|
41 |
+
Utility methods
|
42 |
+
*/
|
43 |
+
mejs.Utility = {
|
44 |
+
encodeUrl: function(url) {
|
45 |
+
return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
|
46 |
+
},
|
47 |
+
escapeHTML: function(s) {
|
48 |
+
return s.toString().split('&').join('&').split('<').join('<').split('"').join('"');
|
49 |
+
},
|
50 |
+
absolutizeUrl: function(url) {
|
51 |
+
var el = document.createElement('div');
|
52 |
+
el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
|
53 |
+
return el.firstChild.href;
|
54 |
+
},
|
55 |
+
getScriptPath: function(scriptNames) {
|
56 |
+
var
|
57 |
+
i = 0,
|
58 |
+
j,
|
59 |
+
path = '',
|
60 |
+
name = '',
|
61 |
+
script,
|
62 |
+
scripts = document.getElementsByTagName('script'),
|
63 |
+
il = scripts.length,
|
64 |
+
jl = scriptNames.length;
|
65 |
+
|
66 |
+
for (; i < il; i++) {
|
67 |
+
script = scripts[i].src;
|
68 |
+
for (j = 0; j < jl; j++) {
|
69 |
+
name = scriptNames[j];
|
70 |
+
if (script.indexOf(name) > -1) {
|
71 |
+
path = script.substring(0, script.indexOf(name));
|
72 |
+
break;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
if (path !== '') {
|
76 |
+
break;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
return path;
|
80 |
+
},
|
81 |
+
secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
|
82 |
+
//add framecount
|
83 |
+
if (typeof showFrameCount == 'undefined') {
|
84 |
+
showFrameCount=false;
|
85 |
+
} else if(typeof fps == 'undefined') {
|
86 |
+
fps = 25;
|
87 |
+
}
|
88 |
+
|
89 |
+
var hours = Math.floor(time / 3600) % 24,
|
90 |
+
minutes = Math.floor(time / 60) % 60,
|
91 |
+
seconds = Math.floor(time % 60),
|
92 |
+
frames = Math.floor(((time % 1)*fps).toFixed(3)),
|
93 |
+
result =
|
94 |
+
( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
|
95 |
+
+ (minutes < 10 ? '0' + minutes : minutes) + ':'
|
96 |
+
+ (seconds < 10 ? '0' + seconds : seconds)
|
97 |
+
+ ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
|
98 |
+
|
99 |
+
return result;
|
100 |
+
},
|
101 |
+
|
102 |
+
timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
|
103 |
+
if (typeof showFrameCount == 'undefined') {
|
104 |
+
showFrameCount=false;
|
105 |
+
} else if(typeof fps == 'undefined') {
|
106 |
+
fps = 25;
|
107 |
+
}
|
108 |
+
|
109 |
+
var tc_array = hh_mm_ss_ff.split(":"),
|
110 |
+
tc_hh = parseInt(tc_array[0], 10),
|
111 |
+
tc_mm = parseInt(tc_array[1], 10),
|
112 |
+
tc_ss = parseInt(tc_array[2], 10),
|
113 |
+
tc_ff = 0,
|
114 |
+
tc_in_seconds = 0;
|
115 |
+
|
116 |
+
if (showFrameCount) {
|
117 |
+
tc_ff = parseInt(tc_array[3])/fps;
|
118 |
+
}
|
119 |
+
|
120 |
+
tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
|
121 |
+
|
122 |
+
return tc_in_seconds;
|
123 |
+
},
|
124 |
+
|
125 |
+
/* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
|
126 |
+
removeSwf: function(id) {
|
127 |
+
var obj = document.getElementById(id);
|
128 |
+
if (obj && obj.nodeName == "OBJECT") {
|
129 |
+
if (mejs.MediaFeatures.isIE) {
|
130 |
+
obj.style.display = "none";
|
131 |
+
(function(){
|
132 |
+
if (obj.readyState == 4) {
|
133 |
+
mejs.Utility.removeObjectInIE(id);
|
134 |
+
} else {
|
135 |
+
setTimeout(arguments.callee, 10);
|
136 |
+
}
|
137 |
+
})();
|
138 |
+
} else {
|
139 |
+
obj.parentNode.removeChild(obj);
|
140 |
+
}
|
141 |
+
}
|
142 |
+
},
|
143 |
+
removeObjectInIE: function(id) {
|
144 |
+
var obj = document.getElementById(id);
|
145 |
+
if (obj) {
|
146 |
+
for (var i in obj) {
|
147 |
+
if (typeof obj[i] == "function") {
|
148 |
+
obj[i] = null;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
obj.parentNode.removeChild(obj);
|
152 |
+
}
|
153 |
+
}
|
154 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
|
157 |
// Core detector, plugins are added below
|
1532 |
} else if (typeof ender != 'undefined') {
|
1533 |
mejs.$ = ender;
|
1534 |
}
|
1535 |
+
(function ($) {
|
1536 |
+
|
1537 |
+
// default player values
|
1538 |
+
mejs.MepDefaults = {
|
1539 |
+
// url to poster (to fix iOS 3.x)
|
1540 |
+
poster: '',
|
1541 |
+
// default if the <video width> is not specified
|
1542 |
+
defaultVideoWidth: 480,
|
1543 |
+
// default if the <video height> is not specified
|
1544 |
+
defaultVideoHeight: 270,
|
1545 |
+
// if set, overrides <video width>
|
1546 |
+
videoWidth: -1,
|
1547 |
+
// if set, overrides <video height>
|
1548 |
+
videoHeight: -1,
|
1549 |
+
// default if the user doesn't specify
|
1550 |
+
defaultAudioWidth: 400,
|
1551 |
+
// default if the user doesn't specify
|
1552 |
+
defaultAudioHeight: 30,
|
1553 |
+
// width of audio player
|
1554 |
+
audioWidth: -1,
|
1555 |
+
// height of audio player
|
1556 |
+
audioHeight: -1,
|
1557 |
+
// initial volume when the player starts (overrided by user cookie)
|
1558 |
+
startVolume: 0.8,
|
1559 |
+
// useful for <audio> player loops
|
1560 |
+
loop: false,
|
1561 |
+
// resize to media dimensions
|
1562 |
+
enableAutosize: true,
|
1563 |
+
// forces the hour marker (##:00:00)
|
1564 |
+
alwaysShowHours: false,
|
1565 |
+
|
1566 |
+
// show framecount in timecode (##:00:00:00)
|
1567 |
+
showTimecodeFrameCount: false,
|
1568 |
+
// used when showTimecodeFrameCount is set to true
|
1569 |
+
framesPerSecond: 25,
|
1570 |
+
|
1571 |
+
// automatically calculate the width of the progress bar based on the sizes of other elements
|
1572 |
+
autosizeProgress : true,
|
1573 |
+
// Hide controls when playing and mouse is not over the video
|
1574 |
+
alwaysShowControls: false,
|
1575 |
+
// force iPad's native controls
|
1576 |
+
iPadUseNativeControls: false,
|
1577 |
+
// force iPhone's native controls
|
1578 |
+
iPhoneUseNativeControls: false,
|
1579 |
+
// force Android's native controls
|
1580 |
+
AndroidUseNativeControls: false,
|
1581 |
+
// features to show
|
1582 |
+
features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
|
1583 |
+
// only for dynamic
|
1584 |
+
isVideo: true,
|
1585 |
+
|
1586 |
+
// turns keyboard support on and off for this instance
|
1587 |
+
enableKeyboard: true,
|
1588 |
+
|
1589 |
+
// whenthis player starts, it will pause other players
|
1590 |
+
pauseOtherPlayers: true,
|
1591 |
+
|
1592 |
+
// array of keyboard actions such as play pause
|
1593 |
+
keyActions: [
|
1594 |
+
{
|
1595 |
+
keys: [
|
1596 |
+
32, // SPACE
|
1597 |
+
179 // GOOGLE play/pause button
|
1598 |
+
],
|
1599 |
+
action: function(player, media) {
|
1600 |
+
if (media.paused || media.ended) {
|
1601 |
+
media.play();
|
1602 |
+
} else {
|
1603 |
+
media.pause();
|
1604 |
+
}
|
1605 |
+
}
|
1606 |
+
},
|
1607 |
+
{
|
1608 |
+
keys: [38], // UP
|
1609 |
+
action: function(player, media) {
|
1610 |
+
var newVolume = Math.min(media.volume + 0.1, 1);
|
1611 |
+
media.setVolume(newVolume);
|
1612 |
+
}
|
1613 |
+
},
|
1614 |
+
{
|
1615 |
+
keys: [40], // DOWN
|
1616 |
+
action: function(player, media) {
|
1617 |
+
var newVolume = Math.max(media.volume - 0.1, 0);
|
1618 |
+
media.setVolume(newVolume);
|
1619 |
+
}
|
1620 |
+
},
|
1621 |
+
{
|
1622 |
+
keys: [
|
1623 |
+
37, // LEFT
|
1624 |
+
227 // Google TV rewind
|
1625 |
+
],
|
1626 |
+
action: function(player, media) {
|
1627 |
+
if (!isNaN(media.duration) && media.duration > 0) {
|
1628 |
+
if (player.isVideo) {
|
1629 |
+
player.showControls();
|
1630 |
+
player.startControlsTimer();
|
1631 |
+
}
|
1632 |
+
|
1633 |
+
// 5%
|
1634 |
+
var newTime = Math.max(media.currentTime - (media.duration * 0.05), 0);
|
1635 |
+
media.setCurrentTime(newTime);
|
1636 |
+
}
|
1637 |
+
}
|
1638 |
+
},
|
1639 |
+
{
|
1640 |
+
keys: [
|
1641 |
+
39, // RIGHT
|
1642 |
+
228 // Google TV forward
|
1643 |
+
],
|
1644 |
+
action: function(player, media) {
|
1645 |
+
if (!isNaN(media.duration) && media.duration > 0) {
|
1646 |
+
if (player.isVideo) {
|
1647 |
+
player.showControls();
|
1648 |
+
player.startControlsTimer();
|
1649 |
+
}
|
1650 |
+
|
1651 |
+
// 5%
|
1652 |
+
var newTime = Math.min(media.currentTime + (media.duration * 0.05), media.duration);
|
1653 |
+
media.setCurrentTime(newTime);
|
1654 |
+
}
|
1655 |
+
}
|
1656 |
+
},
|
1657 |
+
{
|
1658 |
+
keys: [70], // f
|
1659 |
+
action: function(player, media) {
|
1660 |
+
if (typeof player.enterFullScreen != 'undefined') {
|
1661 |
+
if (player.isFullScreen) {
|
1662 |
+
player.exitFullScreen();
|
1663 |
+
} else {
|
1664 |
+
player.enterFullScreen();
|
1665 |
+
}
|
1666 |
+
}
|
1667 |
+
}
|
1668 |
+
}
|
1669 |
+
]
|
1670 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1671 |
|
1672 |
+
mejs.mepIndex = 0;
|
1673 |
+
|
1674 |
+
mejs.players = [];
|
1675 |
|
1676 |
+
// wraps a MediaElement object in player controls
|
1677 |
+
mejs.MediaElementPlayer = function(node, o) {
|
1678 |
+
// enforce object, even without "new" (via John Resig)
|
1679 |
+
if ( !(this instanceof mejs.MediaElementPlayer) ) {
|
1680 |
+
return new mejs.MediaElementPlayer(node, o);
|
1681 |
+
}
|
1682 |
|
1683 |
+
var t = this;
|
1684 |
+
|
1685 |
+
// these will be reset after the MediaElement.success fires
|
1686 |
+
t.$media = t.$node = $(node);
|
1687 |
+
t.node = t.media = t.$media[0];
|
1688 |
+
|
1689 |
+
// check for existing player
|
1690 |
+
if (typeof t.node.player != 'undefined') {
|
1691 |
+
return t.node.player;
|
1692 |
+
} else {
|
1693 |
+
// attach player to DOM node for reference
|
1694 |
+
t.node.player = t;
|
1695 |
+
}
|
1696 |
+
|
1697 |
+
|
1698 |
+
// try to get options from data-mejsoptions
|
1699 |
+
if (typeof o == 'undefined') {
|
1700 |
+
o = t.$node.data('mejsoptions');
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
// extend default options
|
1704 |
+
t.options = $.extend({},mejs.MepDefaults,o);
|
1705 |
+
|
1706 |
+
// add to player array (for focus events)
|
1707 |
+
mejs.players.push(t);
|
1708 |
+
|
1709 |
+
// start up
|
1710 |
+
t.init();
|
1711 |
+
|
1712 |
+
return t;
|
1713 |
+
};
|
1714 |
+
|
1715 |
+
// actual player
|
1716 |
+
mejs.MediaElementPlayer.prototype = {
|
1717 |
+
|
1718 |
+
hasFocus: false,
|
1719 |
+
|
1720 |
+
controlsAreVisible: true,
|
1721 |
+
|
1722 |
+
init: function() {
|
1723 |
+
|
1724 |
+
var
|
1725 |
t = this,
|
1726 |
+
mf = mejs.MediaFeatures,
|
1727 |
+
// options for MediaElement (shim)
|
1728 |
+
meOptions = $.extend(true, {}, t.options, {
|
1729 |
+
success: function(media, domNode) { t.meReady(media, domNode); },
|
1730 |
+
error: function(e) { t.handleError(e);}
|
1731 |
+
}),
|
1732 |
+
tagName = t.media.tagName.toLowerCase();
|
1733 |
+
|
1734 |
+
t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
|
1735 |
+
|
1736 |
+
if (t.isDynamic) {
|
1737 |
+
// get video from src or href?
|
1738 |
+
t.isVideo = t.options.isVideo;
|
1739 |
+
} else {
|
1740 |
+
t.isVideo = (tagName !== 'audio' && t.options.isVideo);
|
1741 |
+
}
|
1742 |
+
|
1743 |
+
// use native controls in iPad, iPhone, and Android
|
1744 |
+
if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
1745 |
|
1746 |
+
// add controls and stop
|
1747 |
+
t.$media.attr('controls', 'controls');
|
1748 |
+
|
1749 |
+
// attempt to fix iOS 3 bug
|
1750 |
+
//t.$media.removeAttr('poster');
|
1751 |
+
// no Issue found on iOS3 -ttroxell
|
1752 |
+
|
1753 |
+
// override Apple's autoplay override for iPads
|
1754 |
+
if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
|
1755 |
+
t.media.load();
|
1756 |
+
t.media.play();
|
1757 |
+
}
|
1758 |
|
1759 |
+
} else if (mf.isAndroid && t.AndroidUseNativeControls) {
|
1760 |
+
|
1761 |
+
// leave default player
|
1762 |
|
1763 |
+
} else {
|
|
|
|
|
|
|
|
|
|
|
1764 |
|
1765 |
+
// DESKTOP: use MediaElementPlayer controls
|
1766 |
+
|
1767 |
+
// remove native controls
|
1768 |
+
t.$media.removeAttr('controls');
|
1769 |
+
|
1770 |
+
// unique ID
|
1771 |
+
t.id = 'mep_' + mejs.mepIndex++;
|
1772 |
+
|
1773 |
+
// build container
|
1774 |
+
t.container =
|
1775 |
+
$('<div id="' + t.id + '" class="mejs-container">'+
|
1776 |
+
'<div class="mejs-inner">'+
|
1777 |
+
'<div class="mejs-mediaelement"></div>'+
|
1778 |
+
'<div class="mejs-layers"></div>'+
|
1779 |
+
'<div class="mejs-controls"></div>'+
|
1780 |
+
'<div class="mejs-clear"></div>'+
|
1781 |
+
'</div>' +
|
1782 |
+
'</div>')
|
1783 |
+
.addClass(t.$media[0].className)
|
1784 |
+
.insertBefore(t.$media);
|
1785 |
+
|
1786 |
+
// add classes for user and content
|
1787 |
+
t.container.addClass(
|
1788 |
+
(mf.isAndroid ? 'mejs-android ' : '') +
|
1789 |
+
(mf.isiOS ? 'mejs-ios ' : '') +
|
1790 |
+
(mf.isiPad ? 'mejs-ipad ' : '') +
|
1791 |
+
(mf.isiPhone ? 'mejs-iphone ' : '') +
|
1792 |
+
(t.isVideo ? 'mejs-video ' : 'mejs-audio ')
|
1793 |
+
);
|
1794 |
+
|
1795 |
|
1796 |
+
// move the <video/video> tag into the right spot
|
1797 |
+
if (mf.isiOS) {
|
1798 |
+
|
1799 |
+
// sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
|
1800 |
+
var $newMedia = t.$media.clone();
|
1801 |
+
|
1802 |
+
t.container.find('.mejs-mediaelement').append($newMedia);
|
1803 |
+
|
1804 |
+
t.$media.remove();
|
1805 |
+
t.$node = t.$media = $newMedia;
|
1806 |
+
t.node = t.media = $newMedia[0]
|
1807 |
+
|
1808 |
+
} else {
|
1809 |
+
|
1810 |
+
// normal way of moving it into place (doesn't work on iOS)
|
1811 |
+
t.container.find('.mejs-mediaelement').append(t.$media);
|
1812 |
+
}
|
1813 |
+
|
1814 |
+
// find parts
|
1815 |
+
t.controls = t.container.find('.mejs-controls');
|
1816 |
+
t.layers = t.container.find('.mejs-layers');
|
1817 |
|
1818 |
+
// determine the size
|
1819 |
+
|
1820 |
+
/* size priority:
|
1821 |
+
(1) videoWidth (forced),
|
1822 |
+
(2) style="width;height;"
|
1823 |
+
(3) width attribute,
|
1824 |
+
(4) defaultVideoWidth (for unspecified cases)
|
1825 |
+
*/
|
1826 |
+
|
1827 |
+
var capsTagName = tagName.substring(0,1).toUpperCase() + tagName.substring(1);
|
1828 |
+
|
1829 |
+
if (t.options[tagName + 'Width'] > 0 || t.options[tagName + 'Width'].toString().indexOf('%') > -1) {
|
1830 |
+
t.width = t.options[tagName + 'Width'];
|
1831 |
+
} else if (t.media.style.width !== '' && t.media.style.width !== null) {
|
1832 |
+
t.width = t.media.style.width;
|
1833 |
+
} else if (t.media.getAttribute('width') !== null) {
|
1834 |
+
t.width = t.$media.attr('width');
|
1835 |
+
} else {
|
1836 |
+
t.width = t.options['default' + capsTagName + 'Width'];
|
1837 |
+
}
|
1838 |
+
|
1839 |
+
if (t.options[tagName + 'Height'] > 0 || t.options[tagName + 'Height'].toString().indexOf('%') > -1) {
|
1840 |
+
t.height = t.options[tagName + 'Height'];
|
1841 |
+
} else if (t.media.style.height !== '' && t.media.style.height !== null) {
|
1842 |
+
t.height = t.media.style.height;
|
1843 |
+
} else if (t.$media[0].getAttribute('height') !== null) {
|
1844 |
+
t.height = t.$media.attr('height');
|
1845 |
+
} else {
|
1846 |
+
t.height = t.options['default' + capsTagName + 'Height'];
|
1847 |
+
}
|
1848 |
|
1849 |
+
// set the size, while we wait for the plugins to load below
|
1850 |
+
t.setPlayerSize(t.width, t.height);
|
1851 |
+
|
1852 |
+
// create MediaElementShim
|
1853 |
+
meOptions.pluginWidth = t.height;
|
1854 |
+
meOptions.pluginHeight = t.width;
|
1855 |
+
}
|
1856 |
+
|
1857 |
+
|
1858 |
+
|
1859 |
+
// create MediaElement shim
|
1860 |
+
mejs.MediaElement(t.$media[0], meOptions);
|
1861 |
+
},
|
1862 |
+
|
1863 |
+
showControls: function(doAnimation) {
|
1864 |
+
var t = this;
|
1865 |
+
|
1866 |
+
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
1867 |
+
|
1868 |
+
if (t.controlsAreVisible)
|
1869 |
+
return;
|
1870 |
+
|
1871 |
+
if (doAnimation) {
|
1872 |
+
t.controls
|
1873 |
+
.css('visibility','visible')
|
1874 |
+
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
1875 |
|
1876 |
+
// any additional controls people might add and want to hide
|
1877 |
+
t.container.find('.mejs-control')
|
1878 |
+
.css('visibility','visible')
|
1879 |
+
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
1880 |
+
|
1881 |
+
} else {
|
1882 |
+
t.controls
|
1883 |
+
.css('visibility','visible')
|
1884 |
+
.css('display','block');
|
1885 |
+
|
1886 |
+
// any additional controls people might add and want to hide
|
1887 |
+
t.container.find('.mejs-control')
|
1888 |
+
.css('visibility','visible')
|
1889 |
+
.css('display','block');
|
1890 |
+
|
1891 |
+
t.controlsAreVisible = true;
|
1892 |
+
}
|
1893 |
+
|
1894 |
+
t.setControlsSize();
|
1895 |
+
|
1896 |
+
},
|
1897 |
|
1898 |
+
hideControls: function(doAnimation) {
|
1899 |
+
var t = this;
|
1900 |
+
|
1901 |
+
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
1902 |
+
|
1903 |
+
if (!t.controlsAreVisible)
|
1904 |
+
return;
|
1905 |
+
|
1906 |
+
if (doAnimation) {
|
1907 |
+
// fade out main controls
|
1908 |
+
t.controls.stop(true, true).fadeOut(200, function() {
|
1909 |
+
$(this)
|
1910 |
+
.css('visibility','hidden')
|
1911 |
+
.css('display','block');
|
1912 |
+
|
1913 |
+
t.controlsAreVisible = false;
|
1914 |
+
});
|
1915 |
+
|
1916 |
+
// any additional controls people might add and want to hide
|
1917 |
+
t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
|
1918 |
+
$(this)
|
1919 |
+
.css('visibility','hidden')
|
1920 |
+
.css('display','block');
|
1921 |
+
});
|
1922 |
+
} else {
|
1923 |
+
|
1924 |
+
// hide main controls
|
1925 |
+
t.controls
|
1926 |
+
.css('visibility','hidden')
|
1927 |
+
.css('display','block');
|
1928 |
+
|
1929 |
+
// hide others
|
1930 |
+
t.container.find('.mejs-control')
|
1931 |
+
.css('visibility','hidden')
|
1932 |
+
.css('display','block');
|
1933 |
+
|
1934 |
+
t.controlsAreVisible = false;
|
1935 |
+
}
|
1936 |
+
},
|
1937 |
|
1938 |
+
controlsTimer: null,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1939 |
|
1940 |
+
startControlsTimer: function(timeout) {
|
1941 |
|
1942 |
+
var t = this;
|
1943 |
+
|
1944 |
+
timeout = typeof timeout != 'undefined' ? timeout : 1500;
|
1945 |
|
1946 |
+
t.killControlsTimer('start');
|
|
|
|
|
|
|
1947 |
|
1948 |
+
t.controlsTimer = setTimeout(function() {
|
1949 |
+
//console.log('timer fired');
|
1950 |
+
t.hideControls();
|
1951 |
+
t.killControlsTimer('hide');
|
1952 |
+
}, timeout);
|
1953 |
+
},
|
1954 |
+
|
1955 |
+
killControlsTimer: function(src) {
|
1956 |
+
|
1957 |
+
var t = this;
|
1958 |
+
|
1959 |
+
if (t.controlsTimer !== null) {
|
1960 |
+
clearTimeout(t.controlsTimer);
|
1961 |
+
delete t.controlsTimer;
|
1962 |
+
t.controlsTimer = null;
|
1963 |
+
}
|
1964 |
+
},
|
1965 |
+
|
1966 |
+
controlsEnabled: true,
|
1967 |
+
|
1968 |
+
disableControls: function() {
|
1969 |
+
var t= this;
|
1970 |
+
|
1971 |
+
t.killControlsTimer();
|
1972 |
+
t.hideControls(false);
|
1973 |
+
this.controlsEnabled = false;
|
1974 |
+
},
|
1975 |
+
|
1976 |
+
enableControls: function() {
|
1977 |
+
var t= this;
|
1978 |
+
|
1979 |
+
t.showControls(false);
|
1980 |
+
|
1981 |
+
t.controlsEnabled = true;
|
1982 |
+
},
|
1983 |
+
|
1984 |
+
|
1985 |
+
// Sets up all controls and events
|
1986 |
+
meReady: function(media, domNode) {
|
1987 |
+
|
1988 |
+
|
1989 |
+
var t = this,
|
1990 |
+
mf = mejs.MediaFeatures,
|
1991 |
+
autoplayAttr = domNode.getAttribute('autoplay'),
|
1992 |
+
autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
|
1993 |
+
featureIndex,
|
1994 |
+
feature;
|
1995 |
+
|
1996 |
+
// make sure it can't create itself again if a plugin reloads
|
1997 |
+
if (t.created)
|
1998 |
+
return;
|
1999 |
+
else
|
2000 |
+
t.created = true;
|
2001 |
+
|
2002 |
+
t.media = media;
|
2003 |
+
t.domNode = domNode;
|
2004 |
+
|
2005 |
+
if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
2006 |
+
|
2007 |
+
// two built in features
|
2008 |
+
t.buildposter(t, t.controls, t.layers, t.media);
|
2009 |
+
t.buildkeyboard(t, t.controls, t.layers, t.media);
|
2010 |
+
t.buildoverlays(t, t.controls, t.layers, t.media);
|
2011 |
+
|
2012 |
+
// grab for use by features
|
2013 |
+
t.findTracks();
|
2014 |
+
|
2015 |
+
// add user-defined features/controls
|
2016 |
+
for (featureIndex in t.options.features) {
|
2017 |
+
feature = t.options.features[featureIndex];
|
2018 |
+
if (t['build' + feature]) {
|
2019 |
+
try {
|
2020 |
+
t['build' + feature](t, t.controls, t.layers, t.media);
|
2021 |
+
} catch (e) {
|
2022 |
+
// TODO: report control error
|
2023 |
+
//throw e;
|
2024 |
+
//console.log('error building ' + feature);
|
2025 |
+
//console.log(e);
|
2026 |
+
}
|
2027 |
+
}
|
2028 |
+
}
|
2029 |
+
|
2030 |
+
t.container.trigger('controlsready');
|
2031 |
+
|
2032 |
+
// reset all layers and controls
|
2033 |
+
t.setPlayerSize(t.width, t.height);
|
2034 |
+
t.setControlsSize();
|
2035 |
+
|
2036 |
+
|
2037 |
+
// controls fade
|
2038 |
+
if (t.isVideo) {
|
2039 |
+
|
2040 |
+
if (mejs.MediaFeatures.hasTouch) {
|
2041 |
+
|
2042 |
+
// for touch devices (iOS, Android)
|
2043 |
+
// show/hide without animation on touch
|
2044 |
+
|
2045 |
+
t.$media.bind('touchstart', function() {
|
2046 |
+
|
2047 |
+
|
2048 |
+
// toggle controls
|
2049 |
+
if (t.controlsAreVisible) {
|
2050 |
+
t.hideControls(false);
|
2051 |
+
} else {
|
2052 |
+
if (t.controlsEnabled) {
|
2053 |
+
t.showControls(false);
|
2054 |
+
}
|
2055 |
+
}
|
2056 |
+
});
|
2057 |
+
|
2058 |
+
} else {
|
2059 |
+
// click controls
|
2060 |
+
var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
|
2061 |
+
|
2062 |
+
// click to play/pause
|
2063 |
+
clickElement.click(function() {
|
2064 |
+
if (media.paused) {
|
2065 |
+
media.play();
|
2066 |
+
} else {
|
2067 |
+
media.pause();
|
2068 |
+
}
|
2069 |
+
});
|
2070 |
+
|
2071 |
+
|
2072 |
+
// show/hide controls
|
2073 |
+
t.container
|
2074 |
+
.bind('mouseenter mouseover', function () {
|
2075 |
+
if (t.controlsEnabled) {
|
2076 |
+
if (!t.options.alwaysShowControls) {
|
2077 |
+
t.killControlsTimer('enter');
|
2078 |
+
t.showControls();
|
2079 |
+
t.startControlsTimer(2500);
|
2080 |
+
}
|
2081 |
+
}
|
2082 |
+
})
|
2083 |
+
.bind('mousemove', function() {
|
2084 |
+
if (t.controlsEnabled) {
|
2085 |
+
if (!t.controlsAreVisible) {
|
2086 |
+
t.showControls();
|
2087 |
+
}
|
2088 |
+
//t.killControlsTimer('move');
|
2089 |
+
if (!t.options.alwaysShowControls) {
|
2090 |
+
t.startControlsTimer(2500);
|
2091 |
+
}
|
2092 |
+
}
|
2093 |
+
})
|
2094 |
+
.bind('mouseleave', function () {
|
2095 |
+
if (t.controlsEnabled) {
|
2096 |
+
if (!t.media.paused && !t.options.alwaysShowControls) {
|
2097 |
+
t.startControlsTimer(1000);
|
2098 |
+
}
|
2099 |
+
}
|
2100 |
+
});
|
2101 |
+
}
|
2102 |
+
|
2103 |
+
// check for autoplay
|
2104 |
+
if (autoplay && !t.options.alwaysShowControls) {
|
2105 |
+
t.hideControls();
|
2106 |
+
}
|
2107 |
+
|
2108 |
+
// resizer
|
2109 |
+
if (t.options.enableAutosize) {
|
2110 |
+
t.media.addEventListener('loadedmetadata', function(e) {
|
2111 |
+
// if the <video height> was not set and the options.videoHeight was not set
|
2112 |
+
// then resize to the real dimensions
|
2113 |
+
if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
|
2114 |
+
t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
|
2115 |
+
t.setControlsSize();
|
2116 |
+
t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
|
2117 |
+
}
|
2118 |
+
}, false);
|
2119 |
+
}
|
2120 |
+
}
|
2121 |
+
|
2122 |
+
// EVENTS
|
2123 |
+
|
2124 |
+
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
|
2125 |
+
media.addEventListener('play', function() {
|
2126 |
+
|
2127 |
+
// go through all other players
|
2128 |
+
for (var i=0, il=mejs.players.length; i<il; i++) {
|
2129 |
+
var p = mejs.players[i];
|
2130 |
+
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
|
2131 |
+
p.pause();
|
2132 |
+
}
|
2133 |
+
p.hasFocus = false;
|
2134 |
+
}
|
2135 |
+
|
2136 |
+
t.hasFocus = true;
|
2137 |
+
},false);
|
2138 |
+
|
2139 |
+
|
2140 |
+
// ended for all
|
2141 |
+
t.media.addEventListener('ended', function (e) {
|
2142 |
+
try{
|
2143 |
+
t.media.setCurrentTime(0);
|
2144 |
+
} catch (exp) {
|
2145 |
+
|
2146 |
+
}
|
2147 |
+
t.media.pause();
|
2148 |
+
|
2149 |
+
if (t.setProgressRail)
|
2150 |
+
t.setProgressRail();
|
2151 |
+
if (t.setCurrentRail)
|
2152 |
+
t.setCurrentRail();
|
2153 |
+
|
2154 |
+
if (t.options.loop) {
|
2155 |
+
t.media.play();
|
2156 |
+
} else if (!t.options.alwaysShowControls && t.controlsEnabled) {
|
2157 |
+
t.showControls();
|
2158 |
+
}
|
2159 |
+
}, false);
|
2160 |
+
|
2161 |
+
// resize on the first play
|
2162 |
+
t.media.addEventListener('loadedmetadata', function(e) {
|
2163 |
+
if (t.updateDuration) {
|
2164 |
+
t.updateDuration();
|
2165 |
+
}
|
2166 |
+
if (t.updateCurrent) {
|
2167 |
+
t.updateCurrent();
|
2168 |
+
}
|
2169 |
+
|
2170 |
+
if (!t.isFullScreen) {
|
2171 |
+
t.setPlayerSize(t.width, t.height);
|
2172 |
+
t.setControlsSize();
|
2173 |
+
}
|
2174 |
+
}, false);
|
2175 |
+
|
2176 |
+
|
2177 |
+
// webkit has trouble doing this without a delay
|
2178 |
+
setTimeout(function () {
|
2179 |
+
t.setPlayerSize(t.width, t.height);
|
2180 |
+
t.setControlsSize();
|
2181 |
+
}, 50);
|
2182 |
+
|
2183 |
+
// adjust controls whenever window sizes (used to be in fullscreen only)
|
2184 |
+
$(window).resize(function() {
|
2185 |
+
|
2186 |
+
// don't resize for fullscreen mode
|
2187 |
+
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
|
2188 |
+
t.setPlayerSize(t.width, t.height);
|
2189 |
+
}
|
2190 |
+
|
2191 |
+
// always adjust controls
|
2192 |
+
t.setControlsSize();
|
2193 |
+
});
|
2194 |
+
|
2195 |
+
// TEMP: needs to be moved somewhere else
|
2196 |
+
if (t.media.pluginType == 'youtube') {
|
2197 |
+
t.container.find('.mejs-overlay-play').hide();
|
2198 |
+
}
|
2199 |
+
}
|
2200 |
+
|
2201 |
+
// force autoplay for HTML5
|
2202 |
+
if (autoplay && media.pluginType == 'native') {
|
2203 |
+
media.load();
|
2204 |
+
media.play();
|
2205 |
+
}
|
2206 |
+
|
2207 |
+
|
2208 |
+
if (t.options.success) {
|
2209 |
+
|
2210 |
+
if (typeof t.options.success == 'string') {
|
2211 |
+
window[t.options.success](t.media, t.domNode, t);
|
2212 |
+
} else {
|
2213 |
+
t.options.success(t.media, t.domNode, t);
|
2214 |
+
}
|
2215 |
+
}
|
2216 |
+
},
|
2217 |
+
|
2218 |
+
handleError: function(e) {
|
2219 |
+
var t = this;
|
2220 |
+
|
2221 |
+
t.controls.hide();
|
2222 |
+
|
2223 |
+
// Tell user that the file cannot be played
|
2224 |
+
if (t.options.error) {
|
2225 |
+
t.options.error(e);
|
2226 |
+
}
|
2227 |
+
},
|
2228 |
+
|
2229 |
+
setPlayerSize: function(width,height) {
|
2230 |
+
var t = this;
|
2231 |
+
|
2232 |
+
if (typeof width != 'undefined')
|
2233 |
+
t.width = width;
|
2234 |
+
|
2235 |
+
if (typeof height != 'undefined')
|
2236 |
+
t.height = height;
|
2237 |
+
|
2238 |
+
// detect 100% mode
|
2239 |
+
if (t.height.toString().indexOf('%') > 0) {
|
2240 |
+
|
2241 |
+
// do we have the native dimensions yet?
|
2242 |
+
var
|
2243 |
+
nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
|
2244 |
+
nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
|
2245 |
+
parentWidth = t.container.parent().width(),
|
2246 |
+
newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
|
2247 |
+
|
2248 |
+
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
2249 |
+
parentWidth = $(window).width();
|
2250 |
+
newHeight = $(window).height();
|
2251 |
+
}
|
2252 |
+
|
2253 |
+
|
2254 |
+
// set outer container size
|
2255 |
+
t.container
|
2256 |
+
.width(parentWidth)
|
2257 |
+
.height(newHeight);
|
2258 |
+
|
2259 |
+
// set native <video>
|
2260 |
+
t.$media
|
2261 |
+
.width('100%')
|
2262 |
+
.height('100%');
|
2263 |
+
|
2264 |
+
// set shims
|
2265 |
+
t.container.find('object, embed, iframe')
|
2266 |
+
.width('100%')
|
2267 |
+
.height('100%');
|
2268 |
+
|
2269 |
+
// if shim is ready, send the size to the embeded plugin
|
2270 |
+
if (t.media.setVideoSize)
|
2271 |
+
t.media.setVideoSize(parentWidth, newHeight);
|
2272 |
+
|
2273 |
+
// set the layers
|
2274 |
+
t.layers.children('.mejs-layer')
|
2275 |
+
.width('100%')
|
2276 |
+
.height('100%');
|
2277 |
+
|
2278 |
+
|
2279 |
+
} else {
|
2280 |
+
|
2281 |
+
t.container
|
2282 |
+
.width(t.width)
|
2283 |
+
.height(t.height);
|
2284 |
+
|
2285 |
+
t.layers.children('.mejs-layer')
|
2286 |
+
.width(t.width)
|
2287 |
+
.height(t.height);
|
2288 |
+
|
2289 |
+
}
|
2290 |
+
},
|
2291 |
+
|
2292 |
+
setControlsSize: function() {
|
2293 |
+
var t = this,
|
2294 |
+
usedWidth = 0,
|
2295 |
+
railWidth = 0,
|
2296 |
+
rail = t.controls.find('.mejs-time-rail'),
|
2297 |
+
total = t.controls.find('.mejs-time-total'),
|
2298 |
+
current = t.controls.find('.mejs-time-current'),
|
2299 |
+
loaded = t.controls.find('.mejs-time-loaded'),
|
2300 |
+
others = rail.siblings();
|
2301 |
+
|
2302 |
+
|
2303 |
+
// allow the size to come from custom CSS
|
2304 |
+
if (t.options && !t.options.autosizeProgress) {
|
2305 |
+
// Also, frontends devs can be more flexible
|
2306 |
+
// due the opportunity of absolute positioning.
|
2307 |
+
railWidth = parseInt(rail.css('width'));
|
2308 |
+
}
|
2309 |
+
|
2310 |
+
// attempt to autosize
|
2311 |
+
if (railWidth === 0 || !railWidth) {
|
2312 |
+
|
2313 |
+
// find the size of all the other controls besides the rail
|
2314 |
+
others.each(function() {
|
2315 |
+
if ($(this).css('position') != 'absolute') {
|
2316 |
+
usedWidth += $(this).outerWidth(true);
|
2317 |
+
}
|
2318 |
+
});
|
2319 |
+
|
2320 |
+
// fit the rail into the remaining space
|
2321 |
+
railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
|
2322 |
+
}
|
2323 |
+
|
2324 |
+
// outer area
|
2325 |
+
rail.width(railWidth);
|
2326 |
+
// dark space
|
2327 |
+
total.width(railWidth - (total.outerWidth(true) - total.width()));
|
2328 |
+
|
2329 |
+
if (t.setProgressRail)
|
2330 |
+
t.setProgressRail();
|
2331 |
+
if (t.setCurrentRail)
|
2332 |
+
t.setCurrentRail();
|
2333 |
+
},
|
2334 |
+
|
2335 |
+
|
2336 |
+
buildposter: function(player, controls, layers, media) {
|
2337 |
+
var t = this,
|
2338 |
+
poster =
|
2339 |
+
$('<div class="mejs-poster mejs-layer">' +
|
2340 |
+
'</div>')
|
2341 |
+
.appendTo(layers),
|
2342 |
+
posterUrl = player.$media.attr('poster');
|
2343 |
+
|
2344 |
+
// prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
|
2345 |
+
if (player.options.poster !== '') {
|
2346 |
+
posterUrl = player.options.poster;
|
2347 |
+
}
|
2348 |
+
|
2349 |
+
// second, try the real poster
|
2350 |
+
if (posterUrl !== '' && posterUrl != null) {
|
2351 |
+
t.setPoster(posterUrl);
|
2352 |
+
} else {
|
2353 |
+
poster.hide();
|
2354 |
+
}
|
2355 |
+
|
2356 |
+
media.addEventListener('play',function() {
|
2357 |
+
poster.hide();
|
2358 |
+
}, false);
|
2359 |
+
},
|
2360 |
+
|
2361 |
+
setPoster: function(url) {
|
2362 |
+
var t = this,
|
2363 |
+
posterDiv = t.container.find('.mejs-poster'),
|
2364 |
+
posterImg = posterDiv.find('img');
|
2365 |
+
|
2366 |
+
if (posterImg.length == 0) {
|
2367 |
+
posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
|
2368 |
+
}
|
2369 |
+
|
2370 |
+
posterImg.attr('src', url);
|
2371 |
+
},
|
2372 |
+
|
2373 |
+
buildoverlays: function(player, controls, layers, media) {
|
2374 |
+
if (!player.isVideo)
|
2375 |
+
return;
|
2376 |
+
|
2377 |
+
var
|
2378 |
+
loading =
|
2379 |
+
$('<div class="mejs-overlay mejs-layer">'+
|
2380 |
+
'<div class="mejs-overlay-loading"><span></span></div>'+
|
2381 |
+
'</div>')
|
2382 |
+
.hide() // start out hidden
|
2383 |
+
.appendTo(layers),
|
2384 |
+
error =
|
2385 |
+
$('<div class="mejs-overlay mejs-layer">'+
|
2386 |
+
'<div class="mejs-overlay-error"></div>'+
|
2387 |
+
'</div>')
|
2388 |
+
.hide() // start out hidden
|
2389 |
+
.appendTo(layers),
|
2390 |
+
// this needs to come last so it's on top
|
2391 |
+
bigPlay =
|
2392 |
+
$('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
|
2393 |
+
'<div class="mejs-overlay-button"></div>'+
|
2394 |
+
'</div>')
|
2395 |
+
.appendTo(layers)
|
2396 |
+
.click(function() {
|
2397 |
+
if (media.paused) {
|
2398 |
+
media.play();
|
2399 |
+
} else {
|
2400 |
+
media.pause();
|
2401 |
+
}
|
2402 |
+
});
|
2403 |
+
|
2404 |
+
/*
|
2405 |
+
if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
|
2406 |
+
bigPlay.remove();
|
2407 |
+
loading.remove();
|
2408 |
+
}
|
2409 |
+
*/
|
2410 |
+
|
2411 |
+
|
2412 |
+
// show/hide big play button
|
2413 |
+
media.addEventListener('play',function() {
|
2414 |
+
bigPlay.hide();
|
2415 |
+
loading.hide();
|
2416 |
+
controls.find('.mejs-time-buffering').hide();
|
2417 |
+
error.hide();
|
2418 |
+
}, false);
|
2419 |
+
|
2420 |
+
media.addEventListener('playing', function() {
|
2421 |
+
bigPlay.hide();
|
2422 |
+
loading.hide();
|
2423 |
+
controls.find('.mejs-time-buffering').hide();
|
2424 |
+
error.hide();
|
2425 |
+
}, false);
|
2426 |
+
|
2427 |
+
media.addEventListener('seeking', function() {
|
2428 |
+
loading.show();
|
2429 |
+
controls.find('.mejs-time-buffering').show();
|
2430 |
+
}, false);
|
2431 |
+
|
2432 |
+
media.addEventListener('seeked', function() {
|
2433 |
+
loading.hide();
|
2434 |
+
controls.find('.mejs-time-buffering').hide();
|
2435 |
+
}, false);
|
2436 |
+
|
2437 |
+
media.addEventListener('pause',function() {
|
2438 |
+
if (!mejs.MediaFeatures.isiPhone) {
|
2439 |
+
bigPlay.show();
|
2440 |
+
}
|
2441 |
+
}, false);
|
2442 |
+
|
2443 |
+
media.addEventListener('waiting', function() {
|
2444 |
+
loading.show();
|
2445 |
+
controls.find('.mejs-time-buffering').show();
|
2446 |
+
}, false);
|
2447 |
+
|
2448 |
+
|
2449 |
+
// show/hide loading
|
2450 |
+
media.addEventListener('loadeddata',function() {
|
2451 |
+
// for some reason Chrome is firing this event
|
2452 |
+
//if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
|
2453 |
+
// return;
|
2454 |
+
|
2455 |
+
loading.show();
|
2456 |
+
controls.find('.mejs-time-buffering').show();
|
2457 |
+
}, false);
|
2458 |
+
media.addEventListener('canplay',function() {
|
2459 |
+
loading.hide();
|
2460 |
+
controls.find('.mejs-time-buffering').hide();
|
2461 |
+
}, false);
|
2462 |
+
|
2463 |
+
// error handling
|
2464 |
+
media.addEventListener('error',function() {
|
2465 |
+
loading.hide();
|
2466 |
+
controls.find('.mejs-time-buffering').hide();
|
2467 |
+
error.show();
|
2468 |
+
error.find('mejs-overlay-error').html("Error loading this resource");
|
2469 |
+
}, false);
|
2470 |
+
},
|
2471 |
+
|
2472 |
+
buildkeyboard: function(player, controls, layers, media) {
|
2473 |
+
|
2474 |
+
var t = this;
|
2475 |
+
|
2476 |
+
// listen for key presses
|
2477 |
+
$(document).keydown(function(e) {
|
2478 |
+
|
2479 |
+
if (player.hasFocus && player.options.enableKeyboard) {
|
2480 |
+
|
2481 |
+
// find a matching key
|
2482 |
+
for (var i=0, il=player.options.keyActions.length; i<il; i++) {
|
2483 |
+
var keyAction = player.options.keyActions[i];
|
2484 |
+
|
2485 |
+
for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
|
2486 |
+
if (e.keyCode == keyAction.keys[j]) {
|
2487 |
+
e.preventDefault();
|
2488 |
+
keyAction.action(player, media);
|
2489 |
+
return false;
|
2490 |
+
}
|
2491 |
+
}
|
2492 |
+
}
|
2493 |
+
}
|
2494 |
+
|
2495 |
+
return true;
|
2496 |
+
});
|
2497 |
+
|
2498 |
+
// check if someone clicked outside a player region, then kill its focus
|
2499 |
+
$(document).click(function(event) {
|
2500 |
+
if ($(event.target).closest('.mejs-container').length == 0) {
|
2501 |
+
player.hasFocus = false;
|
2502 |
+
}
|
2503 |
+
});
|
2504 |
+
|
2505 |
+
},
|
2506 |
+
|
2507 |
+
findTracks: function() {
|
2508 |
+
var t = this,
|
2509 |
+
tracktags = t.$media.find('track');
|
2510 |
+
|
2511 |
+
// store for use by plugins
|
2512 |
+
t.tracks = [];
|
2513 |
+
tracktags.each(function(index, track) {
|
2514 |
+
|
2515 |
+
track = $(track);
|
2516 |
+
|
2517 |
+
t.tracks.push({
|
2518 |
+
srclang: track.attr('srclang').toLowerCase(),
|
2519 |
+
src: track.attr('src'),
|
2520 |
+
kind: track.attr('kind'),
|
2521 |
+
label: track.attr('label') || '',
|
2522 |
+
entries: [],
|
2523 |
+
isLoaded: false
|
2524 |
+
});
|
2525 |
+
});
|
2526 |
+
},
|
2527 |
+
changeSkin: function(className) {
|
2528 |
+
this.container[0].className = 'mejs-container ' + className;
|
2529 |
+
this.setPlayerSize(this.width, this.height);
|
2530 |
+
this.setControlsSize();
|
2531 |
+
},
|
2532 |
+
play: function() {
|
2533 |
+
this.media.play();
|
2534 |
+
},
|
2535 |
+
pause: function() {
|
2536 |
+
this.media.pause();
|
2537 |
+
},
|
2538 |
+
load: function() {
|
2539 |
+
this.media.load();
|
2540 |
+
},
|
2541 |
+
setMuted: function(muted) {
|
2542 |
+
this.media.setMuted(muted);
|
2543 |
+
},
|
2544 |
+
setCurrentTime: function(time) {
|
2545 |
+
this.media.setCurrentTime(time);
|
2546 |
+
},
|
2547 |
+
getCurrentTime: function() {
|
2548 |
+
return this.media.currentTime;
|
2549 |
+
},
|
2550 |
+
setVolume: function(volume) {
|
2551 |
+
this.media.setVolume(volume);
|
2552 |
+
},
|
2553 |
+
getVolume: function() {
|
2554 |
+
return this.media.volume;
|
2555 |
+
},
|
2556 |
+
setSrc: function(src) {
|
2557 |
+
this.media.setSrc(src);
|
2558 |
+
},
|
2559 |
+
remove: function() {
|
2560 |
+
var t = this;
|
2561 |
+
|
2562 |
+
if (t.media.pluginType == 'flash') {
|
2563 |
+
t.media.remove();
|
2564 |
+
} else if (t.media.pluginType == 'native') {
|
2565 |
+
t.media.prop('controls', true);
|
2566 |
+
}
|
2567 |
+
|
2568 |
+
// grab video and put it back in place
|
2569 |
+
if (!t.isDynamic) {
|
2570 |
+
t.$node.insertBefore(t.container)
|
2571 |
+
}
|
2572 |
+
|
2573 |
+
t.container.remove();
|
2574 |
+
}
|
2575 |
+
};
|
2576 |
+
|
2577 |
+
// turn into jQuery plugin
|
2578 |
+
if (typeof jQuery != 'undefined') {
|
2579 |
+
jQuery.fn.mediaelementplayer = function (options) {
|
2580 |
+
return this.each(function () {
|
2581 |
+
new mejs.MediaElementPlayer(this, options);
|
2582 |
+
});
|
2583 |
+
};
|
2584 |
+
}
|
2585 |
+
|
2586 |
+
$(document).ready(function() {
|
2587 |
+
// auto enable using JSON attribute
|
2588 |
+
$('.mejs-player').mediaelementplayer();
|
2589 |
+
});
|
2590 |
+
|
2591 |
+
// push out to window
|
2592 |
+
window.MediaElementPlayer = mejs.MediaElementPlayer;
|
2593 |
+
|
2594 |
+
})(mejs.$);
|
2595 |
+
|
2596 |
+
(function($) {
|
2597 |
+
|
2598 |
+
$.extend(mejs.MepDefaults, {
|
2599 |
+
playpauseText: 'Play/Pause'
|
2600 |
+
});
|
2601 |
+
|
2602 |
+
// PLAY/pause BUTTON
|
2603 |
+
$.extend(MediaElementPlayer.prototype, {
|
2604 |
+
buildplaypause: function(player, controls, layers, media) {
|
2605 |
+
var
|
2606 |
+
t = this,
|
2607 |
+
play =
|
2608 |
+
$('<div class="mejs-button mejs-playpause-button mejs-play" >' +
|
2609 |
+
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.playpauseText + '"></button>' +
|
2610 |
+
'</div>')
|
2611 |
+
.appendTo(controls)
|
2612 |
+
.click(function(e) {
|
2613 |
+
e.preventDefault();
|
2614 |
+
|
2615 |
+
if (media.paused) {
|
2616 |
+
media.play();
|
2617 |
+
} else {
|
2618 |
+
media.pause();
|
2619 |
+
}
|
2620 |
+
|
2621 |
+
return false;
|
2622 |
+
});
|
2623 |
+
|
2624 |
+
media.addEventListener('play',function() {
|
2625 |
+
play.removeClass('mejs-play').addClass('mejs-pause');
|
2626 |
+
}, false);
|
2627 |
+
media.addEventListener('playing',function() {
|
2628 |
+
play.removeClass('mejs-play').addClass('mejs-pause');
|
2629 |
+
}, false);
|
2630 |
+
|
2631 |
+
|
2632 |
+
media.addEventListener('pause',function() {
|
2633 |
+
play.removeClass('mejs-pause').addClass('mejs-play');
|
2634 |
+
}, false);
|
2635 |
+
media.addEventListener('paused',function() {
|
2636 |
+
play.removeClass('mejs-pause').addClass('mejs-play');
|
2637 |
+
}, false);
|
2638 |
+
}
|
2639 |
+
});
|
2640 |
+
|
2641 |
+
})(mejs.$);
|
2642 |
+
(function($) {
|
2643 |
+
|
2644 |
+
$.extend(mejs.MepDefaults, {
|
2645 |
+
stopText: 'Stop'
|
2646 |
+
});
|
2647 |
+
|
2648 |
+
// STOP BUTTON
|
2649 |
+
$.extend(MediaElementPlayer.prototype, {
|
2650 |
+
buildstop: function(player, controls, layers, media) {
|
2651 |
+
var t = this,
|
2652 |
+
stop =
|
2653 |
+
$('<div class="mejs-button mejs-stop-button mejs-stop">' +
|
2654 |
+
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.stopText + '"></button>' +
|
2655 |
+
'</div>')
|
2656 |
+
.appendTo(controls)
|
2657 |
+
.click(function() {
|
2658 |
+
if (!media.paused) {
|
2659 |
+
media.pause();
|
2660 |
+
}
|
2661 |
+
if (media.currentTime > 0) {
|
2662 |
+
media.setCurrentTime(0);
|
2663 |
+
controls.find('.mejs-time-current').width('0px');
|
2664 |
+
controls.find('.mejs-time-handle').css('left', '0px');
|
2665 |
+
controls.find('.mejs-time-float-current').html( mejs.Utility.secondsToTimeCode(0) );
|
2666 |
+
controls.find('.mejs-currenttime').html( mejs.Utility.secondsToTimeCode(0) );
|
2667 |
+
layers.find('.mejs-poster').show();
|
2668 |
+
}
|
2669 |
+
});
|
2670 |
+
}
|
2671 |
+
});
|
2672 |
+
|
2673 |
+
})(mejs.$);
|
2674 |
+
(function($) {
|
2675 |
+
// progress/loaded bar
|
2676 |
+
$.extend(MediaElementPlayer.prototype, {
|
2677 |
+
buildprogress: function(player, controls, layers, media) {
|
2678 |
+
|
2679 |
+
$('<div class="mejs-time-rail">'+
|
2680 |
+
'<span class="mejs-time-total">'+
|
2681 |
+
'<span class="mejs-time-buffering"></span>'+
|
2682 |
+
'<span class="mejs-time-loaded"></span>'+
|
2683 |
+
'<span class="mejs-time-current"></span>'+
|
2684 |
+
'<span class="mejs-time-handle"></span>'+
|
2685 |
+
'<span class="mejs-time-float">' +
|
2686 |
+
'<span class="mejs-time-float-current">00:00</span>' +
|
2687 |
+
'<span class="mejs-time-float-corner"></span>' +
|
2688 |
+
'</span>'+
|
2689 |
+
'</span>'+
|
2690 |
+
'</div>')
|
2691 |
+
.appendTo(controls);
|
2692 |
+
controls.find('.mejs-time-buffering').hide();
|
2693 |
+
|
2694 |
+
var
|
2695 |
+
t = this,
|
2696 |
+
total = controls.find('.mejs-time-total'),
|
2697 |
+
loaded = controls.find('.mejs-time-loaded'),
|
2698 |
+
current = controls.find('.mejs-time-current'),
|
2699 |
+
handle = controls.find('.mejs-time-handle'),
|
2700 |
+
timefloat = controls.find('.mejs-time-float'),
|
2701 |
+
timefloatcurrent = controls.find('.mejs-time-float-current'),
|
2702 |
+
handleMouseMove = function (e) {
|
2703 |
+
// mouse position relative to the object
|
2704 |
+
var x = e.pageX,
|
2705 |
+
offset = total.offset(),
|
2706 |
+
width = total.outerWidth(),
|
2707 |
+
percentage = 0,
|
2708 |
+
newTime = 0,
|
2709 |
+
pos = x - offset.left;
|
2710 |
+
|
2711 |
+
|
2712 |
+
if (x > offset.left && x <= width + offset.left && media.duration) {
|
2713 |
+
percentage = ((x - offset.left) / width);
|
2714 |
+
newTime = (percentage <= 0.02) ? 0 : percentage * media.duration;
|
2715 |
+
|
2716 |
+
// seek to where the mouse is
|
2717 |
+
if (mouseIsDown) {
|
2718 |
+
media.setCurrentTime(newTime);
|
2719 |
+
}
|
2720 |
+
|
2721 |
+
// position floating time box
|
2722 |
+
if (!mejs.MediaFeatures.hasTouch) {
|
2723 |
+
timefloat.css('left', pos);
|
2724 |
+
timefloatcurrent.html( mejs.Utility.secondsToTimeCode(newTime) );
|
2725 |
timefloat.show();
|
2726 |
}
|
2727 |
}
|
2838 |
}
|
2839 |
});
|
2840 |
})(mejs.$);
|
2841 |
+
(function($) {
|
2842 |
+
|
2843 |
+
// options
|
2844 |
+
$.extend(mejs.MepDefaults, {
|
2845 |
+
duration: -1,
|
2846 |
+
timeAndDurationSeparator: ' <span> | </span> '
|
2847 |
+
});
|
2848 |
+
|
2849 |
+
|
2850 |
+
// current and duration 00:00 / 00:00
|
2851 |
+
$.extend(MediaElementPlayer.prototype, {
|
2852 |
+
buildcurrent: function(player, controls, layers, media) {
|
2853 |
+
var t = this;
|
2854 |
+
|
2855 |
+
$('<div class="mejs-time">'+
|
2856 |
+
'<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
|
2857 |
+
+ (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
|
2858 |
+
'</div>')
|
2859 |
+
.appendTo(controls);
|
2860 |
+
|
2861 |
+
t.currenttime = t.controls.find('.mejs-currenttime');
|
2862 |
+
|
2863 |
+
media.addEventListener('timeupdate',function() {
|
2864 |
+
player.updateCurrent();
|
2865 |
+
}, false);
|
2866 |
+
},
|
2867 |
+
|
2868 |
+
|
2869 |
+
buildduration: function(player, controls, layers, media) {
|
2870 |
+
var t = this;
|
2871 |
+
|
2872 |
+
if (controls.children().last().find('.mejs-currenttime').length > 0) {
|
2873 |
+
$(t.options.timeAndDurationSeparator +
|
2874 |
+
'<span class="mejs-duration">' +
|
2875 |
+
(t.options.duration > 0 ?
|
2876 |
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
2877 |
+
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
2878 |
+
) +
|
2879 |
+
'</span>')
|
2880 |
+
.appendTo(controls.find('.mejs-time'));
|
2881 |
+
} else {
|
2882 |
+
|
2883 |
+
// add class to current time
|
2884 |
+
controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
|
2885 |
+
|
2886 |
+
$('<div class="mejs-time mejs-duration-container">'+
|
2887 |
+
'<span class="mejs-duration">' +
|
2888 |
+
(t.options.duration > 0 ?
|
2889 |
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
2890 |
+
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
2891 |
+
) +
|
2892 |
+
'</span>' +
|
2893 |
+
'</div>')
|
2894 |
+
.appendTo(controls);
|
2895 |
+
}
|
2896 |
+
|
2897 |
+
t.durationD = t.controls.find('.mejs-duration');
|
2898 |
+
|
2899 |
+
media.addEventListener('timeupdate',function() {
|
2900 |
+
player.updateDuration();
|
2901 |
+
}, false);
|
2902 |
+
},
|
2903 |
+
|
2904 |
+
updateCurrent: function() {
|
2905 |
+
var t = this;
|
2906 |
+
|
2907 |
+
if (t.currenttime) {
|
2908 |
+
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
2909 |
+
}
|
2910 |
+
},
|
2911 |
+
|
2912 |
+
updateDuration: function() {
|
2913 |
+
var t = this;
|
2914 |
+
|
2915 |
+
if (t.media.duration && t.durationD) {
|
2916 |
+
t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
2917 |
+
}
|
2918 |
+
}
|
2919 |
+
});
|
2920 |
+
|
2921 |
})(mejs.$);
|
2922 |
(function($) {
|
2923 |
|
3141 |
|
3142 |
})(mejs.$);
|
3143 |
|
3144 |
+
(function($) {
|
3145 |
+
|
3146 |
+
$.extend(mejs.MepDefaults, {
|
3147 |
+
usePluginFullScreen: true,
|
3148 |
+
newWindowCallback: function() { return '';},
|
3149 |
+
fullscreenText: 'Fullscreen'
|
3150 |
+
});
|
3151 |
+
|
3152 |
+
$.extend(MediaElementPlayer.prototype, {
|
3153 |
+
|
3154 |
+
isFullScreen: false,
|
3155 |
+
|
3156 |
+
isNativeFullScreen: false,
|
3157 |
+
|
3158 |
+
docStyleOverflow: null,
|
3159 |
+
|
3160 |
+
isInIframe: false,
|
3161 |
+
|
3162 |
+
buildfullscreen: function(player, controls, layers, media) {
|
3163 |
+
|
3164 |
+
if (!player.isVideo)
|
3165 |
+
return;
|
3166 |
+
|
3167 |
+
player.isInIframe = (window.location != window.parent.location);
|
3168 |
+
|
3169 |
+
// native events
|
3170 |
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3171 |
+
|
3172 |
+
// chrome doesn't alays fire this in an iframe
|
3173 |
+
var target = null;
|
3174 |
+
|
3175 |
+
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
|
3176 |
+
target = $(document);
|
3177 |
+
} else {
|
3178 |
+
target = player.container;
|
3179 |
+
}
|
3180 |
+
|
3181 |
+
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
|
3182 |
+
//player.container.bind('webkitfullscreenchange', function(e) {
|
3183 |
+
|
3184 |
+
|
3185 |
+
if (mejs.MediaFeatures.isFullScreen()) {
|
3186 |
+
player.isNativeFullScreen = true;
|
3187 |
+
// reset the controls once we are fully in full screen
|
3188 |
+
player.setControlsSize();
|
3189 |
+
} else {
|
3190 |
+
player.isNativeFullScreen = false;
|
3191 |
+
// when a user presses ESC
|
3192 |
+
// make sure to put the player back into place
|
3193 |
+
player.exitFullScreen();
|
3194 |
+
}
|
3195 |
+
});
|
3196 |
+
}
|
3197 |
+
|
3198 |
+
var t = this,
|
3199 |
+
normalHeight = 0,
|
3200 |
+
normalWidth = 0,
|
3201 |
+
container = player.container,
|
3202 |
+
fullscreenBtn =
|
3203 |
+
$('<div class="mejs-button mejs-fullscreen-button">' +
|
3204 |
+
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
|
3205 |
+
'</div>')
|
3206 |
+
.appendTo(controls);
|
3207 |
+
|
3208 |
+
if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
|
3209 |
+
|
3210 |
+
fullscreenBtn.click(function() {
|
3211 |
+
var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
|
3212 |
+
|
3213 |
+
if (isFullScreen) {
|
3214 |
+
player.exitFullScreen();
|
3215 |
+
} else {
|
3216 |
+
player.enterFullScreen();
|
3217 |
+
}
|
3218 |
+
});
|
3219 |
+
|
3220 |
+
} else {
|
3221 |
+
|
3222 |
+
var hideTimeout = null,
|
3223 |
+
supportsPointerEvents = (function() {
|
3224 |
+
// TAKEN FROM MODERNIZR
|
3225 |
+
var element = document.createElement('x'),
|
3226 |
+
documentElement = document.documentElement,
|
3227 |
+
getComputedStyle = window.getComputedStyle,
|
3228 |
+
supports;
|
3229 |
+
if(!('pointerEvents' in element.style)){
|
3230 |
+
return false;
|
3231 |
+
}
|
3232 |
+
element.style.pointerEvents = 'auto';
|
3233 |
+
element.style.pointerEvents = 'x';
|
3234 |
+
documentElement.appendChild(element);
|
3235 |
+
supports = getComputedStyle &&
|
3236 |
+
getComputedStyle(element, '').pointerEvents === 'auto';
|
3237 |
+
documentElement.removeChild(element);
|
3238 |
+
return !!supports;
|
3239 |
+
})();
|
3240 |
+
|
3241 |
+
console.log('supportsPointerEvents', supportsPointerEvents);
|
3242 |
+
|
3243 |
+
if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
|
3244 |
+
|
3245 |
+
// allows clicking through the fullscreen button and controls down directly to Flash
|
3246 |
+
|
3247 |
+
/*
|
3248 |
+
When a user puts his mouse over the fullscreen button, the controls are disabled
|
3249 |
+
So we put a div over the video and another one on iether side of the fullscreen button
|
3250 |
+
that caputre mouse movement
|
3251 |
+
and restore the controls once the mouse moves outside of the fullscreen button
|
3252 |
+
*/
|
3253 |
+
|
3254 |
+
var fullscreenIsDisabled = false,
|
3255 |
+
restoreControls = function() {
|
3256 |
+
if (fullscreenIsDisabled) {
|
3257 |
+
// hide the hovers
|
3258 |
+
videoHoverDiv.hide();
|
3259 |
+
controlsLeftHoverDiv.hide();
|
3260 |
+
controlsRightHoverDiv.hide();
|
3261 |
+
|
3262 |
+
// restore the control bar
|
3263 |
+
fullscreenBtn.css('pointer-events', '');
|
3264 |
+
t.controls.css('pointer-events', '');
|
3265 |
+
|
3266 |
+
// store for later
|
3267 |
+
fullscreenIsDisabled = false;
|
3268 |
+
}
|
3269 |
+
},
|
3270 |
+
videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
3271 |
+
controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
3272 |
+
controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
3273 |
+
positionHoverDivs = function() {
|
3274 |
+
var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
|
3275 |
+
videoHoverDiv.css(style);
|
3276 |
+
controlsLeftHoverDiv.css(style);
|
3277 |
+
controlsRightHoverDiv.css(style);
|
3278 |
+
|
3279 |
+
// over video, but not controls
|
3280 |
+
videoHoverDiv
|
3281 |
+
.width( t.container.width() )
|
3282 |
+
.height( t.container.height() - t.controls.height() );
|
3283 |
+
|
3284 |
+
// over controls, but not the fullscreen button
|
3285 |
+
var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
|
3286 |
+
fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
|
3287 |
+
|
3288 |
+
controlsLeftHoverDiv
|
3289 |
+
.width( fullScreenBtnOffset )
|
3290 |
+
.height( t.controls.height() )
|
3291 |
+
.css({top: t.container.height() - t.controls.height()});
|
3292 |
+
|
3293 |
+
// after the fullscreen button
|
3294 |
+
controlsRightHoverDiv
|
3295 |
+
.width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
|
3296 |
+
.height( t.controls.height() )
|
3297 |
+
.css({top: t.container.height() - t.controls.height(),
|
3298 |
+
left: fullScreenBtnOffset + fullScreenBtnWidth});
|
3299 |
+
};
|
3300 |
+
|
3301 |
+
$(document).resize(function() {
|
3302 |
+
positionHoverDivs();
|
3303 |
+
});
|
3304 |
+
|
3305 |
+
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
|
3306 |
+
fullscreenBtn
|
3307 |
+
.mouseover(function() {
|
3308 |
+
|
3309 |
+
if (!t.isFullScreen) {
|
3310 |
+
|
3311 |
+
var buttonPos = fullscreenBtn.offset(),
|
3312 |
+
containerPos = player.container.offset();
|
3313 |
+
|
3314 |
+
// move the button in Flash into place
|
3315 |
+
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
|
3316 |
+
|
3317 |
+
// allows click through
|
3318 |
+
fullscreenBtn.css('pointer-events', 'none');
|
3319 |
+
t.controls.css('pointer-events', 'none');
|
3320 |
+
|
3321 |
+
// show the divs that will restore things
|
3322 |
+
videoHoverDiv.show();
|
3323 |
+
controlsRightHoverDiv.show();
|
3324 |
+
controlsLeftHoverDiv.show();
|
3325 |
+
positionHoverDivs();
|
3326 |
+
|
3327 |
+
fullscreenIsDisabled = true;
|
3328 |
+
}
|
3329 |
+
|
3330 |
+
});
|
3331 |
+
|
3332 |
+
// restore controls anytime the user enters or leaves fullscreen
|
3333 |
+
media.addEventListener('fullscreenchange', function(e) {
|
3334 |
+
restoreControls();
|
3335 |
+
});
|
3336 |
+
|
3337 |
+
|
3338 |
+
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
|
3339 |
+
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
|
3340 |
+
/*
|
3341 |
+
$(document).mousemove(function(e) {
|
3342 |
+
|
3343 |
+
// if the mouse is anywhere but the fullsceen button, then restore it all
|
3344 |
+
if (fullscreenIsDisabled) {
|
3345 |
+
|
3346 |
+
var fullscreenBtnPos = fullscreenBtn.offset();
|
3347 |
+
|
3348 |
+
|
3349 |
+
if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
|
3350 |
+
e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
|
3351 |
+
) {
|
3352 |
+
|
3353 |
+
fullscreenBtn.css('pointer-events', '');
|
3354 |
+
t.controls.css('pointer-events', '');
|
3355 |
+
|
3356 |
+
fullscreenIsDisabled = false;
|
3357 |
+
}
|
3358 |
+
}
|
3359 |
+
});
|
3360 |
+
*/
|
3361 |
+
|
3362 |
+
|
3363 |
+
} else {
|
3364 |
+
|
3365 |
+
// the hover state will show the fullscreen button in Flash to hover up and click
|
3366 |
+
|
3367 |
+
fullscreenBtn
|
3368 |
+
.mouseover(function() {
|
3369 |
+
|
3370 |
+
if (hideTimeout !== null) {
|
3371 |
+
clearTimeout(hideTimeout);
|
3372 |
+
delete hideTimeout;
|
3373 |
+
}
|
3374 |
+
|
3375 |
+
var buttonPos = fullscreenBtn.offset(),
|
3376 |
+
containerPos = player.container.offset();
|
3377 |
+
|
3378 |
+
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
|
3379 |
+
|
3380 |
+
})
|
3381 |
+
.mouseout(function() {
|
3382 |
+
|
3383 |
+
if (hideTimeout !== null) {
|
3384 |
+
clearTimeout(hideTimeout);
|
3385 |
+
delete hideTimeout;
|
3386 |
+
}
|
3387 |
+
|
3388 |
+
hideTimeout = setTimeout(function() {
|
3389 |
+
media.hideFullscreenButton();
|
3390 |
+
}, 1500);
|
3391 |
+
|
3392 |
+
|
3393 |
+
});
|
3394 |
+
}
|
3395 |
+
}
|
3396 |
+
|
3397 |
+
player.fullscreenBtn = fullscreenBtn;
|
3398 |
+
|
3399 |
+
$(document).bind('keydown',function (e) {
|
3400 |
+
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
|
3401 |
+
player.exitFullScreen();
|
3402 |
+
}
|
3403 |
+
});
|
3404 |
+
|
3405 |
+
},
|
3406 |
+
enterFullScreen: function() {
|
3407 |
+
|
3408 |
+
var t = this;
|
3409 |
+
|
3410 |
+
// firefox+flash can't adjust plugin sizes without resetting :(
|
3411 |
+
if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
|
3412 |
+
//t.media.setFullscreen(true);
|
3413 |
+
//player.isFullScreen = true;
|
3414 |
+
return;
|
3415 |
+
}
|
3416 |
+
|
3417 |
+
// store overflow
|
3418 |
+
docStyleOverflow = document.documentElement.style.overflow;
|
3419 |
+
// set it to not show scroll bars so 100% will work
|
3420 |
+
document.documentElement.style.overflow = 'hidden';
|
3421 |
+
|
3422 |
+
// store sizing
|
3423 |
+
normalHeight = t.container.height();
|
3424 |
+
normalWidth = t.container.width();
|
3425 |
+
|
3426 |
+
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
3427 |
+
if (t.media.pluginType === 'native') {
|
3428 |
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3429 |
+
|
3430 |
+
mejs.MediaFeatures.requestFullScreen(t.container[0]);
|
3431 |
+
//return;
|
3432 |
+
|
3433 |
+
if (t.isInIframe) {
|
3434 |
+
// sometimes exiting from fullscreen doesn't work
|
3435 |
+
// notably in Chrome <iframe>. Fixed in version 17
|
3436 |
+
setTimeout(function checkFullscreen() {
|
3437 |
+
|
3438 |
+
if (t.isNativeFullScreen) {
|
3439 |
+
|
3440 |
+
// check if the video is suddenly not really fullscreen
|
3441 |
+
if ($(window).width() !== screen.width) {
|
3442 |
+
// manually exit
|
3443 |
+
t.exitFullScreen();
|
3444 |
+
} else {
|
3445 |
+
// test again
|
3446 |
+
setTimeout(checkFullscreen, 500);
|
3447 |
+
}
|
3448 |
+
}
|
3449 |
+
|
3450 |
+
|
3451 |
+
}, 500);
|
3452 |
+
}
|
3453 |
+
|
3454 |
+
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
3455 |
+
t.media.webkitEnterFullscreen();
|
3456 |
+
return;
|
3457 |
+
}
|
3458 |
+
}
|
3459 |
+
|
3460 |
+
// check for iframe launch
|
3461 |
+
if (t.isInIframe) {
|
3462 |
+
var url = t.options.newWindowCallback(this);
|
3463 |
+
|
3464 |
+
|
3465 |
+
if (url !== '') {
|
3466 |
+
|
3467 |
+
// launch immediately
|
3468 |
+
if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3469 |
+
t.pause();
|
3470 |
+
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
3471 |
+
return;
|
3472 |
+
} else {
|
3473 |
+
setTimeout(function() {
|
3474 |
+
if (!t.isNativeFullScreen) {
|
3475 |
+
t.pause();
|
3476 |
+
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
3477 |
+
}
|
3478 |
+
}, 250);
|
3479 |
+
}
|
3480 |
+
}
|
3481 |
+
|
3482 |
+
}
|
3483 |
+
|
3484 |
+
// full window code
|
3485 |
+
|
3486 |
+
|
3487 |
+
|
3488 |
+
// make full size
|
3489 |
+
t.container
|
3490 |
+
.addClass('mejs-container-fullscreen')
|
3491 |
+
.width('100%')
|
3492 |
+
.height('100%');
|
3493 |
+
//.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
|
3494 |
+
|
3495 |
+
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
|
3496 |
+
// Actually, it seems to be needed for IE8, too
|
3497 |
+
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3498 |
+
setTimeout(function() {
|
3499 |
+
t.container.css({width: '100%', height: '100%'});
|
3500 |
+
t.setControlsSize();
|
3501 |
+
}, 500);
|
3502 |
+
//}
|
3503 |
+
|
3504 |
+
if (t.pluginType === 'native') {
|
3505 |
+
t.$media
|
3506 |
+
.width('100%')
|
3507 |
+
.height('100%');
|
3508 |
+
} else {
|
3509 |
+
t.container.find('object, embed, iframe')
|
3510 |
+
.width('100%')
|
3511 |
+
.height('100%');
|
3512 |
+
|
3513 |
+
//if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
3514 |
+
t.media.setVideoSize($(window).width(),$(window).height());
|
3515 |
+
//}
|
3516 |
+
}
|
3517 |
+
|
3518 |
+
t.layers.children('div')
|
3519 |
+
.width('100%')
|
3520 |
+
.height('100%');
|
3521 |
+
|
3522 |
+
if (t.fullscreenBtn) {
|
3523 |
+
t.fullscreenBtn
|
3524 |
+
.removeClass('mejs-fullscreen')
|
3525 |
+
.addClass('mejs-unfullscreen');
|
3526 |
+
}
|
3527 |
+
|
3528 |
+
t.setControlsSize();
|
3529 |
+
t.isFullScreen = true;
|
3530 |
+
},
|
3531 |
+
|
3532 |
+
exitFullScreen: function() {
|
3533 |
+
|
3534 |
+
var t = this;
|
3535 |
+
|
3536 |
+
// firefox can't adjust plugins
|
3537 |
+
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
|
3538 |
+
t.media.setFullscreen(false);
|
3539 |
+
//player.isFullScreen = false;
|
3540 |
+
return;
|
3541 |
+
}
|
3542 |
+
|
3543 |
+
// come outo of native fullscreen
|
3544 |
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
|
3545 |
+
mejs.MediaFeatures.cancelFullScreen();
|
3546 |
+
}
|
3547 |
+
|
3548 |
+
// restore scroll bars to document
|
3549 |
+
document.documentElement.style.overflow = docStyleOverflow;
|
3550 |
+
|
3551 |
+
t.container
|
3552 |
+
.removeClass('mejs-container-fullscreen')
|
3553 |
+
.width(normalWidth)
|
3554 |
+
.height(normalHeight);
|
3555 |
+
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
3556 |
+
|
3557 |
+
if (t.pluginType === 'native') {
|
3558 |
+
t.$media
|
3559 |
+
.width(normalWidth)
|
3560 |
+
.height(normalHeight);
|
3561 |
+
} else {
|
3562 |
+
t.container.find('object embed')
|
3563 |
+
.width(normalWidth)
|
3564 |
+
.height(normalHeight);
|
3565 |
+
|
3566 |
+
t.media.setVideoSize(normalWidth, normalHeight);
|
3567 |
+
}
|
3568 |
+
|
3569 |
+
t.layers.children('div')
|
3570 |
+
.width(normalWidth)
|
3571 |
+
.height(normalHeight);
|
3572 |
+
|
3573 |
+
t.fullscreenBtn
|
3574 |
+
.removeClass('mejs-unfullscreen')
|
3575 |
+
.addClass('mejs-fullscreen');
|
3576 |
+
|
3577 |
+
t.setControlsSize();
|
3578 |
+
t.isFullScreen = false;
|
3579 |
+
}
|
3580 |
+
});
|
3581 |
+
|
3582 |
+
})(mejs.$);
|
3583 |
|
3584 |
(function($) {
|
3585 |
|
4066 |
|
4067 |
})(mejs.$);
|
4068 |
|
4069 |
+
/*
|
4070 |
+
* ContextMenu Plugin
|
4071 |
+
*
|
4072 |
+
*
|
4073 |
+
*/
|
4074 |
+
|
4075 |
+
(function($) {
|
4076 |
+
|
4077 |
+
$.extend(mejs.MepDefaults,
|
4078 |
+
{ 'contextMenuItems': [
|
4079 |
+
// demo of a fullscreen option
|
4080 |
+
{
|
4081 |
+
render: function(player) {
|
4082 |
+
|
4083 |
+
// check for fullscreen plugin
|
4084 |
+
if (typeof player.enterFullScreen == 'undefined')
|
4085 |
+
return null;
|
4086 |
+
|
4087 |
+
if (player.isFullScreen) {
|
4088 |
+
return "Turn off Fullscreen";
|
4089 |
+
} else {
|
4090 |
+
return "Go Fullscreen";
|
4091 |
+
}
|
4092 |
+
},
|
4093 |
+
click: function(player) {
|
4094 |
+
if (player.isFullScreen) {
|
4095 |
+
player.exitFullScreen();
|
4096 |
+
} else {
|
4097 |
+
player.enterFullScreen();
|
4098 |
+
}
|
4099 |
+
}
|
4100 |
+
}
|
4101 |
+
,
|
4102 |
+
// demo of a mute/unmute button
|
4103 |
+
{
|
4104 |
+
render: function(player) {
|
4105 |
+
if (player.media.muted) {
|
4106 |
+
return "Unmute";
|
4107 |
+
} else {
|
4108 |
+
return "Mute";
|
4109 |
+
}
|
4110 |
+
},
|
4111 |
+
click: function(player) {
|
4112 |
+
if (player.media.muted) {
|
4113 |
+
player.setMuted(false);
|
4114 |
+
} else {
|
4115 |
+
player.setMuted(true);
|
4116 |
+
}
|
4117 |
+
}
|
4118 |
+
},
|
4119 |
+
// separator
|
4120 |
+
{
|
4121 |
+
isSeparator: true
|
4122 |
+
}
|
4123 |
+
,
|
4124 |
+
// demo of simple download video
|
4125 |
+
{
|
4126 |
+
render: function(player) {
|
4127 |
+
return "Download Video";
|
4128 |
+
},
|
4129 |
+
click: function(player) {
|
4130 |
+
window.location.href = player.media.currentSrc;
|
4131 |
+
}
|
4132 |
+
}
|
4133 |
+
]}
|
4134 |
+
);
|
4135 |
+
|
4136 |
+
|
4137 |
+
$.extend(MediaElementPlayer.prototype, {
|
4138 |
+
buildcontextmenu: function(player, controls, layers, media) {
|
4139 |
+
|
4140 |
+
// create context menu
|
4141 |
+
player.contextMenu = $('<div class="mejs-contextmenu"></div>')
|
4142 |
+
.appendTo($('body'))
|
4143 |
+
.hide();
|
4144 |
+
|
4145 |
+
// create events for showing context menu
|
4146 |
+
player.container.bind('contextmenu', function(e) {
|
4147 |
+
if (player.isContextMenuEnabled) {
|
4148 |
+
e.preventDefault();
|
4149 |
+
player.renderContextMenu(e.clientX-1, e.clientY-1);
|
4150 |
+
return false;
|
4151 |
+
}
|
4152 |
+
});
|
4153 |
+
player.container.bind('click', function() {
|
4154 |
+
player.contextMenu.hide();
|
4155 |
+
});
|
4156 |
+
player.contextMenu.bind('mouseleave', function() {
|
4157 |
+
|
4158 |
+
//console.log('context hover out');
|
4159 |
+
player.startContextMenuTimer();
|
4160 |
+
|
4161 |
+
});
|
4162 |
+
},
|
4163 |
+
|
4164 |
+
isContextMenuEnabled: true,
|
4165 |
+
enableContextMenu: function() {
|
4166 |
+
this.isContextMenuEnabled = true;
|
4167 |
+
},
|
4168 |
+
disableContextMenu: function() {
|
4169 |
+
this.isContextMenuEnabled = false;
|
4170 |
+
},
|
4171 |
+
|
4172 |
+
contextMenuTimeout: null,
|
4173 |
+
startContextMenuTimer: function() {
|
4174 |
+
//console.log('startContextMenuTimer');
|
4175 |
+
|
4176 |
+
var t = this;
|
4177 |
+
|
4178 |
+
t.killContextMenuTimer();
|
4179 |
+
|
4180 |
+
t.contextMenuTimer = setTimeout(function() {
|
4181 |
+
t.hideContextMenu();
|
4182 |
+
t.killContextMenuTimer();
|
4183 |
+
}, 750);
|
4184 |
+
},
|
4185 |
+
killContextMenuTimer: function() {
|
4186 |
+
var timer = this.contextMenuTimer;
|
4187 |
+
|
4188 |
+
//console.log('killContextMenuTimer', timer);
|
4189 |
+
|
4190 |
+
if (timer != null) {
|
4191 |
+
clearTimeout(timer);
|
4192 |
+
delete timer;
|
4193 |
+
timer = null;
|
4194 |
+
}
|
4195 |
+
},
|
4196 |
+
|
4197 |
+
hideContextMenu: function() {
|
4198 |
+
this.contextMenu.hide();
|
4199 |
+
},
|
4200 |
+
|
4201 |
+
renderContextMenu: function(x,y) {
|
4202 |
+
|
4203 |
+
// alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
|
4204 |
+
var t = this,
|
4205 |
+
html = '',
|
4206 |
+
items = t.options.contextMenuItems;
|
4207 |
+
|
4208 |
+
for (var i=0, il=items.length; i<il; i++) {
|
4209 |
+
|
4210 |
+
if (items[i].isSeparator) {
|
4211 |
+
html += '<div class="mejs-contextmenu-separator"></div>';
|
4212 |
+
} else {
|
4213 |
+
|
4214 |
+
var rendered = items[i].render(t);
|
4215 |
+
|
4216 |
+
// render can return null if the item doesn't need to be used at the moment
|
4217 |
+
if (rendered != null) {
|
4218 |
+
html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
|
4219 |
+
}
|
4220 |
+
}
|
4221 |
+
}
|
4222 |
+
|
4223 |
+
// position and show the context menu
|
4224 |
+
t.contextMenu
|
4225 |
+
.empty()
|
4226 |
+
.append($(html))
|
4227 |
+
.css({top:y, left:x})
|
4228 |
+
.show();
|
4229 |
+
|
4230 |
+
// bind events
|
4231 |
+
t.contextMenu.find('.mejs-contextmenu-item').each(function() {
|
4232 |
+
|
4233 |
+
// which one is this?
|
4234 |
+
var $dom = $(this),
|
4235 |
+
itemIndex = parseInt( $dom.data('itemindex'), 10 ),
|
4236 |
+
item = t.options.contextMenuItems[itemIndex];
|
4237 |
+
|
4238 |
+
// bind extra functionality?
|
4239 |
+
if (typeof item.show != 'undefined')
|
4240 |
+
item.show( $dom , t);
|
4241 |
+
|
4242 |
+
// bind click action
|
4243 |
+
$dom.click(function() {
|
4244 |
+
// perform click action
|
4245 |
+
if (typeof item.click != 'undefined')
|
4246 |
+
item.click(t);
|
4247 |
+
|
4248 |
+
// close
|
4249 |
+
t.contextMenu.hide();
|
4250 |
+
});
|
4251 |
+
});
|
4252 |
+
|
4253 |
+
// stop the controls from hiding
|
4254 |
+
setTimeout(function() {
|
4255 |
+
t.killControlsTimer('rev3');
|
4256 |
+
}, 100);
|
4257 |
+
|
4258 |
+
}
|
4259 |
+
});
|
4260 |
+
|
4261 |
})(mejs.$);
|
4262 |
|
includes/media-element/mediaelement.js
CHANGED
@@ -11,147 +11,147 @@
|
|
11 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
12 |
*
|
13 |
*/
|
14 |
-
// Namespace
|
15 |
-
var mejs = mejs || {};
|
16 |
-
|
17 |
-
// version number
|
18 |
-
mejs.version = '2.9.1';
|
19 |
-
|
20 |
-
// player number (for missing, same id attr)
|
21 |
-
mejs.meIndex = 0;
|
22 |
-
|
23 |
-
// media types accepted by plugins
|
24 |
-
mejs.plugins = {
|
25 |
-
silverlight: [
|
26 |
-
{version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
|
27 |
-
],
|
28 |
-
flash: [
|
29 |
-
{version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
|
30 |
-
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
|
31 |
-
],
|
32 |
-
youtube: [
|
33 |
-
{version: null, types: ['video/youtube', 'video/x-youtube']}
|
34 |
-
],
|
35 |
-
vimeo: [
|
36 |
-
{version: null, types: ['video/vimeo']}
|
37 |
-
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
};
|
39 |
-
|
40 |
-
/*
|
41 |
-
Utility methods
|
42 |
-
*/
|
43 |
-
mejs.Utility = {
|
44 |
-
encodeUrl: function(url) {
|
45 |
-
return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
|
46 |
-
},
|
47 |
-
escapeHTML: function(s) {
|
48 |
-
return s.toString().split('&').join('&').split('<').join('<').split('"').join('"');
|
49 |
-
},
|
50 |
-
absolutizeUrl: function(url) {
|
51 |
-
var el = document.createElement('div');
|
52 |
-
el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
|
53 |
-
return el.firstChild.href;
|
54 |
-
},
|
55 |
-
getScriptPath: function(scriptNames) {
|
56 |
-
var
|
57 |
-
i = 0,
|
58 |
-
j,
|
59 |
-
path = '',
|
60 |
-
name = '',
|
61 |
-
script,
|
62 |
-
scripts = document.getElementsByTagName('script'),
|
63 |
-
il = scripts.length,
|
64 |
-
jl = scriptNames.length;
|
65 |
-
|
66 |
-
for (; i < il; i++) {
|
67 |
-
script = scripts[i].src;
|
68 |
-
for (j = 0; j < jl; j++) {
|
69 |
-
name = scriptNames[j];
|
70 |
-
if (script.indexOf(name) > -1) {
|
71 |
-
path = script.substring(0, script.indexOf(name));
|
72 |
-
break;
|
73 |
-
}
|
74 |
-
}
|
75 |
-
if (path !== '') {
|
76 |
-
break;
|
77 |
-
}
|
78 |
-
}
|
79 |
-
return path;
|
80 |
-
},
|
81 |
-
secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
|
82 |
-
//add framecount
|
83 |
-
if (typeof showFrameCount == 'undefined') {
|
84 |
-
showFrameCount=false;
|
85 |
-
} else if(typeof fps == 'undefined') {
|
86 |
-
fps = 25;
|
87 |
-
}
|
88 |
-
|
89 |
-
var hours = Math.floor(time / 3600) % 24,
|
90 |
-
minutes = Math.floor(time / 60) % 60,
|
91 |
-
seconds = Math.floor(time % 60),
|
92 |
-
frames = Math.floor(((time % 1)*fps).toFixed(3)),
|
93 |
-
result =
|
94 |
-
( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
|
95 |
-
+ (minutes < 10 ? '0' + minutes : minutes) + ':'
|
96 |
-
+ (seconds < 10 ? '0' + seconds : seconds)
|
97 |
-
+ ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
|
98 |
-
|
99 |
-
return result;
|
100 |
-
},
|
101 |
-
|
102 |
-
timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
|
103 |
-
if (typeof showFrameCount == 'undefined') {
|
104 |
-
showFrameCount=false;
|
105 |
-
} else if(typeof fps == 'undefined') {
|
106 |
-
fps = 25;
|
107 |
-
}
|
108 |
-
|
109 |
-
var tc_array = hh_mm_ss_ff.split(":"),
|
110 |
-
tc_hh = parseInt(tc_array[0], 10),
|
111 |
-
tc_mm = parseInt(tc_array[1], 10),
|
112 |
-
tc_ss = parseInt(tc_array[2], 10),
|
113 |
-
tc_ff = 0,
|
114 |
-
tc_in_seconds = 0;
|
115 |
-
|
116 |
-
if (showFrameCount) {
|
117 |
-
tc_ff = parseInt(tc_array[3])/fps;
|
118 |
-
}
|
119 |
-
|
120 |
-
tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
|
121 |
-
|
122 |
-
return tc_in_seconds;
|
123 |
-
},
|
124 |
-
|
125 |
-
/* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
|
126 |
-
removeSwf: function(id) {
|
127 |
-
var obj = document.getElementById(id);
|
128 |
-
if (obj && obj.nodeName == "OBJECT") {
|
129 |
-
if (mejs.MediaFeatures.isIE) {
|
130 |
-
obj.style.display = "none";
|
131 |
-
(function(){
|
132 |
-
if (obj.readyState == 4) {
|
133 |
-
mejs.Utility.removeObjectInIE(id);
|
134 |
-
} else {
|
135 |
-
setTimeout(arguments.callee, 10);
|
136 |
-
}
|
137 |
-
})();
|
138 |
-
} else {
|
139 |
-
obj.parentNode.removeChild(obj);
|
140 |
-
}
|
141 |
-
}
|
142 |
-
},
|
143 |
-
removeObjectInIE: function(id) {
|
144 |
-
var obj = document.getElementById(id);
|
145 |
-
if (obj) {
|
146 |
-
for (var i in obj) {
|
147 |
-
if (typeof obj[i] == "function") {
|
148 |
-
obj[i] = null;
|
149 |
-
}
|
150 |
-
}
|
151 |
-
obj.parentNode.removeChild(obj);
|
152 |
-
}
|
153 |
-
}
|
154 |
-
};
|
155 |
|
156 |
|
157 |
// Core detector, plugins are added below
|
11 |
* Dual licensed under the MIT or GPL Version 2 licenses.
|
12 |
*
|
13 |
*/
|
14 |
+
// Namespace
|
15 |
+
var mejs = mejs || {};
|
16 |
+
|
17 |
+
// version number
|
18 |
+
mejs.version = '2.9.1';
|
19 |
+
|
20 |
+
// player number (for missing, same id attr)
|
21 |
+
mejs.meIndex = 0;
|
22 |
+
|
23 |
+
// media types accepted by plugins
|
24 |
+
mejs.plugins = {
|
25 |
+
silverlight: [
|
26 |
+
{version: [3,0], types: ['video/mp4','video/m4v','video/mov','video/wmv','audio/wma','audio/m4a','audio/mp3','audio/wav','audio/mpeg']}
|
27 |
+
],
|
28 |
+
flash: [
|
29 |
+
{version: [9,0,124], types: ['video/mp4','video/m4v','video/mov','video/flv','video/x-flv','audio/flv','audio/x-flv','audio/mp3','audio/m4a','audio/mpeg', 'video/youtube', 'video/x-youtube']}
|
30 |
+
//,{version: [12,0], types: ['video/webm']} // for future reference (hopefully!)
|
31 |
+
],
|
32 |
+
youtube: [
|
33 |
+
{version: null, types: ['video/youtube', 'video/x-youtube']}
|
34 |
+
],
|
35 |
+
vimeo: [
|
36 |
+
{version: null, types: ['video/vimeo']}
|
37 |
+
]
|
38 |
+
};
|
39 |
+
|
40 |
+
/*
|
41 |
+
Utility methods
|
42 |
+
*/
|
43 |
+
mejs.Utility = {
|
44 |
+
encodeUrl: function(url) {
|
45 |
+
return encodeURIComponent(url); //.replace(/\?/gi,'%3F').replace(/=/gi,'%3D').replace(/&/gi,'%26');
|
46 |
+
},
|
47 |
+
escapeHTML: function(s) {
|
48 |
+
return s.toString().split('&').join('&').split('<').join('<').split('"').join('"');
|
49 |
+
},
|
50 |
+
absolutizeUrl: function(url) {
|
51 |
+
var el = document.createElement('div');
|
52 |
+
el.innerHTML = '<a href="' + this.escapeHTML(url) + '">x</a>';
|
53 |
+
return el.firstChild.href;
|
54 |
+
},
|
55 |
+
getScriptPath: function(scriptNames) {
|
56 |
+
var
|
57 |
+
i = 0,
|
58 |
+
j,
|
59 |
+
path = '',
|
60 |
+
name = '',
|
61 |
+
script,
|
62 |
+
scripts = document.getElementsByTagName('script'),
|
63 |
+
il = scripts.length,
|
64 |
+
jl = scriptNames.length;
|
65 |
+
|
66 |
+
for (; i < il; i++) {
|
67 |
+
script = scripts[i].src;
|
68 |
+
for (j = 0; j < jl; j++) {
|
69 |
+
name = scriptNames[j];
|
70 |
+
if (script.indexOf(name) > -1) {
|
71 |
+
path = script.substring(0, script.indexOf(name));
|
72 |
+
break;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
if (path !== '') {
|
76 |
+
break;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
return path;
|
80 |
+
},
|
81 |
+
secondsToTimeCode: function(time, forceHours, showFrameCount, fps) {
|
82 |
+
//add framecount
|
83 |
+
if (typeof showFrameCount == 'undefined') {
|
84 |
+
showFrameCount=false;
|
85 |
+
} else if(typeof fps == 'undefined') {
|
86 |
+
fps = 25;
|
87 |
+
}
|
88 |
+
|
89 |
+
var hours = Math.floor(time / 3600) % 24,
|
90 |
+
minutes = Math.floor(time / 60) % 60,
|
91 |
+
seconds = Math.floor(time % 60),
|
92 |
+
frames = Math.floor(((time % 1)*fps).toFixed(3)),
|
93 |
+
result =
|
94 |
+
( (forceHours || hours > 0) ? (hours < 10 ? '0' + hours : hours) + ':' : '')
|
95 |
+
+ (minutes < 10 ? '0' + minutes : minutes) + ':'
|
96 |
+
+ (seconds < 10 ? '0' + seconds : seconds)
|
97 |
+
+ ((showFrameCount) ? ':' + (frames < 10 ? '0' + frames : frames) : '');
|
98 |
+
|
99 |
+
return result;
|
100 |
+
},
|
101 |
+
|
102 |
+
timeCodeToSeconds: function(hh_mm_ss_ff, forceHours, showFrameCount, fps){
|
103 |
+
if (typeof showFrameCount == 'undefined') {
|
104 |
+
showFrameCount=false;
|
105 |
+
} else if(typeof fps == 'undefined') {
|
106 |
+
fps = 25;
|
107 |
+
}
|
108 |
+
|
109 |
+
var tc_array = hh_mm_ss_ff.split(":"),
|
110 |
+
tc_hh = parseInt(tc_array[0], 10),
|
111 |
+
tc_mm = parseInt(tc_array[1], 10),
|
112 |
+
tc_ss = parseInt(tc_array[2], 10),
|
113 |
+
tc_ff = 0,
|
114 |
+
tc_in_seconds = 0;
|
115 |
+
|
116 |
+
if (showFrameCount) {
|
117 |
+
tc_ff = parseInt(tc_array[3])/fps;
|
118 |
+
}
|
119 |
+
|
120 |
+
tc_in_seconds = ( tc_hh * 3600 ) + ( tc_mm * 60 ) + tc_ss + tc_ff;
|
121 |
+
|
122 |
+
return tc_in_seconds;
|
123 |
+
},
|
124 |
+
|
125 |
+
/* borrowed from SWFObject: http://code.google.com/p/swfobject/source/browse/trunk/swfobject/src/swfobject.js#474 */
|
126 |
+
removeSwf: function(id) {
|
127 |
+
var obj = document.getElementById(id);
|
128 |
+
if (obj && obj.nodeName == "OBJECT") {
|
129 |
+
if (mejs.MediaFeatures.isIE) {
|
130 |
+
obj.style.display = "none";
|
131 |
+
(function(){
|
132 |
+
if (obj.readyState == 4) {
|
133 |
+
mejs.Utility.removeObjectInIE(id);
|
134 |
+
} else {
|
135 |
+
setTimeout(arguments.callee, 10);
|
136 |
+
}
|
137 |
+
})();
|
138 |
+
} else {
|
139 |
+
obj.parentNode.removeChild(obj);
|
140 |
+
}
|
141 |
+
}
|
142 |
+
},
|
143 |
+
removeObjectInIE: function(id) {
|
144 |
+
var obj = document.getElementById(id);
|
145 |
+
if (obj) {
|
146 |
+
for (var i in obj) {
|
147 |
+
if (typeof obj[i] == "function") {
|
148 |
+
obj[i] = null;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
obj.parentNode.removeChild(obj);
|
152 |
+
}
|
153 |
+
}
|
154 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
|
157 |
// Core detector, plugins are added below
|
includes/media-element/mediaelementplayer.js
CHANGED
@@ -14,1066 +14,1066 @@ if (typeof jQuery != 'undefined') {
|
|
14 |
} else if (typeof ender != 'undefined') {
|
15 |
mejs.$ = ender;
|
16 |
}
|
17 |
-
(function ($) {
|
18 |
-
|
19 |
-
// default player values
|
20 |
-
mejs.MepDefaults = {
|
21 |
-
// url to poster (to fix iOS 3.x)
|
22 |
-
poster: '',
|
23 |
-
// default if the <video width> is not specified
|
24 |
-
defaultVideoWidth: 480,
|
25 |
-
// default if the <video height> is not specified
|
26 |
-
defaultVideoHeight: 270,
|
27 |
-
// if set, overrides <video width>
|
28 |
-
videoWidth: -1,
|
29 |
-
// if set, overrides <video height>
|
30 |
-
videoHeight: -1,
|
31 |
-
// default if the user doesn't specify
|
32 |
-
defaultAudioWidth: 400,
|
33 |
-
// default if the user doesn't specify
|
34 |
-
defaultAudioHeight: 30,
|
35 |
-
// width of audio player
|
36 |
-
audioWidth: -1,
|
37 |
-
// height of audio player
|
38 |
-
audioHeight: -1,
|
39 |
-
// initial volume when the player starts (overrided by user cookie)
|
40 |
-
startVolume: 0.8,
|
41 |
-
// useful for <audio> player loops
|
42 |
-
loop: false,
|
43 |
-
// resize to media dimensions
|
44 |
-
enableAutosize: true,
|
45 |
-
// forces the hour marker (##:00:00)
|
46 |
-
alwaysShowHours: false,
|
47 |
-
|
48 |
-
// show framecount in timecode (##:00:00:00)
|
49 |
-
showTimecodeFrameCount: false,
|
50 |
-
// used when showTimecodeFrameCount is set to true
|
51 |
-
framesPerSecond: 25,
|
52 |
-
|
53 |
-
// automatically calculate the width of the progress bar based on the sizes of other elements
|
54 |
-
autosizeProgress : true,
|
55 |
-
// Hide controls when playing and mouse is not over the video
|
56 |
-
alwaysShowControls: false,
|
57 |
-
// force iPad's native controls
|
58 |
-
iPadUseNativeControls: false,
|
59 |
-
// force iPhone's native controls
|
60 |
-
iPhoneUseNativeControls: false,
|
61 |
-
// force Android's native controls
|
62 |
-
AndroidUseNativeControls: false,
|
63 |
-
// features to show
|
64 |
-
features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
|
65 |
-
// only for dynamic
|
66 |
-
isVideo: true,
|
67 |
-
|
68 |
-
// turns keyboard support on and off for this instance
|
69 |
-
enableKeyboard: true,
|
70 |
-
|
71 |
-
// whenthis player starts, it will pause other players
|
72 |
-
pauseOtherPlayers: true,
|
73 |
-
|
74 |
-
// array of keyboard actions such as play pause
|
75 |
-
keyActions: [
|
76 |
-
{
|
77 |
-
keys: [
|
78 |
-
32, // SPACE
|
79 |
-
179 // GOOGLE play/pause button
|
80 |
-
],
|
81 |
-
action: function(player, media) {
|
82 |
-
if (media.paused || media.ended) {
|
83 |
-
media.play();
|
84 |
-
} else {
|
85 |
-
media.pause();
|
86 |
-
}
|
87 |
-
}
|
88 |
-
},
|
89 |
-
{
|
90 |
-
keys: [38], // UP
|
91 |
-
action: function(player, media) {
|
92 |
-
var newVolume = Math.min(media.volume + 0.1, 1);
|
93 |
-
media.setVolume(newVolume);
|
94 |
-
}
|
95 |
-
},
|
96 |
-
{
|
97 |
-
keys: [40], // DOWN
|
98 |
-
action: function(player, media) {
|
99 |
-
var newVolume = Math.max(media.volume - 0.1, 0);
|
100 |
-
media.setVolume(newVolume);
|
101 |
-
}
|
102 |
-
},
|
103 |
-
{
|
104 |
-
keys: [
|
105 |
-
37, // LEFT
|
106 |
-
227 // Google TV rewind
|
107 |
-
],
|
108 |
-
action: function(player, media) {
|
109 |
-
if (!isNaN(media.duration) && media.duration > 0) {
|
110 |
-
if (player.isVideo) {
|
111 |
-
player.showControls();
|
112 |
-
player.startControlsTimer();
|
113 |
-
}
|
114 |
-
|
115 |
-
// 5%
|
116 |
-
var newTime = Math.max(media.currentTime - (media.duration * 0.05), 0);
|
117 |
-
media.setCurrentTime(newTime);
|
118 |
-
}
|
119 |
-
}
|
120 |
-
},
|
121 |
-
{
|
122 |
-
keys: [
|
123 |
-
39, // RIGHT
|
124 |
-
228 // Google TV forward
|
125 |
-
],
|
126 |
-
action: function(player, media) {
|
127 |
-
if (!isNaN(media.duration) && media.duration > 0) {
|
128 |
-
if (player.isVideo) {
|
129 |
-
player.showControls();
|
130 |
-
player.startControlsTimer();
|
131 |
-
}
|
132 |
-
|
133 |
-
// 5%
|
134 |
-
var newTime = Math.min(media.currentTime + (media.duration * 0.05), media.duration);
|
135 |
-
media.setCurrentTime(newTime);
|
136 |
-
}
|
137 |
-
}
|
138 |
-
},
|
139 |
-
{
|
140 |
-
keys: [70], // f
|
141 |
-
action: function(player, media) {
|
142 |
-
if (typeof player.enterFullScreen != 'undefined') {
|
143 |
-
if (player.isFullScreen) {
|
144 |
-
player.exitFullScreen();
|
145 |
-
} else {
|
146 |
-
player.enterFullScreen();
|
147 |
-
}
|
148 |
-
}
|
149 |
-
}
|
150 |
-
}
|
151 |
-
]
|
152 |
-
};
|
153 |
-
|
154 |
-
mejs.mepIndex = 0;
|
155 |
-
|
156 |
-
mejs.players = [];
|
157 |
-
|
158 |
-
// wraps a MediaElement object in player controls
|
159 |
-
mejs.MediaElementPlayer = function(node, o) {
|
160 |
-
// enforce object, even without "new" (via John Resig)
|
161 |
-
if ( !(this instanceof mejs.MediaElementPlayer) ) {
|
162 |
-
return new mejs.MediaElementPlayer(node, o);
|
163 |
-
}
|
164 |
-
|
165 |
-
var t = this;
|
166 |
-
|
167 |
-
// these will be reset after the MediaElement.success fires
|
168 |
-
t.$media = t.$node = $(node);
|
169 |
-
t.node = t.media = t.$media[0];
|
170 |
-
|
171 |
-
// check for existing player
|
172 |
-
if (typeof t.node.player != 'undefined') {
|
173 |
-
return t.node.player;
|
174 |
-
} else {
|
175 |
-
// attach player to DOM node for reference
|
176 |
-
t.node.player = t;
|
177 |
-
}
|
178 |
-
|
179 |
-
|
180 |
-
// try to get options from data-mejsoptions
|
181 |
-
if (typeof o == 'undefined') {
|
182 |
-
o = t.$node.data('mejsoptions');
|
183 |
-
}
|
184 |
-
|
185 |
-
// extend default options
|
186 |
-
t.options = $.extend({},mejs.MepDefaults,o);
|
187 |
-
|
188 |
-
// add to player array (for focus events)
|
189 |
-
mejs.players.push(t);
|
190 |
-
|
191 |
-
// start up
|
192 |
-
t.init();
|
193 |
-
|
194 |
-
return t;
|
195 |
-
};
|
196 |
-
|
197 |
-
// actual player
|
198 |
-
mejs.MediaElementPlayer.prototype = {
|
199 |
-
|
200 |
-
hasFocus: false,
|
201 |
-
|
202 |
-
controlsAreVisible: true,
|
203 |
-
|
204 |
-
init: function() {
|
205 |
-
|
206 |
-
var
|
207 |
-
t = this,
|
208 |
-
mf = mejs.MediaFeatures,
|
209 |
-
// options for MediaElement (shim)
|
210 |
-
meOptions = $.extend(true, {}, t.options, {
|
211 |
-
success: function(media, domNode) { t.meReady(media, domNode); },
|
212 |
-
error: function(e) { t.handleError(e);}
|
213 |
-
}),
|
214 |
-
tagName = t.media.tagName.toLowerCase();
|
215 |
-
|
216 |
-
t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
|
217 |
-
|
218 |
-
if (t.isDynamic) {
|
219 |
-
// get video from src or href?
|
220 |
-
t.isVideo = t.options.isVideo;
|
221 |
-
} else {
|
222 |
-
t.isVideo = (tagName !== 'audio' && t.options.isVideo);
|
223 |
-
}
|
224 |
-
|
225 |
-
// use native controls in iPad, iPhone, and Android
|
226 |
-
if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
227 |
-
|
228 |
-
// add controls and stop
|
229 |
-
t.$media.attr('controls', 'controls');
|
230 |
-
|
231 |
-
// attempt to fix iOS 3 bug
|
232 |
-
//t.$media.removeAttr('poster');
|
233 |
-
// no Issue found on iOS3 -ttroxell
|
234 |
-
|
235 |
-
// override Apple's autoplay override for iPads
|
236 |
-
if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
|
237 |
-
t.media.load();
|
238 |
-
t.media.play();
|
239 |
-
}
|
240 |
-
|
241 |
-
} else if (mf.isAndroid && t.AndroidUseNativeControls) {
|
242 |
-
|
243 |
-
// leave default player
|
244 |
-
|
245 |
-
} else {
|
246 |
-
|
247 |
-
// DESKTOP: use MediaElementPlayer controls
|
248 |
-
|
249 |
-
// remove native controls
|
250 |
-
t.$media.removeAttr('controls');
|
251 |
-
|
252 |
-
// unique ID
|
253 |
-
t.id = 'mep_' + mejs.mepIndex++;
|
254 |
-
|
255 |
-
// build container
|
256 |
-
t.container =
|
257 |
-
$('<div id="' + t.id + '" class="mejs-container">'+
|
258 |
-
'<div class="mejs-inner">'+
|
259 |
-
'<div class="mejs-mediaelement"></div>'+
|
260 |
-
'<div class="mejs-layers"></div>'+
|
261 |
-
'<div class="mejs-controls"></div>'+
|
262 |
-
'<div class="mejs-clear"></div>'+
|
263 |
-
'</div>' +
|
264 |
-
'</div>')
|
265 |
-
.addClass(t.$media[0].className)
|
266 |
-
.insertBefore(t.$media);
|
267 |
-
|
268 |
-
// add classes for user and content
|
269 |
-
t.container.addClass(
|
270 |
-
(mf.isAndroid ? 'mejs-android ' : '') +
|
271 |
-
(mf.isiOS ? 'mejs-ios ' : '') +
|
272 |
-
(mf.isiPad ? 'mejs-ipad ' : '') +
|
273 |
-
(mf.isiPhone ? 'mejs-iphone ' : '') +
|
274 |
-
(t.isVideo ? 'mejs-video ' : 'mejs-audio ')
|
275 |
-
);
|
276 |
-
|
277 |
-
|
278 |
-
// move the <video/video> tag into the right spot
|
279 |
-
if (mf.isiOS) {
|
280 |
-
|
281 |
-
// sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
|
282 |
-
var $newMedia = t.$media.clone();
|
283 |
-
|
284 |
-
t.container.find('.mejs-mediaelement').append($newMedia);
|
285 |
-
|
286 |
-
t.$media.remove();
|
287 |
-
t.$node = t.$media = $newMedia;
|
288 |
-
t.node = t.media = $newMedia[0]
|
289 |
-
|
290 |
-
} else {
|
291 |
-
|
292 |
-
// normal way of moving it into place (doesn't work on iOS)
|
293 |
-
t.container.find('.mejs-mediaelement').append(t.$media);
|
294 |
-
}
|
295 |
-
|
296 |
-
// find parts
|
297 |
-
t.controls = t.container.find('.mejs-controls');
|
298 |
-
t.layers = t.container.find('.mejs-layers');
|
299 |
-
|
300 |
-
// determine the size
|
301 |
-
|
302 |
-
/* size priority:
|
303 |
-
(1) videoWidth (forced),
|
304 |
-
(2) style="width;height;"
|
305 |
-
(3) width attribute,
|
306 |
-
(4) defaultVideoWidth (for unspecified cases)
|
307 |
-
*/
|
308 |
-
|
309 |
-
var capsTagName = tagName.substring(0,1).toUpperCase() + tagName.substring(1);
|
310 |
-
|
311 |
-
if (t.options[tagName + 'Width'] > 0 || t.options[tagName + 'Width'].toString().indexOf('%') > -1) {
|
312 |
-
t.width = t.options[tagName + 'Width'];
|
313 |
-
} else if (t.media.style.width !== '' && t.media.style.width !== null) {
|
314 |
-
t.width = t.media.style.width;
|
315 |
-
} else if (t.media.getAttribute('width') !== null) {
|
316 |
-
t.width = t.$media.attr('width');
|
317 |
-
} else {
|
318 |
-
t.width = t.options['default' + capsTagName + 'Width'];
|
319 |
-
}
|
320 |
-
|
321 |
-
if (t.options[tagName + 'Height'] > 0 || t.options[tagName + 'Height'].toString().indexOf('%') > -1) {
|
322 |
-
t.height = t.options[tagName + 'Height'];
|
323 |
-
} else if (t.media.style.height !== '' && t.media.style.height !== null) {
|
324 |
-
t.height = t.media.style.height;
|
325 |
-
} else if (t.$media[0].getAttribute('height') !== null) {
|
326 |
-
t.height = t.$media.attr('height');
|
327 |
-
} else {
|
328 |
-
t.height = t.options['default' + capsTagName + 'Height'];
|
329 |
-
}
|
330 |
-
|
331 |
-
// set the size, while we wait for the plugins to load below
|
332 |
-
t.setPlayerSize(t.width, t.height);
|
333 |
-
|
334 |
-
// create MediaElementShim
|
335 |
-
meOptions.pluginWidth = t.height;
|
336 |
-
meOptions.pluginHeight = t.width;
|
337 |
-
}
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
// create MediaElement shim
|
342 |
-
mejs.MediaElement(t.$media[0], meOptions);
|
343 |
-
},
|
344 |
-
|
345 |
-
showControls: function(doAnimation) {
|
346 |
-
var t = this;
|
347 |
-
|
348 |
-
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
349 |
-
|
350 |
-
if (t.controlsAreVisible)
|
351 |
-
return;
|
352 |
-
|
353 |
-
if (doAnimation) {
|
354 |
-
t.controls
|
355 |
-
.css('visibility','visible')
|
356 |
-
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
357 |
-
|
358 |
-
// any additional controls people might add and want to hide
|
359 |
-
t.container.find('.mejs-control')
|
360 |
-
.css('visibility','visible')
|
361 |
-
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
362 |
-
|
363 |
-
} else {
|
364 |
-
t.controls
|
365 |
-
.css('visibility','visible')
|
366 |
-
.css('display','block');
|
367 |
-
|
368 |
-
// any additional controls people might add and want to hide
|
369 |
-
t.container.find('.mejs-control')
|
370 |
-
.css('visibility','visible')
|
371 |
-
.css('display','block');
|
372 |
-
|
373 |
-
t.controlsAreVisible = true;
|
374 |
-
}
|
375 |
-
|
376 |
-
t.setControlsSize();
|
377 |
-
|
378 |
-
},
|
379 |
-
|
380 |
-
hideControls: function(doAnimation) {
|
381 |
-
var t = this;
|
382 |
-
|
383 |
-
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
384 |
-
|
385 |
-
if (!t.controlsAreVisible)
|
386 |
-
return;
|
387 |
-
|
388 |
-
if (doAnimation) {
|
389 |
-
// fade out main controls
|
390 |
-
t.controls.stop(true, true).fadeOut(200, function() {
|
391 |
-
$(this)
|
392 |
-
.css('visibility','hidden')
|
393 |
-
.css('display','block');
|
394 |
-
|
395 |
-
t.controlsAreVisible = false;
|
396 |
-
});
|
397 |
-
|
398 |
-
// any additional controls people might add and want to hide
|
399 |
-
t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
|
400 |
-
$(this)
|
401 |
-
.css('visibility','hidden')
|
402 |
-
.css('display','block');
|
403 |
-
});
|
404 |
-
} else {
|
405 |
-
|
406 |
-
// hide main controls
|
407 |
-
t.controls
|
408 |
-
.css('visibility','hidden')
|
409 |
-
.css('display','block');
|
410 |
-
|
411 |
-
// hide others
|
412 |
-
t.container.find('.mejs-control')
|
413 |
-
.css('visibility','hidden')
|
414 |
-
.css('display','block');
|
415 |
-
|
416 |
-
t.controlsAreVisible = false;
|
417 |
-
}
|
418 |
-
},
|
419 |
-
|
420 |
-
controlsTimer: null,
|
421 |
-
|
422 |
-
startControlsTimer: function(timeout) {
|
423 |
-
|
424 |
-
var t = this;
|
425 |
-
|
426 |
-
timeout = typeof timeout != 'undefined' ? timeout : 1500;
|
427 |
-
|
428 |
-
t.killControlsTimer('start');
|
429 |
-
|
430 |
-
t.controlsTimer = setTimeout(function() {
|
431 |
-
//console.log('timer fired');
|
432 |
-
t.hideControls();
|
433 |
-
t.killControlsTimer('hide');
|
434 |
-
}, timeout);
|
435 |
-
},
|
436 |
-
|
437 |
-
killControlsTimer: function(src) {
|
438 |
-
|
439 |
-
var t = this;
|
440 |
-
|
441 |
-
if (t.controlsTimer !== null) {
|
442 |
-
clearTimeout(t.controlsTimer);
|
443 |
-
delete t.controlsTimer;
|
444 |
-
t.controlsTimer = null;
|
445 |
-
}
|
446 |
-
},
|
447 |
-
|
448 |
-
controlsEnabled: true,
|
449 |
-
|
450 |
-
disableControls: function() {
|
451 |
-
var t= this;
|
452 |
-
|
453 |
-
t.killControlsTimer();
|
454 |
-
t.hideControls(false);
|
455 |
-
this.controlsEnabled = false;
|
456 |
-
},
|
457 |
-
|
458 |
-
enableControls: function() {
|
459 |
-
var t= this;
|
460 |
-
|
461 |
-
t.showControls(false);
|
462 |
-
|
463 |
-
t.controlsEnabled = true;
|
464 |
-
},
|
465 |
-
|
466 |
-
|
467 |
-
// Sets up all controls and events
|
468 |
-
meReady: function(media, domNode) {
|
469 |
-
|
470 |
-
|
471 |
-
var t = this,
|
472 |
-
mf = mejs.MediaFeatures,
|
473 |
-
autoplayAttr = domNode.getAttribute('autoplay'),
|
474 |
-
autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
|
475 |
-
featureIndex,
|
476 |
-
feature;
|
477 |
-
|
478 |
-
// make sure it can't create itself again if a plugin reloads
|
479 |
-
if (t.created)
|
480 |
-
return;
|
481 |
-
else
|
482 |
-
t.created = true;
|
483 |
-
|
484 |
-
t.media = media;
|
485 |
-
t.domNode = domNode;
|
486 |
-
|
487 |
-
if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
488 |
-
|
489 |
-
// two built in features
|
490 |
-
t.buildposter(t, t.controls, t.layers, t.media);
|
491 |
-
t.buildkeyboard(t, t.controls, t.layers, t.media);
|
492 |
-
t.buildoverlays(t, t.controls, t.layers, t.media);
|
493 |
-
|
494 |
-
// grab for use by features
|
495 |
-
t.findTracks();
|
496 |
-
|
497 |
-
// add user-defined features/controls
|
498 |
-
for (featureIndex in t.options.features) {
|
499 |
-
feature = t.options.features[featureIndex];
|
500 |
-
if (t['build' + feature]) {
|
501 |
-
try {
|
502 |
-
t['build' + feature](t, t.controls, t.layers, t.media);
|
503 |
-
} catch (e) {
|
504 |
-
// TODO: report control error
|
505 |
-
//throw e;
|
506 |
-
//console.log('error building ' + feature);
|
507 |
-
//console.log(e);
|
508 |
-
}
|
509 |
-
}
|
510 |
-
}
|
511 |
-
|
512 |
-
t.container.trigger('controlsready');
|
513 |
-
|
514 |
-
// reset all layers and controls
|
515 |
-
t.setPlayerSize(t.width, t.height);
|
516 |
-
t.setControlsSize();
|
517 |
-
|
518 |
-
|
519 |
-
// controls fade
|
520 |
-
if (t.isVideo) {
|
521 |
-
|
522 |
-
if (mejs.MediaFeatures.hasTouch) {
|
523 |
-
|
524 |
-
// for touch devices (iOS, Android)
|
525 |
-
// show/hide without animation on touch
|
526 |
-
|
527 |
-
t.$media.bind('touchstart', function() {
|
528 |
-
|
529 |
-
|
530 |
-
// toggle controls
|
531 |
-
if (t.controlsAreVisible) {
|
532 |
-
t.hideControls(false);
|
533 |
-
} else {
|
534 |
-
if (t.controlsEnabled) {
|
535 |
-
t.showControls(false);
|
536 |
-
}
|
537 |
-
}
|
538 |
-
});
|
539 |
-
|
540 |
-
} else {
|
541 |
-
// click controls
|
542 |
-
var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
|
543 |
-
|
544 |
-
// click to play/pause
|
545 |
-
clickElement.click(function() {
|
546 |
-
if (media.paused) {
|
547 |
-
media.play();
|
548 |
-
} else {
|
549 |
-
media.pause();
|
550 |
-
}
|
551 |
-
});
|
552 |
-
|
553 |
-
|
554 |
-
// show/hide controls
|
555 |
-
t.container
|
556 |
-
.bind('mouseenter mouseover', function () {
|
557 |
-
if (t.controlsEnabled) {
|
558 |
-
if (!t.options.alwaysShowControls) {
|
559 |
-
t.killControlsTimer('enter');
|
560 |
-
t.showControls();
|
561 |
-
t.startControlsTimer(2500);
|
562 |
-
}
|
563 |
-
}
|
564 |
-
})
|
565 |
-
.bind('mousemove', function() {
|
566 |
-
if (t.controlsEnabled) {
|
567 |
-
if (!t.controlsAreVisible) {
|
568 |
-
t.showControls();
|
569 |
-
}
|
570 |
-
//t.killControlsTimer('move');
|
571 |
-
if (!t.options.alwaysShowControls) {
|
572 |
-
t.startControlsTimer(2500);
|
573 |
-
}
|
574 |
-
}
|
575 |
-
})
|
576 |
-
.bind('mouseleave', function () {
|
577 |
-
if (t.controlsEnabled) {
|
578 |
-
if (!t.media.paused && !t.options.alwaysShowControls) {
|
579 |
-
t.startControlsTimer(1000);
|
580 |
-
}
|
581 |
-
}
|
582 |
-
});
|
583 |
-
}
|
584 |
-
|
585 |
-
// check for autoplay
|
586 |
-
if (autoplay && !t.options.alwaysShowControls) {
|
587 |
-
t.hideControls();
|
588 |
-
}
|
589 |
-
|
590 |
-
// resizer
|
591 |
-
if (t.options.enableAutosize) {
|
592 |
-
t.media.addEventListener('loadedmetadata', function(e) {
|
593 |
-
// if the <video height> was not set and the options.videoHeight was not set
|
594 |
-
// then resize to the real dimensions
|
595 |
-
if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
|
596 |
-
t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
|
597 |
-
t.setControlsSize();
|
598 |
-
t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
|
599 |
-
}
|
600 |
-
}, false);
|
601 |
-
}
|
602 |
-
}
|
603 |
-
|
604 |
-
// EVENTS
|
605 |
-
|
606 |
-
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
|
607 |
-
media.addEventListener('play', function() {
|
608 |
-
|
609 |
-
// go through all other players
|
610 |
-
for (var i=0, il=mejs.players.length; i<il; i++) {
|
611 |
-
var p = mejs.players[i];
|
612 |
-
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
|
613 |
-
p.pause();
|
614 |
-
}
|
615 |
-
p.hasFocus = false;
|
616 |
-
}
|
617 |
-
|
618 |
-
t.hasFocus = true;
|
619 |
-
},false);
|
620 |
-
|
621 |
-
|
622 |
-
// ended for all
|
623 |
-
t.media.addEventListener('ended', function (e) {
|
624 |
-
try{
|
625 |
-
t.media.setCurrentTime(0);
|
626 |
-
} catch (exp) {
|
627 |
-
|
628 |
-
}
|
629 |
-
t.media.pause();
|
630 |
-
|
631 |
-
if (t.setProgressRail)
|
632 |
-
t.setProgressRail();
|
633 |
-
if (t.setCurrentRail)
|
634 |
-
t.setCurrentRail();
|
635 |
-
|
636 |
-
if (t.options.loop) {
|
637 |
-
t.media.play();
|
638 |
-
} else if (!t.options.alwaysShowControls && t.controlsEnabled) {
|
639 |
-
t.showControls();
|
640 |
-
}
|
641 |
-
}, false);
|
642 |
-
|
643 |
-
// resize on the first play
|
644 |
-
t.media.addEventListener('loadedmetadata', function(e) {
|
645 |
-
if (t.updateDuration) {
|
646 |
-
t.updateDuration();
|
647 |
-
}
|
648 |
-
if (t.updateCurrent) {
|
649 |
-
t.updateCurrent();
|
650 |
-
}
|
651 |
-
|
652 |
-
if (!t.isFullScreen) {
|
653 |
-
t.setPlayerSize(t.width, t.height);
|
654 |
-
t.setControlsSize();
|
655 |
-
}
|
656 |
-
}, false);
|
657 |
-
|
658 |
-
|
659 |
-
// webkit has trouble doing this without a delay
|
660 |
-
setTimeout(function () {
|
661 |
-
t.setPlayerSize(t.width, t.height);
|
662 |
-
t.setControlsSize();
|
663 |
-
}, 50);
|
664 |
-
|
665 |
-
// adjust controls whenever window sizes (used to be in fullscreen only)
|
666 |
-
$(window).resize(function() {
|
667 |
-
|
668 |
-
// don't resize for fullscreen mode
|
669 |
-
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
|
670 |
-
t.setPlayerSize(t.width, t.height);
|
671 |
-
}
|
672 |
-
|
673 |
-
// always adjust controls
|
674 |
-
t.setControlsSize();
|
675 |
-
});
|
676 |
-
|
677 |
-
// TEMP: needs to be moved somewhere else
|
678 |
-
if (t.media.pluginType == 'youtube') {
|
679 |
-
t.container.find('.mejs-overlay-play').hide();
|
680 |
-
}
|
681 |
-
}
|
682 |
-
|
683 |
-
// force autoplay for HTML5
|
684 |
-
if (autoplay && media.pluginType == 'native') {
|
685 |
-
media.load();
|
686 |
-
media.play();
|
687 |
-
}
|
688 |
-
|
689 |
-
|
690 |
-
if (t.options.success) {
|
691 |
-
|
692 |
-
if (typeof t.options.success == 'string') {
|
693 |
-
window[t.options.success](t.media, t.domNode, t);
|
694 |
-
} else {
|
695 |
-
t.options.success(t.media, t.domNode, t);
|
696 |
-
}
|
697 |
-
}
|
698 |
-
},
|
699 |
-
|
700 |
-
handleError: function(e) {
|
701 |
-
var t = this;
|
702 |
-
|
703 |
-
t.controls.hide();
|
704 |
-
|
705 |
-
// Tell user that the file cannot be played
|
706 |
-
if (t.options.error) {
|
707 |
-
t.options.error(e);
|
708 |
-
}
|
709 |
-
},
|
710 |
-
|
711 |
-
setPlayerSize: function(width,height) {
|
712 |
-
var t = this;
|
713 |
-
|
714 |
-
if (typeof width != 'undefined')
|
715 |
-
t.width = width;
|
716 |
-
|
717 |
-
if (typeof height != 'undefined')
|
718 |
-
t.height = height;
|
719 |
-
|
720 |
-
// detect 100% mode
|
721 |
-
if (t.height.toString().indexOf('%') > 0) {
|
722 |
-
|
723 |
-
// do we have the native dimensions yet?
|
724 |
-
var
|
725 |
-
nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
|
726 |
-
nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
|
727 |
-
parentWidth = t.container.parent().width(),
|
728 |
-
newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
|
729 |
-
|
730 |
-
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
731 |
-
parentWidth = $(window).width();
|
732 |
-
newHeight = $(window).height();
|
733 |
-
}
|
734 |
-
|
735 |
-
|
736 |
-
// set outer container size
|
737 |
-
t.container
|
738 |
-
.width(parentWidth)
|
739 |
-
.height(newHeight);
|
740 |
-
|
741 |
-
// set native <video>
|
742 |
-
t.$media
|
743 |
-
.width('100%')
|
744 |
-
.height('100%');
|
745 |
-
|
746 |
-
// set shims
|
747 |
-
t.container.find('object, embed, iframe')
|
748 |
-
.width('100%')
|
749 |
-
.height('100%');
|
750 |
-
|
751 |
-
// if shim is ready, send the size to the embeded plugin
|
752 |
-
if (t.media.setVideoSize)
|
753 |
-
t.media.setVideoSize(parentWidth, newHeight);
|
754 |
-
|
755 |
-
// set the layers
|
756 |
-
t.layers.children('.mejs-layer')
|
757 |
-
.width('100%')
|
758 |
-
.height('100%');
|
759 |
-
|
760 |
-
|
761 |
-
} else {
|
762 |
-
|
763 |
-
t.container
|
764 |
-
.width(t.width)
|
765 |
-
.height(t.height);
|
766 |
-
|
767 |
-
t.layers.children('.mejs-layer')
|
768 |
-
.width(t.width)
|
769 |
-
.height(t.height);
|
770 |
-
|
771 |
-
}
|
772 |
-
},
|
773 |
-
|
774 |
-
setControlsSize: function() {
|
775 |
-
var t = this,
|
776 |
-
usedWidth = 0,
|
777 |
-
railWidth = 0,
|
778 |
-
rail = t.controls.find('.mejs-time-rail'),
|
779 |
-
total = t.controls.find('.mejs-time-total'),
|
780 |
-
current = t.controls.find('.mejs-time-current'),
|
781 |
-
loaded = t.controls.find('.mejs-time-loaded'),
|
782 |
-
others = rail.siblings();
|
783 |
-
|
784 |
-
|
785 |
-
// allow the size to come from custom CSS
|
786 |
-
if (t.options && !t.options.autosizeProgress) {
|
787 |
-
// Also, frontends devs can be more flexible
|
788 |
-
// due the opportunity of absolute positioning.
|
789 |
-
railWidth = parseInt(rail.css('width'));
|
790 |
-
}
|
791 |
-
|
792 |
-
// attempt to autosize
|
793 |
-
if (railWidth === 0 || !railWidth) {
|
794 |
-
|
795 |
-
// find the size of all the other controls besides the rail
|
796 |
-
others.each(function() {
|
797 |
-
if ($(this).css('position') != 'absolute') {
|
798 |
-
usedWidth += $(this).outerWidth(true);
|
799 |
-
}
|
800 |
-
});
|
801 |
-
|
802 |
-
// fit the rail into the remaining space
|
803 |
-
railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
|
804 |
-
}
|
805 |
-
|
806 |
-
// outer area
|
807 |
-
rail.width(railWidth);
|
808 |
-
// dark space
|
809 |
-
total.width(railWidth - (total.outerWidth(true) - total.width()));
|
810 |
-
|
811 |
-
if (t.setProgressRail)
|
812 |
-
t.setProgressRail();
|
813 |
-
if (t.setCurrentRail)
|
814 |
-
t.setCurrentRail();
|
815 |
-
},
|
816 |
-
|
817 |
-
|
818 |
-
buildposter: function(player, controls, layers, media) {
|
819 |
-
var t = this,
|
820 |
-
poster =
|
821 |
-
$('<div class="mejs-poster mejs-layer">' +
|
822 |
-
'</div>')
|
823 |
-
.appendTo(layers),
|
824 |
-
posterUrl = player.$media.attr('poster');
|
825 |
-
|
826 |
-
// prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
|
827 |
-
if (player.options.poster !== '') {
|
828 |
-
posterUrl = player.options.poster;
|
829 |
-
}
|
830 |
-
|
831 |
-
// second, try the real poster
|
832 |
-
if (posterUrl !== '' && posterUrl != null) {
|
833 |
-
t.setPoster(posterUrl);
|
834 |
-
} else {
|
835 |
-
poster.hide();
|
836 |
-
}
|
837 |
-
|
838 |
-
media.addEventListener('play',function() {
|
839 |
-
poster.hide();
|
840 |
-
}, false);
|
841 |
-
},
|
842 |
-
|
843 |
-
setPoster: function(url) {
|
844 |
-
var t = this,
|
845 |
-
posterDiv = t.container.find('.mejs-poster'),
|
846 |
-
posterImg = posterDiv.find('img');
|
847 |
-
|
848 |
-
if (posterImg.length == 0) {
|
849 |
-
posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
|
850 |
-
}
|
851 |
-
|
852 |
-
posterImg.attr('src', url);
|
853 |
-
},
|
854 |
-
|
855 |
-
buildoverlays: function(player, controls, layers, media) {
|
856 |
-
if (!player.isVideo)
|
857 |
-
return;
|
858 |
-
|
859 |
-
var
|
860 |
-
loading =
|
861 |
-
$('<div class="mejs-overlay mejs-layer">'+
|
862 |
-
'<div class="mejs-overlay-loading"><span></span></div>'+
|
863 |
-
'</div>')
|
864 |
-
.hide() // start out hidden
|
865 |
-
.appendTo(layers),
|
866 |
-
error =
|
867 |
-
$('<div class="mejs-overlay mejs-layer">'+
|
868 |
-
'<div class="mejs-overlay-error"></div>'+
|
869 |
-
'</div>')
|
870 |
-
.hide() // start out hidden
|
871 |
-
.appendTo(layers),
|
872 |
-
// this needs to come last so it's on top
|
873 |
-
bigPlay =
|
874 |
-
$('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
|
875 |
-
'<div class="mejs-overlay-button"></div>'+
|
876 |
-
'</div>')
|
877 |
-
.appendTo(layers)
|
878 |
-
.click(function() {
|
879 |
-
if (media.paused) {
|
880 |
-
media.play();
|
881 |
-
} else {
|
882 |
-
media.pause();
|
883 |
-
}
|
884 |
-
});
|
885 |
-
|
886 |
-
/*
|
887 |
-
if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
|
888 |
-
bigPlay.remove();
|
889 |
-
loading.remove();
|
890 |
-
}
|
891 |
-
*/
|
892 |
-
|
893 |
-
|
894 |
-
// show/hide big play button
|
895 |
-
media.addEventListener('play',function() {
|
896 |
-
bigPlay.hide();
|
897 |
-
loading.hide();
|
898 |
-
controls.find('.mejs-time-buffering').hide();
|
899 |
-
error.hide();
|
900 |
-
}, false);
|
901 |
-
|
902 |
-
media.addEventListener('playing', function() {
|
903 |
-
bigPlay.hide();
|
904 |
-
loading.hide();
|
905 |
-
controls.find('.mejs-time-buffering').hide();
|
906 |
-
error.hide();
|
907 |
-
}, false);
|
908 |
-
|
909 |
-
media.addEventListener('seeking', function() {
|
910 |
-
loading.show();
|
911 |
-
controls.find('.mejs-time-buffering').show();
|
912 |
-
}, false);
|
913 |
-
|
914 |
-
media.addEventListener('seeked', function() {
|
915 |
-
loading.hide();
|
916 |
-
controls.find('.mejs-time-buffering').hide();
|
917 |
-
}, false);
|
918 |
-
|
919 |
-
media.addEventListener('pause',function() {
|
920 |
-
if (!mejs.MediaFeatures.isiPhone) {
|
921 |
-
bigPlay.show();
|
922 |
-
}
|
923 |
-
}, false);
|
924 |
-
|
925 |
-
media.addEventListener('waiting', function() {
|
926 |
-
loading.show();
|
927 |
-
controls.find('.mejs-time-buffering').show();
|
928 |
-
}, false);
|
929 |
-
|
930 |
-
|
931 |
-
// show/hide loading
|
932 |
-
media.addEventListener('loadeddata',function() {
|
933 |
-
// for some reason Chrome is firing this event
|
934 |
-
//if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
|
935 |
-
// return;
|
936 |
-
|
937 |
-
loading.show();
|
938 |
-
controls.find('.mejs-time-buffering').show();
|
939 |
-
}, false);
|
940 |
-
media.addEventListener('canplay',function() {
|
941 |
-
loading.hide();
|
942 |
-
controls.find('.mejs-time-buffering').hide();
|
943 |
-
}, false);
|
944 |
-
|
945 |
-
// error handling
|
946 |
-
media.addEventListener('error',function() {
|
947 |
-
loading.hide();
|
948 |
-
controls.find('.mejs-time-buffering').hide();
|
949 |
-
error.show();
|
950 |
-
error.find('mejs-overlay-error').html("Error loading this resource");
|
951 |
-
}, false);
|
952 |
-
},
|
953 |
-
|
954 |
-
buildkeyboard: function(player, controls, layers, media) {
|
955 |
-
|
956 |
-
var t = this;
|
957 |
-
|
958 |
-
// listen for key presses
|
959 |
-
$(document).keydown(function(e) {
|
960 |
-
|
961 |
-
if (player.hasFocus && player.options.enableKeyboard) {
|
962 |
-
|
963 |
-
// find a matching key
|
964 |
-
for (var i=0, il=player.options.keyActions.length; i<il; i++) {
|
965 |
-
var keyAction = player.options.keyActions[i];
|
966 |
-
|
967 |
-
for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
|
968 |
-
if (e.keyCode == keyAction.keys[j]) {
|
969 |
-
e.preventDefault();
|
970 |
-
keyAction.action(player, media);
|
971 |
-
return false;
|
972 |
-
}
|
973 |
-
}
|
974 |
-
}
|
975 |
-
}
|
976 |
-
|
977 |
-
return true;
|
978 |
-
});
|
979 |
-
|
980 |
-
// check if someone clicked outside a player region, then kill its focus
|
981 |
-
$(document).click(function(event) {
|
982 |
-
if ($(event.target).closest('.mejs-container').length == 0) {
|
983 |
-
player.hasFocus = false;
|
984 |
-
}
|
985 |
-
});
|
986 |
-
|
987 |
-
},
|
988 |
-
|
989 |
-
findTracks: function() {
|
990 |
-
var t = this,
|
991 |
-
tracktags = t.$media.find('track');
|
992 |
-
|
993 |
-
// store for use by plugins
|
994 |
-
t.tracks = [];
|
995 |
-
tracktags.each(function(index, track) {
|
996 |
-
|
997 |
-
track = $(track);
|
998 |
-
|
999 |
-
t.tracks.push({
|
1000 |
-
srclang: track.attr('srclang').toLowerCase(),
|
1001 |
-
src: track.attr('src'),
|
1002 |
-
kind: track.attr('kind'),
|
1003 |
-
label: track.attr('label') || '',
|
1004 |
-
entries: [],
|
1005 |
-
isLoaded: false
|
1006 |
-
});
|
1007 |
-
});
|
1008 |
-
},
|
1009 |
-
changeSkin: function(className) {
|
1010 |
-
this.container[0].className = 'mejs-container ' + className;
|
1011 |
-
this.setPlayerSize(this.width, this.height);
|
1012 |
-
this.setControlsSize();
|
1013 |
-
},
|
1014 |
-
play: function() {
|
1015 |
-
this.media.play();
|
1016 |
-
},
|
1017 |
-
pause: function() {
|
1018 |
-
this.media.pause();
|
1019 |
-
},
|
1020 |
-
load: function() {
|
1021 |
-
this.media.load();
|
1022 |
-
},
|
1023 |
-
setMuted: function(muted) {
|
1024 |
-
this.media.setMuted(muted);
|
1025 |
-
},
|
1026 |
-
setCurrentTime: function(time) {
|
1027 |
-
this.media.setCurrentTime(time);
|
1028 |
-
},
|
1029 |
-
getCurrentTime: function() {
|
1030 |
-
return this.media.currentTime;
|
1031 |
-
},
|
1032 |
-
setVolume: function(volume) {
|
1033 |
-
this.media.setVolume(volume);
|
1034 |
-
},
|
1035 |
-
getVolume: function() {
|
1036 |
-
return this.media.volume;
|
1037 |
-
},
|
1038 |
-
setSrc: function(src) {
|
1039 |
-
this.media.setSrc(src);
|
1040 |
-
},
|
1041 |
-
remove: function() {
|
1042 |
-
var t = this;
|
1043 |
-
|
1044 |
-
if (t.media.pluginType == 'flash') {
|
1045 |
-
t.media.remove();
|
1046 |
-
} else if (t.media.pluginType == 'native') {
|
1047 |
-
t.media.prop('controls', true);
|
1048 |
-
}
|
1049 |
-
|
1050 |
-
// grab video and put it back in place
|
1051 |
-
if (!t.isDynamic) {
|
1052 |
-
t.$node.insertBefore(t.container)
|
1053 |
-
}
|
1054 |
-
|
1055 |
-
t.container.remove();
|
1056 |
-
}
|
1057 |
-
};
|
1058 |
-
|
1059 |
-
// turn into jQuery plugin
|
1060 |
-
if (typeof jQuery != 'undefined') {
|
1061 |
-
jQuery.fn.mediaelementplayer = function (options) {
|
1062 |
-
return this.each(function () {
|
1063 |
-
new mejs.MediaElementPlayer(this, options);
|
1064 |
-
});
|
1065 |
-
};
|
1066 |
-
}
|
1067 |
-
|
1068 |
-
$(document).ready(function() {
|
1069 |
-
// auto enable using JSON attribute
|
1070 |
-
$('.mejs-player').mediaelementplayer();
|
1071 |
-
});
|
1072 |
-
|
1073 |
-
// push out to window
|
1074 |
-
window.MediaElementPlayer = mejs.MediaElementPlayer;
|
1075 |
-
|
1076 |
-
})(mejs.$);
|
1077 |
|
1078 |
(function($) {
|
1079 |
|
@@ -1320,86 +1320,86 @@ if (typeof jQuery != 'undefined') {
|
|
1320 |
}
|
1321 |
});
|
1322 |
})(mejs.$);
|
1323 |
-
(function($) {
|
1324 |
-
|
1325 |
-
// options
|
1326 |
-
$.extend(mejs.MepDefaults, {
|
1327 |
-
duration: -1,
|
1328 |
-
timeAndDurationSeparator: ' <span> | </span> '
|
1329 |
-
});
|
1330 |
-
|
1331 |
-
|
1332 |
-
// current and duration 00:00 / 00:00
|
1333 |
-
$.extend(MediaElementPlayer.prototype, {
|
1334 |
-
buildcurrent: function(player, controls, layers, media) {
|
1335 |
-
var t = this;
|
1336 |
-
|
1337 |
-
$('<div class="mejs-time">'+
|
1338 |
-
'<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
|
1339 |
-
+ (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
|
1340 |
-
'</div>')
|
1341 |
-
.appendTo(controls);
|
1342 |
-
|
1343 |
-
t.currenttime = t.controls.find('.mejs-currenttime');
|
1344 |
-
|
1345 |
-
media.addEventListener('timeupdate',function() {
|
1346 |
-
player.updateCurrent();
|
1347 |
-
}, false);
|
1348 |
-
},
|
1349 |
-
|
1350 |
-
|
1351 |
-
buildduration: function(player, controls, layers, media) {
|
1352 |
-
var t = this;
|
1353 |
-
|
1354 |
-
if (controls.children().last().find('.mejs-currenttime').length > 0) {
|
1355 |
-
$(t.options.timeAndDurationSeparator +
|
1356 |
-
'<span class="mejs-duration">' +
|
1357 |
-
(t.options.duration > 0 ?
|
1358 |
-
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1359 |
-
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1360 |
-
) +
|
1361 |
-
'</span>')
|
1362 |
-
.appendTo(controls.find('.mejs-time'));
|
1363 |
-
} else {
|
1364 |
-
|
1365 |
-
// add class to current time
|
1366 |
-
controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
|
1367 |
-
|
1368 |
-
$('<div class="mejs-time mejs-duration-container">'+
|
1369 |
-
'<span class="mejs-duration">' +
|
1370 |
-
(t.options.duration > 0 ?
|
1371 |
-
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1372 |
-
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1373 |
-
) +
|
1374 |
-
'</span>' +
|
1375 |
-
'</div>')
|
1376 |
-
.appendTo(controls);
|
1377 |
-
}
|
1378 |
-
|
1379 |
-
t.durationD = t.controls.find('.mejs-duration');
|
1380 |
-
|
1381 |
-
media.addEventListener('timeupdate',function() {
|
1382 |
-
player.updateDuration();
|
1383 |
-
}, false);
|
1384 |
-
},
|
1385 |
-
|
1386 |
-
updateCurrent: function() {
|
1387 |
-
var t = this;
|
1388 |
-
|
1389 |
-
if (t.currenttime) {
|
1390 |
-
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
1391 |
-
}
|
1392 |
-
},
|
1393 |
-
|
1394 |
-
updateDuration: function() {
|
1395 |
-
var t = this;
|
1396 |
-
|
1397 |
-
if (t.media.duration && t.durationD) {
|
1398 |
-
t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
1399 |
-
}
|
1400 |
-
}
|
1401 |
-
});
|
1402 |
-
|
1403 |
})(mejs.$);
|
1404 |
(function($) {
|
1405 |
|
@@ -1623,445 +1623,445 @@ if (typeof jQuery != 'undefined') {
|
|
1623 |
|
1624 |
})(mejs.$);
|
1625 |
|
1626 |
-
(function($) {
|
1627 |
-
|
1628 |
-
$.extend(mejs.MepDefaults, {
|
1629 |
-
usePluginFullScreen: true,
|
1630 |
-
newWindowCallback: function() { return '';},
|
1631 |
-
fullscreenText: 'Fullscreen'
|
1632 |
-
});
|
1633 |
-
|
1634 |
-
$.extend(MediaElementPlayer.prototype, {
|
1635 |
-
|
1636 |
-
isFullScreen: false,
|
1637 |
-
|
1638 |
-
isNativeFullScreen: false,
|
1639 |
-
|
1640 |
-
docStyleOverflow: null,
|
1641 |
-
|
1642 |
-
isInIframe: false,
|
1643 |
-
|
1644 |
-
buildfullscreen: function(player, controls, layers, media) {
|
1645 |
-
|
1646 |
-
if (!player.isVideo)
|
1647 |
-
return;
|
1648 |
-
|
1649 |
-
player.isInIframe = (window.location != window.parent.location);
|
1650 |
-
|
1651 |
-
// native events
|
1652 |
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1653 |
-
|
1654 |
-
// chrome doesn't alays fire this in an iframe
|
1655 |
-
var target = null;
|
1656 |
-
|
1657 |
-
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
|
1658 |
-
target = $(document);
|
1659 |
-
} else {
|
1660 |
-
target = player.container;
|
1661 |
-
}
|
1662 |
-
|
1663 |
-
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
|
1664 |
-
//player.container.bind('webkitfullscreenchange', function(e) {
|
1665 |
-
|
1666 |
-
|
1667 |
-
if (mejs.MediaFeatures.isFullScreen()) {
|
1668 |
-
player.isNativeFullScreen = true;
|
1669 |
-
// reset the controls once we are fully in full screen
|
1670 |
-
player.setControlsSize();
|
1671 |
-
} else {
|
1672 |
-
player.isNativeFullScreen = false;
|
1673 |
-
// when a user presses ESC
|
1674 |
-
// make sure to put the player back into place
|
1675 |
-
player.exitFullScreen();
|
1676 |
-
}
|
1677 |
-
});
|
1678 |
-
}
|
1679 |
-
|
1680 |
-
var t = this,
|
1681 |
-
normalHeight = 0,
|
1682 |
-
normalWidth = 0,
|
1683 |
-
container = player.container,
|
1684 |
-
fullscreenBtn =
|
1685 |
-
$('<div class="mejs-button mejs-fullscreen-button">' +
|
1686 |
-
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
|
1687 |
-
'</div>')
|
1688 |
-
.appendTo(controls);
|
1689 |
-
|
1690 |
-
if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
|
1691 |
-
|
1692 |
-
fullscreenBtn.click(function() {
|
1693 |
-
var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
|
1694 |
-
|
1695 |
-
if (isFullScreen) {
|
1696 |
-
player.exitFullScreen();
|
1697 |
-
} else {
|
1698 |
-
player.enterFullScreen();
|
1699 |
-
}
|
1700 |
-
});
|
1701 |
-
|
1702 |
-
} else {
|
1703 |
-
|
1704 |
-
var hideTimeout = null,
|
1705 |
-
supportsPointerEvents = (function() {
|
1706 |
-
// TAKEN FROM MODERNIZR
|
1707 |
-
var element = document.createElement('x'),
|
1708 |
-
documentElement = document.documentElement,
|
1709 |
-
getComputedStyle = window.getComputedStyle,
|
1710 |
-
supports;
|
1711 |
-
if(!('pointerEvents' in element.style)){
|
1712 |
-
return false;
|
1713 |
-
}
|
1714 |
-
element.style.pointerEvents = 'auto';
|
1715 |
-
element.style.pointerEvents = 'x';
|
1716 |
-
documentElement.appendChild(element);
|
1717 |
-
supports = getComputedStyle &&
|
1718 |
-
getComputedStyle(element, '').pointerEvents === 'auto';
|
1719 |
-
documentElement.removeChild(element);
|
1720 |
-
return !!supports;
|
1721 |
-
})();
|
1722 |
-
|
1723 |
-
console.log('supportsPointerEvents', supportsPointerEvents);
|
1724 |
-
|
1725 |
-
if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
|
1726 |
-
|
1727 |
-
// allows clicking through the fullscreen button and controls down directly to Flash
|
1728 |
-
|
1729 |
-
/*
|
1730 |
-
When a user puts his mouse over the fullscreen button, the controls are disabled
|
1731 |
-
So we put a div over the video and another one on iether side of the fullscreen button
|
1732 |
-
that caputre mouse movement
|
1733 |
-
and restore the controls once the mouse moves outside of the fullscreen button
|
1734 |
-
*/
|
1735 |
-
|
1736 |
-
var fullscreenIsDisabled = false,
|
1737 |
-
restoreControls = function() {
|
1738 |
-
if (fullscreenIsDisabled) {
|
1739 |
-
// hide the hovers
|
1740 |
-
videoHoverDiv.hide();
|
1741 |
-
controlsLeftHoverDiv.hide();
|
1742 |
-
controlsRightHoverDiv.hide();
|
1743 |
-
|
1744 |
-
// restore the control bar
|
1745 |
-
fullscreenBtn.css('pointer-events', '');
|
1746 |
-
t.controls.css('pointer-events', '');
|
1747 |
-
|
1748 |
-
// store for later
|
1749 |
-
fullscreenIsDisabled = false;
|
1750 |
-
}
|
1751 |
-
},
|
1752 |
-
videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1753 |
-
controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1754 |
-
controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1755 |
-
positionHoverDivs = function() {
|
1756 |
-
var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
|
1757 |
-
videoHoverDiv.css(style);
|
1758 |
-
controlsLeftHoverDiv.css(style);
|
1759 |
-
controlsRightHoverDiv.css(style);
|
1760 |
-
|
1761 |
-
// over video, but not controls
|
1762 |
-
videoHoverDiv
|
1763 |
-
.width( t.container.width() )
|
1764 |
-
.height( t.container.height() - t.controls.height() );
|
1765 |
-
|
1766 |
-
// over controls, but not the fullscreen button
|
1767 |
-
var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
|
1768 |
-
fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
|
1769 |
-
|
1770 |
-
controlsLeftHoverDiv
|
1771 |
-
.width( fullScreenBtnOffset )
|
1772 |
-
.height( t.controls.height() )
|
1773 |
-
.css({top: t.container.height() - t.controls.height()});
|
1774 |
-
|
1775 |
-
// after the fullscreen button
|
1776 |
-
controlsRightHoverDiv
|
1777 |
-
.width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
|
1778 |
-
.height( t.controls.height() )
|
1779 |
-
.css({top: t.container.height() - t.controls.height(),
|
1780 |
-
left: fullScreenBtnOffset + fullScreenBtnWidth});
|
1781 |
-
};
|
1782 |
-
|
1783 |
-
$(document).resize(function() {
|
1784 |
-
positionHoverDivs();
|
1785 |
-
});
|
1786 |
-
|
1787 |
-
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
|
1788 |
-
fullscreenBtn
|
1789 |
-
.mouseover(function() {
|
1790 |
-
|
1791 |
-
if (!t.isFullScreen) {
|
1792 |
-
|
1793 |
-
var buttonPos = fullscreenBtn.offset(),
|
1794 |
-
containerPos = player.container.offset();
|
1795 |
-
|
1796 |
-
// move the button in Flash into place
|
1797 |
-
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
|
1798 |
-
|
1799 |
-
// allows click through
|
1800 |
-
fullscreenBtn.css('pointer-events', 'none');
|
1801 |
-
t.controls.css('pointer-events', 'none');
|
1802 |
-
|
1803 |
-
// show the divs that will restore things
|
1804 |
-
videoHoverDiv.show();
|
1805 |
-
controlsRightHoverDiv.show();
|
1806 |
-
controlsLeftHoverDiv.show();
|
1807 |
-
positionHoverDivs();
|
1808 |
-
|
1809 |
-
fullscreenIsDisabled = true;
|
1810 |
-
}
|
1811 |
-
|
1812 |
-
});
|
1813 |
-
|
1814 |
-
// restore controls anytime the user enters or leaves fullscreen
|
1815 |
-
media.addEventListener('fullscreenchange', function(e) {
|
1816 |
-
restoreControls();
|
1817 |
-
});
|
1818 |
-
|
1819 |
-
|
1820 |
-
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
|
1821 |
-
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
|
1822 |
-
/*
|
1823 |
-
$(document).mousemove(function(e) {
|
1824 |
-
|
1825 |
-
// if the mouse is anywhere but the fullsceen button, then restore it all
|
1826 |
-
if (fullscreenIsDisabled) {
|
1827 |
-
|
1828 |
-
var fullscreenBtnPos = fullscreenBtn.offset();
|
1829 |
-
|
1830 |
-
|
1831 |
-
if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
|
1832 |
-
e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
|
1833 |
-
) {
|
1834 |
-
|
1835 |
-
fullscreenBtn.css('pointer-events', '');
|
1836 |
-
t.controls.css('pointer-events', '');
|
1837 |
-
|
1838 |
-
fullscreenIsDisabled = false;
|
1839 |
-
}
|
1840 |
-
}
|
1841 |
-
});
|
1842 |
-
*/
|
1843 |
-
|
1844 |
-
|
1845 |
-
} else {
|
1846 |
-
|
1847 |
-
// the hover state will show the fullscreen button in Flash to hover up and click
|
1848 |
-
|
1849 |
-
fullscreenBtn
|
1850 |
-
.mouseover(function() {
|
1851 |
-
|
1852 |
-
if (hideTimeout !== null) {
|
1853 |
-
clearTimeout(hideTimeout);
|
1854 |
-
delete hideTimeout;
|
1855 |
-
}
|
1856 |
-
|
1857 |
-
var buttonPos = fullscreenBtn.offset(),
|
1858 |
-
containerPos = player.container.offset();
|
1859 |
-
|
1860 |
-
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
|
1861 |
-
|
1862 |
-
})
|
1863 |
-
.mouseout(function() {
|
1864 |
-
|
1865 |
-
if (hideTimeout !== null) {
|
1866 |
-
clearTimeout(hideTimeout);
|
1867 |
-
delete hideTimeout;
|
1868 |
-
}
|
1869 |
-
|
1870 |
-
hideTimeout = setTimeout(function() {
|
1871 |
-
media.hideFullscreenButton();
|
1872 |
-
}, 1500);
|
1873 |
-
|
1874 |
-
|
1875 |
-
});
|
1876 |
-
}
|
1877 |
-
}
|
1878 |
-
|
1879 |
-
player.fullscreenBtn = fullscreenBtn;
|
1880 |
-
|
1881 |
-
$(document).bind('keydown',function (e) {
|
1882 |
-
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
|
1883 |
-
player.exitFullScreen();
|
1884 |
-
}
|
1885 |
-
});
|
1886 |
-
|
1887 |
-
},
|
1888 |
-
enterFullScreen: function() {
|
1889 |
-
|
1890 |
-
var t = this;
|
1891 |
-
|
1892 |
-
// firefox+flash can't adjust plugin sizes without resetting :(
|
1893 |
-
if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
|
1894 |
-
//t.media.setFullscreen(true);
|
1895 |
-
//player.isFullScreen = true;
|
1896 |
-
return;
|
1897 |
-
}
|
1898 |
-
|
1899 |
-
// store overflow
|
1900 |
-
docStyleOverflow = document.documentElement.style.overflow;
|
1901 |
-
// set it to not show scroll bars so 100% will work
|
1902 |
-
document.documentElement.style.overflow = 'hidden';
|
1903 |
-
|
1904 |
-
// store sizing
|
1905 |
-
normalHeight = t.container.height();
|
1906 |
-
normalWidth = t.container.width();
|
1907 |
-
|
1908 |
-
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
1909 |
-
if (t.media.pluginType === 'native') {
|
1910 |
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1911 |
-
|
1912 |
-
mejs.MediaFeatures.requestFullScreen(t.container[0]);
|
1913 |
-
//return;
|
1914 |
-
|
1915 |
-
if (t.isInIframe) {
|
1916 |
-
// sometimes exiting from fullscreen doesn't work
|
1917 |
-
// notably in Chrome <iframe>. Fixed in version 17
|
1918 |
-
setTimeout(function checkFullscreen() {
|
1919 |
-
|
1920 |
-
if (t.isNativeFullScreen) {
|
1921 |
-
|
1922 |
-
// check if the video is suddenly not really fullscreen
|
1923 |
-
if ($(window).width() !== screen.width) {
|
1924 |
-
// manually exit
|
1925 |
-
t.exitFullScreen();
|
1926 |
-
} else {
|
1927 |
-
// test again
|
1928 |
-
setTimeout(checkFullscreen, 500);
|
1929 |
-
}
|
1930 |
-
}
|
1931 |
-
|
1932 |
-
|
1933 |
-
}, 500);
|
1934 |
-
}
|
1935 |
-
|
1936 |
-
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
1937 |
-
t.media.webkitEnterFullscreen();
|
1938 |
-
return;
|
1939 |
-
}
|
1940 |
-
}
|
1941 |
-
|
1942 |
-
// check for iframe launch
|
1943 |
-
if (t.isInIframe) {
|
1944 |
-
var url = t.options.newWindowCallback(this);
|
1945 |
-
|
1946 |
-
|
1947 |
-
if (url !== '') {
|
1948 |
-
|
1949 |
-
// launch immediately
|
1950 |
-
if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1951 |
-
t.pause();
|
1952 |
-
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1953 |
-
return;
|
1954 |
-
} else {
|
1955 |
-
setTimeout(function() {
|
1956 |
-
if (!t.isNativeFullScreen) {
|
1957 |
-
t.pause();
|
1958 |
-
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1959 |
-
}
|
1960 |
-
}, 250);
|
1961 |
-
}
|
1962 |
-
}
|
1963 |
-
|
1964 |
-
}
|
1965 |
-
|
1966 |
-
// full window code
|
1967 |
-
|
1968 |
-
|
1969 |
-
|
1970 |
-
// make full size
|
1971 |
-
t.container
|
1972 |
-
.addClass('mejs-container-fullscreen')
|
1973 |
-
.width('100%')
|
1974 |
-
.height('100%');
|
1975 |
-
//.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
|
1976 |
-
|
1977 |
-
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
|
1978 |
-
// Actually, it seems to be needed for IE8, too
|
1979 |
-
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1980 |
-
setTimeout(function() {
|
1981 |
-
t.container.css({width: '100%', height: '100%'});
|
1982 |
-
t.setControlsSize();
|
1983 |
-
}, 500);
|
1984 |
-
//}
|
1985 |
-
|
1986 |
-
if (t.pluginType === 'native') {
|
1987 |
-
t.$media
|
1988 |
-
.width('100%')
|
1989 |
-
.height('100%');
|
1990 |
-
} else {
|
1991 |
-
t.container.find('object, embed, iframe')
|
1992 |
-
.width('100%')
|
1993 |
-
.height('100%');
|
1994 |
-
|
1995 |
-
//if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1996 |
-
t.media.setVideoSize($(window).width(),$(window).height());
|
1997 |
-
//}
|
1998 |
-
}
|
1999 |
-
|
2000 |
-
t.layers.children('div')
|
2001 |
-
.width('100%')
|
2002 |
-
.height('100%');
|
2003 |
-
|
2004 |
-
if (t.fullscreenBtn) {
|
2005 |
-
t.fullscreenBtn
|
2006 |
-
.removeClass('mejs-fullscreen')
|
2007 |
-
.addClass('mejs-unfullscreen');
|
2008 |
-
}
|
2009 |
-
|
2010 |
-
t.setControlsSize();
|
2011 |
-
t.isFullScreen = true;
|
2012 |
-
},
|
2013 |
-
|
2014 |
-
exitFullScreen: function() {
|
2015 |
-
|
2016 |
-
var t = this;
|
2017 |
-
|
2018 |
-
// firefox can't adjust plugins
|
2019 |
-
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
|
2020 |
-
t.media.setFullscreen(false);
|
2021 |
-
//player.isFullScreen = false;
|
2022 |
-
return;
|
2023 |
-
}
|
2024 |
-
|
2025 |
-
// come outo of native fullscreen
|
2026 |
-
if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
|
2027 |
-
mejs.MediaFeatures.cancelFullScreen();
|
2028 |
-
}
|
2029 |
-
|
2030 |
-
// restore scroll bars to document
|
2031 |
-
document.documentElement.style.overflow = docStyleOverflow;
|
2032 |
-
|
2033 |
-
t.container
|
2034 |
-
.removeClass('mejs-container-fullscreen')
|
2035 |
-
.width(normalWidth)
|
2036 |
-
.height(normalHeight);
|
2037 |
-
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
2038 |
-
|
2039 |
-
if (t.pluginType === 'native') {
|
2040 |
-
t.$media
|
2041 |
-
.width(normalWidth)
|
2042 |
-
.height(normalHeight);
|
2043 |
-
} else {
|
2044 |
-
t.container.find('object embed')
|
2045 |
-
.width(normalWidth)
|
2046 |
-
.height(normalHeight);
|
2047 |
-
|
2048 |
-
t.media.setVideoSize(normalWidth, normalHeight);
|
2049 |
-
}
|
2050 |
-
|
2051 |
-
t.layers.children('div')
|
2052 |
-
.width(normalWidth)
|
2053 |
-
.height(normalHeight);
|
2054 |
-
|
2055 |
-
t.fullscreenBtn
|
2056 |
-
.removeClass('mejs-unfullscreen')
|
2057 |
-
.addClass('mejs-fullscreen');
|
2058 |
-
|
2059 |
-
t.setControlsSize();
|
2060 |
-
t.isFullScreen = false;
|
2061 |
-
}
|
2062 |
-
});
|
2063 |
-
|
2064 |
-
})(mejs.$);
|
2065 |
|
2066 |
(function($) {
|
2067 |
|
@@ -2548,196 +2548,196 @@ if (typeof jQuery != 'undefined') {
|
|
2548 |
|
2549 |
})(mejs.$);
|
2550 |
|
2551 |
-
/*
|
2552 |
-
* ContextMenu Plugin
|
2553 |
-
*
|
2554 |
-
*
|
2555 |
-
*/
|
2556 |
-
|
2557 |
-
(function($) {
|
2558 |
-
|
2559 |
-
$.extend(mejs.MepDefaults,
|
2560 |
-
{ 'contextMenuItems': [
|
2561 |
-
// demo of a fullscreen option
|
2562 |
-
{
|
2563 |
-
render: function(player) {
|
2564 |
-
|
2565 |
-
// check for fullscreen plugin
|
2566 |
-
if (typeof player.enterFullScreen == 'undefined')
|
2567 |
-
return null;
|
2568 |
-
|
2569 |
-
if (player.isFullScreen) {
|
2570 |
-
return "Turn off Fullscreen";
|
2571 |
-
} else {
|
2572 |
-
return "Go Fullscreen";
|
2573 |
-
}
|
2574 |
-
},
|
2575 |
-
click: function(player) {
|
2576 |
-
if (player.isFullScreen) {
|
2577 |
-
player.exitFullScreen();
|
2578 |
-
} else {
|
2579 |
-
player.enterFullScreen();
|
2580 |
-
}
|
2581 |
-
}
|
2582 |
-
}
|
2583 |
-
,
|
2584 |
-
// demo of a mute/unmute button
|
2585 |
-
{
|
2586 |
-
render: function(player) {
|
2587 |
-
if (player.media.muted) {
|
2588 |
-
return "Unmute";
|
2589 |
-
} else {
|
2590 |
-
return "Mute";
|
2591 |
-
}
|
2592 |
-
},
|
2593 |
-
click: function(player) {
|
2594 |
-
if (player.media.muted) {
|
2595 |
-
player.setMuted(false);
|
2596 |
-
} else {
|
2597 |
-
player.setMuted(true);
|
2598 |
-
}
|
2599 |
-
}
|
2600 |
-
},
|
2601 |
-
// separator
|
2602 |
-
{
|
2603 |
-
isSeparator: true
|
2604 |
-
}
|
2605 |
-
,
|
2606 |
-
// demo of simple download video
|
2607 |
-
{
|
2608 |
-
render: function(player) {
|
2609 |
-
return "Download Video";
|
2610 |
-
},
|
2611 |
-
click: function(player) {
|
2612 |
-
window.location.href = player.media.currentSrc;
|
2613 |
-
}
|
2614 |
-
}
|
2615 |
-
]}
|
2616 |
-
);
|
2617 |
-
|
2618 |
-
|
2619 |
-
$.extend(MediaElementPlayer.prototype, {
|
2620 |
-
buildcontextmenu: function(player, controls, layers, media) {
|
2621 |
-
|
2622 |
-
// create context menu
|
2623 |
-
player.contextMenu = $('<div class="mejs-contextmenu"></div>')
|
2624 |
-
.appendTo($('body'))
|
2625 |
-
.hide();
|
2626 |
-
|
2627 |
-
// create events for showing context menu
|
2628 |
-
player.container.bind('contextmenu', function(e) {
|
2629 |
-
if (player.isContextMenuEnabled) {
|
2630 |
-
e.preventDefault();
|
2631 |
-
player.renderContextMenu(e.clientX-1, e.clientY-1);
|
2632 |
-
return false;
|
2633 |
-
}
|
2634 |
-
});
|
2635 |
-
player.container.bind('click', function() {
|
2636 |
-
player.contextMenu.hide();
|
2637 |
-
});
|
2638 |
-
player.contextMenu.bind('mouseleave', function() {
|
2639 |
-
|
2640 |
-
//console.log('context hover out');
|
2641 |
-
player.startContextMenuTimer();
|
2642 |
-
|
2643 |
-
});
|
2644 |
-
},
|
2645 |
-
|
2646 |
-
isContextMenuEnabled: true,
|
2647 |
-
enableContextMenu: function() {
|
2648 |
-
this.isContextMenuEnabled = true;
|
2649 |
-
},
|
2650 |
-
disableContextMenu: function() {
|
2651 |
-
this.isContextMenuEnabled = false;
|
2652 |
-
},
|
2653 |
-
|
2654 |
-
contextMenuTimeout: null,
|
2655 |
-
startContextMenuTimer: function() {
|
2656 |
-
//console.log('startContextMenuTimer');
|
2657 |
-
|
2658 |
-
var t = this;
|
2659 |
-
|
2660 |
-
t.killContextMenuTimer();
|
2661 |
-
|
2662 |
-
t.contextMenuTimer = setTimeout(function() {
|
2663 |
-
t.hideContextMenu();
|
2664 |
-
t.killContextMenuTimer();
|
2665 |
-
}, 750);
|
2666 |
-
},
|
2667 |
-
killContextMenuTimer: function() {
|
2668 |
-
var timer = this.contextMenuTimer;
|
2669 |
-
|
2670 |
-
//console.log('killContextMenuTimer', timer);
|
2671 |
-
|
2672 |
-
if (timer != null) {
|
2673 |
-
clearTimeout(timer);
|
2674 |
-
delete timer;
|
2675 |
-
timer = null;
|
2676 |
-
}
|
2677 |
-
},
|
2678 |
-
|
2679 |
-
hideContextMenu: function() {
|
2680 |
-
this.contextMenu.hide();
|
2681 |
-
},
|
2682 |
-
|
2683 |
-
renderContextMenu: function(x,y) {
|
2684 |
-
|
2685 |
-
// alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
|
2686 |
-
var t = this,
|
2687 |
-
html = '',
|
2688 |
-
items = t.options.contextMenuItems;
|
2689 |
-
|
2690 |
-
for (var i=0, il=items.length; i<il; i++) {
|
2691 |
-
|
2692 |
-
if (items[i].isSeparator) {
|
2693 |
-
html += '<div class="mejs-contextmenu-separator"></div>';
|
2694 |
-
} else {
|
2695 |
-
|
2696 |
-
var rendered = items[i].render(t);
|
2697 |
-
|
2698 |
-
// render can return null if the item doesn't need to be used at the moment
|
2699 |
-
if (rendered != null) {
|
2700 |
-
html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
|
2701 |
-
}
|
2702 |
-
}
|
2703 |
-
}
|
2704 |
-
|
2705 |
-
// position and show the context menu
|
2706 |
-
t.contextMenu
|
2707 |
-
.empty()
|
2708 |
-
.append($(html))
|
2709 |
-
.css({top:y, left:x})
|
2710 |
-
.show();
|
2711 |
-
|
2712 |
-
// bind events
|
2713 |
-
t.contextMenu.find('.mejs-contextmenu-item').each(function() {
|
2714 |
-
|
2715 |
-
// which one is this?
|
2716 |
-
var $dom = $(this),
|
2717 |
-
itemIndex = parseInt( $dom.data('itemindex'), 10 ),
|
2718 |
-
item = t.options.contextMenuItems[itemIndex];
|
2719 |
-
|
2720 |
-
// bind extra functionality?
|
2721 |
-
if (typeof item.show != 'undefined')
|
2722 |
-
item.show( $dom , t);
|
2723 |
-
|
2724 |
-
// bind click action
|
2725 |
-
$dom.click(function() {
|
2726 |
-
// perform click action
|
2727 |
-
if (typeof item.click != 'undefined')
|
2728 |
-
item.click(t);
|
2729 |
-
|
2730 |
-
// close
|
2731 |
-
t.contextMenu.hide();
|
2732 |
-
});
|
2733 |
-
});
|
2734 |
-
|
2735 |
-
// stop the controls from hiding
|
2736 |
-
setTimeout(function() {
|
2737 |
-
t.killControlsTimer('rev3');
|
2738 |
-
}, 100);
|
2739 |
-
|
2740 |
-
}
|
2741 |
-
});
|
2742 |
-
|
2743 |
})(mejs.$);
|
14 |
} else if (typeof ender != 'undefined') {
|
15 |
mejs.$ = ender;
|
16 |
}
|
17 |
+
(function ($) {
|
18 |
+
|
19 |
+
// default player values
|
20 |
+
mejs.MepDefaults = {
|
21 |
+
// url to poster (to fix iOS 3.x)
|
22 |
+
poster: '',
|
23 |
+
// default if the <video width> is not specified
|
24 |
+
defaultVideoWidth: 480,
|
25 |
+
// default if the <video height> is not specified
|
26 |
+
defaultVideoHeight: 270,
|
27 |
+
// if set, overrides <video width>
|
28 |
+
videoWidth: -1,
|
29 |
+
// if set, overrides <video height>
|
30 |
+
videoHeight: -1,
|
31 |
+
// default if the user doesn't specify
|
32 |
+
defaultAudioWidth: 400,
|
33 |
+
// default if the user doesn't specify
|
34 |
+
defaultAudioHeight: 30,
|
35 |
+
// width of audio player
|
36 |
+
audioWidth: -1,
|
37 |
+
// height of audio player
|
38 |
+
audioHeight: -1,
|
39 |
+
// initial volume when the player starts (overrided by user cookie)
|
40 |
+
startVolume: 0.8,
|
41 |
+
// useful for <audio> player loops
|
42 |
+
loop: false,
|
43 |
+
// resize to media dimensions
|
44 |
+
enableAutosize: true,
|
45 |
+
// forces the hour marker (##:00:00)
|
46 |
+
alwaysShowHours: false,
|
47 |
+
|
48 |
+
// show framecount in timecode (##:00:00:00)
|
49 |
+
showTimecodeFrameCount: false,
|
50 |
+
// used when showTimecodeFrameCount is set to true
|
51 |
+
framesPerSecond: 25,
|
52 |
+
|
53 |
+
// automatically calculate the width of the progress bar based on the sizes of other elements
|
54 |
+
autosizeProgress : true,
|
55 |
+
// Hide controls when playing and mouse is not over the video
|
56 |
+
alwaysShowControls: false,
|
57 |
+
// force iPad's native controls
|
58 |
+
iPadUseNativeControls: false,
|
59 |
+
// force iPhone's native controls
|
60 |
+
iPhoneUseNativeControls: false,
|
61 |
+
// force Android's native controls
|
62 |
+
AndroidUseNativeControls: false,
|
63 |
+
// features to show
|
64 |
+
features: ['playpause','current','progress','duration','tracks','volume','fullscreen'],
|
65 |
+
// only for dynamic
|
66 |
+
isVideo: true,
|
67 |
+
|
68 |
+
// turns keyboard support on and off for this instance
|
69 |
+
enableKeyboard: true,
|
70 |
+
|
71 |
+
// whenthis player starts, it will pause other players
|
72 |
+
pauseOtherPlayers: true,
|
73 |
+
|
74 |
+
// array of keyboard actions such as play pause
|
75 |
+
keyActions: [
|
76 |
+
{
|
77 |
+
keys: [
|
78 |
+
32, // SPACE
|
79 |
+
179 // GOOGLE play/pause button
|
80 |
+
],
|
81 |
+
action: function(player, media) {
|
82 |
+
if (media.paused || media.ended) {
|
83 |
+
media.play();
|
84 |
+
} else {
|
85 |
+
media.pause();
|
86 |
+
}
|
87 |
+
}
|
88 |
+
},
|
89 |
+
{
|
90 |
+
keys: [38], // UP
|
91 |
+
action: function(player, media) {
|
92 |
+
var newVolume = Math.min(media.volume + 0.1, 1);
|
93 |
+
media.setVolume(newVolume);
|
94 |
+
}
|
95 |
+
},
|
96 |
+
{
|
97 |
+
keys: [40], // DOWN
|
98 |
+
action: function(player, media) {
|
99 |
+
var newVolume = Math.max(media.volume - 0.1, 0);
|
100 |
+
media.setVolume(newVolume);
|
101 |
+
}
|
102 |
+
},
|
103 |
+
{
|
104 |
+
keys: [
|
105 |
+
37, // LEFT
|
106 |
+
227 // Google TV rewind
|
107 |
+
],
|
108 |
+
action: function(player, media) {
|
109 |
+
if (!isNaN(media.duration) && media.duration > 0) {
|
110 |
+
if (player.isVideo) {
|
111 |
+
player.showControls();
|
112 |
+
player.startControlsTimer();
|
113 |
+
}
|
114 |
+
|
115 |
+
// 5%
|
116 |
+
var newTime = Math.max(media.currentTime - (media.duration * 0.05), 0);
|
117 |
+
media.setCurrentTime(newTime);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
},
|
121 |
+
{
|
122 |
+
keys: [
|
123 |
+
39, // RIGHT
|
124 |
+
228 // Google TV forward
|
125 |
+
],
|
126 |
+
action: function(player, media) {
|
127 |
+
if (!isNaN(media.duration) && media.duration > 0) {
|
128 |
+
if (player.isVideo) {
|
129 |
+
player.showControls();
|
130 |
+
player.startControlsTimer();
|
131 |
+
}
|
132 |
+
|
133 |
+
// 5%
|
134 |
+
var newTime = Math.min(media.currentTime + (media.duration * 0.05), media.duration);
|
135 |
+
media.setCurrentTime(newTime);
|
136 |
+
}
|
137 |
+
}
|
138 |
+
},
|
139 |
+
{
|
140 |
+
keys: [70], // f
|
141 |
+
action: function(player, media) {
|
142 |
+
if (typeof player.enterFullScreen != 'undefined') {
|
143 |
+
if (player.isFullScreen) {
|
144 |
+
player.exitFullScreen();
|
145 |
+
} else {
|
146 |
+
player.enterFullScreen();
|
147 |
+
}
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
]
|
152 |
+
};
|
153 |
+
|
154 |
+
mejs.mepIndex = 0;
|
155 |
+
|
156 |
+
mejs.players = [];
|
157 |
+
|
158 |
+
// wraps a MediaElement object in player controls
|
159 |
+
mejs.MediaElementPlayer = function(node, o) {
|
160 |
+
// enforce object, even without "new" (via John Resig)
|
161 |
+
if ( !(this instanceof mejs.MediaElementPlayer) ) {
|
162 |
+
return new mejs.MediaElementPlayer(node, o);
|
163 |
+
}
|
164 |
+
|
165 |
+
var t = this;
|
166 |
+
|
167 |
+
// these will be reset after the MediaElement.success fires
|
168 |
+
t.$media = t.$node = $(node);
|
169 |
+
t.node = t.media = t.$media[0];
|
170 |
+
|
171 |
+
// check for existing player
|
172 |
+
if (typeof t.node.player != 'undefined') {
|
173 |
+
return t.node.player;
|
174 |
+
} else {
|
175 |
+
// attach player to DOM node for reference
|
176 |
+
t.node.player = t;
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
// try to get options from data-mejsoptions
|
181 |
+
if (typeof o == 'undefined') {
|
182 |
+
o = t.$node.data('mejsoptions');
|
183 |
+
}
|
184 |
+
|
185 |
+
// extend default options
|
186 |
+
t.options = $.extend({},mejs.MepDefaults,o);
|
187 |
+
|
188 |
+
// add to player array (for focus events)
|
189 |
+
mejs.players.push(t);
|
190 |
+
|
191 |
+
// start up
|
192 |
+
t.init();
|
193 |
+
|
194 |
+
return t;
|
195 |
+
};
|
196 |
+
|
197 |
+
// actual player
|
198 |
+
mejs.MediaElementPlayer.prototype = {
|
199 |
+
|
200 |
+
hasFocus: false,
|
201 |
+
|
202 |
+
controlsAreVisible: true,
|
203 |
+
|
204 |
+
init: function() {
|
205 |
+
|
206 |
+
var
|
207 |
+
t = this,
|
208 |
+
mf = mejs.MediaFeatures,
|
209 |
+
// options for MediaElement (shim)
|
210 |
+
meOptions = $.extend(true, {}, t.options, {
|
211 |
+
success: function(media, domNode) { t.meReady(media, domNode); },
|
212 |
+
error: function(e) { t.handleError(e);}
|
213 |
+
}),
|
214 |
+
tagName = t.media.tagName.toLowerCase();
|
215 |
+
|
216 |
+
t.isDynamic = (tagName !== 'audio' && tagName !== 'video');
|
217 |
+
|
218 |
+
if (t.isDynamic) {
|
219 |
+
// get video from src or href?
|
220 |
+
t.isVideo = t.options.isVideo;
|
221 |
+
} else {
|
222 |
+
t.isVideo = (tagName !== 'audio' && t.options.isVideo);
|
223 |
+
}
|
224 |
+
|
225 |
+
// use native controls in iPad, iPhone, and Android
|
226 |
+
if ((mf.isiPad && t.options.iPadUseNativeControls) || (mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
227 |
+
|
228 |
+
// add controls and stop
|
229 |
+
t.$media.attr('controls', 'controls');
|
230 |
+
|
231 |
+
// attempt to fix iOS 3 bug
|
232 |
+
//t.$media.removeAttr('poster');
|
233 |
+
// no Issue found on iOS3 -ttroxell
|
234 |
+
|
235 |
+
// override Apple's autoplay override for iPads
|
236 |
+
if (mf.isiPad && t.media.getAttribute('autoplay') !== null) {
|
237 |
+
t.media.load();
|
238 |
+
t.media.play();
|
239 |
+
}
|
240 |
+
|
241 |
+
} else if (mf.isAndroid && t.AndroidUseNativeControls) {
|
242 |
+
|
243 |
+
// leave default player
|
244 |
+
|
245 |
+
} else {
|
246 |
+
|
247 |
+
// DESKTOP: use MediaElementPlayer controls
|
248 |
+
|
249 |
+
// remove native controls
|
250 |
+
t.$media.removeAttr('controls');
|
251 |
+
|
252 |
+
// unique ID
|
253 |
+
t.id = 'mep_' + mejs.mepIndex++;
|
254 |
+
|
255 |
+
// build container
|
256 |
+
t.container =
|
257 |
+
$('<div id="' + t.id + '" class="mejs-container">'+
|
258 |
+
'<div class="mejs-inner">'+
|
259 |
+
'<div class="mejs-mediaelement"></div>'+
|
260 |
+
'<div class="mejs-layers"></div>'+
|
261 |
+
'<div class="mejs-controls"></div>'+
|
262 |
+
'<div class="mejs-clear"></div>'+
|
263 |
+
'</div>' +
|
264 |
+
'</div>')
|
265 |
+
.addClass(t.$media[0].className)
|
266 |
+
.insertBefore(t.$media);
|
267 |
+
|
268 |
+
// add classes for user and content
|
269 |
+
t.container.addClass(
|
270 |
+
(mf.isAndroid ? 'mejs-android ' : '') +
|
271 |
+
(mf.isiOS ? 'mejs-ios ' : '') +
|
272 |
+
(mf.isiPad ? 'mejs-ipad ' : '') +
|
273 |
+
(mf.isiPhone ? 'mejs-iphone ' : '') +
|
274 |
+
(t.isVideo ? 'mejs-video ' : 'mejs-audio ')
|
275 |
+
);
|
276 |
+
|
277 |
+
|
278 |
+
// move the <video/video> tag into the right spot
|
279 |
+
if (mf.isiOS) {
|
280 |
+
|
281 |
+
// sadly, you can't move nodes in iOS, so we have to destroy and recreate it!
|
282 |
+
var $newMedia = t.$media.clone();
|
283 |
+
|
284 |
+
t.container.find('.mejs-mediaelement').append($newMedia);
|
285 |
+
|
286 |
+
t.$media.remove();
|
287 |
+
t.$node = t.$media = $newMedia;
|
288 |
+
t.node = t.media = $newMedia[0]
|
289 |
+
|
290 |
+
} else {
|
291 |
+
|
292 |
+
// normal way of moving it into place (doesn't work on iOS)
|
293 |
+
t.container.find('.mejs-mediaelement').append(t.$media);
|
294 |
+
}
|
295 |
+
|
296 |
+
// find parts
|
297 |
+
t.controls = t.container.find('.mejs-controls');
|
298 |
+
t.layers = t.container.find('.mejs-layers');
|
299 |
+
|
300 |
+
// determine the size
|
301 |
+
|
302 |
+
/* size priority:
|
303 |
+
(1) videoWidth (forced),
|
304 |
+
(2) style="width;height;"
|
305 |
+
(3) width attribute,
|
306 |
+
(4) defaultVideoWidth (for unspecified cases)
|
307 |
+
*/
|
308 |
+
|
309 |
+
var capsTagName = tagName.substring(0,1).toUpperCase() + tagName.substring(1);
|
310 |
+
|
311 |
+
if (t.options[tagName + 'Width'] > 0 || t.options[tagName + 'Width'].toString().indexOf('%') > -1) {
|
312 |
+
t.width = t.options[tagName + 'Width'];
|
313 |
+
} else if (t.media.style.width !== '' && t.media.style.width !== null) {
|
314 |
+
t.width = t.media.style.width;
|
315 |
+
} else if (t.media.getAttribute('width') !== null) {
|
316 |
+
t.width = t.$media.attr('width');
|
317 |
+
} else {
|
318 |
+
t.width = t.options['default' + capsTagName + 'Width'];
|
319 |
+
}
|
320 |
+
|
321 |
+
if (t.options[tagName + 'Height'] > 0 || t.options[tagName + 'Height'].toString().indexOf('%') > -1) {
|
322 |
+
t.height = t.options[tagName + 'Height'];
|
323 |
+
} else if (t.media.style.height !== '' && t.media.style.height !== null) {
|
324 |
+
t.height = t.media.style.height;
|
325 |
+
} else if (t.$media[0].getAttribute('height') !== null) {
|
326 |
+
t.height = t.$media.attr('height');
|
327 |
+
} else {
|
328 |
+
t.height = t.options['default' + capsTagName + 'Height'];
|
329 |
+
}
|
330 |
+
|
331 |
+
// set the size, while we wait for the plugins to load below
|
332 |
+
t.setPlayerSize(t.width, t.height);
|
333 |
+
|
334 |
+
// create MediaElementShim
|
335 |
+
meOptions.pluginWidth = t.height;
|
336 |
+
meOptions.pluginHeight = t.width;
|
337 |
+
}
|
338 |
+
|
339 |
+
|
340 |
+
|
341 |
+
// create MediaElement shim
|
342 |
+
mejs.MediaElement(t.$media[0], meOptions);
|
343 |
+
},
|
344 |
+
|
345 |
+
showControls: function(doAnimation) {
|
346 |
+
var t = this;
|
347 |
+
|
348 |
+
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
349 |
+
|
350 |
+
if (t.controlsAreVisible)
|
351 |
+
return;
|
352 |
+
|
353 |
+
if (doAnimation) {
|
354 |
+
t.controls
|
355 |
+
.css('visibility','visible')
|
356 |
+
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
357 |
+
|
358 |
+
// any additional controls people might add and want to hide
|
359 |
+
t.container.find('.mejs-control')
|
360 |
+
.css('visibility','visible')
|
361 |
+
.stop(true, true).fadeIn(200, function() {t.controlsAreVisible = true;});
|
362 |
+
|
363 |
+
} else {
|
364 |
+
t.controls
|
365 |
+
.css('visibility','visible')
|
366 |
+
.css('display','block');
|
367 |
+
|
368 |
+
// any additional controls people might add and want to hide
|
369 |
+
t.container.find('.mejs-control')
|
370 |
+
.css('visibility','visible')
|
371 |
+
.css('display','block');
|
372 |
+
|
373 |
+
t.controlsAreVisible = true;
|
374 |
+
}
|
375 |
+
|
376 |
+
t.setControlsSize();
|
377 |
+
|
378 |
+
},
|
379 |
+
|
380 |
+
hideControls: function(doAnimation) {
|
381 |
+
var t = this;
|
382 |
+
|
383 |
+
doAnimation = typeof doAnimation == 'undefined' || doAnimation;
|
384 |
+
|
385 |
+
if (!t.controlsAreVisible)
|
386 |
+
return;
|
387 |
+
|
388 |
+
if (doAnimation) {
|
389 |
+
// fade out main controls
|
390 |
+
t.controls.stop(true, true).fadeOut(200, function() {
|
391 |
+
$(this)
|
392 |
+
.css('visibility','hidden')
|
393 |
+
.css('display','block');
|
394 |
+
|
395 |
+
t.controlsAreVisible = false;
|
396 |
+
});
|
397 |
+
|
398 |
+
// any additional controls people might add and want to hide
|
399 |
+
t.container.find('.mejs-control').stop(true, true).fadeOut(200, function() {
|
400 |
+
$(this)
|
401 |
+
.css('visibility','hidden')
|
402 |
+
.css('display','block');
|
403 |
+
});
|
404 |
+
} else {
|
405 |
+
|
406 |
+
// hide main controls
|
407 |
+
t.controls
|
408 |
+
.css('visibility','hidden')
|
409 |
+
.css('display','block');
|
410 |
+
|
411 |
+
// hide others
|
412 |
+
t.container.find('.mejs-control')
|
413 |
+
.css('visibility','hidden')
|
414 |
+
.css('display','block');
|
415 |
+
|
416 |
+
t.controlsAreVisible = false;
|
417 |
+
}
|
418 |
+
},
|
419 |
+
|
420 |
+
controlsTimer: null,
|
421 |
+
|
422 |
+
startControlsTimer: function(timeout) {
|
423 |
+
|
424 |
+
var t = this;
|
425 |
+
|
426 |
+
timeout = typeof timeout != 'undefined' ? timeout : 1500;
|
427 |
+
|
428 |
+
t.killControlsTimer('start');
|
429 |
+
|
430 |
+
t.controlsTimer = setTimeout(function() {
|
431 |
+
//console.log('timer fired');
|
432 |
+
t.hideControls();
|
433 |
+
t.killControlsTimer('hide');
|
434 |
+
}, timeout);
|
435 |
+
},
|
436 |
+
|
437 |
+
killControlsTimer: function(src) {
|
438 |
+
|
439 |
+
var t = this;
|
440 |
+
|
441 |
+
if (t.controlsTimer !== null) {
|
442 |
+
clearTimeout(t.controlsTimer);
|
443 |
+
delete t.controlsTimer;
|
444 |
+
t.controlsTimer = null;
|
445 |
+
}
|
446 |
+
},
|
447 |
+
|
448 |
+
controlsEnabled: true,
|
449 |
+
|
450 |
+
disableControls: function() {
|
451 |
+
var t= this;
|
452 |
+
|
453 |
+
t.killControlsTimer();
|
454 |
+
t.hideControls(false);
|
455 |
+
this.controlsEnabled = false;
|
456 |
+
},
|
457 |
+
|
458 |
+
enableControls: function() {
|
459 |
+
var t= this;
|
460 |
+
|
461 |
+
t.showControls(false);
|
462 |
+
|
463 |
+
t.controlsEnabled = true;
|
464 |
+
},
|
465 |
+
|
466 |
+
|
467 |
+
// Sets up all controls and events
|
468 |
+
meReady: function(media, domNode) {
|
469 |
+
|
470 |
+
|
471 |
+
var t = this,
|
472 |
+
mf = mejs.MediaFeatures,
|
473 |
+
autoplayAttr = domNode.getAttribute('autoplay'),
|
474 |
+
autoplay = !(typeof autoplayAttr == 'undefined' || autoplayAttr === null || autoplayAttr === 'false'),
|
475 |
+
featureIndex,
|
476 |
+
feature;
|
477 |
+
|
478 |
+
// make sure it can't create itself again if a plugin reloads
|
479 |
+
if (t.created)
|
480 |
+
return;
|
481 |
+
else
|
482 |
+
t.created = true;
|
483 |
+
|
484 |
+
t.media = media;
|
485 |
+
t.domNode = domNode;
|
486 |
+
|
487 |
+
if (!(mf.isAndroid && t.options.AndroidUseNativeControls) && !(mf.isiPad && t.options.iPadUseNativeControls) && !(mf.isiPhone && t.options.iPhoneUseNativeControls)) {
|
488 |
+
|
489 |
+
// two built in features
|
490 |
+
t.buildposter(t, t.controls, t.layers, t.media);
|
491 |
+
t.buildkeyboard(t, t.controls, t.layers, t.media);
|
492 |
+
t.buildoverlays(t, t.controls, t.layers, t.media);
|
493 |
+
|
494 |
+
// grab for use by features
|
495 |
+
t.findTracks();
|
496 |
+
|
497 |
+
// add user-defined features/controls
|
498 |
+
for (featureIndex in t.options.features) {
|
499 |
+
feature = t.options.features[featureIndex];
|
500 |
+
if (t['build' + feature]) {
|
501 |
+
try {
|
502 |
+
t['build' + feature](t, t.controls, t.layers, t.media);
|
503 |
+
} catch (e) {
|
504 |
+
// TODO: report control error
|
505 |
+
//throw e;
|
506 |
+
//console.log('error building ' + feature);
|
507 |
+
//console.log(e);
|
508 |
+
}
|
509 |
+
}
|
510 |
+
}
|
511 |
+
|
512 |
+
t.container.trigger('controlsready');
|
513 |
+
|
514 |
+
// reset all layers and controls
|
515 |
+
t.setPlayerSize(t.width, t.height);
|
516 |
+
t.setControlsSize();
|
517 |
+
|
518 |
+
|
519 |
+
// controls fade
|
520 |
+
if (t.isVideo) {
|
521 |
+
|
522 |
+
if (mejs.MediaFeatures.hasTouch) {
|
523 |
+
|
524 |
+
// for touch devices (iOS, Android)
|
525 |
+
// show/hide without animation on touch
|
526 |
+
|
527 |
+
t.$media.bind('touchstart', function() {
|
528 |
+
|
529 |
+
|
530 |
+
// toggle controls
|
531 |
+
if (t.controlsAreVisible) {
|
532 |
+
t.hideControls(false);
|
533 |
+
} else {
|
534 |
+
if (t.controlsEnabled) {
|
535 |
+
t.showControls(false);
|
536 |
+
}
|
537 |
+
}
|
538 |
+
});
|
539 |
+
|
540 |
+
} else {
|
541 |
+
// click controls
|
542 |
+
var clickElement = (t.media.pluginType == 'native') ? t.$media : $(t.media.pluginElement);
|
543 |
+
|
544 |
+
// click to play/pause
|
545 |
+
clickElement.click(function() {
|
546 |
+
if (media.paused) {
|
547 |
+
media.play();
|
548 |
+
} else {
|
549 |
+
media.pause();
|
550 |
+
}
|
551 |
+
});
|
552 |
+
|
553 |
+
|
554 |
+
// show/hide controls
|
555 |
+
t.container
|
556 |
+
.bind('mouseenter mouseover', function () {
|
557 |
+
if (t.controlsEnabled) {
|
558 |
+
if (!t.options.alwaysShowControls) {
|
559 |
+
t.killControlsTimer('enter');
|
560 |
+
t.showControls();
|
561 |
+
t.startControlsTimer(2500);
|
562 |
+
}
|
563 |
+
}
|
564 |
+
})
|
565 |
+
.bind('mousemove', function() {
|
566 |
+
if (t.controlsEnabled) {
|
567 |
+
if (!t.controlsAreVisible) {
|
568 |
+
t.showControls();
|
569 |
+
}
|
570 |
+
//t.killControlsTimer('move');
|
571 |
+
if (!t.options.alwaysShowControls) {
|
572 |
+
t.startControlsTimer(2500);
|
573 |
+
}
|
574 |
+
}
|
575 |
+
})
|
576 |
+
.bind('mouseleave', function () {
|
577 |
+
if (t.controlsEnabled) {
|
578 |
+
if (!t.media.paused && !t.options.alwaysShowControls) {
|
579 |
+
t.startControlsTimer(1000);
|
580 |
+
}
|
581 |
+
}
|
582 |
+
});
|
583 |
+
}
|
584 |
+
|
585 |
+
// check for autoplay
|
586 |
+
if (autoplay && !t.options.alwaysShowControls) {
|
587 |
+
t.hideControls();
|
588 |
+
}
|
589 |
+
|
590 |
+
// resizer
|
591 |
+
if (t.options.enableAutosize) {
|
592 |
+
t.media.addEventListener('loadedmetadata', function(e) {
|
593 |
+
// if the <video height> was not set and the options.videoHeight was not set
|
594 |
+
// then resize to the real dimensions
|
595 |
+
if (t.options.videoHeight <= 0 && t.domNode.getAttribute('height') === null && !isNaN(e.target.videoHeight)) {
|
596 |
+
t.setPlayerSize(e.target.videoWidth, e.target.videoHeight);
|
597 |
+
t.setControlsSize();
|
598 |
+
t.media.setVideoSize(e.target.videoWidth, e.target.videoHeight);
|
599 |
+
}
|
600 |
+
}, false);
|
601 |
+
}
|
602 |
+
}
|
603 |
+
|
604 |
+
// EVENTS
|
605 |
+
|
606 |
+
// FOCUS: when a video starts playing, it takes focus from other players (possibily pausing them)
|
607 |
+
media.addEventListener('play', function() {
|
608 |
+
|
609 |
+
// go through all other players
|
610 |
+
for (var i=0, il=mejs.players.length; i<il; i++) {
|
611 |
+
var p = mejs.players[i];
|
612 |
+
if (p.id != t.id && t.options.pauseOtherPlayers && !p.paused && !p.ended) {
|
613 |
+
p.pause();
|
614 |
+
}
|
615 |
+
p.hasFocus = false;
|
616 |
+
}
|
617 |
+
|
618 |
+
t.hasFocus = true;
|
619 |
+
},false);
|
620 |
+
|
621 |
+
|
622 |
+
// ended for all
|
623 |
+
t.media.addEventListener('ended', function (e) {
|
624 |
+
try{
|
625 |
+
t.media.setCurrentTime(0);
|
626 |
+
} catch (exp) {
|
627 |
+
|
628 |
+
}
|
629 |
+
t.media.pause();
|
630 |
+
|
631 |
+
if (t.setProgressRail)
|
632 |
+
t.setProgressRail();
|
633 |
+
if (t.setCurrentRail)
|
634 |
+
t.setCurrentRail();
|
635 |
+
|
636 |
+
if (t.options.loop) {
|
637 |
+
t.media.play();
|
638 |
+
} else if (!t.options.alwaysShowControls && t.controlsEnabled) {
|
639 |
+
t.showControls();
|
640 |
+
}
|
641 |
+
}, false);
|
642 |
+
|
643 |
+
// resize on the first play
|
644 |
+
t.media.addEventListener('loadedmetadata', function(e) {
|
645 |
+
if (t.updateDuration) {
|
646 |
+
t.updateDuration();
|
647 |
+
}
|
648 |
+
if (t.updateCurrent) {
|
649 |
+
t.updateCurrent();
|
650 |
+
}
|
651 |
+
|
652 |
+
if (!t.isFullScreen) {
|
653 |
+
t.setPlayerSize(t.width, t.height);
|
654 |
+
t.setControlsSize();
|
655 |
+
}
|
656 |
+
}, false);
|
657 |
+
|
658 |
+
|
659 |
+
// webkit has trouble doing this without a delay
|
660 |
+
setTimeout(function () {
|
661 |
+
t.setPlayerSize(t.width, t.height);
|
662 |
+
t.setControlsSize();
|
663 |
+
}, 50);
|
664 |
+
|
665 |
+
// adjust controls whenever window sizes (used to be in fullscreen only)
|
666 |
+
$(window).resize(function() {
|
667 |
+
|
668 |
+
// don't resize for fullscreen mode
|
669 |
+
if ( !(t.isFullScreen || (mejs.MediaFeatures.hasTrueNativeFullScreen && document.webkitIsFullScreen)) ) {
|
670 |
+
t.setPlayerSize(t.width, t.height);
|
671 |
+
}
|
672 |
+
|
673 |
+
// always adjust controls
|
674 |
+
t.setControlsSize();
|
675 |
+
});
|
676 |
+
|
677 |
+
// TEMP: needs to be moved somewhere else
|
678 |
+
if (t.media.pluginType == 'youtube') {
|
679 |
+
t.container.find('.mejs-overlay-play').hide();
|
680 |
+
}
|
681 |
+
}
|
682 |
+
|
683 |
+
// force autoplay for HTML5
|
684 |
+
if (autoplay && media.pluginType == 'native') {
|
685 |
+
media.load();
|
686 |
+
media.play();
|
687 |
+
}
|
688 |
+
|
689 |
+
|
690 |
+
if (t.options.success) {
|
691 |
+
|
692 |
+
if (typeof t.options.success == 'string') {
|
693 |
+
window[t.options.success](t.media, t.domNode, t);
|
694 |
+
} else {
|
695 |
+
t.options.success(t.media, t.domNode, t);
|
696 |
+
}
|
697 |
+
}
|
698 |
+
},
|
699 |
+
|
700 |
+
handleError: function(e) {
|
701 |
+
var t = this;
|
702 |
+
|
703 |
+
t.controls.hide();
|
704 |
+
|
705 |
+
// Tell user that the file cannot be played
|
706 |
+
if (t.options.error) {
|
707 |
+
t.options.error(e);
|
708 |
+
}
|
709 |
+
},
|
710 |
+
|
711 |
+
setPlayerSize: function(width,height) {
|
712 |
+
var t = this;
|
713 |
+
|
714 |
+
if (typeof width != 'undefined')
|
715 |
+
t.width = width;
|
716 |
+
|
717 |
+
if (typeof height != 'undefined')
|
718 |
+
t.height = height;
|
719 |
+
|
720 |
+
// detect 100% mode
|
721 |
+
if (t.height.toString().indexOf('%') > 0) {
|
722 |
+
|
723 |
+
// do we have the native dimensions yet?
|
724 |
+
var
|
725 |
+
nativeWidth = (t.media.videoWidth && t.media.videoWidth > 0) ? t.media.videoWidth : t.options.defaultVideoWidth,
|
726 |
+
nativeHeight = (t.media.videoHeight && t.media.videoHeight > 0) ? t.media.videoHeight : t.options.defaultVideoHeight,
|
727 |
+
parentWidth = t.container.parent().width(),
|
728 |
+
newHeight = parseInt(parentWidth * nativeHeight/nativeWidth, 10);
|
729 |
+
|
730 |
+
if (t.container.parent()[0].tagName.toLowerCase() === 'body') { // && t.container.siblings().count == 0) {
|
731 |
+
parentWidth = $(window).width();
|
732 |
+
newHeight = $(window).height();
|
733 |
+
}
|
734 |
+
|
735 |
+
|
736 |
+
// set outer container size
|
737 |
+
t.container
|
738 |
+
.width(parentWidth)
|
739 |
+
.height(newHeight);
|
740 |
+
|
741 |
+
// set native <video>
|
742 |
+
t.$media
|
743 |
+
.width('100%')
|
744 |
+
.height('100%');
|
745 |
+
|
746 |
+
// set shims
|
747 |
+
t.container.find('object, embed, iframe')
|
748 |
+
.width('100%')
|
749 |
+
.height('100%');
|
750 |
+
|
751 |
+
// if shim is ready, send the size to the embeded plugin
|
752 |
+
if (t.media.setVideoSize)
|
753 |
+
t.media.setVideoSize(parentWidth, newHeight);
|
754 |
+
|
755 |
+
// set the layers
|
756 |
+
t.layers.children('.mejs-layer')
|
757 |
+
.width('100%')
|
758 |
+
.height('100%');
|
759 |
+
|
760 |
+
|
761 |
+
} else {
|
762 |
+
|
763 |
+
t.container
|
764 |
+
.width(t.width)
|
765 |
+
.height(t.height);
|
766 |
+
|
767 |
+
t.layers.children('.mejs-layer')
|
768 |
+
.width(t.width)
|
769 |
+
.height(t.height);
|
770 |
+
|
771 |
+
}
|
772 |
+
},
|
773 |
+
|
774 |
+
setControlsSize: function() {
|
775 |
+
var t = this,
|
776 |
+
usedWidth = 0,
|
777 |
+
railWidth = 0,
|
778 |
+
rail = t.controls.find('.mejs-time-rail'),
|
779 |
+
total = t.controls.find('.mejs-time-total'),
|
780 |
+
current = t.controls.find('.mejs-time-current'),
|
781 |
+
loaded = t.controls.find('.mejs-time-loaded'),
|
782 |
+
others = rail.siblings();
|
783 |
+
|
784 |
+
|
785 |
+
// allow the size to come from custom CSS
|
786 |
+
if (t.options && !t.options.autosizeProgress) {
|
787 |
+
// Also, frontends devs can be more flexible
|
788 |
+
// due the opportunity of absolute positioning.
|
789 |
+
railWidth = parseInt(rail.css('width'));
|
790 |
+
}
|
791 |
+
|
792 |
+
// attempt to autosize
|
793 |
+
if (railWidth === 0 || !railWidth) {
|
794 |
+
|
795 |
+
// find the size of all the other controls besides the rail
|
796 |
+
others.each(function() {
|
797 |
+
if ($(this).css('position') != 'absolute') {
|
798 |
+
usedWidth += $(this).outerWidth(true);
|
799 |
+
}
|
800 |
+
});
|
801 |
+
|
802 |
+
// fit the rail into the remaining space
|
803 |
+
railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
|
804 |
+
}
|
805 |
+
|
806 |
+
// outer area
|
807 |
+
rail.width(railWidth);
|
808 |
+
// dark space
|
809 |
+
total.width(railWidth - (total.outerWidth(true) - total.width()));
|
810 |
+
|
811 |
+
if (t.setProgressRail)
|
812 |
+
t.setProgressRail();
|
813 |
+
if (t.setCurrentRail)
|
814 |
+
t.setCurrentRail();
|
815 |
+
},
|
816 |
+
|
817 |
+
|
818 |
+
buildposter: function(player, controls, layers, media) {
|
819 |
+
var t = this,
|
820 |
+
poster =
|
821 |
+
$('<div class="mejs-poster mejs-layer">' +
|
822 |
+
'</div>')
|
823 |
+
.appendTo(layers),
|
824 |
+
posterUrl = player.$media.attr('poster');
|
825 |
+
|
826 |
+
// prioriy goes to option (this is useful if you need to support iOS 3.x (iOS completely fails with poster)
|
827 |
+
if (player.options.poster !== '') {
|
828 |
+
posterUrl = player.options.poster;
|
829 |
+
}
|
830 |
+
|
831 |
+
// second, try the real poster
|
832 |
+
if (posterUrl !== '' && posterUrl != null) {
|
833 |
+
t.setPoster(posterUrl);
|
834 |
+
} else {
|
835 |
+
poster.hide();
|
836 |
+
}
|
837 |
+
|
838 |
+
media.addEventListener('play',function() {
|
839 |
+
poster.hide();
|
840 |
+
}, false);
|
841 |
+
},
|
842 |
+
|
843 |
+
setPoster: function(url) {
|
844 |
+
var t = this,
|
845 |
+
posterDiv = t.container.find('.mejs-poster'),
|
846 |
+
posterImg = posterDiv.find('img');
|
847 |
+
|
848 |
+
if (posterImg.length == 0) {
|
849 |
+
posterImg = $('<img width="100%" height="100%" />').appendTo(posterDiv);
|
850 |
+
}
|
851 |
+
|
852 |
+
posterImg.attr('src', url);
|
853 |
+
},
|
854 |
+
|
855 |
+
buildoverlays: function(player, controls, layers, media) {
|
856 |
+
if (!player.isVideo)
|
857 |
+
return;
|
858 |
+
|
859 |
+
var
|
860 |
+
loading =
|
861 |
+
$('<div class="mejs-overlay mejs-layer">'+
|
862 |
+
'<div class="mejs-overlay-loading"><span></span></div>'+
|
863 |
+
'</div>')
|
864 |
+
.hide() // start out hidden
|
865 |
+
.appendTo(layers),
|
866 |
+
error =
|
867 |
+
$('<div class="mejs-overlay mejs-layer">'+
|
868 |
+
'<div class="mejs-overlay-error"></div>'+
|
869 |
+
'</div>')
|
870 |
+
.hide() // start out hidden
|
871 |
+
.appendTo(layers),
|
872 |
+
// this needs to come last so it's on top
|
873 |
+
bigPlay =
|
874 |
+
$('<div class="mejs-overlay mejs-layer mejs-overlay-play">'+
|
875 |
+
'<div class="mejs-overlay-button"></div>'+
|
876 |
+
'</div>')
|
877 |
+
.appendTo(layers)
|
878 |
+
.click(function() {
|
879 |
+
if (media.paused) {
|
880 |
+
media.play();
|
881 |
+
} else {
|
882 |
+
media.pause();
|
883 |
+
}
|
884 |
+
});
|
885 |
+
|
886 |
+
/*
|
887 |
+
if (mejs.MediaFeatures.isiOS || mejs.MediaFeatures.isAndroid) {
|
888 |
+
bigPlay.remove();
|
889 |
+
loading.remove();
|
890 |
+
}
|
891 |
+
*/
|
892 |
+
|
893 |
+
|
894 |
+
// show/hide big play button
|
895 |
+
media.addEventListener('play',function() {
|
896 |
+
bigPlay.hide();
|
897 |
+
loading.hide();
|
898 |
+
controls.find('.mejs-time-buffering').hide();
|
899 |
+
error.hide();
|
900 |
+
}, false);
|
901 |
+
|
902 |
+
media.addEventListener('playing', function() {
|
903 |
+
bigPlay.hide();
|
904 |
+
loading.hide();
|
905 |
+
controls.find('.mejs-time-buffering').hide();
|
906 |
+
error.hide();
|
907 |
+
}, false);
|
908 |
+
|
909 |
+
media.addEventListener('seeking', function() {
|
910 |
+
loading.show();
|
911 |
+
controls.find('.mejs-time-buffering').show();
|
912 |
+
}, false);
|
913 |
+
|
914 |
+
media.addEventListener('seeked', function() {
|
915 |
+
loading.hide();
|
916 |
+
controls.find('.mejs-time-buffering').hide();
|
917 |
+
}, false);
|
918 |
+
|
919 |
+
media.addEventListener('pause',function() {
|
920 |
+
if (!mejs.MediaFeatures.isiPhone) {
|
921 |
+
bigPlay.show();
|
922 |
+
}
|
923 |
+
}, false);
|
924 |
+
|
925 |
+
media.addEventListener('waiting', function() {
|
926 |
+
loading.show();
|
927 |
+
controls.find('.mejs-time-buffering').show();
|
928 |
+
}, false);
|
929 |
+
|
930 |
+
|
931 |
+
// show/hide loading
|
932 |
+
media.addEventListener('loadeddata',function() {
|
933 |
+
// for some reason Chrome is firing this event
|
934 |
+
//if (mejs.MediaFeatures.isChrome && media.getAttribute && media.getAttribute('preload') === 'none')
|
935 |
+
// return;
|
936 |
+
|
937 |
+
loading.show();
|
938 |
+
controls.find('.mejs-time-buffering').show();
|
939 |
+
}, false);
|
940 |
+
media.addEventListener('canplay',function() {
|
941 |
+
loading.hide();
|
942 |
+
controls.find('.mejs-time-buffering').hide();
|
943 |
+
}, false);
|
944 |
+
|
945 |
+
// error handling
|
946 |
+
media.addEventListener('error',function() {
|
947 |
+
loading.hide();
|
948 |
+
controls.find('.mejs-time-buffering').hide();
|
949 |
+
error.show();
|
950 |
+
error.find('mejs-overlay-error').html("Error loading this resource");
|
951 |
+
}, false);
|
952 |
+
},
|
953 |
+
|
954 |
+
buildkeyboard: function(player, controls, layers, media) {
|
955 |
+
|
956 |
+
var t = this;
|
957 |
+
|
958 |
+
// listen for key presses
|
959 |
+
$(document).keydown(function(e) {
|
960 |
+
|
961 |
+
if (player.hasFocus && player.options.enableKeyboard) {
|
962 |
+
|
963 |
+
// find a matching key
|
964 |
+
for (var i=0, il=player.options.keyActions.length; i<il; i++) {
|
965 |
+
var keyAction = player.options.keyActions[i];
|
966 |
+
|
967 |
+
for (var j=0, jl=keyAction.keys.length; j<jl; j++) {
|
968 |
+
if (e.keyCode == keyAction.keys[j]) {
|
969 |
+
e.preventDefault();
|
970 |
+
keyAction.action(player, media);
|
971 |
+
return false;
|
972 |
+
}
|
973 |
+
}
|
974 |
+
}
|
975 |
+
}
|
976 |
+
|
977 |
+
return true;
|
978 |
+
});
|
979 |
+
|
980 |
+
// check if someone clicked outside a player region, then kill its focus
|
981 |
+
$(document).click(function(event) {
|
982 |
+
if ($(event.target).closest('.mejs-container').length == 0) {
|
983 |
+
player.hasFocus = false;
|
984 |
+
}
|
985 |
+
});
|
986 |
+
|
987 |
+
},
|
988 |
+
|
989 |
+
findTracks: function() {
|
990 |
+
var t = this,
|
991 |
+
tracktags = t.$media.find('track');
|
992 |
+
|
993 |
+
// store for use by plugins
|
994 |
+
t.tracks = [];
|
995 |
+
tracktags.each(function(index, track) {
|
996 |
+
|
997 |
+
track = $(track);
|
998 |
+
|
999 |
+
t.tracks.push({
|
1000 |
+
srclang: track.attr('srclang').toLowerCase(),
|
1001 |
+
src: track.attr('src'),
|
1002 |
+
kind: track.attr('kind'),
|
1003 |
+
label: track.attr('label') || '',
|
1004 |
+
entries: [],
|
1005 |
+
isLoaded: false
|
1006 |
+
});
|
1007 |
+
});
|
1008 |
+
},
|
1009 |
+
changeSkin: function(className) {
|
1010 |
+
this.container[0].className = 'mejs-container ' + className;
|
1011 |
+
this.setPlayerSize(this.width, this.height);
|
1012 |
+
this.setControlsSize();
|
1013 |
+
},
|
1014 |
+
play: function() {
|
1015 |
+
this.media.play();
|
1016 |
+
},
|
1017 |
+
pause: function() {
|
1018 |
+
this.media.pause();
|
1019 |
+
},
|
1020 |
+
load: function() {
|
1021 |
+
this.media.load();
|
1022 |
+
},
|
1023 |
+
setMuted: function(muted) {
|
1024 |
+
this.media.setMuted(muted);
|
1025 |
+
},
|
1026 |
+
setCurrentTime: function(time) {
|
1027 |
+
this.media.setCurrentTime(time);
|
1028 |
+
},
|
1029 |
+
getCurrentTime: function() {
|
1030 |
+
return this.media.currentTime;
|
1031 |
+
},
|
1032 |
+
setVolume: function(volume) {
|
1033 |
+
this.media.setVolume(volume);
|
1034 |
+
},
|
1035 |
+
getVolume: function() {
|
1036 |
+
return this.media.volume;
|
1037 |
+
},
|
1038 |
+
setSrc: function(src) {
|
1039 |
+
this.media.setSrc(src);
|
1040 |
+
},
|
1041 |
+
remove: function() {
|
1042 |
+
var t = this;
|
1043 |
+
|
1044 |
+
if (t.media.pluginType == 'flash') {
|
1045 |
+
t.media.remove();
|
1046 |
+
} else if (t.media.pluginType == 'native') {
|
1047 |
+
t.media.prop('controls', true);
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
// grab video and put it back in place
|
1051 |
+
if (!t.isDynamic) {
|
1052 |
+
t.$node.insertBefore(t.container)
|
1053 |
+
}
|
1054 |
+
|
1055 |
+
t.container.remove();
|
1056 |
+
}
|
1057 |
+
};
|
1058 |
+
|
1059 |
+
// turn into jQuery plugin
|
1060 |
+
if (typeof jQuery != 'undefined') {
|
1061 |
+
jQuery.fn.mediaelementplayer = function (options) {
|
1062 |
+
return this.each(function () {
|
1063 |
+
new mejs.MediaElementPlayer(this, options);
|
1064 |
+
});
|
1065 |
+
};
|
1066 |
+
}
|
1067 |
+
|
1068 |
+
$(document).ready(function() {
|
1069 |
+
// auto enable using JSON attribute
|
1070 |
+
$('.mejs-player').mediaelementplayer();
|
1071 |
+
});
|
1072 |
+
|
1073 |
+
// push out to window
|
1074 |
+
window.MediaElementPlayer = mejs.MediaElementPlayer;
|
1075 |
+
|
1076 |
+
})(mejs.$);
|
1077 |
|
1078 |
(function($) {
|
1079 |
|
1320 |
}
|
1321 |
});
|
1322 |
})(mejs.$);
|
1323 |
+
(function($) {
|
1324 |
+
|
1325 |
+
// options
|
1326 |
+
$.extend(mejs.MepDefaults, {
|
1327 |
+
duration: -1,
|
1328 |
+
timeAndDurationSeparator: ' <span> | </span> '
|
1329 |
+
});
|
1330 |
+
|
1331 |
+
|
1332 |
+
// current and duration 00:00 / 00:00
|
1333 |
+
$.extend(MediaElementPlayer.prototype, {
|
1334 |
+
buildcurrent: function(player, controls, layers, media) {
|
1335 |
+
var t = this;
|
1336 |
+
|
1337 |
+
$('<div class="mejs-time">'+
|
1338 |
+
'<span class="mejs-currenttime">' + (player.options.alwaysShowHours ? '00:' : '')
|
1339 |
+
+ (player.options.showTimecodeFrameCount? '00:00:00':'00:00')+ '</span>'+
|
1340 |
+
'</div>')
|
1341 |
+
.appendTo(controls);
|
1342 |
+
|
1343 |
+
t.currenttime = t.controls.find('.mejs-currenttime');
|
1344 |
+
|
1345 |
+
media.addEventListener('timeupdate',function() {
|
1346 |
+
player.updateCurrent();
|
1347 |
+
}, false);
|
1348 |
+
},
|
1349 |
+
|
1350 |
+
|
1351 |
+
buildduration: function(player, controls, layers, media) {
|
1352 |
+
var t = this;
|
1353 |
+
|
1354 |
+
if (controls.children().last().find('.mejs-currenttime').length > 0) {
|
1355 |
+
$(t.options.timeAndDurationSeparator +
|
1356 |
+
'<span class="mejs-duration">' +
|
1357 |
+
(t.options.duration > 0 ?
|
1358 |
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1359 |
+
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1360 |
+
) +
|
1361 |
+
'</span>')
|
1362 |
+
.appendTo(controls.find('.mejs-time'));
|
1363 |
+
} else {
|
1364 |
+
|
1365 |
+
// add class to current time
|
1366 |
+
controls.find('.mejs-currenttime').parent().addClass('mejs-currenttime-container');
|
1367 |
+
|
1368 |
+
$('<div class="mejs-time mejs-duration-container">'+
|
1369 |
+
'<span class="mejs-duration">' +
|
1370 |
+
(t.options.duration > 0 ?
|
1371 |
+
mejs.Utility.secondsToTimeCode(t.options.duration, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25) :
|
1372 |
+
((player.options.alwaysShowHours ? '00:' : '') + (player.options.showTimecodeFrameCount? '00:00:00':'00:00'))
|
1373 |
+
) +
|
1374 |
+
'</span>' +
|
1375 |
+
'</div>')
|
1376 |
+
.appendTo(controls);
|
1377 |
+
}
|
1378 |
+
|
1379 |
+
t.durationD = t.controls.find('.mejs-duration');
|
1380 |
+
|
1381 |
+
media.addEventListener('timeupdate',function() {
|
1382 |
+
player.updateDuration();
|
1383 |
+
}, false);
|
1384 |
+
},
|
1385 |
+
|
1386 |
+
updateCurrent: function() {
|
1387 |
+
var t = this;
|
1388 |
+
|
1389 |
+
if (t.currenttime) {
|
1390 |
+
t.currenttime.html(mejs.Utility.secondsToTimeCode(t.media.currentTime, t.options.alwaysShowHours || t.media.duration > 3600, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
1391 |
+
}
|
1392 |
+
},
|
1393 |
+
|
1394 |
+
updateDuration: function() {
|
1395 |
+
var t = this;
|
1396 |
+
|
1397 |
+
if (t.media.duration && t.durationD) {
|
1398 |
+
t.durationD.html(mejs.Utility.secondsToTimeCode(t.media.duration, t.options.alwaysShowHours, t.options.showTimecodeFrameCount, t.options.framesPerSecond || 25));
|
1399 |
+
}
|
1400 |
+
}
|
1401 |
+
});
|
1402 |
+
|
1403 |
})(mejs.$);
|
1404 |
(function($) {
|
1405 |
|
1623 |
|
1624 |
})(mejs.$);
|
1625 |
|
1626 |
+
(function($) {
|
1627 |
+
|
1628 |
+
$.extend(mejs.MepDefaults, {
|
1629 |
+
usePluginFullScreen: true,
|
1630 |
+
newWindowCallback: function() { return '';},
|
1631 |
+
fullscreenText: 'Fullscreen'
|
1632 |
+
});
|
1633 |
+
|
1634 |
+
$.extend(MediaElementPlayer.prototype, {
|
1635 |
+
|
1636 |
+
isFullScreen: false,
|
1637 |
+
|
1638 |
+
isNativeFullScreen: false,
|
1639 |
+
|
1640 |
+
docStyleOverflow: null,
|
1641 |
+
|
1642 |
+
isInIframe: false,
|
1643 |
+
|
1644 |
+
buildfullscreen: function(player, controls, layers, media) {
|
1645 |
+
|
1646 |
+
if (!player.isVideo)
|
1647 |
+
return;
|
1648 |
+
|
1649 |
+
player.isInIframe = (window.location != window.parent.location);
|
1650 |
+
|
1651 |
+
// native events
|
1652 |
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1653 |
+
|
1654 |
+
// chrome doesn't alays fire this in an iframe
|
1655 |
+
var target = null;
|
1656 |
+
|
1657 |
+
if (mejs.MediaFeatures.hasMozNativeFullScreen) {
|
1658 |
+
target = $(document);
|
1659 |
+
} else {
|
1660 |
+
target = player.container;
|
1661 |
+
}
|
1662 |
+
|
1663 |
+
target.bind(mejs.MediaFeatures.fullScreenEventName, function(e) {
|
1664 |
+
//player.container.bind('webkitfullscreenchange', function(e) {
|
1665 |
+
|
1666 |
+
|
1667 |
+
if (mejs.MediaFeatures.isFullScreen()) {
|
1668 |
+
player.isNativeFullScreen = true;
|
1669 |
+
// reset the controls once we are fully in full screen
|
1670 |
+
player.setControlsSize();
|
1671 |
+
} else {
|
1672 |
+
player.isNativeFullScreen = false;
|
1673 |
+
// when a user presses ESC
|
1674 |
+
// make sure to put the player back into place
|
1675 |
+
player.exitFullScreen();
|
1676 |
+
}
|
1677 |
+
});
|
1678 |
+
}
|
1679 |
+
|
1680 |
+
var t = this,
|
1681 |
+
normalHeight = 0,
|
1682 |
+
normalWidth = 0,
|
1683 |
+
container = player.container,
|
1684 |
+
fullscreenBtn =
|
1685 |
+
$('<div class="mejs-button mejs-fullscreen-button">' +
|
1686 |
+
'<button type="button" aria-controls="' + t.id + '" title="' + t.options.fullscreenText + '"></button>' +
|
1687 |
+
'</div>')
|
1688 |
+
.appendTo(controls);
|
1689 |
+
|
1690 |
+
if (t.media.pluginType === 'native' || (!t.options.usePluginFullScreen && !mejs.MediaFeatures.isFirefox)) {
|
1691 |
+
|
1692 |
+
fullscreenBtn.click(function() {
|
1693 |
+
var isFullScreen = (mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || player.isFullScreen;
|
1694 |
+
|
1695 |
+
if (isFullScreen) {
|
1696 |
+
player.exitFullScreen();
|
1697 |
+
} else {
|
1698 |
+
player.enterFullScreen();
|
1699 |
+
}
|
1700 |
+
});
|
1701 |
+
|
1702 |
+
} else {
|
1703 |
+
|
1704 |
+
var hideTimeout = null,
|
1705 |
+
supportsPointerEvents = (function() {
|
1706 |
+
// TAKEN FROM MODERNIZR
|
1707 |
+
var element = document.createElement('x'),
|
1708 |
+
documentElement = document.documentElement,
|
1709 |
+
getComputedStyle = window.getComputedStyle,
|
1710 |
+
supports;
|
1711 |
+
if(!('pointerEvents' in element.style)){
|
1712 |
+
return false;
|
1713 |
+
}
|
1714 |
+
element.style.pointerEvents = 'auto';
|
1715 |
+
element.style.pointerEvents = 'x';
|
1716 |
+
documentElement.appendChild(element);
|
1717 |
+
supports = getComputedStyle &&
|
1718 |
+
getComputedStyle(element, '').pointerEvents === 'auto';
|
1719 |
+
documentElement.removeChild(element);
|
1720 |
+
return !!supports;
|
1721 |
+
})();
|
1722 |
+
|
1723 |
+
console.log('supportsPointerEvents', supportsPointerEvents);
|
1724 |
+
|
1725 |
+
if (supportsPointerEvents && !mejs.MediaFeatures.isOpera) { // opera doesn't allow this :(
|
1726 |
+
|
1727 |
+
// allows clicking through the fullscreen button and controls down directly to Flash
|
1728 |
+
|
1729 |
+
/*
|
1730 |
+
When a user puts his mouse over the fullscreen button, the controls are disabled
|
1731 |
+
So we put a div over the video and another one on iether side of the fullscreen button
|
1732 |
+
that caputre mouse movement
|
1733 |
+
and restore the controls once the mouse moves outside of the fullscreen button
|
1734 |
+
*/
|
1735 |
+
|
1736 |
+
var fullscreenIsDisabled = false,
|
1737 |
+
restoreControls = function() {
|
1738 |
+
if (fullscreenIsDisabled) {
|
1739 |
+
// hide the hovers
|
1740 |
+
videoHoverDiv.hide();
|
1741 |
+
controlsLeftHoverDiv.hide();
|
1742 |
+
controlsRightHoverDiv.hide();
|
1743 |
+
|
1744 |
+
// restore the control bar
|
1745 |
+
fullscreenBtn.css('pointer-events', '');
|
1746 |
+
t.controls.css('pointer-events', '');
|
1747 |
+
|
1748 |
+
// store for later
|
1749 |
+
fullscreenIsDisabled = false;
|
1750 |
+
}
|
1751 |
+
},
|
1752 |
+
videoHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1753 |
+
controlsLeftHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1754 |
+
controlsRightHoverDiv = $('<div class="mejs-fullscreen-hover" />').appendTo(t.container).mouseover(restoreControls),
|
1755 |
+
positionHoverDivs = function() {
|
1756 |
+
var style = {position: 'absolute', top: 0, left: 0}; //, backgroundColor: '#f00'};
|
1757 |
+
videoHoverDiv.css(style);
|
1758 |
+
controlsLeftHoverDiv.css(style);
|
1759 |
+
controlsRightHoverDiv.css(style);
|
1760 |
+
|
1761 |
+
// over video, but not controls
|
1762 |
+
videoHoverDiv
|
1763 |
+
.width( t.container.width() )
|
1764 |
+
.height( t.container.height() - t.controls.height() );
|
1765 |
+
|
1766 |
+
// over controls, but not the fullscreen button
|
1767 |
+
var fullScreenBtnOffset = fullscreenBtn.offset().left - t.container.offset().left;
|
1768 |
+
fullScreenBtnWidth = fullscreenBtn.outerWidth(true);
|
1769 |
+
|
1770 |
+
controlsLeftHoverDiv
|
1771 |
+
.width( fullScreenBtnOffset )
|
1772 |
+
.height( t.controls.height() )
|
1773 |
+
.css({top: t.container.height() - t.controls.height()});
|
1774 |
+
|
1775 |
+
// after the fullscreen button
|
1776 |
+
controlsRightHoverDiv
|
1777 |
+
.width( t.container.width() - fullScreenBtnOffset - fullScreenBtnWidth )
|
1778 |
+
.height( t.controls.height() )
|
1779 |
+
.css({top: t.container.height() - t.controls.height(),
|
1780 |
+
left: fullScreenBtnOffset + fullScreenBtnWidth});
|
1781 |
+
};
|
1782 |
+
|
1783 |
+
$(document).resize(function() {
|
1784 |
+
positionHoverDivs();
|
1785 |
+
});
|
1786 |
+
|
1787 |
+
// on hover, kill the fullscreen button's HTML handling, allowing clicks down to Flash
|
1788 |
+
fullscreenBtn
|
1789 |
+
.mouseover(function() {
|
1790 |
+
|
1791 |
+
if (!t.isFullScreen) {
|
1792 |
+
|
1793 |
+
var buttonPos = fullscreenBtn.offset(),
|
1794 |
+
containerPos = player.container.offset();
|
1795 |
+
|
1796 |
+
// move the button in Flash into place
|
1797 |
+
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, false);
|
1798 |
+
|
1799 |
+
// allows click through
|
1800 |
+
fullscreenBtn.css('pointer-events', 'none');
|
1801 |
+
t.controls.css('pointer-events', 'none');
|
1802 |
+
|
1803 |
+
// show the divs that will restore things
|
1804 |
+
videoHoverDiv.show();
|
1805 |
+
controlsRightHoverDiv.show();
|
1806 |
+
controlsLeftHoverDiv.show();
|
1807 |
+
positionHoverDivs();
|
1808 |
+
|
1809 |
+
fullscreenIsDisabled = true;
|
1810 |
+
}
|
1811 |
+
|
1812 |
+
});
|
1813 |
+
|
1814 |
+
// restore controls anytime the user enters or leaves fullscreen
|
1815 |
+
media.addEventListener('fullscreenchange', function(e) {
|
1816 |
+
restoreControls();
|
1817 |
+
});
|
1818 |
+
|
1819 |
+
|
1820 |
+
// the mouseout event doesn't work on the fullscren button, because we already killed the pointer-events
|
1821 |
+
// so we use the document.mousemove event to restore controls when the mouse moves outside the fullscreen button
|
1822 |
+
/*
|
1823 |
+
$(document).mousemove(function(e) {
|
1824 |
+
|
1825 |
+
// if the mouse is anywhere but the fullsceen button, then restore it all
|
1826 |
+
if (fullscreenIsDisabled) {
|
1827 |
+
|
1828 |
+
var fullscreenBtnPos = fullscreenBtn.offset();
|
1829 |
+
|
1830 |
+
|
1831 |
+
if (e.pageY < fullscreenBtnPos.top || e.pageY > fullscreenBtnPos.top + fullscreenBtn.outerHeight(true) ||
|
1832 |
+
e.pageX < fullscreenBtnPos.left || e.pageX > fullscreenBtnPos.left + fullscreenBtn.outerWidth(true)
|
1833 |
+
) {
|
1834 |
+
|
1835 |
+
fullscreenBtn.css('pointer-events', '');
|
1836 |
+
t.controls.css('pointer-events', '');
|
1837 |
+
|
1838 |
+
fullscreenIsDisabled = false;
|
1839 |
+
}
|
1840 |
+
}
|
1841 |
+
});
|
1842 |
+
*/
|
1843 |
+
|
1844 |
+
|
1845 |
+
} else {
|
1846 |
+
|
1847 |
+
// the hover state will show the fullscreen button in Flash to hover up and click
|
1848 |
+
|
1849 |
+
fullscreenBtn
|
1850 |
+
.mouseover(function() {
|
1851 |
+
|
1852 |
+
if (hideTimeout !== null) {
|
1853 |
+
clearTimeout(hideTimeout);
|
1854 |
+
delete hideTimeout;
|
1855 |
+
}
|
1856 |
+
|
1857 |
+
var buttonPos = fullscreenBtn.offset(),
|
1858 |
+
containerPos = player.container.offset();
|
1859 |
+
|
1860 |
+
media.positionFullscreenButton(buttonPos.left - containerPos.left, buttonPos.top - containerPos.top, true);
|
1861 |
+
|
1862 |
+
})
|
1863 |
+
.mouseout(function() {
|
1864 |
+
|
1865 |
+
if (hideTimeout !== null) {
|
1866 |
+
clearTimeout(hideTimeout);
|
1867 |
+
delete hideTimeout;
|
1868 |
+
}
|
1869 |
+
|
1870 |
+
hideTimeout = setTimeout(function() {
|
1871 |
+
media.hideFullscreenButton();
|
1872 |
+
}, 1500);
|
1873 |
+
|
1874 |
+
|
1875 |
+
});
|
1876 |
+
}
|
1877 |
+
}
|
1878 |
+
|
1879 |
+
player.fullscreenBtn = fullscreenBtn;
|
1880 |
+
|
1881 |
+
$(document).bind('keydown',function (e) {
|
1882 |
+
if (((mejs.MediaFeatures.hasTrueNativeFullScreen && mejs.MediaFeatures.isFullScreen()) || t.isFullScreen) && e.keyCode == 27) {
|
1883 |
+
player.exitFullScreen();
|
1884 |
+
}
|
1885 |
+
});
|
1886 |
+
|
1887 |
+
},
|
1888 |
+
enterFullScreen: function() {
|
1889 |
+
|
1890 |
+
var t = this;
|
1891 |
+
|
1892 |
+
// firefox+flash can't adjust plugin sizes without resetting :(
|
1893 |
+
if (t.media.pluginType !== 'native' && (mejs.MediaFeatures.isFirefox || t.options.usePluginFullScreen)) {
|
1894 |
+
//t.media.setFullscreen(true);
|
1895 |
+
//player.isFullScreen = true;
|
1896 |
+
return;
|
1897 |
+
}
|
1898 |
+
|
1899 |
+
// store overflow
|
1900 |
+
docStyleOverflow = document.documentElement.style.overflow;
|
1901 |
+
// set it to not show scroll bars so 100% will work
|
1902 |
+
document.documentElement.style.overflow = 'hidden';
|
1903 |
+
|
1904 |
+
// store sizing
|
1905 |
+
normalHeight = t.container.height();
|
1906 |
+
normalWidth = t.container.width();
|
1907 |
+
|
1908 |
+
// attempt to do true fullscreen (Safari 5.1 and Firefox Nightly only for now)
|
1909 |
+
if (t.media.pluginType === 'native') {
|
1910 |
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1911 |
+
|
1912 |
+
mejs.MediaFeatures.requestFullScreen(t.container[0]);
|
1913 |
+
//return;
|
1914 |
+
|
1915 |
+
if (t.isInIframe) {
|
1916 |
+
// sometimes exiting from fullscreen doesn't work
|
1917 |
+
// notably in Chrome <iframe>. Fixed in version 17
|
1918 |
+
setTimeout(function checkFullscreen() {
|
1919 |
+
|
1920 |
+
if (t.isNativeFullScreen) {
|
1921 |
+
|
1922 |
+
// check if the video is suddenly not really fullscreen
|
1923 |
+
if ($(window).width() !== screen.width) {
|
1924 |
+
// manually exit
|
1925 |
+
t.exitFullScreen();
|
1926 |
+
} else {
|
1927 |
+
// test again
|
1928 |
+
setTimeout(checkFullscreen, 500);
|
1929 |
+
}
|
1930 |
+
}
|
1931 |
+
|
1932 |
+
|
1933 |
+
}, 500);
|
1934 |
+
}
|
1935 |
+
|
1936 |
+
} else if (mejs.MediaFeatures.hasSemiNativeFullScreen) {
|
1937 |
+
t.media.webkitEnterFullscreen();
|
1938 |
+
return;
|
1939 |
+
}
|
1940 |
+
}
|
1941 |
+
|
1942 |
+
// check for iframe launch
|
1943 |
+
if (t.isInIframe) {
|
1944 |
+
var url = t.options.newWindowCallback(this);
|
1945 |
+
|
1946 |
+
|
1947 |
+
if (url !== '') {
|
1948 |
+
|
1949 |
+
// launch immediately
|
1950 |
+
if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1951 |
+
t.pause();
|
1952 |
+
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1953 |
+
return;
|
1954 |
+
} else {
|
1955 |
+
setTimeout(function() {
|
1956 |
+
if (!t.isNativeFullScreen) {
|
1957 |
+
t.pause();
|
1958 |
+
window.open(url, t.id, 'top=0,left=0,width=' + screen.availWidth + ',height=' + screen.availHeight + ',resizable=yes,scrollbars=no,status=no,toolbar=no');
|
1959 |
+
}
|
1960 |
+
}, 250);
|
1961 |
+
}
|
1962 |
+
}
|
1963 |
+
|
1964 |
+
}
|
1965 |
+
|
1966 |
+
// full window code
|
1967 |
+
|
1968 |
+
|
1969 |
+
|
1970 |
+
// make full size
|
1971 |
+
t.container
|
1972 |
+
.addClass('mejs-container-fullscreen')
|
1973 |
+
.width('100%')
|
1974 |
+
.height('100%');
|
1975 |
+
//.css({position: 'fixed', left: 0, top: 0, right: 0, bottom: 0, overflow: 'hidden', width: '100%', height: '100%', 'z-index': 1000});
|
1976 |
+
|
1977 |
+
// Only needed for safari 5.1 native full screen, can cause display issues elsewhere
|
1978 |
+
// Actually, it seems to be needed for IE8, too
|
1979 |
+
//if (mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1980 |
+
setTimeout(function() {
|
1981 |
+
t.container.css({width: '100%', height: '100%'});
|
1982 |
+
t.setControlsSize();
|
1983 |
+
}, 500);
|
1984 |
+
//}
|
1985 |
+
|
1986 |
+
if (t.pluginType === 'native') {
|
1987 |
+
t.$media
|
1988 |
+
.width('100%')
|
1989 |
+
.height('100%');
|
1990 |
+
} else {
|
1991 |
+
t.container.find('object, embed, iframe')
|
1992 |
+
.width('100%')
|
1993 |
+
.height('100%');
|
1994 |
+
|
1995 |
+
//if (!mejs.MediaFeatures.hasTrueNativeFullScreen) {
|
1996 |
+
t.media.setVideoSize($(window).width(),$(window).height());
|
1997 |
+
//}
|
1998 |
+
}
|
1999 |
+
|
2000 |
+
t.layers.children('div')
|
2001 |
+
.width('100%')
|
2002 |
+
.height('100%');
|
2003 |
+
|
2004 |
+
if (t.fullscreenBtn) {
|
2005 |
+
t.fullscreenBtn
|
2006 |
+
.removeClass('mejs-fullscreen')
|
2007 |
+
.addClass('mejs-unfullscreen');
|
2008 |
+
}
|
2009 |
+
|
2010 |
+
t.setControlsSize();
|
2011 |
+
t.isFullScreen = true;
|
2012 |
+
},
|
2013 |
+
|
2014 |
+
exitFullScreen: function() {
|
2015 |
+
|
2016 |
+
var t = this;
|
2017 |
+
|
2018 |
+
// firefox can't adjust plugins
|
2019 |
+
if (t.media.pluginType !== 'native' && mejs.MediaFeatures.isFirefox) {
|
2020 |
+
t.media.setFullscreen(false);
|
2021 |
+
//player.isFullScreen = false;
|
2022 |
+
return;
|
2023 |
+
}
|
2024 |
+
|
2025 |
+
// come outo of native fullscreen
|
2026 |
+
if (mejs.MediaFeatures.hasTrueNativeFullScreen && (mejs.MediaFeatures.isFullScreen() || t.isFullScreen)) {
|
2027 |
+
mejs.MediaFeatures.cancelFullScreen();
|
2028 |
+
}
|
2029 |
+
|
2030 |
+
// restore scroll bars to document
|
2031 |
+
document.documentElement.style.overflow = docStyleOverflow;
|
2032 |
+
|
2033 |
+
t.container
|
2034 |
+
.removeClass('mejs-container-fullscreen')
|
2035 |
+
.width(normalWidth)
|
2036 |
+
.height(normalHeight);
|
2037 |
+
//.css({position: '', left: '', top: '', right: '', bottom: '', overflow: 'inherit', width: normalWidth + 'px', height: normalHeight + 'px', 'z-index': 1});
|
2038 |
+
|
2039 |
+
if (t.pluginType === 'native') {
|
2040 |
+
t.$media
|
2041 |
+
.width(normalWidth)
|
2042 |
+
.height(normalHeight);
|
2043 |
+
} else {
|
2044 |
+
t.container.find('object embed')
|
2045 |
+
.width(normalWidth)
|
2046 |
+
.height(normalHeight);
|
2047 |
+
|
2048 |
+
t.media.setVideoSize(normalWidth, normalHeight);
|
2049 |
+
}
|
2050 |
+
|
2051 |
+
t.layers.children('div')
|
2052 |
+
.width(normalWidth)
|
2053 |
+
.height(normalHeight);
|
2054 |
+
|
2055 |
+
t.fullscreenBtn
|
2056 |
+
.removeClass('mejs-unfullscreen')
|
2057 |
+
.addClass('mejs-fullscreen');
|
2058 |
+
|
2059 |
+
t.setControlsSize();
|
2060 |
+
t.isFullScreen = false;
|
2061 |
+
}
|
2062 |
+
});
|
2063 |
+
|
2064 |
+
})(mejs.$);
|
2065 |
|
2066 |
(function($) {
|
2067 |
|
2548 |
|
2549 |
})(mejs.$);
|
2550 |
|
2551 |
+
/*
|
2552 |
+
* ContextMenu Plugin
|
2553 |
+
*
|
2554 |
+
*
|
2555 |
+
*/
|
2556 |
+
|
2557 |
+
(function($) {
|
2558 |
+
|
2559 |
+
$.extend(mejs.MepDefaults,
|
2560 |
+
{ 'contextMenuItems': [
|
2561 |
+
// demo of a fullscreen option
|
2562 |
+
{
|
2563 |
+
render: function(player) {
|
2564 |
+
|
2565 |
+
// check for fullscreen plugin
|
2566 |
+
if (typeof player.enterFullScreen == 'undefined')
|
2567 |
+
return null;
|
2568 |
+
|
2569 |
+
if (player.isFullScreen) {
|
2570 |
+
return "Turn off Fullscreen";
|
2571 |
+
} else {
|
2572 |
+
return "Go Fullscreen";
|
2573 |
+
}
|
2574 |
+
},
|
2575 |
+
click: function(player) {
|
2576 |
+
if (player.isFullScreen) {
|
2577 |
+
player.exitFullScreen();
|
2578 |
+
} else {
|
2579 |
+
player.enterFullScreen();
|
2580 |
+
}
|
2581 |
+
}
|
2582 |
+
}
|
2583 |
+
,
|
2584 |
+
// demo of a mute/unmute button
|
2585 |
+
{
|
2586 |
+
render: function(player) {
|
2587 |
+
if (player.media.muted) {
|
2588 |
+
return "Unmute";
|
2589 |
+
} else {
|
2590 |
+
return "Mute";
|
2591 |
+
}
|
2592 |
+
},
|
2593 |
+
click: function(player) {
|
2594 |
+
if (player.media.muted) {
|
2595 |
+
player.setMuted(false);
|
2596 |
+
} else {
|
2597 |
+
player.setMuted(true);
|
2598 |
+
}
|
2599 |
+
}
|
2600 |
+
},
|
2601 |
+
// separator
|
2602 |
+
{
|
2603 |
+
isSeparator: true
|
2604 |
+
}
|
2605 |
+
,
|
2606 |
+
// demo of simple download video
|
2607 |
+
{
|
2608 |
+
render: function(player) {
|
2609 |
+
return "Download Video";
|
2610 |
+
},
|
2611 |
+
click: function(player) {
|
2612 |
+
window.location.href = player.media.currentSrc;
|
2613 |
+
}
|
2614 |
+
}
|
2615 |
+
]}
|
2616 |
+
);
|
2617 |
+
|
2618 |
+
|
2619 |
+
$.extend(MediaElementPlayer.prototype, {
|
2620 |
+
buildcontextmenu: function(player, controls, layers, media) {
|
2621 |
+
|
2622 |
+
// create context menu
|
2623 |
+
player.contextMenu = $('<div class="mejs-contextmenu"></div>')
|
2624 |
+
.appendTo($('body'))
|
2625 |
+
.hide();
|
2626 |
+
|
2627 |
+
// create events for showing context menu
|
2628 |
+
player.container.bind('contextmenu', function(e) {
|
2629 |
+
if (player.isContextMenuEnabled) {
|
2630 |
+
e.preventDefault();
|
2631 |
+
player.renderContextMenu(e.clientX-1, e.clientY-1);
|
2632 |
+
return false;
|
2633 |
+
}
|
2634 |
+
});
|
2635 |
+
player.container.bind('click', function() {
|
2636 |
+
player.contextMenu.hide();
|
2637 |
+
});
|
2638 |
+
player.contextMenu.bind('mouseleave', function() {
|
2639 |
+
|
2640 |
+
//console.log('context hover out');
|
2641 |
+
player.startContextMenuTimer();
|
2642 |
+
|
2643 |
+
});
|
2644 |
+
},
|
2645 |
+
|
2646 |
+
isContextMenuEnabled: true,
|
2647 |
+
enableContextMenu: function() {
|
2648 |
+
this.isContextMenuEnabled = true;
|
2649 |
+
},
|
2650 |
+
disableContextMenu: function() {
|
2651 |
+
this.isContextMenuEnabled = false;
|
2652 |
+
},
|
2653 |
+
|
2654 |
+
contextMenuTimeout: null,
|
2655 |
+
startContextMenuTimer: function() {
|
2656 |
+
//console.log('startContextMenuTimer');
|
2657 |
+
|
2658 |
+
var t = this;
|
2659 |
+
|
2660 |
+
t.killContextMenuTimer();
|
2661 |
+
|
2662 |
+
t.contextMenuTimer = setTimeout(function() {
|
2663 |
+
t.hideContextMenu();
|
2664 |
+
t.killContextMenuTimer();
|
2665 |
+
}, 750);
|
2666 |
+
},
|
2667 |
+
killContextMenuTimer: function() {
|
2668 |
+
var timer = this.contextMenuTimer;
|
2669 |
+
|
2670 |
+
//console.log('killContextMenuTimer', timer);
|
2671 |
+
|
2672 |
+
if (timer != null) {
|
2673 |
+
clearTimeout(timer);
|
2674 |
+
delete timer;
|
2675 |
+
timer = null;
|
2676 |
+
}
|
2677 |
+
},
|
2678 |
+
|
2679 |
+
hideContextMenu: function() {
|
2680 |
+
this.contextMenu.hide();
|
2681 |
+
},
|
2682 |
+
|
2683 |
+
renderContextMenu: function(x,y) {
|
2684 |
+
|
2685 |
+
// alway re-render the items so that things like "turn fullscreen on" and "turn fullscreen off" are always written correctly
|
2686 |
+
var t = this,
|
2687 |
+
html = '',
|
2688 |
+
items = t.options.contextMenuItems;
|
2689 |
+
|
2690 |
+
for (var i=0, il=items.length; i<il; i++) {
|
2691 |
+
|
2692 |
+
if (items[i].isSeparator) {
|
2693 |
+
html += '<div class="mejs-contextmenu-separator"></div>';
|
2694 |
+
} else {
|
2695 |
+
|
2696 |
+
var rendered = items[i].render(t);
|
2697 |
+
|
2698 |
+
// render can return null if the item doesn't need to be used at the moment
|
2699 |
+
if (rendered != null) {
|
2700 |
+
html += '<div class="mejs-contextmenu-item" data-itemindex="' + i + '" id="element-' + (Math.random()*1000000) + '">' + rendered + '</div>';
|
2701 |
+
}
|
2702 |
+
}
|
2703 |
+
}
|
2704 |
+
|
2705 |
+
// position and show the context menu
|
2706 |
+
t.contextMenu
|
2707 |
+
.empty()
|
2708 |
+
.append($(html))
|
2709 |
+
.css({top:y, left:x})
|
2710 |
+
.show();
|
2711 |
+
|
2712 |
+
// bind events
|
2713 |
+
t.contextMenu.find('.mejs-contextmenu-item').each(function() {
|
2714 |
+
|
2715 |
+
// which one is this?
|
2716 |
+
var $dom = $(this),
|
2717 |
+
itemIndex = parseInt( $dom.data('itemindex'), 10 ),
|
2718 |
+
item = t.options.contextMenuItems[itemIndex];
|
2719 |
+
|
2720 |
+
// bind extra functionality?
|
2721 |
+
if (typeof item.show != 'undefined')
|
2722 |
+
item.show( $dom , t);
|
2723 |
+
|
2724 |
+
// bind click action
|
2725 |
+
$dom.click(function() {
|
2726 |
+
// perform click action
|
2727 |
+
if (typeof item.click != 'undefined')
|
2728 |
+
item.click(t);
|
2729 |
+
|
2730 |
+
// close
|
2731 |
+
t.contextMenu.hide();
|
2732 |
+
});
|
2733 |
+
});
|
2734 |
+
|
2735 |
+
// stop the controls from hiding
|
2736 |
+
setTimeout(function() {
|
2737 |
+
t.killControlsTimer('rev3');
|
2738 |
+
}, 100);
|
2739 |
+
|
2740 |
+
}
|
2741 |
+
});
|
2742 |
+
|
2743 |
})(mejs.$);
|
loader.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: BuddyPress Media Component
|
4 |
Plugin URI: http://rtcamp.com/buddypress-media/
|
5 |
Description: This component adds missing media rich features like photos, videos and audios uploading to BuddyPress which are essential if you are building social network, seriously!
|
6 |
-
Version: 2.1.
|
7 |
Author: rtCamp
|
8 |
Author URI: http://rtcamp.com
|
9 |
*/
|
@@ -12,7 +12,7 @@ Author URI: http://rtcamp.com
|
|
12 |
define('BP_MEDIA_IS_INSTALLED', 1);
|
13 |
|
14 |
/* Constant to store the current version of the BP Media Plugin. */
|
15 |
-
define('BP_MEDIA_VERSION', '2.1.
|
16 |
|
17 |
/* A constant to be used as base for other URLs throughout the plugin */
|
18 |
define('BP_MEDIA_PLUGIN_DIR', dirname(__FILE__));
|
@@ -35,7 +35,6 @@ define('BP_MEDIA_REQUIRED_BP','1.5.5');
|
|
35 |
function bp_media_init() {
|
36 |
if (defined('BP_VERSION')&&version_compare(BP_VERSION, BP_MEDIA_REQUIRED_BP, '>')) {
|
37 |
require( BP_MEDIA_PLUGIN_DIR . '/includes/bp-media-loader.php' );
|
38 |
-
do_action('bp_media_init');
|
39 |
}
|
40 |
}
|
41 |
add_action('bp_include', 'bp_media_init');
|
@@ -44,7 +43,7 @@ add_action('bp_include', 'bp_media_init');
|
|
44 |
* Function to do the tasks required to be done while activating the plugin
|
45 |
*/
|
46 |
function bp_media_activate() {
|
47 |
-
|
48 |
}
|
49 |
register_activation_hook(__FILE__, 'bp_media_activate');
|
50 |
|
3 |
Plugin Name: BuddyPress Media Component
|
4 |
Plugin URI: http://rtcamp.com/buddypress-media/
|
5 |
Description: This component adds missing media rich features like photos, videos and audios uploading to BuddyPress which are essential if you are building social network, seriously!
|
6 |
+
Version: 2.1.2
|
7 |
Author: rtCamp
|
8 |
Author URI: http://rtcamp.com
|
9 |
*/
|
12 |
define('BP_MEDIA_IS_INSTALLED', 1);
|
13 |
|
14 |
/* Constant to store the current version of the BP Media Plugin. */
|
15 |
+
define('BP_MEDIA_VERSION', '2.1.2');
|
16 |
|
17 |
/* A constant to be used as base for other URLs throughout the plugin */
|
18 |
define('BP_MEDIA_PLUGIN_DIR', dirname(__FILE__));
|
35 |
function bp_media_init() {
|
36 |
if (defined('BP_VERSION')&&version_compare(BP_VERSION, BP_MEDIA_REQUIRED_BP, '>')) {
|
37 |
require( BP_MEDIA_PLUGIN_DIR . '/includes/bp-media-loader.php' );
|
|
|
38 |
}
|
39 |
}
|
40 |
add_action('bp_include', 'bp_media_init');
|
43 |
* Function to do the tasks required to be done while activating the plugin
|
44 |
*/
|
45 |
function bp_media_activate() {
|
46 |
+
update_option('bp_media_remove_linkback', '1');
|
47 |
}
|
48 |
register_activation_hook(__FILE__, 'bp_media_activate');
|
49 |
|
readme.txt
CHANGED
@@ -1,90 +1,93 @@
|
|
1 |
-
=== BuddyPress Media Component ===
|
2 |
-
Contributors: rtcamp
|
3 |
-
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9488824
|
4 |
-
Tags: BuddyPress, media, multimedia, audio, video, photo, images, upload, share, MediaElement.js, ffmpeg, kaltura
|
5 |
-
License: GPLv2 or later
|
6 |
-
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
7 |
-
Requires at least: 3.3.2
|
8 |
-
Tested up to: 3.4.2
|
9 |
-
Stable tag: 2.1.
|
10 |
-
|
11 |
-
Adds multimedia features to your BuddyPress based social network. Support mobile devices.& audio/video conversion.
|
12 |
-
|
13 |
-
== Description ==
|
14 |
-
|
15 |
-
BuddyPress Media Component adds multimedia features to your BuddyPress based social network, so that your members can upload and share photos, audio and videos with their friends.
|
16 |
-
|
17 |
-
= Features =
|
18 |
-
* Images, Audio and Video Support
|
19 |
-
* Uploading Photos/Videos via mobile (Tested on iPhone running iOS6)
|
20 |
-
* HTML5 player (with fall back to flash/silverlight player support)
|
21 |
-
* Automatic conversion of common audio & video formats to mp3/mp4. via [Premium Add-On](http://rtcamp.com/store "Visit rtCamp's Store")
|
22 |
-
|
23 |
-
= Roadmap =
|
24 |
-
* Kaltura Integration (work already started).
|
25 |
-
* Paid membership plans, i.e. "Upload Quota" for buddypress members (in planning stage).
|
26 |
-
|
27 |
-
== Installation ==
|
28 |
-
|
29 |
-
= BuddyPress Media Plugin =
|
30 |
-
|
31 |
-
Install the plugin from the 'Plugins' section in your dashboard (Go to `Plugins > Add New > Search` and search for BuddyPress Media).
|
32 |
-
|
33 |
-
Alternatively, you can [download](http://downloads.wordpress.org/plugin/buddypress-media.zip "Download BuddyPress Media") the plugin from the repository. Unzip it and upload it to the plugins folder of your WordPress installation (`wp-content/plugins/` directory of your WordPress installation).
|
34 |
-
|
35 |
-
Activate it through the 'Plugins' section.
|
36 |
-
|
37 |
-
= BuddyPress Media Add-ons =
|
38 |
-
|
39 |
-
= bpm-ffmpeg addon =
|
40 |
-
|
41 |
-
It also supports many video formats including *.avi, *.mkv, *.asf, *.flv, *.wmv, *.rm, *.mpg.
|
42 |
-
It also supports many audio formats including *.mp3, *.ogg, *.wav, *.aac, *.m4a, *.wma.
|
43 |
-
|
44 |
-
You can purchase it from [here](http://rtcamp.com/store/buddypress-media-ffmpeg-converter/ "Buy bpm-ffmpeg from rtCamp").
|
45 |
-
|
46 |
-
Important: bpm-ffmpeg addon needs free & open-source [Media Node](https://github.com/rtCamp/media-node "Media Node on GitHub").
|
47 |
-
|
48 |
-
|
49 |
-
== Frequently Asked Questions ==
|
50 |
-
|
51 |
-
Please visit [BuddyPress Media Component's FAQ page](http://rtcamp.com/buddypress-media/faq/ "Visit BuddyPress Media Component's FAQ page").
|
52 |
-
|
53 |
-
== Screenshots ==
|
54 |
-
|
55 |
-
Please visit [BuddyPress Media Component's Features page](http://rtcamp.com/buddypress-media/features/ "Visit BuddyPress Media Component's Features page").
|
56 |
-
|
57 |
-
== Changelog ==
|
58 |
-
|
59 |
-
= 2.1.
|
60 |
-
*
|
61 |
-
|
62 |
-
= 2.1 =
|
63 |
-
*
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
*
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
* Added
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
*
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
*
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
*
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
1 |
+
=== BuddyPress Media Component ===
|
2 |
+
Contributors: rtcamp
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9488824
|
4 |
+
Tags: BuddyPress, media, multimedia, audio, video, photo, images, upload, share, MediaElement.js, ffmpeg, kaltura
|
5 |
+
License: GPLv2 or later
|
6 |
+
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
7 |
+
Requires at least: 3.3.2
|
8 |
+
Tested up to: 3.4.2
|
9 |
+
Stable tag: 2.1.2
|
10 |
+
|
11 |
+
Adds multimedia features to your BuddyPress based social network. Support mobile devices.& audio/video conversion.
|
12 |
+
|
13 |
+
== Description ==
|
14 |
+
|
15 |
+
BuddyPress Media Component adds multimedia features to your BuddyPress based social network, so that your members can upload and share photos, audio and videos with their friends.
|
16 |
+
|
17 |
+
= Features =
|
18 |
+
* Images, Audio and Video Support
|
19 |
+
* Uploading Photos/Videos via mobile (Tested on iPhone running iOS6)
|
20 |
+
* HTML5 player (with fall back to flash/silverlight player support)
|
21 |
+
* Automatic conversion of common audio & video formats to mp3/mp4. via [Premium Add-On](http://rtcamp.com/store "Visit rtCamp's Store")
|
22 |
+
|
23 |
+
= Roadmap =
|
24 |
+
* Kaltura Integration (work already started).
|
25 |
+
* Paid membership plans, i.e. "Upload Quota" for buddypress members (in planning stage).
|
26 |
+
|
27 |
+
== Installation ==
|
28 |
+
|
29 |
+
= BuddyPress Media Plugin =
|
30 |
+
|
31 |
+
Install the plugin from the 'Plugins' section in your dashboard (Go to `Plugins > Add New > Search` and search for BuddyPress Media).
|
32 |
+
|
33 |
+
Alternatively, you can [download](http://downloads.wordpress.org/plugin/buddypress-media.zip "Download BuddyPress Media") the plugin from the repository. Unzip it and upload it to the plugins folder of your WordPress installation (`wp-content/plugins/` directory of your WordPress installation).
|
34 |
+
|
35 |
+
Activate it through the 'Plugins' section.
|
36 |
+
|
37 |
+
= BuddyPress Media Add-ons =
|
38 |
+
|
39 |
+
= bpm-ffmpeg addon =
|
40 |
+
|
41 |
+
It also supports many video formats including *.avi, *.mkv, *.asf, *.flv, *.wmv, *.rm, *.mpg.
|
42 |
+
It also supports many audio formats including *.mp3, *.ogg, *.wav, *.aac, *.m4a, *.wma.
|
43 |
+
|
44 |
+
You can purchase it from [here](http://rtcamp.com/store/buddypress-media-ffmpeg-converter/ "Buy bpm-ffmpeg from rtCamp").
|
45 |
+
|
46 |
+
Important: bpm-ffmpeg addon needs free & open-source [Media Node](https://github.com/rtCamp/media-node "Media Node on GitHub").
|
47 |
+
|
48 |
+
|
49 |
+
== Frequently Asked Questions ==
|
50 |
+
|
51 |
+
Please visit [BuddyPress Media Component's FAQ page](http://rtcamp.com/buddypress-media/faq/ "Visit BuddyPress Media Component's FAQ page").
|
52 |
+
|
53 |
+
== Screenshots ==
|
54 |
+
|
55 |
+
Please visit [BuddyPress Media Component's Features page](http://rtcamp.com/buddypress-media/features/ "Visit BuddyPress Media Component's Features page").
|
56 |
+
|
57 |
+
== Changelog ==
|
58 |
+
|
59 |
+
= 2.1.2 =
|
60 |
+
* Changed some default values and normalized all files with end of file as line feed only
|
61 |
+
|
62 |
+
= 2.1.1 =
|
63 |
+
* Some changes in readme file
|
64 |
+
|
65 |
+
= 2.1 =
|
66 |
+
* Added necessary hooks & filters to support buddypress-media add-on creation.
|
67 |
+
* Support for video format added including *.avi, *.mkv, *.asf, *.flv, *.wmv, *.rm, *.mpg.
|
68 |
+
* Support for audio format added including *.mp3, *.ogg, *.wav, *.aac, *.m4a, *.wma.
|
69 |
+
|
70 |
+
= 2.0.4 =
|
71 |
+
* Added remaining modules of getID3 php library
|
72 |
+
* Added checking for MP3 filetype and its content before uploading
|
73 |
+
|
74 |
+
= 2.0.3 =
|
75 |
+
* Added a few filters and actions for addon support
|
76 |
+
* Fixed the short open tag bug
|
77 |
+
|
78 |
+
= 2.0.2 =
|
79 |
+
* Delete functionality fixed
|
80 |
+
* Edit functionality for Media Title and Media Description
|
81 |
+
* Admins can manage which media types to allow
|
82 |
+
|
83 |
+
= 2.0.1 =
|
84 |
+
* Replaced codec finding library
|
85 |
+
* Fixed warning on activities page
|
86 |
+
|
87 |
+
= 2.0 =
|
88 |
+
* Integration into BuddyPress Activities
|
89 |
+
* HTML5 Audio Tag Support (with fallback)
|
90 |
+
* HTML5 Video Tag Support (with fallback)
|
91 |
+
|
92 |
+
== Upgrade Notice ==
|
93 |
+
Added support for common video & audio format conversion using FFMPEG. Also added support for third-party add-ons.
|