Преглед на файлове

Evolution #472: Inclusion jPlayer

Sevajol Bastien преди 11 години
родител
ревизия
ee1af208ec
променени са 62 файла, в които са добавени 6718 реда и са изтрити 71 реда
  1. 1 1
      app/Resources/translations/userui.fr.yml
  2. 0 0
      src/Muzich/CoreBundle/Command/TagOrderCommand.php
  3. 24 0
      src/Muzich/CoreBundle/Controller/ElementController.php
  4. 0 0
      src/Muzich/CoreBundle/Factory/ElementFactory.php
  5. 0 0
      src/Muzich/CoreBundle/Factory/Elements/Dailymotioncom.php
  6. 0 0
      src/Muzich/CoreBundle/Factory/Elements/Deezercom.php
  7. 62 7
      src/Muzich/CoreBundle/Factory/Elements/Jamendocom.php
  8. 0 0
      src/Muzich/CoreBundle/Factory/Elements/Soundcloudcom.php
  9. 0 0
      src/Muzich/CoreBundle/Factory/Elements/Youtube.php
  10. 0 0
      src/Muzich/CoreBundle/Factory/Elements/Youtubecom.php
  11. 1 1
      src/Muzich/CoreBundle/Managers/ElementManager.php
  12. 4 0
      src/Muzich/CoreBundle/Resources/config/routing.yml
  13. 64 12
      src/Muzich/CoreBundle/Resources/views/layout.html.twig
  14. 0 0
      src/Muzich/CoreBundle/Searcher/ElementSearcherQueryBuilder.php
  15. 0 0
      src/Muzich/CoreBundle/Tests/User/UserTest.php
  16. 0 0
      src/Muzich/CoreBundle/lib/AutoplayManager.php
  17. 0 0
      src/Muzich/CoreBundle/lib/Tag.php
  18. 0 0
      src/Muzich/HomeBundle/Resources/views/Home/need_tags.html.twig
  19. 19 13
      web/bundles/muzichcore/css/main.css
  20. 0 0
      web/bundles/muzichcore/img/1349338086_adept_update.png
  21. 0 0
      web/bundles/muzichcore/img/1353494305_player_play.png
  22. 0 0
      web/bundles/muzichcore/img/1353498913_window-close.png
  23. 0 0
      web/bundles/muzichcore/img/1353503730_button-previous.png
  24. 0 0
      web/bundles/muzichcore/img/1353503762_button-next.png
  25. 0 0
      web/bundles/muzichcore/img/1353505865_button_previous.png
  26. 0 0
      web/bundles/muzichcore/img/1353505874_button_next.png
  27. 0 0
      web/bundles/muzichcore/img/autoplay_next.png
  28. 0 0
      web/bundles/muzichcore/img/autoplay_previous.png
  29. 0 0
      web/bundles/muzichcore/img/player_end.png
  30. 0 0
      web/bundles/muzichcore/img/player_pause.png
  31. 0 0
      web/bundles/muzichcore/img/player_play.png
  32. 0 0
      web/bundles/muzichcore/img/player_start.png
  33. 271 37
      web/bundles/muzichcore/js/autoplay.js
  34. BIN
      web/jplayer/js/Jplayer.swf
  35. 243 0
      web/jplayer/js/circle.player.js
  36. 30 0
      web/jplayer/js/jplayer.playlist.min.js
  37. 201 0
      web/jplayer/js/jquery.grab.js
  38. 331 0
      web/jplayer/js/jquery.jplayer.inspector.js
  39. 97 0
      web/jplayer/js/jquery.jplayer.min.js
  40. 551 0
      web/jplayer/js/jquery.transform2d.js
  41. 2 0
      web/jplayer/js/mod.csstransforms.min.js
  42. 559 0
      web/jplayer/js/popcorn.jplayer.js
  43. 2212 0
      web/jplayer/js/popcorn.js
  44. 460 0
      web/jplayer/js/popcorn.player.js
  45. 143 0
      web/jplayer/js/popcorn.subtitle.js
  46. 640 0
      web/jplayer/skin/blue.monday/jplayer.blue.monday.css
  47. BIN
      web/jplayer/skin/blue.monday/jplayer.blue.monday.jpg
  48. BIN
      web/jplayer/skin/blue.monday/jplayer.blue.monday.seeking.gif
  49. BIN
      web/jplayer/skin/blue.monday/jplayer.blue.monday.video.play.png
  50. BIN
      web/jplayer/skin/circle.skin/bgr.jpg
  51. BIN
      web/jplayer/skin/circle.skin/buffer.png
  52. 133 0
      web/jplayer/skin/circle.skin/circle.player.css
  53. BIN
      web/jplayer/skin/circle.skin/controls.jpg
  54. BIN
      web/jplayer/skin/circle.skin/progress.png
  55. BIN
      web/jplayer/skin/circle.skin/progress_sprite.jpg
  56. 670 0
      web/jplayer/skin/pink.flag/jplayer.pink.flag.css
  57. BIN
      web/jplayer/skin/pink.flag/jplayer.pink.flag.jpg
  58. BIN
      web/jplayer/skin/pink.flag/jplayer.pink.flag.seeking.gif
  59. BIN
      web/jplayer/skin/pink.flag/jplayer.pink.flag.video.play.png
  60. 0 0
      web/js/jquery-1.8.2.dev.js
  61. 0 0
      web/js/jquery-1.8.2.prod.js
  62. 0 0
      web/js/swfobject.js

+ 1 - 1
app/Resources/translations/userui.fr.yml Целия файл

@@ -167,4 +167,4 @@ need_tags:
167 167
                          Gagnez en réputation en leurs proposants les tags qui conviennent !
168 168
 
169 169
 autoplay:
170
-  limitations_players:   La lecture automatique ne supporte actuellement que les lecteurs youtube et soundcloud.
170
+  limitations_players:   La lecture automatique ne supporte actuellement que les lecteurs youtube, soundcloud et jamendo.

+ 0 - 0
src/Muzich/CoreBundle/Command/TagOrderCommand.php Целия файл


+ 24 - 0
src/Muzich/CoreBundle/Controller/ElementController.php Целия файл

@@ -1130,4 +1130,28 @@ class ElementController extends Controller
1130 1130
     ));
1131 1131
   }
1132 1132
   
1133
+  
1134
+  
1135
+  public function geJamendotStreamDatasAction(Request $request, $element_id)
1136
+  {
1137
+    if (($response = $this->mustBeConnected(true)))
1138
+    {
1139
+      return $response;
1140
+    }
1141
+    
1142
+    if (!($element = $this->getDoctrine()->getRepository('MuzichCoreBundle:Element')
1143
+      ->findOneById($element_id)))
1144
+    {
1145
+      throw $this->createNotFoundException('Not found');
1146
+    }
1147
+        
1148
+    $manager = new ElementManager($element, $this->getEntityManager(), $this->container);
1149
+    $stream_data = $manager->getFactory()->getStreamData();
1150
+    
1151
+    return $this->jsonResponse(array(
1152
+      'status' => 'success',
1153
+      'data'   => $stream_data,
1154
+    ));
1155
+  }
1156
+  
1133 1157
 }

+ 0 - 0
src/Muzich/CoreBundle/Factory/ElementFactory.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/Factory/Elements/Dailymotioncom.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/Factory/Elements/Deezercom.php Целия файл


+ 62 - 7
src/Muzich/CoreBundle/Factory/Elements/Jamendocom.php Целия файл

@@ -13,13 +13,7 @@ use Muzich\CoreBundle\Entity\Element;
13 13
 class Jamendocom extends ElementFactory
14 14
 {
15 15
   
16
-  /**
17
-   *  ALBUM = http://www.jamendo.com/fr/album/30661
18
-   *  TRACK = http://www.jamendo.com/fr/track/207079
19
-   * 
20
-   * API: http://developer.jamendo.com/fr/wiki/Musiclist2ApiFields
21
-   */
22
-  public function retrieveDatas()
16
+  protected function proceedTypeAndId()
23 17
   {
24 18
     $url_clean = $this->getCleanedUrl();
25 19
         
@@ -56,6 +50,67 @@ class Jamendocom extends ElementFactory
56 50
     
57 51
     $this->element->setData(Element::DATA_TYPE  , $type);
58 52
     $this->element->setData(Element::DATA_REF_ID, $ref_id);
53
+  }
54
+  
55
+  public function getStreamData()
56
+  {
57
+    // On determine le type et l'url
58
+    $this->proceedTypeAndId();
59
+    
60
+    $type = $this->element->getData(Element::DATA_TYPE);
61
+    $ref_id = $this->element->getData(Element::DATA_REF_ID);
62
+    
63
+    // Récupération de données avec l'API
64
+    $api_url = null;
65
+    switch ($type)
66
+    {
67
+      case 'track':
68
+        $api_url = "http://api.jamendo.com/get2/name+stream/track/json/?track_id=".$ref_id;
69
+      break;
70
+    
71
+      case 'album':
72
+        $api_url = "http://api.jamendo.com/get2/name+stream/track/json/?album_id=".$ref_id;
73
+      break;
74
+    }
75
+    
76
+    if ($api_url)
77
+    {
78
+      $ch = curl_init($api_url);
79
+      $options = array(
80
+        CURLOPT_RETURNTRANSFER => true,
81
+        CURLOPT_HTTPHEADER => array('Content-type: text/plain')
82
+      );
83
+      curl_setopt_array( $ch, $options );
84
+      $result = json_decode(curl_exec($ch), true);
85
+      
86
+      if (count($result))
87
+      {
88
+        $data_return = array();
89
+        foreach ($result as $song)
90
+        {
91
+          $data_return[] = array(
92
+            'name' => $song['name'],
93
+            'url'  => $song['stream'],
94
+          );
95
+        }
96
+        return $data_return;
97
+      }
98
+    }
99
+  }
100
+  
101
+  /**
102
+   *  ALBUM = http://www.jamendo.com/fr/album/30661
103
+   *  TRACK = http://www.jamendo.com/fr/track/207079
104
+   * 
105
+   * API: http://developer.jamendo.com/fr/wiki/Musiclist2ApiFields
106
+   */
107
+  public function retrieveDatas()
108
+  {
109
+    // On determine le type et l'url
110
+    $this->proceedTypeAndId();
111
+    
112
+    $type = $this->element->getData(Element::DATA_TYPE);
113
+    $ref_id = $this->element->getData(Element::DATA_REF_ID);
59 114
     
60 115
     // Récupération de données avec l'API
61 116
     $api_url = null;

+ 0 - 0
src/Muzich/CoreBundle/Factory/Elements/Soundcloudcom.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/Factory/Elements/Youtube.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/Factory/Elements/Youtubecom.php Целия файл


+ 1 - 1
src/Muzich/CoreBundle/Managers/ElementManager.php Целия файл

@@ -142,7 +142,7 @@ class ElementManager
142 142
     
143 143
   }
144 144
   
145
-  protected function getFactory()
145
+  public function getFactory()
146 146
   { 
147 147
 //    $factory_name = ucfirst(str_replace('.', '', $this->element->getType())).'Factory';
148 148
 //    return new $factory_name($this->element, $this->container);

+ 4 - 0
src/Muzich/CoreBundle/Resources/config/routing.yml Целия файл

@@ -179,3 +179,7 @@ element_show_need_tags:
179 179
 element_dom_get_one:
180 180
   pattern: /ajax/element/dom/get/{type}/{element_id}
181 181
   defaults: { _controller: MuzichCoreBundle:Element:getOneDom, element_id: null }
182
+
183
+element_get_stream_data:
184
+  pattern: /ajax/element/data/get/stream/{element_id}
185
+  defaults: { _controller: MuzichCoreBundle:Element:geJamendotStreamDatas, element_id: null }

+ 64 - 12
src/Muzich/CoreBundle/Resources/views/layout.html.twig Целия файл

@@ -3,9 +3,8 @@
3 3
 	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4 4
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
5 5
 <head>
6
-	<title>Muzi.ch - {% block title %}{% endblock %}</title>
7
-	
8
-	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
6
+  <title>Muzi.ch - {% block title %}{% endblock %}</title>
7
+  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
9 8
 	<meta http-equiv="Content-Style-Type" content="text/css" />
10 9
 	<meta name="description" content="" />
11 10
 	<meta name="keywords" content="" />
@@ -22,15 +21,20 @@
22 21
 	<script src="{{ asset('js/jquery-1.8.2.prod.js') }}" type="text/javascript"></script>
23 22
   {% endif %}
24 23
   <script src="{{ asset('js/jquery-ui-1.8.7.min.js') }}" type="text/javascript"></script>
25
-	<script src="{{ asset('bundles/muzichcore/js/muzich.js') }}" type="text/javascript"></script>
24
+  <script src="{{ asset('bundles/muzichcore/js/muzich.js') }}" type="text/javascript"></script>
26 25
 	
27 26
   <script type="text/javascript" src="{{ asset('js/swfobject.js') }}"></script> 
28
-  
29
-       <script src="http://connect.soundcloud.com/sdk.js"></script>
30
-       <script src="http://w.soundcloud.com/player/api.js"></script>
27
+  {# TODO: On peux piquer les js ?  #}
28
+  <script src="http://connect.soundcloud.com/sdk.js"></script>
29
+  <script src="http://w.soundcloud.com/player/api.js"></script>
31 30
        
32 31
   <script src="{{ asset('bundles/muzichcore/js/autoplay.js') }}" type="text/javascript"></script>
33 32
   
33
+  {# jPlayer #}
34
+  <link href="{{ asset('jplayer/skin/blue.monday/jplayer.blue.monday.css') }}" rel="stylesheet" type="text/css" />
35
+  <script type="text/javascript" src="{{ asset('jplayer/js/jquery.jplayer.min.js') }}"></script>
36
+  <script type="text/javascript" src="{{ asset('jplayer/js/jplayer.playlist.min.js') }}"></script>
37
+  
34 38
   <script src="{{ asset('js/tags/jquery.autoGrowInput.js') }}" type="text/javascript"></script>
35 39
   <script src="{{ asset('js/tags/jquery.tagBox.js') }}" type="text/javascript"></script>
36 40
   <script src="{{ asset('js/formdefault/jquery.formdefaults.js') }}" type="text/javascript"></script>
@@ -77,6 +81,7 @@
77 81
     url_datas_api = "{{ path('element_retrieve_api_datas') }}";
78 82
     url_element_add = "{{ path('element_add') }}";
79 83
     url_element_dom_get_one_autoplay = "{{ path('element_dom_get_one', {'type':'autoplay'}) }}";
84
+    url_element_get_stream_data = "{{ path('element_get_stream_data') }}";
80 85
     
81 86
     url_img_ajax_loader = "{{ asset('/bundles/muzichcore/img/ajax-loader.gif') }}";
82 87
   </script>
@@ -90,6 +95,11 @@
90 95
       <a href="javascript:void(0);" id="autoplay_previous">
91 96
         <img src="{{ asset('/bundles/muzichcore/img/autoplay_previous.png') }}" alt="previous" />
92 97
       </a>
98
+      
99
+	<a href="javascript:void(0);" id="autoplay_close" >
100
+	  <img src="{{ asset('/bundles/muzichcore/img/1317386146_cancel.png') }}" alt="close" />
101
+	</a>
102
+      
93 103
       <a href="javascript:void(0);" id="autoplay_next">
94 104
         <img src="{{ asset('/bundles/muzichcore/img/autoplay_next.png') }}" alt="next" />
95 105
       </a>
@@ -100,13 +110,55 @@
100 110
       <div id="autoplay_player"></div>
101 111
     </div>
102 112
     <div id="autoplay_player_soundcloud"></div>
113
+    <div id="autoplay_player_generic" style="display: none;">
114
+      <div id="jquery_jplayer_1" class="jp-jplayer"></div>
115
+      <div id="jp_container_1" class="jp-audio">
116
+        <div class="jp-type-playlist">
117
+          <div class="jp-gui jp-interface">
118
+            <ul class="jp-controls">
119
+              <li><a href="javascript:;" class="jp-previous" tabindex="1">previous</a></li>
120
+              <li><a href="javascript:;" class="jp-play" tabindex="1">play</a></li>
121
+              <li><a href="javascript:;" class="jp-pause" tabindex="1">pause</a></li>
122
+              <li><a href="javascript:;" class="jp-next" tabindex="1">next</a></li>
123
+              <li><a href="javascript:;" class="jp-stop" tabindex="1">stop</a></li>
124
+              <li><a href="javascript:;" class="jp-mute" tabindex="1" title="mute">mute</a></li>
125
+              <li><a href="javascript:;" class="jp-unmute" tabindex="1" title="unmute">unmute</a></li>
126
+              <li><a href="javascript:;" class="jp-volume-max" tabindex="1" title="max volume">max volume</a></li>
127
+            </ul>
128
+            <div class="jp-progress">
129
+              <div class="jp-seek-bar">
130
+                <div class="jp-play-bar"></div>
131
+              </div>
132
+            </div>
133
+            <div class="jp-volume-bar">
134
+              <div class="jp-volume-bar-value"></div>
135
+            </div>
136
+            <div class="jp-time-holder">
137
+              <div class="jp-current-time"></div>
138
+              <div class="jp-duration"></div>
139
+            </div>
140
+            <ul class="jp-toggles" style="display: none;">
141
+              <li><a href="javascript:;" class="jp-shuffle" tabindex="1" title="shuffle">shuffle</a></li>
142
+              <li><a href="javascript:;" class="jp-shuffle-off" tabindex="1" title="shuffle off">shuffle off</a></li>
143
+              <li><a href="javascript:;" class="jp-repeat" tabindex="1" title="repeat">repeat</a></li>
144
+              <li><a href="javascript:;" class="jp-repeat-off" tabindex="1" title="repeat off">repeat off</a></li>
145
+            </ul>
146
+          </div>
147
+          <div class="jp-playlist">
148
+            <ul>
149
+              <li></li>
150
+            </ul>
151
+          </div>
152
+          <div class="jp-no-solution">
153
+            <span>Update Required</span>
154
+            To play the media you will need to either update your browser to a recent version or update your <a href="http://get.adobe.com/flashplayer/" target="_blank">Flash plugin</a>.
155
+          </div>
156
+        </div>
157
+      </div>
158
+    </div>
103 159
     <img id="autoplay_loader" src="{{ asset('/bundles/muzichcore/img/ajax-loader.gif') }}" alt="loader" />
104 160
     <p id="autoplay_noelements_text" style="display: none;">{{ 'elements.autoplay.noelements.text'|trans({}, 'elements') }}</p>
105
-    
106
-    <a href="javascript:void(0);" id="autoplay_close" >
107
-      <img src="{{ asset('/bundles/muzichcore/img/1317386146_cancel.png') }}" alt="close" />
108
-    </a>
109
-    
161
+        
110 162
     <p><span class="sinfo">{{ 'autoplay.limitations_players'|trans({}, 'userui') }}</span></p>
111 163
     
112 164
   </div>

+ 0 - 0
src/Muzich/CoreBundle/Searcher/ElementSearcherQueryBuilder.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/Tests/User/UserTest.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/lib/AutoplayManager.php Целия файл


+ 0 - 0
src/Muzich/CoreBundle/lib/Tag.php Целия файл


+ 0 - 0
src/Muzich/HomeBundle/Resources/views/Home/need_tags.html.twig Целия файл


+ 19 - 13
web/bundles/muzichcore/css/main.css Целия файл

@@ -90,6 +90,11 @@ input.button, button.button {
90 90
   color: #00d0de;
91 91
 }
92 92
 
93
+#autoplay div.jp-audio a
94
+{
95
+  color: black;
96
+}
97
+
93 98
 #container a.button, #autoplay a.button
94 99
 {
95 100
   color: white;
@@ -1344,25 +1349,26 @@ a#autoplay_next
1344 1349
 a#autoplay_previous, a#autoplay_next, a#autoplay_close
1345 1350
 {
1346 1351
   background: #fff;
1347
-	padding: 5px;
1348
-	border: 10px solid #ddd;
1349
-	z-index: 99999;
1350
-	/*--Les différentes définitions de Box Shadow en CSS3--*/
1351
-	-webkit-box-shadow: 0px 0px 20px #000;
1352
-	-moz-box-shadow: 0px 0px 20px #000;
1353
-	box-shadow: 0px 0px 20px #000;
1354
-	/*--Coins arrondis en CSS3--*/
1355
-	-webkit-border-radius: 10px;
1356
-	-moz-border-radius: 10px;
1357
-	border-radius: 10px;
1352
+  padding: 5px;
1353
+  border: 10px solid #ddd;
1354
+  z-index: 99999;
1355
+  /*--Les différentes définitions de Box Shadow en CSS3--*/
1356
+  -webkit-box-shadow: 0px 0px 20px #000;
1357
+  -moz-box-shadow: 0px 0px 20px #000;
1358
+  box-shadow: 0px 0px 20px #000;
1359
+  /*--Coins arrondis en CSS3--*/
1360
+  -webkit-border-radius: 10px;
1361
+  -moz-border-radius: 10px;
1362
+  border-radius: 10px;
1358 1363
 }
1359 1364
 
1360 1365
 a#autoplay_close
1361 1366
 {
1362 1367
   float: left;
1363 1368
   text-decoration: none;
1364
-  margin-top: -100px;
1365
-  margin-left: -120px;
1369
+  margin-top: 130px;
1370
+  margin-left: -110px;
1371
+  z-index: 99;
1366 1372
 }
1367 1373
 
1368 1374
 div#autoplay_title

+ 0 - 0
web/bundles/muzichcore/img/1349338086_adept_update.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/1353494305_player_play.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/1353498913_window-close.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/1353503730_button-previous.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/1353503762_button-next.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/1353505865_button_previous.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/1353505874_button_next.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/autoplay_next.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/autoplay_previous.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/player_end.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/player_pause.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/player_play.png Целия файл


+ 0 - 0
web/bundles/muzichcore/img/player_start.png Целия файл


+ 271 - 37
web/bundles/muzichcore/js/autoplay.js Целия файл

@@ -22,6 +22,17 @@ $(document).ready(function(){
22 22
   var autoplay_last_element_id = null;
23 23
   // Pour savoir si on est en bout de ligne
24 24
   var autoplay_no_more = false;
25
+  // Pour savoir si le lecteur générique a déjà été lancé
26
+  var autoplay_generic_player_launched = false;
27
+  // contient l'objet playlist du lecteur générique
28
+  var autoplay_generic_player_playlist = null;
29
+  // contient le nombre de tracks dans la playlist du lecteur générique
30
+  var autoplay_generic_player_playlist_count = 0;
31
+  // Index dernière piste lu par lecteur générique
32
+  var autoplay_generic_player_index_track_previous = 0;
33
+  // pour notre hack: les données previous track, current track sont
34
+  // interprété différemment lorsque on est a notre 2ème lecture ...
35
+  var autoplay_generic_player_first_launch = null;
25 36
   
26 37
   // En cas de click sur un bouton de lecture
27 38
   $('a#autoplay_launch').click(function(){
@@ -38,29 +49,56 @@ $(document).ready(function(){
38 49
       
39 50
       if (response.status == 'success')
40 51
       {
52
+        
53
+        // hack
54
+          autoplay_generic_player_playlist = new jPlayerPlaylist({
55
+            jPlayer: "#jquery_jplayer_1",
56
+            cssSelectorAncestor: "#jp_container_1"
57
+          },
58
+          []
59
+          , {
60
+             playlistOptions: {
61
+              autoPlay: true,
62
+              enableRemoveControls: true
63
+            },
64
+            swfPath: "/jplayer/js",
65
+            supplied: "mp3",
66
+            wmode: "window"
67
+          });
68
+        
41 69
         // On récupère la liste d'élèments
42 70
         autoplay_list = response.data;
71
+        // On renseigne l'id de l'élèment en cours de demande de lecture
43 72
         autoplay_last_element_id = autoplay_list[0].element_id;
73
+        // On par sur l'index premier de la liste de lecture
44 74
         autoplay_step = 0;
45
-        autoplay_run(0);
75
+        // On lance la lecture auo
76
+        autoplay_run(autoplay_step, false);
46 77
       }
47 78
       
48 79
     });
49 80
     return false;
50 81
   });
51 82
   
52
-  function autoplay_load_element(element_id, timeouted)
83
+  /**
84
+   * Cette fonction est chargé de récupérer le bloc élent avec le nom, la note etc ...
85
+   * @param {int} element_id
86
+   * @param {boolean} timed
87
+   */
88
+  function autoplay_load_element(element_id, timed)
53 89
   {
54
-    // On vérifie ici que c'est le dernier élement demandé, ca evite de multiples
55
-    // requetes en cas de brute click sur les flèches.
56
-    if (!timeouted)
90
+    // Si on a pas retardé cette demande
91
+    if (!timed)
57 92
     {
93
+      // Alors il faut que l'on attende un peu, au cas ou il y avait plein de clics simultanés
58 94
       $('#autoplay_element_loader').show();
59 95
       $('li#autoplay_element_container').html('');
60
-      setTimeout(autoplay_load_element, 1000, element_id, true);
96
+      // On relance le bousin dans x millisecondes
97
+      setTimeout(autoplay_load_element, 500, element_id, true);
61 98
     }
62 99
     else
63 100
     {
101
+      // On ne lance la procédure que si il n'y as pas eu de nouvelle demande depuis
64 102
       if (autoplay_last_element_id == element_id)
65 103
       {
66 104
         $.getJSON(url_element_dom_get_one_autoplay+'/'+element_id, function(response) {
@@ -91,50 +129,76 @@ $(document).ready(function(){
91 129
     }
92 130
   }
93 131
   
94
-  // Lancement de l'élèment suivant
95
-  function autoplay_run(step)
132
+  /**
133
+   * Lancement d'une lecture d'élément
134
+   * @param {int} step
135
+   * @param {boolean} timed
136
+   */
137
+  function autoplay_run(step, timed)
96 138
   {
97
-    // En premier lieu on réinitialise le lecteur en détruisant le dom qui a
98
-    // pu être créé par la lecture précedente.
99
-    autoplay_clean_for_player_creation();
100
-    
101
-    // Pause des lecteurs potentiels
102
-    autoplay_pause_all_players();
103 139
     
104
-    if (autoplay_list.length)
140
+    if (!timed)
141
+    {     
142
+      // En premier lieu on réinitialise le lecteur en détruisant le dom qui a
143
+      // pu être créé par la lecture précedente.
144
+      autoplay_clean_for_player_creation();
145
+      
146
+      // Pause des lecteurs potentiels
147
+      autoplay_pause_all_players();
148
+      
149
+      // On la relance au cas ou il y a eu de multiples clicks
150
+      setTimeout(autoplay_run, 500, step, true);
151
+    }
152
+    else if (autoplay_last_element_id == autoplay_list[step].element_id)
105 153
     {
106
-    
107
-      if (array_key_exists(step, autoplay_list))
154
+      
155
+      if (autoplay_list.length)
108 156
       {
109
-        
110
-        // Youtube case
111
-        if (autoplay_list[step].element_type == 'youtube.com' || autoplay_list[step].element_type == 'youtu.be')
112
-        {
113
-          autoplay_load_element(autoplay_list[step].element_id, false);
114
-          youtube_create_player(autoplay_list[step].element_ref_id);
115
-        }
116
-
117
-        if (autoplay_list[step].element_type == 'soundcloud.com')
157
+      
158
+        if (array_key_exists(step, autoplay_list))
118 159
         {
119
-          autoplay_load_element(autoplay_list[step].element_id, false);
120
-          soundcloud_create_player(autoplay_list[step].element_ref_id, autoplay_list[step].element_normalized_url);
160
+          // Youtube case
161
+          if (autoplay_list[step].element_type == 'youtube.com' || autoplay_list[step].element_type == 'youtu.be')
162
+          {
163
+            autoplay_load_element(autoplay_list[step].element_id, false);
164
+            youtube_create_player(autoplay_list[step].element_ref_id);
165
+          }
166
+  
167
+          if (autoplay_list[step].element_type == 'soundcloud.com')
168
+          {
169
+            autoplay_load_element(autoplay_list[step].element_id, false);
170
+            soundcloud_create_player(autoplay_list[step].element_ref_id, autoplay_list[step].element_normalized_url);
171
+          }
172
+  
173
+          if (autoplay_list[step].element_type == 'jamendo.com')
174
+          {
175
+            autoplay_load_element(autoplay_list[step].element_id, false);
176
+            jamendo_create_player(autoplay_list[step].element_id);
177
+          }
178
+          
121 179
         }
122
-        
180
+      
181
+      }
182
+      else
183
+      {
184
+        autoplay_display_nomore();
123 185
       }
124 186
     
125 187
     }
126
-    else
127
-    {
128
-      autoplay_display_nomore();
129
-    }
130 188
   }
131 189
   
190
+  /**
191
+   * Nettoyage du lecteur autoplay pour l'ouverture d'un nouvel élément
192
+   *
193
+   */
132 194
   function autoplay_clean_for_player_creation(clean_element)
133 195
   {
134 196
     autoplay_pause_all_players();
135 197
     
136 198
     $('div#'+autoplay_player_div_id+'_container').html('<div id="'+autoplay_player_div_id+'"></div>');
137 199
     $('#autoplay_noelements_text').hide();
200
+    $('div#autoplay_player_generic').hide();
201
+    
138 202
     if (clean_element)
139 203
     {
140 204
       $('li#autoplay_element_container').html('');
@@ -142,11 +206,20 @@ $(document).ready(function(){
142 206
     $('img#autoplay_loader').show();
143 207
   }
144 208
   
209
+  /**
210
+   * Fonction qui regroupe les méthode de mise en pause de tout les lecteurs
211
+   *
212
+   */
145 213
   function autoplay_pause_all_players()
146 214
   {
215
+    // Pas youtube car on détruit son lecteur
147 216
     soundcloud_stop_player();
217
+    jamendo_stop_player();
148 218
   }
149 219
   
220
+  /**
221
+   * Affichage du message indiquant qu'il n'y a plus rien a lire
222
+   */
150 223
   function autoplay_display_nomore()
151 224
   {
152 225
     autoplay_no_more = true;
@@ -161,7 +234,7 @@ $(document).ready(function(){
161 234
     }
162 235
   }
163 236
   
164
-  // Avancer d'un élelement dans la liste
237
+  // Avancer d'un éleement dans la liste
165 238
   function autoplay_next()
166 239
   {
167 240
     autoplay_no_more = false;
@@ -169,7 +242,7 @@ $(document).ready(function(){
169 242
     if (array_key_exists(autoplay_step, autoplay_list))
170 243
     {
171 244
       autoplay_last_element_id = autoplay_list[autoplay_step].element_id;
172
-      autoplay_run(autoplay_step);
245
+      autoplay_run(autoplay_step, false);
173 246
     }
174 247
     else
175 248
     {
@@ -186,7 +259,7 @@ $(document).ready(function(){
186 259
     if (array_key_exists(autoplay_step, autoplay_list))
187 260
     {
188 261
       autoplay_last_element_id = autoplay_list[autoplay_step].element_id;
189
-      autoplay_run(autoplay_step);
262
+      autoplay_run(autoplay_step, false);
190 263
     }
191 264
     else
192 265
     {
@@ -209,6 +282,8 @@ $(document).ready(function(){
209 282
     $('div#'+autoplay_player_div_id+'_container').html('<div id="'+autoplay_player_div_id+'"></div>');
210 283
     // Plus rien de dois être lu
211 284
     autoplay_pause_all_players();
285
+    // TODO: Pour le moment c'est surtout pour détruire la variable du lecteur générique
286
+    autoplay_clean_for_player_creation();
212 287
   });
213 288
    
214 289
   
@@ -281,6 +356,7 @@ $(document).ready(function(){
281 356
   
282 357
   /*
283 358
    * 
359
+   *
284 360
    * 
285 361
    * Fonctions soundcloud
286 362
    * 
@@ -382,7 +458,6 @@ $(document).ready(function(){
382 458
         if (error) 
383 459
         { 
384 460
           // En cas d'erreur on passe a al suivante
385
-          console.log('Not found!');
386 461
           autoplay_next(); 
387 462
         }
388 463
         else
@@ -409,4 +484,163 @@ $(document).ready(function(){
409 484
     $('div#autoplay_player_soundcloud').hide();
410 485
   }
411 486
   
487
+  /*
488
+   * 
489
+   *
490
+   * 
491
+   * Jamendo.com (utilise le lecteur générique)
492
+   * 
493
+   * 
494
+   */
495
+  
496
+  function jamendo_create_player(element_id)
497
+  {
498
+    autoplay_generic_player_load(element_id);
499
+  }
500
+  
501
+  function jamendo_stop_player()
502
+  {
503
+    autoplay_generic_player_stop();
504
+  }
505
+  
506
+  
507
+  /*
508
+   * 
509
+   * 
510
+   * Lecteur générique
511
+   * 
512
+   */
513
+  
514
+   /**
515
+   * Objet son
516
+   * @param {string} title Nom du morceau qui sera affiché dans la liste de lecture
517
+   * @param {string} mp3 adresse du flux sonore
518
+   */
519
+  function GenericSong(title, mp3)
520
+  {
521
+    this.title = title;
522
+    this.mp3   = mp3;
523
+  }
524
+  
525
+  /**
526
+   * Fonction de lecture d'un élèment avec le lecteur générique
527
+   *
528
+   * @param {int} element_id identifiant internet de l'élément
529
+   */
530
+  function autoplay_generic_player_load(element_id)
531
+  {
532
+    // On doit récupérer les informations pour la lecture streaming
533
+    $.getJSON(url_element_get_stream_data+'/'+element_id, function(response) {
534
+          
535
+      if (response.status == 'mustbeconnected')
536
+      {
537
+        $(location).attr('href', url_index);
538
+      }
539
+
540
+      if (response.status == 'success')
541
+      {
542
+        if (response.data)
543
+        {
544
+          
545
+          // Pour stocker localement les données de notre base
546
+          var autoplay_generic_playlist_data = new Array;
547
+          
548
+          for(var i = 0; i < response.data.length; i++)
549
+          {
550
+            // On construit un objet son pour constituer une bibliothèque (autoplay_generic_playlist_data)
551
+            var song = new GenericSong(response.data[i].name, response.data[i].url);
552
+            autoplay_generic_playlist_data[i] = song;
553
+          }
554
+          
555
+          // On garde en mémoire le nombre de piste que l'on à, ca nous sera utlie pour
556
+          // savoir si on est en fin de lecture par exemple
557
+          autoplay_generic_player_playlist_count = autoplay_generic_playlist_data.length;
558
+          
559
+          $('div#autoplay_player_generic').show();
560
+          
561
+          // On a besoin de savoir si c'est la première fois que l'on charge ce lecteur
562
+          if (autoplay_generic_player_first_launch === null)
563
+          {
564
+            autoplay_generic_player_first_launch = true;
565
+          }
566
+          else if (autoplay_generic_player_first_launch === true)
567
+          {
568
+            autoplay_generic_player_first_launch = false;
569
+          }
570
+          
571
+          // On construit l'objet de jPlayerv avec une playlist
572
+          autoplay_generic_player_playlist = new jPlayerPlaylist({
573
+            jPlayer: "#jquery_jplayer_1",
574
+            cssSelectorAncestor: "#jp_container_1"
575
+          },
576
+          // On stransmet la plsylist a cette position
577
+          autoplay_generic_playlist_data
578
+          , {
579
+             playlistOptions: {
580
+              autoPlay: true,
581
+              enableRemoveControls: true
582
+            },
583
+            swfPath: "/jplayer/js",
584
+            supplied: "mp3",
585
+            wmode: "window"
586
+          });
587
+          
588
+          // On ne bind qu'un seule fois les functions
589
+          if (autoplay_generic_player_launched == false)
590
+          {
591
+            
592
+            // On garde en mémoire la piste lu en ce moment
593
+            $("#jquery_jplayer_1").bind($.jPlayer.event.play, function(event) { 
594
+              autoplay_generic_player_index_track_previous = autoplay_generic_player_playlist.current;
595
+              $('img#autoplay_loader').hide();
596
+            });
597
+            
598
+            $("#jquery_jplayer_1").bind($.jPlayer.event.ended, function(event) { 
599
+              
600
+              // Si la index_track_previous est la même maintenant que la piste
601
+              // est terminé, c'est que l'on est arrivé en fin de liste.
602
+              // Cependant, si c'est une liste avec une piste unique, on passe 
603
+              if (
604
+                  (
605
+                    // Si c'est la première fois il faut qu'après la lecture ce soit les mêmes index
606
+                    ( autoplay_generic_player_first_launch &&
607
+                      autoplay_generic_player_index_track_previous == autoplay_generic_player_playlist.current )
608
+                    ||
609
+                    // Si c'est pas la première fois, on obtient le current avant de passer a al suitante
610
+                    // du coup on peut regarder si on était a la dernière piste
611
+                    ( !autoplay_generic_player_first_launch &&
612
+                      autoplay_generic_player_playlist.current == autoplay_generic_player_playlist_count -1 )
613
+                  )
614
+                || autoplay_generic_player_playlist_count == 1
615
+              )
616
+              {
617
+                console.log('next...')
618
+                autoplay_next();
619
+              }
620
+              
621
+            });
622
+            
623
+            $("#jquery_jplayer_1").bind($.jPlayer.event.error, function(event)
624
+            {
625
+              autoplay_next();
626
+            });
627
+          
628
+          }
629
+          
630
+          autoplay_generic_player_launched = true;
631
+        }
632
+        else
633
+        {
634
+          autoplay_next(); 
635
+        }
636
+      }
637
+
638
+    });
639
+  }
640
+  
641
+  function autoplay_generic_player_stop()
642
+  {
643
+    $("#jquery_jplayer_1").jPlayer("destroy");
644
+  }
645
+  
412 646
 });

BIN
web/jplayer/js/Jplayer.swf Целия файл


+ 243 - 0
web/jplayer/js/circle.player.js Целия файл

@@ -0,0 +1,243 @@
1
+/*
2
+ * CirclePlayer for the jPlayer Plugin (jQuery)
3
+ * http://www.jplayer.org
4
+ *
5
+ * Copyright (c) 2009 - 2012 Happyworm Ltd
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ *  - http://www.opensource.org/licenses/mit-license.php
8
+ *  - http://www.gnu.org/copyleft/gpl.html
9
+ *
10
+ * Version: 1.0.1 (jPlayer 2.1.0+)
11
+ * Date: 30th May 2011
12
+ *
13
+ * Author: Mark J Panaghiston @thepag
14
+ *
15
+ * CirclePlayer prototype developed by:
16
+ * Mark Boas @maboa
17
+ * Silvia Benvenuti @aulentina
18
+ * Jussi Kalliokoski @quinirill
19
+ *
20
+ * Inspired by :
21
+ * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt
22
+ * and
23
+ * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause
24
+ *
25
+ * Standing on the shoulders of :
26
+ * John Resig @jresig
27
+ * Mark Panaghiston @thepag
28
+ * Louis-Rémi Babé @Louis_Remi
29
+ */
30
+
31
+
32
+var CirclePlayer = function(jPlayerSelector, media, options) {
33
+	var	self = this,
34
+
35
+		defaults = {
36
+			// solution: "flash, html", // For testing Flash with CSS3
37
+			supplied: "m4a, oga",
38
+			// Android 2.3 corrupts media element if preload:"none" is used.
39
+			// preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too.
40
+			cssSelectorAncestor: "#cp_container_1",
41
+			cssSelector: {
42
+				play: ".cp-play",
43
+				pause: ".cp-pause"
44
+			}
45
+		},
46
+
47
+		cssSelector = {
48
+			bufferHolder: ".cp-buffer-holder",
49
+			buffer1: ".cp-buffer-1",
50
+			buffer2: ".cp-buffer-2",
51
+			progressHolder: ".cp-progress-holder",
52
+			progress1: ".cp-progress-1",
53
+			progress2: ".cp-progress-2",
54
+			circleControl: ".cp-circle-control"
55
+		};
56
+
57
+	this.cssClass = {
58
+		gt50: "cp-gt50",
59
+		fallback: "cp-fallback"
60
+	};
61
+
62
+	this.spritePitch = 104;
63
+	this.spriteRatio = 0.24; // Number of steps / 100
64
+
65
+	this.player = $(jPlayerSelector);
66
+	this.media = $.extend({}, media);
67
+	this.options = $.extend(true, {}, defaults, options); // Deep copy
68
+
69
+	this.cssTransforms = Modernizr.csstransforms;
70
+	this.audio = {};
71
+	this.dragging = false; // Indicates if the progressbar is being 'dragged'.
72
+
73
+	this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy.
74
+
75
+	this.jq = {};
76
+	$.each(cssSelector, function(entity, cssSel) {
77
+		self.jq[entity] = $(self.options.cssSelectorAncestor + " " + cssSel);
78
+	});
79
+
80
+	this._initSolution();
81
+	this._initPlayer();
82
+};
83
+
84
+CirclePlayer.prototype = {
85
+	_createHtml: function() {
86
+	},
87
+	_initPlayer: function() {
88
+		var self = this;
89
+		this.player.jPlayer(this.options);
90
+
91
+		this.player.bind($.jPlayer.event.ready + this.eventNamespace, function(event) {
92
+			if(event.jPlayer.html.used && event.jPlayer.html.audio.available) {
93
+				self.audio = $(this).data("jPlayer").htmlElement.audio;
94
+			}
95
+			$(this).jPlayer("setMedia", self.media);
96
+			self._initCircleControl();
97
+		});
98
+
99
+		this.player.bind($.jPlayer.event.play + this.eventNamespace, function(event) {
100
+			$(this).jPlayer("pauseOthers");
101
+		});
102
+
103
+		// This event fired as play time increments
104
+		this.player.bind($.jPlayer.event.timeupdate + this.eventNamespace, function(event) {
105
+			if (!self.dragging) {
106
+				self._timeupdate(event.jPlayer.status.currentPercentAbsolute);
107
+			}
108
+		});
109
+
110
+		// This event fired as buffered time increments
111
+		this.player.bind($.jPlayer.event.progress + this.eventNamespace, function(event) {
112
+			var percent = 0;
113
+			if((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) {
114
+				if(self.audio.duration > 0) {
115
+					var bufferTime = 0;
116
+					for(var i = 0; i < self.audio.buffered.length; i++) {
117
+						bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i);
118
+						// console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration);
119
+					}
120
+					percent = 100 * bufferTime / self.audio.duration;
121
+				} // else the Metadata has not been read yet.
122
+				// console.log("percent = " + percent);
123
+			} else { // Fallback if buffered not supported
124
+				// percent = event.jPlayer.status.seekPercent;
125
+				percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined.
126
+			}
127
+			self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill.
128
+			// Firefox 4 does not always give the final progress event when buffered = 100%
129
+		});
130
+
131
+		this.player.bind($.jPlayer.event.ended + this.eventNamespace, function(event) {
132
+			self._resetSolution();
133
+		});
134
+	},
135
+	_initSolution: function() {
136
+		if (this.cssTransforms) {
137
+			this.jq.progressHolder.show();
138
+			this.jq.bufferHolder.show();
139
+		}
140
+		else {
141
+			this.jq.progressHolder.addClass(this.cssClass.gt50).show();
142
+			this.jq.progress1.addClass(this.cssClass.fallback);
143
+			this.jq.progress2.hide();
144
+			this.jq.bufferHolder.hide();
145
+		}
146
+		this._resetSolution();
147
+	},
148
+	_resetSolution: function() {
149
+		if (this.cssTransforms) {
150
+			this.jq.progressHolder.removeClass(this.cssClass.gt50);
151
+			this.jq.progress1.css({'transform': 'rotate(0deg)'});
152
+			this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide();
153
+		}
154
+		else {
155
+			this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px');
156
+		}
157
+	},
158
+	_initCircleControl: function() {
159
+		var self = this;
160
+		this.jq.circleControl.grab({
161
+			onstart: function(){
162
+				self.dragging = true;
163
+			}, onmove: function(event){
164
+				var pc = self._getArcPercent(event.position.x, event.position.y);
165
+				self.player.jPlayer("playHead", pc).jPlayer("play");
166
+				self._timeupdate(pc);
167
+			}, onfinish: function(event){
168
+				self.dragging = false;
169
+				var pc = self._getArcPercent(event.position.x, event.position.y);
170
+				self.player.jPlayer("playHead", pc).jPlayer("play");
171
+			}
172
+		});
173
+	},
174
+	_timeupdate: function(percent) {
175
+		var degs = percent * 3.6+"deg";
176
+
177
+		var spriteOffset = (Math.floor((Math.round(percent))*this.spriteRatio)-1)*-this.spritePitch;
178
+
179
+		if (percent <= 50) {
180
+			if (this.cssTransforms) {
181
+				this.jq.progressHolder.removeClass(this.cssClass.gt50);
182
+				this.jq.progress1.css({'transform': 'rotate(' + degs + ')'});
183
+				this.jq.progress2.hide();
184
+			} else { // fall back
185
+				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
186
+			}
187
+		} else if (percent <= 100) {
188
+			if (this.cssTransforms) {
189
+				this.jq.progressHolder.addClass(this.cssClass.gt50);
190
+				this.jq.progress1.css({'transform': 'rotate(180deg)'});
191
+				this.jq.progress2.css({'transform': 'rotate(' + degs + ')'});
192
+				this.jq.progress2.show();
193
+			} else { // fall back
194
+				this.jq.progress1.css('background-position', '0 '+spriteOffset+'px');
195
+			}
196
+		}
197
+	},
198
+	_progress: function(percent) {
199
+		var degs = percent * 3.6+"deg";
200
+
201
+		if (this.cssTransforms) {
202
+			if (percent <= 50) {
203
+				this.jq.bufferHolder.removeClass(this.cssClass.gt50);
204
+				this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'});
205
+				this.jq.buffer2.hide();
206
+			} else if (percent <= 100) {
207
+				this.jq.bufferHolder.addClass(this.cssClass.gt50);
208
+				this.jq.buffer1.css({'transform': 'rotate(180deg)'});
209
+				this.jq.buffer2.show();
210
+				this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'});
211
+			}
212
+		}
213
+	},
214
+	_getArcPercent: function(pageX, pageY) {
215
+		var	offset	= this.jq.circleControl.offset(),
216
+			x	= pageX - offset.left - this.jq.circleControl.width()/2,
217
+			y	= pageY - offset.top - this.jq.circleControl.height()/2,
218
+			theta	= Math.atan2(y,x);
219
+
220
+		if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) {
221
+			theta = 2 * Math.PI + theta;
222
+		}
223
+
224
+		// theta is now value between -0.5PI and 1.5PI
225
+		// ready to be normalized and applied
226
+
227
+		return (theta + Math.PI / 2) / 2 * Math.PI * 10;
228
+	},
229
+	setMedia: function(media) {
230
+		this.media = $.extend({}, media);
231
+		this.player.jPlayer("setMedia", this.media);
232
+	},
233
+	play: function(time) {
234
+		this.player.jPlayer("play", time);
235
+	},
236
+	pause: function(time) {
237
+		this.player.jPlayer("pause", time);
238
+	},
239
+	destroy: function() {
240
+		this.player.unbind(this.eventNamespace);
241
+		this.player.jPlayer("destroy");
242
+	}
243
+};

+ 30 - 0
web/jplayer/js/jplayer.playlist.min.js Целия файл

@@ -0,0 +1,30 @@
1
+/*
2
+ * Playlist Object for the jPlayer Plugin
3
+ * http://www.jplayer.org
4
+ *
5
+ * Copyright (c) 2009 - 2011 Happyworm Ltd
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ *  - http://www.opensource.org/licenses/mit-license.php
8
+ *  - http://www.gnu.org/copyleft/gpl.html
9
+ *
10
+ * Author: Mark J Panaghiston
11
+ * Version: 2.1.0 (jPlayer 2.1.0)
12
+ * Date: 1st September 2011
13
+ */
14
+
15
+(function(b,f){jPlayerPlaylist=function(a,c,d){var e=this;this.current=0;this.removing=this.shuffled=this.loop=!1;this.cssSelector=b.extend({},this._cssSelector,a);this.options=b.extend(!0,{},this._options,d);this.playlist=[];this.original=[];this._initPlaylist(c);this.cssSelector.title=this.cssSelector.cssSelectorAncestor+" .jp-title";this.cssSelector.playlist=this.cssSelector.cssSelectorAncestor+" .jp-playlist";this.cssSelector.next=this.cssSelector.cssSelectorAncestor+" .jp-next";this.cssSelector.previous=
16
+this.cssSelector.cssSelectorAncestor+" .jp-previous";this.cssSelector.shuffle=this.cssSelector.cssSelectorAncestor+" .jp-shuffle";this.cssSelector.shuffleOff=this.cssSelector.cssSelectorAncestor+" .jp-shuffle-off";this.options.cssSelectorAncestor=this.cssSelector.cssSelectorAncestor;this.options.repeat=function(a){e.loop=a.jPlayer.options.loop};b(this.cssSelector.jPlayer).bind(b.jPlayer.event.ready,function(){e._init()});b(this.cssSelector.jPlayer).bind(b.jPlayer.event.ended,function(){e.next()});
17
+b(this.cssSelector.jPlayer).bind(b.jPlayer.event.play,function(){b(this).jPlayer("pauseOthers")});b(this.cssSelector.jPlayer).bind(b.jPlayer.event.resize,function(a){a.jPlayer.options.fullScreen?b(e.cssSelector.title).show():b(e.cssSelector.title).hide()});b(this.cssSelector.previous).click(function(){e.previous();b(this).blur();return!1});b(this.cssSelector.next).click(function(){e.next();b(this).blur();return!1});b(this.cssSelector.shuffle).click(function(){e.shuffle(!0);return!1});b(this.cssSelector.shuffleOff).click(function(){e.shuffle(!1);
18
+return!1}).hide();this.options.fullScreen||b(this.cssSelector.title).hide();b(this.cssSelector.playlist+" ul").empty();this._createItemHandlers();b(this.cssSelector.jPlayer).jPlayer(this.options)};jPlayerPlaylist.prototype={_cssSelector:{jPlayer:"#jquery_jplayer_1",cssSelectorAncestor:"#jp_container_1"},_options:{playlistOptions:{autoPlay:!1,loopOnPrevious:!1,shuffleOnLoop:!0,enableRemoveControls:!1,displayTime:"slow",addTime:"fast",removeTime:"fast",shuffleTime:"slow",itemClass:"jp-playlist-item",
19
+freeGroupClass:"jp-free-media",freeItemClass:"jp-playlist-item-free",removeItemClass:"jp-playlist-item-remove"}},option:function(a,b){if(b===f)return this.options.playlistOptions[a];this.options.playlistOptions[a]=b;switch(a){case "enableRemoveControls":this._updateControls();break;case "itemClass":case "freeGroupClass":case "freeItemClass":case "removeItemClass":this._refresh(!0),this._createItemHandlers()}return this},_init:function(){var a=this;this._refresh(function(){a.options.playlistOptions.autoPlay?
20
+a.play(a.current):a.select(a.current)})},_initPlaylist:function(a){this.current=0;this.removing=this.shuffled=!1;this.original=b.extend(!0,[],a);this._originalPlaylist()},_originalPlaylist:function(){var a=this;this.playlist=[];b.each(this.original,function(b){a.playlist[b]=a.original[b]})},_refresh:function(a){var c=this;if(a&&!b.isFunction(a))b(this.cssSelector.playlist+" ul").empty(),b.each(this.playlist,function(a){b(c.cssSelector.playlist+" ul").append(c._createListItem(c.playlist[a]))}),this._updateControls();
21
+else{var d=b(this.cssSelector.playlist+" ul").children().length?this.options.playlistOptions.displayTime:0;b(this.cssSelector.playlist+" ul").slideUp(d,function(){var d=b(this);b(this).empty();b.each(c.playlist,function(a){d.append(c._createListItem(c.playlist[a]))});c._updateControls();b.isFunction(a)&&a();c.playlist.length?b(this).slideDown(c.options.playlistOptions.displayTime):b(this).show()})}},_createListItem:function(a){var c=this,d="<li><div>";d+="<a href='javascript:;' class='"+this.options.playlistOptions.removeItemClass+
22
+"'>&times;</a>";if(a.free){var e=!0;d+="<span class='"+this.options.playlistOptions.freeGroupClass+"'>(";b.each(a,function(a,f){b.jPlayer.prototype.format[a]&&(e?e=!1:d+=" | ",d+="<a class='"+c.options.playlistOptions.freeItemClass+"' href='"+f+"' tabindex='1'>"+a+"</a>")});d+=")</span>"}d+="<a href='javascript:;' class='"+this.options.playlistOptions.itemClass+"' tabindex='1'>"+a.title+(a.artist?" <span class='jp-artist'>by "+a.artist+"</span>":"")+"</a>";d+="</div></li>";return d},_createItemHandlers:function(){var a=
23
+this;b(this.cssSelector.playlist+" a."+this.options.playlistOptions.itemClass).die("click").live("click",function(){var c=b(this).parent().parent().index();a.current!==c?a.play(c):b(a.cssSelector.jPlayer).jPlayer("play");b(this).blur();return!1});b(a.cssSelector.playlist+" a."+this.options.playlistOptions.freeItemClass).die("click").live("click",function(){b(this).parent().parent().find("."+a.options.playlistOptions.itemClass).click();b(this).blur();return!1});b(a.cssSelector.playlist+" a."+this.options.playlistOptions.removeItemClass).die("click").live("click",
24
+function(){var c=b(this).parent().parent().index();a.remove(c);b(this).blur();return!1})},_updateControls:function(){this.options.playlistOptions.enableRemoveControls?b(this.cssSelector.playlist+" ."+this.options.playlistOptions.removeItemClass).show():b(this.cssSelector.playlist+" ."+this.options.playlistOptions.removeItemClass).hide();this.shuffled?(b(this.cssSelector.shuffleOff).show(),b(this.cssSelector.shuffle).hide()):(b(this.cssSelector.shuffleOff).hide(),b(this.cssSelector.shuffle).show())},
25
+_highlight:function(a){this.playlist.length&&a!==f&&(b(this.cssSelector.playlist+" .jp-playlist-current").removeClass("jp-playlist-current"),b(this.cssSelector.playlist+" li:nth-child("+(a+1)+")").addClass("jp-playlist-current").find(".jp-playlist-item").addClass("jp-playlist-current"),b(this.cssSelector.title+" li").html(this.playlist[a].title+(this.playlist[a].artist?" <span class='jp-artist'>by "+this.playlist[a].artist+"</span>":"")))},setPlaylist:function(a){this._initPlaylist(a);this._init()},
26
+add:function(a,c){b(this.cssSelector.playlist+" ul").append(this._createListItem(a)).find("li:last-child").hide().slideDown(this.options.playlistOptions.addTime);this._updateControls();this.original.push(a);this.playlist.push(a);c?this.play(this.playlist.length-1):this.original.length===1&&this.select(0)},remove:function(a){var c=this;if(a===f)return this._initPlaylist([]),this._refresh(function(){b(c.cssSelector.jPlayer).jPlayer("clearMedia")}),!0;else if(this.removing)return!1;else{a=a<0?c.original.length+
27
+a:a;if(0<=a&&a<this.playlist.length)this.removing=!0,b(this.cssSelector.playlist+" li:nth-child("+(a+1)+")").slideUp(this.options.playlistOptions.removeTime,function(){b(this).remove();if(c.shuffled){var d=c.playlist[a];b.each(c.original,function(a){if(c.original[a]===d)return c.original.splice(a,1),!1})}else c.original.splice(a,1);c.playlist.splice(a,1);c.original.length?a===c.current?(c.current=a<c.original.length?c.current:c.original.length-1,c.select(c.current)):a<c.current&&c.current--:(b(c.cssSelector.jPlayer).jPlayer("clearMedia"),
28
+c.current=0,c.shuffled=!1,c._updateControls());c.removing=!1});return!0}},select:function(a){a=a<0?this.original.length+a:a;0<=a&&a<this.playlist.length?(this.current=a,this._highlight(a),b(this.cssSelector.jPlayer).jPlayer("setMedia",this.playlist[this.current])):this.current=0},play:function(a){a=a<0?this.original.length+a:a;0<=a&&a<this.playlist.length?this.playlist.length&&(this.select(a),b(this.cssSelector.jPlayer).jPlayer("play")):a===f&&b(this.cssSelector.jPlayer).jPlayer("play")},pause:function(){b(this.cssSelector.jPlayer).jPlayer("pause")},
29
+next:function(){var a=this.current+1<this.playlist.length?this.current+1:0;this.loop?a===0&&this.shuffled&&this.options.playlistOptions.shuffleOnLoop&&this.playlist.length>1?this.shuffle(!0,!0):this.play(a):a>0&&this.play(a)},previous:function(){var a=this.current-1>=0?this.current-1:this.playlist.length-1;(this.loop&&this.options.playlistOptions.loopOnPrevious||a<this.playlist.length-1)&&this.play(a)},shuffle:function(a,c){var d=this;a===f&&(a=!this.shuffled);(a||a!==this.shuffled)&&b(this.cssSelector.playlist+
30
+" ul").slideUp(this.options.playlistOptions.shuffleTime,function(){(d.shuffled=a)?d.playlist.sort(function(){return 0.5-Math.random()}):d._originalPlaylist();d._refresh(!0);c||!b(d.cssSelector.jPlayer).data("jPlayer").status.paused?d.play(0):d.select(0);b(this).slideDown(d.options.playlistOptions.shuffleTime)})}}})(jQuery);

+ 201 - 0
web/jplayer/js/jquery.grab.js Целия файл

@@ -0,0 +1,201 @@
1
+/*
2
+jQuery grab 
3
+https://github.com/jussi-kalliokoski/jQuery.grab
4
+Ported from Jin.js::gestures   
5
+https://github.com/jussi-kalliokoski/jin.js/
6
+Created by Jussi Kalliokoski
7
+Licensed under MIT License. 
8
+
9
+Includes fix for IE
10
+*/
11
+
12
+
13
+(function($){
14
+	var	extend		= $.extend,
15
+		mousedown	= 'mousedown',
16
+		mousemove	= 'mousemove',
17
+		mouseup		= 'mouseup',
18
+		touchstart	= 'touchstart',
19
+		touchmove	= 'touchmove',
20
+		touchend	= 'touchend',
21
+		touchcancel	= 'touchcancel';
22
+
23
+	function unbind(elem, type, func){
24
+		if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin.
25
+			return $(elem).unbind(type, func);
26
+		}
27
+		var fnc, i;
28
+		for (i=0; i<bind._binds.length; i++){
29
+			if (bind._binds[i].elem === elem && bind._binds[i].type === type && bind._binds[i].func === func){
30
+				if (document.addEventListener){
31
+					elem.removeEventListener(type, bind._binds[i].fnc, false);
32
+				} else {
33
+					elem.detachEvent('on'+type, bind._binds[i].fnc);
34
+				}
35
+				bind._binds.splice(i--, 1);
36
+			}
37
+		}
38
+	}
39
+
40
+	function bind(elem, type, func, pass){
41
+		if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin.
42
+			return $(elem).bind(type, pass, func);
43
+		}
44
+		var fnc, i;
45
+		if (bind[type]){
46
+			return bind[type].bind(elem, type, func, pass);
47
+		}
48
+		fnc = function(e){
49
+			if (!e){ // Fix some ie bugs...
50
+				e = window.event;
51
+			}
52
+			if (!e.stopPropagation){
53
+				e.stopPropagation = function(){ this.cancelBubble = true; };
54
+			}
55
+			e.data = pass;
56
+			func.call(elem, e);
57
+		};
58
+		if (document.addEventListener){
59
+			elem.addEventListener(type, fnc, false);
60
+		} else {
61
+			elem.attachEvent('on' + type, fnc);
62
+		}
63
+		bind._binds.push({elem: elem, type: type, func: func, fnc: fnc});
64
+	}
65
+
66
+	function grab(elem, options)
67
+	{
68
+		var data = {
69
+			move: {x: 0, y: 0},
70
+			offset: {x: 0, y: 0},
71
+			position: {x: 0, y: 0},
72
+			start: {x: 0, y: 0},
73
+			affects: document.documentElement,
74
+			stopPropagation: false,
75
+			preventDefault: true,
76
+			touch: true // Implementation unfinished, and doesn't support multitouch
77
+		};
78
+		extend(data, options);
79
+		data.element = elem;
80
+		bind(elem, mousedown, mouseDown, data);
81
+		if (data.touch){
82
+			bind(elem, touchstart, touchStart, data);
83
+		}
84
+	}
85
+	function ungrab(elem){
86
+		unbind(elem, mousedown, mousedown);
87
+	}
88
+	function mouseDown(e){
89
+		e.data.position.x = e.pageX;
90
+		e.data.position.y = e.pageY;
91
+		e.data.start.x = e.pageX;
92
+		e.data.start.y = e.pageY;
93
+		e.data.event = e;
94
+		if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)){
95
+			return;
96
+		}
97
+		if (e.preventDefault && e.data.preventDefault){
98
+			e.preventDefault();
99
+		}
100
+		if (e.stopPropagation && e.data.stopPropagation){
101
+			e.stopPropagation();
102
+		}
103
+		bind(e.data.affects, mousemove, mouseMove, e.data);
104
+		bind(e.data.affects, mouseup, mouseUp, e.data);
105
+	}
106
+	function mouseMove(e){
107
+		if (e.preventDefault && e.data.preventDefault){
108
+			e.preventDefault();
109
+		}
110
+		if (e.stopPropagation && e.data.preventDefault){
111
+			e.stopPropagation();
112
+		}
113
+		e.data.move.x = e.pageX - e.data.position.x;
114
+		e.data.move.y = e.pageY - e.data.position.y;
115
+		e.data.position.x = e.pageX;
116
+		e.data.position.y = e.pageY;
117
+		e.data.offset.x = e.pageX - e.data.start.x;
118
+		e.data.offset.y = e.pageY - e.data.start.y;
119
+		e.data.event = e;
120
+		if (e.data.onmove){
121
+			e.data.onmove.call(e.data.element, e.data);
122
+		}
123
+	}
124
+	function mouseUp(e){
125
+		if (e.preventDefault && e.data.preventDefault){
126
+			e.preventDefault();
127
+		}
128
+		if (e.stopPropagation && e.data.stopPropagation){
129
+			e.stopPropagation();
130
+		}
131
+		unbind(e.data.affects, mousemove, mouseMove);
132
+		unbind(e.data.affects, mouseup, mouseUp);
133
+		e.data.event = e;
134
+		if (e.data.onfinish){
135
+			e.data.onfinish.call(e.data.element, e.data);
136
+		}
137
+	}
138
+	function touchStart(e){
139
+		e.data.position.x = e.touches[0].pageX;
140
+		e.data.position.y = e.touches[0].pageY;
141
+		e.data.start.x = e.touches[0].pageX;
142
+		e.data.start.y = e.touches[0].pageY;
143
+		e.data.event = e;
144
+		if (e.data.onstart && e.data.onstart.call(e.data.element, e.data)){
145
+			return;
146
+		}
147
+		if (e.preventDefault && e.data.preventDefault){
148
+			e.preventDefault();
149
+		}
150
+		if (e.stopPropagation && e.data.stopPropagation){
151
+			e.stopPropagation();
152
+		}
153
+		bind(e.data.affects, touchmove, touchMove, e.data);
154
+		bind(e.data.affects, touchend, touchEnd, e.data);
155
+	}
156
+	function touchMove(e){
157
+		if (e.preventDefault && e.data.preventDefault){
158
+			e.preventDefault();
159
+		}
160
+		if (e.stopPropagation && e.data.stopPropagation){
161
+			e.stopPropagation();
162
+		}
163
+		e.data.move.x = e.touches[0].pageX - e.data.position.x;
164
+		e.data.move.y = e.touches[0].pageY - e.data.position.y;
165
+		e.data.position.x = e.touches[0].pageX;
166
+		e.data.position.y = e.touches[0].pageY;
167
+		e.data.offset.x = e.touches[0].pageX - e.data.start.x;
168
+		e.data.offset.y = e.touches[0].pageY - e.data.start.y;
169
+		e.data.event = e;
170
+		if (e.data.onmove){
171
+			e.data.onmove.call(e.data.elem, e.data);
172
+		}
173
+	}
174
+	function touchEnd(e){
175
+		if (e.preventDefault && e.data.preventDefault){
176
+			e.preventDefault();
177
+		}
178
+		if (e.stopPropagation && e.data.stopPropagation){
179
+			e.stopPropagation();
180
+		}
181
+		unbind(e.data.affects, touchmove, touchMove);
182
+		unbind(e.data.affects, touchend, touchEnd);
183
+		e.data.event = e;
184
+		if (e.data.onfinish){
185
+			e.data.onfinish.call(e.data.element, e.data);
186
+		}
187
+	}
188
+
189
+	bind._binds = [];
190
+
191
+	$.fn.grab = function(a, b){
192
+		return this.each(function(){
193
+			return grab(this, a, b);
194
+		});
195
+	};
196
+	$.fn.ungrab = function(a){
197
+		return this.each(function(){
198
+			return ungrab(this, a);
199
+		});
200
+	};
201
+})(jQuery);

+ 331 - 0
web/jplayer/js/jquery.jplayer.inspector.js Целия файл

@@ -0,0 +1,331 @@
1
+/*
2
+ * jPlayerInspector Plugin for jPlayer (2.0.0+) Plugin for jQuery JavaScript Library
3
+ * http://www.happyworm.com/jquery/jplayer
4
+ *
5
+ * Copyright (c) 2009 - 2011 Happyworm Ltd
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ *  - http://www.opensource.org/licenses/mit-license.php
8
+ *  - http://www.gnu.org/copyleft/gpl.html
9
+ *
10
+ * Author: Mark J Panaghiston
11
+ * Version: 1.0.3
12
+ * Date: 7th August 2011
13
+ *
14
+ * For use with jPlayer Version: 2.0.29
15
+ *
16
+ * Note: Declare inspector instances after jPlayer instances. ie., Otherwise the jPlayer instance is nonsense.
17
+ */
18
+
19
+(function($, undefined) {
20
+	$.jPlayerInspector = {};
21
+	$.jPlayerInspector.i = 0;
22
+	$.jPlayerInspector.defaults = {
23
+		jPlayer: undefined, // The jQuery selector of the jPlayer instance to inspect.
24
+		idPrefix: "jplayer_inspector_",
25
+		visible: false
26
+	};
27
+	
28
+	var methods = {
29
+		init: function(options) {
30
+			var self = this;
31
+			var $this = $(this);
32
+			
33
+			var config = $.extend({}, $.jPlayerInspector.defaults, options);
34
+			$(this).data("jPlayerInspector", config);
35
+
36
+			config.id = $(this).attr("id");
37
+			config.jPlayerId = config.jPlayer.attr("id");
38
+
39
+			config.windowId = config.idPrefix + "window_" + $.jPlayerInspector.i;
40
+			config.statusId = config.idPrefix + "status_" + $.jPlayerInspector.i;
41
+			config.configId = config.idPrefix + "config_" + $.jPlayerInspector.i;
42
+			config.toggleId = config.idPrefix + "toggle_" + $.jPlayerInspector.i;
43
+			config.eventResetId = config.idPrefix + "event_reset_" + $.jPlayerInspector.i;
44
+			config.updateId = config.idPrefix + "update_" + $.jPlayerInspector.i;
45
+			config.eventWindowId = config.idPrefix + "event_window_" + $.jPlayerInspector.i;
46
+			
47
+			config.eventId = {};
48
+			config.eventJq = {};
49
+			config.eventTimeout = {};
50
+			config.eventOccurrence = {};
51
+			
52
+			$.each($.jPlayer.event, function(eventName,eventType) {
53
+				config.eventId[eventType] = config.idPrefix + "event_" + eventName + "_" + $.jPlayerInspector.i;
54
+				config.eventOccurrence[eventType] = 0;
55
+			});
56
+			
57
+			var structure = 
58
+				'<p><a href="#" id="' + config.toggleId + '">' + (config.visible ? "Hide" : "Show") + '</a> jPlayer Inspector</p>' 
59
+				+ '<div id="' + config.windowId + '">'
60
+					+ '<div id="' + config.statusId + '"></div>'
61
+					+ '<div id="' + config.eventWindowId + '" style="padding:5px 5px 0 5px;background-color:#eee;border:1px dotted #000;">'
62
+						+ '<p style="margin:0 0 10px 0;"><strong>jPlayer events that have occurred over the past 1 second:</strong>'
63
+						+ '<br />(Backgrounds: <span style="padding:0 5px;background-color:#eee;border:1px dotted #000;">Never occurred</span> <span style="padding:0 5px;background-color:#fff;border:1px dotted #000;">Occurred before</span> <span style="padding:0 5px;background-color:#9f9;border:1px dotted #000;">Occurred</span> <span style="padding:0 5px;background-color:#ff9;border:1px dotted #000;">Multiple occurrences</span> <a href="#" id="' + config.eventResetId + '">reset</a>)</p>';
64
+			
65
+			// MJP: Would use the next 3 lines for ease, but the events are just slapped on the page.
66
+			// $.each($.jPlayer.event, function(eventName,eventType) {
67
+			// 	structure += '<div id="' + config.eventId[eventType] + '" style="float:left;">' + eventName + '</div>';
68
+			// });
69
+			
70
+			var eventStyle = "float:left;margin:0 5px 5px 0;padding:0 5px;border:1px dotted #000;";
71
+			// MJP: Doing it longhand so order and layout easier to control.
72
+			structure +=
73
+						'<div id="' + config.eventId[$.jPlayer.event.ready] + '" style="' + eventStyle + '"></div>'
74
+						+ '<div id="' + config.eventId[$.jPlayer.event.flashreset] + '" style="' + eventStyle + '"></div>'
75
+						+ '<div id="' + config.eventId[$.jPlayer.event.resize] + '" style="' + eventStyle + '"></div>'
76
+						+ '<div id="' + config.eventId[$.jPlayer.event.repeat] + '" style="' + eventStyle + '"></div>'
77
+						+ '<div id="' + config.eventId[$.jPlayer.event.click] + '" style="' + eventStyle + '"></div>'
78
+						+ '<div id="' + config.eventId[$.jPlayer.event.error] + '" style="' + eventStyle + '"></div>'
79
+						+ '<div id="' + config.eventId[$.jPlayer.event.warning] + '" style="' + eventStyle + '"></div>'
80
+
81
+						+ '<div id="' + config.eventId[$.jPlayer.event.loadstart] + '" style="clear:left;' + eventStyle + '"></div>'
82
+						+ '<div id="' + config.eventId[$.jPlayer.event.progress] + '" style="' + eventStyle + '"></div>'
83
+						+ '<div id="' + config.eventId[$.jPlayer.event.timeupdate] + '" style="' + eventStyle + '"></div>'
84
+						+ '<div id="' + config.eventId[$.jPlayer.event.volumechange] + '" style="' + eventStyle + '"></div>'
85
+
86
+						+ '<div id="' + config.eventId[$.jPlayer.event.play] + '" style="clear:left;' + eventStyle + '"></div>'
87
+						+ '<div id="' + config.eventId[$.jPlayer.event.pause] + '" style="' + eventStyle + '"></div>'
88
+						+ '<div id="' + config.eventId[$.jPlayer.event.waiting] + '" style="' + eventStyle + '"></div>'
89
+						+ '<div id="' + config.eventId[$.jPlayer.event.playing] + '" style="' + eventStyle + '"></div>'
90
+						+ '<div id="' + config.eventId[$.jPlayer.event.seeking] + '" style="' + eventStyle + '"></div>'
91
+						+ '<div id="' + config.eventId[$.jPlayer.event.seeked] + '" style="' + eventStyle + '"></div>'
92
+						+ '<div id="' + config.eventId[$.jPlayer.event.ended] + '" style="' + eventStyle + '"></div>'
93
+
94
+						+ '<div id="' + config.eventId[$.jPlayer.event.loadeddata] + '" style="clear:left;' + eventStyle + '"></div>'
95
+						+ '<div id="' + config.eventId[$.jPlayer.event.loadedmetadata] + '" style="' + eventStyle + '"></div>'
96
+						+ '<div id="' + config.eventId[$.jPlayer.event.canplay] + '" style="' + eventStyle + '"></div>'
97
+						+ '<div id="' + config.eventId[$.jPlayer.event.canplaythrough] + '" style="' + eventStyle + '"></div>'
98
+
99
+						+ '<div id="' + config.eventId[$.jPlayer.event.suspend] + '" style="clear:left;' + eventStyle + '"></div>'
100
+						+ '<div id="' + config.eventId[$.jPlayer.event.abort] + '" style="' + eventStyle + '"></div>'
101
+						+ '<div id="' + config.eventId[$.jPlayer.event.emptied] + '" style="' + eventStyle + '"></div>'
102
+						+ '<div id="' + config.eventId[$.jPlayer.event.stalled] + '" style="' + eventStyle + '"></div>'
103
+						+ '<div id="' + config.eventId[$.jPlayer.event.ratechange] + '" style="' + eventStyle + '"></div>'
104
+						+ '<div id="' + config.eventId[$.jPlayer.event.durationchange] + '" style="' + eventStyle + '"></div>'
105
+
106
+						+ '<div style="clear:both"></div>';
107
+
108
+			// MJP: Would like a check here in case we missed an event.
109
+
110
+			// MJP: Check fails, since it is not on the page yet.
111
+/*			$.each($.jPlayer.event, function(eventName,eventType) {
112
+				if($("#" + config.eventId[eventType])[0] === undefined) {
113
+					structure += '<div id="' + config.eventId[eventType] + '" style="clear:left;' + eventStyle + '">' + eventName + '</div>';
114
+				}
115
+			});
116
+*/
117
+			structure +=
118
+					'</div>'
119
+					+ '<p><a href="#" id="' + config.updateId + '">Update</a> jPlayer Inspector</p>'
120
+					+ '<div id="' + config.configId + '"></div>'
121
+				+ '</div>';
122
+			$(this).html(structure);
123
+			
124
+			config.windowJq = $("#" + config.windowId);
125
+			config.statusJq = $("#" + config.statusId);
126
+			config.configJq = $("#" + config.configId);
127
+			config.toggleJq = $("#" + config.toggleId);
128
+			config.eventResetJq = $("#" + config.eventResetId);
129
+			config.updateJq = $("#" + config.updateId);
130
+
131
+			$.each($.jPlayer.event, function(eventName,eventType) {
132
+				config.eventJq[eventType] = $("#" + config.eventId[eventType]);
133
+				config.eventJq[eventType].text(eventName + " (" + config.eventOccurrence[eventType] + ")"); // Sets the text to the event name and (0);
134
+				
135
+				config.jPlayer.bind(eventType + ".jPlayerInspector", function(e) {
136
+					config.eventOccurrence[e.type]++;
137
+					if(config.eventOccurrence[e.type] > 1) {
138
+						config.eventJq[e.type].css("background-color","#ff9");
139
+					} else {
140
+						config.eventJq[e.type].css("background-color","#9f9");
141
+					}
142
+					config.eventJq[e.type].text(eventName + " (" + config.eventOccurrence[e.type] + ")");
143
+					// The timer to handle the color
144
+					clearTimeout(config.eventTimeout[e.type]);
145
+					config.eventTimeout[e.type] = setTimeout(function() {
146
+						config.eventJq[e.type].css("background-color","#fff");
147
+					}, 1000);
148
+					// The timer to handle the occurences.
149
+					setTimeout(function() {
150
+						config.eventOccurrence[e.type]--;
151
+						config.eventJq[e.type].text(eventName + " (" + config.eventOccurrence[e.type] + ")");
152
+					}, 1000);
153
+					if(config.visible) { // Update the status, if inspector open.
154
+						$this.jPlayerInspector("updateStatus");
155
+					}
156
+				});
157
+			});
158
+
159
+			config.jPlayer.bind($.jPlayer.event.ready + ".jPlayerInspector", function(e) {
160
+				$this.jPlayerInspector("updateConfig");
161
+			});
162
+
163
+			config.toggleJq.click(function() {
164
+				if(config.visible) {
165
+					$(this).text("Show");
166
+					config.windowJq.hide();
167
+					config.statusJq.empty();
168
+					config.configJq.empty();
169
+				} else {
170
+					$(this).text("Hide");
171
+					config.windowJq.show();
172
+					config.updateJq.click();
173
+				}
174
+				config.visible = !config.visible;
175
+				$(this).blur();
176
+				return false;
177
+			});
178
+
179
+			config.eventResetJq.click(function() {
180
+				$.each($.jPlayer.event, function(eventName,eventType) {
181
+					config.eventJq[eventType].css("background-color","#eee");
182
+				});
183
+				$(this).blur();
184
+				return false;
185
+			});
186
+
187
+			config.updateJq.click(function() {
188
+				$this.jPlayerInspector("updateStatus");
189
+				$this.jPlayerInspector("updateConfig");
190
+				return false;
191
+			});
192
+
193
+			if(!config.visible) {
194
+				config.windowJq.hide();
195
+			} else {
196
+				// config.updateJq.click();
197
+			}
198
+			
199
+			$.jPlayerInspector.i++;
200
+
201
+			return this;
202
+		},
203
+		destroy: function() {
204
+			$(this).data("jPlayerInspector") && $(this).data("jPlayerInspector").jPlayer.unbind(".jPlayerInspector");
205
+			$(this).empty();
206
+		},
207
+		updateConfig: function() { // This displays information about jPlayer's configuration in inspector
208
+		
209
+			var jPlayerInfo = "<p>This jPlayer instance is running in your browser where:<br />"
210
+
211
+			for(i = 0; i < $(this).data("jPlayerInspector").jPlayer.data("jPlayer").solutions.length; i++) {
212
+				var solution = $(this).data("jPlayerInspector").jPlayer.data("jPlayer").solutions[i];
213
+				jPlayerInfo += "&nbsp;jPlayer's <strong>" + solution + "</strong> solution is";				
214
+				if($(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].used) {
215
+					jPlayerInfo += " being <strong>used</strong> and will support:<strong>";
216
+					for(format in $(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].support) {
217
+						if($(this).data("jPlayerInspector").jPlayer.data("jPlayer")[solution].support[format]) {
218
+							jPlayerInfo += " " + format;
219
+						}
220
+					}
221
+					jPlayerInfo += "</strong><br />";
222
+				} else {
223
+					jPlayerInfo += " <strong>not required</strong><br />";
224
+				}
225
+			}
226
+			jPlayerInfo += "</p>";
227
+
228
+			if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.active) {
229
+				if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").flash.active) {
230
+					jPlayerInfo += "<strong>Problem with jPlayer since both HTML5 and Flash are active.</strong>";
231
+				} else {
232
+					jPlayerInfo += "The <strong>HTML5 is active</strong>.";
233
+				}
234
+			} else {
235
+				if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").flash.active) {
236
+					jPlayerInfo += "The <strong>Flash is active</strong>.";
237
+				} else {
238
+					jPlayerInfo += "No solution is currently active. jPlayer needs a setMedia().";
239
+				}
240
+			}
241
+			jPlayerInfo += "</p>";
242
+
243
+			var formatType = $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.formatType;
244
+			jPlayerInfo += "<p><code>status.formatType = '" + formatType + "'</code><br />";
245
+			if(formatType) {
246
+				jPlayerInfo += "<code>Browser canPlay('" + $.jPlayer.prototype.format[formatType].codec + "')</code>";
247
+			} else {
248
+				jPlayerInfo += "</p>";
249
+			}
250
+			
251
+			jPlayerInfo += "<p><code>status.src = '" + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.src + "'</code></p>";
252
+
253
+			jPlayerInfo += "<p><code>status.media = {<br />";
254
+			for(prop in $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.media) {
255
+				jPlayerInfo += "&nbsp;" + prop + ": " + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.media[prop] + "<br />"; // Some are strings
256
+			}
257
+			jPlayerInfo += "};</code></p>"
258
+
259
+			+ "<p>Raw browser test for HTML5 support. Should equal a function if HTML5 is available.<br />";
260
+			if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.audio.available) {
261
+				jPlayerInfo += "<code>htmlElement.audio.canPlayType = " + (typeof $(this).data("jPlayerInspector").jPlayer.data("jPlayer").htmlElement.audio.canPlayType) +"</code><br />"
262
+			}
263
+			if($(this).data("jPlayerInspector").jPlayer.data("jPlayer").html.video.available) {
264
+				jPlayerInfo += "<code>htmlElement.video.canPlayType = " + (typeof $(this).data("jPlayerInspector").jPlayer.data("jPlayer").htmlElement.video.canPlayType) +"</code>";
265
+			}
266
+			jPlayerInfo += "</p>";
267
+
268
+			jPlayerInfo += "<p>This instance is using the constructor options:<br />"
269
+			+ "<code>$('#" + $(this).data("jPlayerInspector").jPlayer.data("jPlayer").internal.self.id + "').jPlayer({<br />"
270
+
271
+			+ "&nbsp;swfPath: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "swfPath") + "',<br />"
272
+
273
+			+ "&nbsp;solution: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "solution") + "',<br />"
274
+
275
+			+ "&nbsp;supplied: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "supplied") + "',<br />"
276
+
277
+			+ "&nbsp;preload: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "preload") + "',<br />"
278
+			
279
+			+ "&nbsp;volume: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "volume") + ",<br />"
280
+			
281
+			+ "&nbsp;muted: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "muted") + ",<br />"
282
+
283
+			+ "&nbsp;backgroundColor: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "backgroundColor") + "',<br />"
284
+
285
+			+ "&nbsp;cssSelectorAncestor: '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelectorAncestor") + "',<br />"
286
+
287
+			+ "&nbsp;cssSelector: {";
288
+
289
+			var cssSelector = $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelector");
290
+			for(prop in cssSelector) {
291
+				
292
+				// jPlayerInfo += "<br />&nbsp;&nbsp;" + prop + ": '" + cssSelector[prop] + "'," // This works too of course, but want to use option method for deep keys.
293
+				jPlayerInfo += "<br />&nbsp;&nbsp;" + prop + ": '" + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "cssSelector." + prop) + "',"
294
+			}
295
+
296
+			jPlayerInfo = jPlayerInfo.slice(0, -1); // Because the sloppy comma was bugging me.
297
+
298
+			jPlayerInfo += "<br />&nbsp;},<br />"
299
+
300
+			+ "&nbsp;errorAlerts: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "errorAlerts") + ",<br />"
301
+			
302
+			+ "&nbsp;warningAlerts: " + $(this).data("jPlayerInspector").jPlayer.jPlayer("option", "warningAlerts") + "<br />"
303
+
304
+			+ "});</code></p>";
305
+			$(this).data("jPlayerInspector").configJq.html(jPlayerInfo);
306
+			return this;
307
+		},
308
+		updateStatus: function() { // This displays information about jPlayer's status in the inspector
309
+			$(this).data("jPlayerInspector").statusJq.html(
310
+				"<p>jPlayer is " +
311
+				($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.paused ? "paused" : "playing") +
312
+				" at time: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentTime*10)/10 + "s." +
313
+				" (d: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.duration*10)/10 + "s" +
314
+				", sp: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.seekPercent) + "%" +
315
+				", cpr: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentPercentRelative) + "%" +
316
+				", cpa: " + Math.floor($(this).data("jPlayerInspector").jPlayer.data("jPlayer").status.currentPercentAbsolute) + "%)</p>"
317
+			);
318
+			return this;
319
+		}
320
+	};
321
+	$.fn.jPlayerInspector = function( method ) {
322
+		// Method calling logic
323
+		if ( methods[method] ) {
324
+			return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
325
+		} else if ( typeof method === 'object' || ! method ) {
326
+			return methods.init.apply( this, arguments );
327
+		} else {
328
+			$.error( 'Method ' +  method + ' does not exist on jQuery.jPlayerInspector' );
329
+		}    
330
+	};
331
+})(jQuery);

+ 97 - 0
web/jplayer/js/jquery.jplayer.min.js Целия файл

@@ -0,0 +1,97 @@
1
+/*
2
+ * jPlayer Plugin for jQuery JavaScript Library
3
+ * http://www.jplayer.org
4
+ *
5
+ * Copyright (c) 2009 - 2012 Happyworm Ltd
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ *  - http://www.opensource.org/licenses/mit-license.php
8
+ *  - http://www.gnu.org/copyleft/gpl.html
9
+ *
10
+ * Author: Mark J Panaghiston
11
+ * Version: 2.2.0
12
+ * Date: 13th September 2012
13
+ */
14
+
15
+(function(b,f){b.fn.jPlayer=function(a){var c="string"===typeof a,d=Array.prototype.slice.call(arguments,1),e=this,a=!c&&d.length?b.extend.apply(null,[!0,a].concat(d)):a;if(c&&"_"===a.charAt(0))return e;c?this.each(function(){var c=b.data(this,"jPlayer"),h=c&&b.isFunction(c[a])?c[a].apply(c,d):c;if(h!==c&&h!==f)return e=h,!1}):this.each(function(){var c=b.data(this,"jPlayer");c?c.option(a||{}):b.data(this,"jPlayer",new b.jPlayer(a,this))});return e};b.jPlayer=function(a,c){if(arguments.length){this.element=
16
+b(c);this.options=b.extend(!0,{},this.options,a);var d=this;this.element.bind("remove.jPlayer",function(){d.destroy()});this._init()}};b.jPlayer.emulateMethods="load play pause";b.jPlayer.emulateStatus="src readyState networkState currentTime duration paused ended playbackRate";b.jPlayer.emulateOptions="muted volume";b.jPlayer.reservedEvent="ready flashreset resize repeat error warning";b.jPlayer.event={ready:"jPlayer_ready",flashreset:"jPlayer_flashreset",resize:"jPlayer_resize",repeat:"jPlayer_repeat",
17
+click:"jPlayer_click",error:"jPlayer_error",warning:"jPlayer_warning",loadstart:"jPlayer_loadstart",progress:"jPlayer_progress",suspend:"jPlayer_suspend",abort:"jPlayer_abort",emptied:"jPlayer_emptied",stalled:"jPlayer_stalled",play:"jPlayer_play",pause:"jPlayer_pause",loadedmetadata:"jPlayer_loadedmetadata",loadeddata:"jPlayer_loadeddata",waiting:"jPlayer_waiting",playing:"jPlayer_playing",canplay:"jPlayer_canplay",canplaythrough:"jPlayer_canplaythrough",seeking:"jPlayer_seeking",seeked:"jPlayer_seeked",
18
+timeupdate:"jPlayer_timeupdate",ended:"jPlayer_ended",ratechange:"jPlayer_ratechange",durationchange:"jPlayer_durationchange",volumechange:"jPlayer_volumechange"};b.jPlayer.htmlEvent="loadstart abort emptied stalled loadedmetadata loadeddata canplay canplaythrough ratechange".split(" ");b.jPlayer.pause=function(){b.each(b.jPlayer.prototype.instances,function(a,c){c.data("jPlayer").status.srcSet&&c.jPlayer("pause")})};b.jPlayer.timeFormat={showHour:!1,showMin:!0,showSec:!0,padHour:!1,padMin:!0,padSec:!0,
19
+sepHour:":",sepMin:":",sepSec:""};b.jPlayer.convertTime=function(a){var c=new Date(1E3*a),d=c.getUTCHours(),a=c.getUTCMinutes(),c=c.getUTCSeconds(),d=b.jPlayer.timeFormat.padHour&&10>d?"0"+d:d,a=b.jPlayer.timeFormat.padMin&&10>a?"0"+a:a,c=b.jPlayer.timeFormat.padSec&&10>c?"0"+c:c;return(b.jPlayer.timeFormat.showHour?d+b.jPlayer.timeFormat.sepHour:"")+(b.jPlayer.timeFormat.showMin?a+b.jPlayer.timeFormat.sepMin:"")+(b.jPlayer.timeFormat.showSec?c+b.jPlayer.timeFormat.sepSec:"")};b.jPlayer.uaBrowser=
20
+function(a){var a=a.toLowerCase(),c=/(opera)(?:.*version)?[ \/]([\w.]+)/,b=/(msie) ([\w.]+)/,e=/(mozilla)(?:.*? rv:([\w.]+))?/,a=/(webkit)[ \/]([\w.]+)/.exec(a)||c.exec(a)||b.exec(a)||0>a.indexOf("compatible")&&e.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}};b.jPlayer.uaPlatform=function(a){var b=a.toLowerCase(),d=/(android)/,e=/(mobile)/,a=/(ipad|iphone|ipod|android|blackberry|playbook|windows ce|webos)/.exec(b)||[],b=/(ipad|playbook)/.exec(b)||!e.exec(b)&&d.exec(b)||[];a[1]&&(a[1]=a[1].replace(/\s/g,
21
+"_"));return{platform:a[1]||"",tablet:b[1]||""}};b.jPlayer.browser={};b.jPlayer.platform={};var i=b.jPlayer.uaBrowser(navigator.userAgent);i.browser&&(b.jPlayer.browser[i.browser]=!0,b.jPlayer.browser.version=i.version);i=b.jPlayer.uaPlatform(navigator.userAgent);i.platform&&(b.jPlayer.platform[i.platform]=!0,b.jPlayer.platform.mobile=!i.tablet,b.jPlayer.platform.tablet=!!i.tablet);b.jPlayer.prototype={count:0,version:{script:"2.2.0",needFlash:"2.2.0",flash:"unknown"},options:{swfPath:"js",solution:"html, flash",
22
+supplied:"mp3",preload:"metadata",volume:0.8,muted:!1,wmode:"opaque",backgroundColor:"#000000",cssSelectorAncestor:"#jp_container_1",cssSelector:{videoPlay:".jp-video-play",play:".jp-play",pause:".jp-pause",stop:".jp-stop",seekBar:".jp-seek-bar",playBar:".jp-play-bar",mute:".jp-mute",unmute:".jp-unmute",volumeBar:".jp-volume-bar",volumeBarValue:".jp-volume-bar-value",volumeMax:".jp-volume-max",currentTime:".jp-current-time",duration:".jp-duration",fullScreen:".jp-full-screen",restoreScreen:".jp-restore-screen",
23
+repeat:".jp-repeat",repeatOff:".jp-repeat-off",gui:".jp-gui",noSolution:".jp-no-solution"},fullScreen:!1,autohide:{restored:!1,full:!0,fadeIn:200,fadeOut:600,hold:1E3},loop:!1,repeat:function(a){a.jPlayer.options.loop?b(this).unbind(".jPlayerRepeat").bind(b.jPlayer.event.ended+".jPlayer.jPlayerRepeat",function(){b(this).jPlayer("play")}):b(this).unbind(".jPlayerRepeat")},nativeVideoControls:{},noFullScreen:{msie:/msie [0-6]/,ipad:/ipad.*?os [0-4]/,iphone:/iphone/,ipod:/ipod/,android_pad:/android [0-3](?!.*?mobile)/,
24
+android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,webos:/webos/},noVolume:{ipad:/ipad/,iphone:/iphone/,ipod:/ipod/,android_pad:/android(?!.*?mobile)/,android_phone:/android.*?mobile/,blackberry:/blackberry/,windows_ce:/windows ce/,webos:/webos/,playbook:/playbook/},verticalVolume:!1,idPrefix:"jp",noConflict:"jQuery",emulateHtml:!1,errorAlerts:!1,warningAlerts:!1},optionsAudio:{size:{width:"0px",height:"0px",cssClass:""},sizeFull:{width:"0px",height:"0px",cssClass:""}},
25
+optionsVideo:{size:{width:"480px",height:"270px",cssClass:"jp-video-270p"},sizeFull:{width:"100%",height:"100%",cssClass:"jp-video-full"}},instances:{},status:{src:"",media:{},paused:!0,format:{},formatType:"",waitForPlay:!0,waitForLoad:!0,srcSet:!1,video:!1,seekPercent:0,currentPercentRelative:0,currentPercentAbsolute:0,currentTime:0,duration:0,readyState:0,networkState:0,playbackRate:1,ended:0},internal:{ready:!1},solution:{html:!0,flash:!0},format:{mp3:{codec:'audio/mpeg; codecs="mp3"',flashCanPlay:!0,
26
+media:"audio"},m4a:{codec:'audio/mp4; codecs="mp4a.40.2"',flashCanPlay:!0,media:"audio"},oga:{codec:'audio/ogg; codecs="vorbis"',flashCanPlay:!1,media:"audio"},wav:{codec:'audio/wav; codecs="1"',flashCanPlay:!1,media:"audio"},webma:{codec:'audio/webm; codecs="vorbis"',flashCanPlay:!1,media:"audio"},fla:{codec:"audio/x-flv",flashCanPlay:!0,media:"audio"},rtmpa:{codec:'audio/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"audio"},m4v:{codec:'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',flashCanPlay:!0,media:"video"},
27
+ogv:{codec:'video/ogg; codecs="theora, vorbis"',flashCanPlay:!1,media:"video"},webmv:{codec:'video/webm; codecs="vorbis, vp8"',flashCanPlay:!1,media:"video"},flv:{codec:"video/x-flv",flashCanPlay:!0,media:"video"},rtmpv:{codec:'video/rtmp; codecs="rtmp"',flashCanPlay:!0,media:"video"}},_init:function(){var a=this;this.element.empty();this.status=b.extend({},this.status);this.internal=b.extend({},this.internal);this.internal.domNode=this.element.get(0);this.formats=[];this.solutions=[];this.require=
28
+{};this.htmlElement={};this.html={};this.html.audio={};this.html.video={};this.flash={};this.css={};this.css.cs={};this.css.jq={};this.ancestorJq=[];this.options.volume=this._limitValue(this.options.volume,0,1);b.each(this.options.supplied.toLowerCase().split(","),function(c,d){var e=d.replace(/^\s+|\s+$/g,"");if(a.format[e]){var f=false;b.each(a.formats,function(a,b){if(e===b){f=true;return false}});f||a.formats.push(e)}});b.each(this.options.solution.toLowerCase().split(","),function(c,d){var e=
29
+d.replace(/^\s+|\s+$/g,"");if(a.solution[e]){var f=false;b.each(a.solutions,function(a,b){if(e===b){f=true;return false}});f||a.solutions.push(e)}});this.internal.instance="jp_"+this.count;this.instances[this.internal.instance]=this.element;this.element.attr("id")||this.element.attr("id",this.options.idPrefix+"_jplayer_"+this.count);this.internal.self=b.extend({},{id:this.element.attr("id"),jq:this.element});this.internal.audio=b.extend({},{id:this.options.idPrefix+"_audio_"+this.count,jq:f});this.internal.video=
30
+b.extend({},{id:this.options.idPrefix+"_video_"+this.count,jq:f});this.internal.flash=b.extend({},{id:this.options.idPrefix+"_flash_"+this.count,jq:f,swf:this.options.swfPath+(this.options.swfPath.toLowerCase().slice(-4)!==".swf"?(this.options.swfPath&&this.options.swfPath.slice(-1)!=="/"?"/":"")+"Jplayer.swf":"")});this.internal.poster=b.extend({},{id:this.options.idPrefix+"_poster_"+this.count,jq:f});b.each(b.jPlayer.event,function(b,c){if(a.options[b]!==f){a.element.bind(c+".jPlayer",a.options[b]);
31
+a.options[b]=f}});this.require.audio=false;this.require.video=false;b.each(this.formats,function(b,c){a.require[a.format[c].media]=true});this.options=this.require.video?b.extend(true,{},this.optionsVideo,this.options):b.extend(true,{},this.optionsAudio,this.options);this._setSize();this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullScreen=this._uaBlocklist(this.options.noFullScreen);this.status.noVolume=this._uaBlocklist(this.options.noVolume);this._restrictNativeVideoControls();
32
+this.htmlElement.poster=document.createElement("img");this.htmlElement.poster.id=this.internal.poster.id;this.htmlElement.poster.onload=function(){(!a.status.video||a.status.waitForPlay)&&a.internal.poster.jq.show()};this.element.append(this.htmlElement.poster);this.internal.poster.jq=b("#"+this.internal.poster.id);this.internal.poster.jq.css({width:this.status.width,height:this.status.height});this.internal.poster.jq.hide();this.internal.poster.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)});
33
+this.html.audio.available=false;if(this.require.audio){this.htmlElement.audio=document.createElement("audio");this.htmlElement.audio.id=this.internal.audio.id;this.html.audio.available=!!this.htmlElement.audio.canPlayType&&this._testCanPlayType(this.htmlElement.audio)}this.html.video.available=false;if(this.require.video){this.htmlElement.video=document.createElement("video");this.htmlElement.video.id=this.internal.video.id;this.html.video.available=!!this.htmlElement.video.canPlayType&&this._testCanPlayType(this.htmlElement.video)}this.flash.available=
34
+this._checkForFlash(10);this.html.canPlay={};this.flash.canPlay={};b.each(this.formats,function(b,c){a.html.canPlay[c]=a.html[a.format[c].media].available&&""!==a.htmlElement[a.format[c].media].canPlayType(a.format[c].codec);a.flash.canPlay[c]=a.format[c].flashCanPlay&&a.flash.available});this.html.desired=false;this.flash.desired=false;b.each(this.solutions,function(c,d){if(c===0)a[d].desired=true;else{var e=false,f=false;b.each(a.formats,function(b,c){a[a.solutions[0]].canPlay[c]&&(a.format[c].media===
35
+"video"?f=true:e=true)});a[d].desired=a.require.audio&&!e||a.require.video&&!f}});this.html.support={};this.flash.support={};b.each(this.formats,function(b,c){a.html.support[c]=a.html.canPlay[c]&&a.html.desired;a.flash.support[c]=a.flash.canPlay[c]&&a.flash.desired});this.html.used=false;this.flash.used=false;b.each(this.solutions,function(c,d){b.each(a.formats,function(b,c){if(a[d].support[c]){a[d].used=true;return false}})});this._resetActive();this._resetGate();this._cssSelectorAncestor(this.options.cssSelectorAncestor);
36
+if(!this.html.used&&!this.flash.used){this._error({type:b.jPlayer.error.NO_SOLUTION,context:"{solution:'"+this.options.solution+"', supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SOLUTION,hint:b.jPlayer.errorHint.NO_SOLUTION});this.css.jq.noSolution.length&&this.css.jq.noSolution.show()}else this.css.jq.noSolution.length&&this.css.jq.noSolution.hide();if(this.flash.used){var c,d="jQuery="+encodeURI(this.options.noConflict)+"&id="+encodeURI(this.internal.self.id)+"&vol="+this.options.volume+
37
+"&muted="+this.options.muted;if(b.jPlayer.browser.msie&&Number(b.jPlayer.browser.version)<=8){d=['<param name="movie" value="'+this.internal.flash.swf+'" />','<param name="FlashVars" value="'+d+'" />','<param name="allowScriptAccess" value="always" />','<param name="bgcolor" value="'+this.options.backgroundColor+'" />','<param name="wmode" value="'+this.options.wmode+'" />'];c=document.createElement('<object id="'+this.internal.flash.id+'" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="0" height="0"></object>');
38
+for(var e=0;e<d.length;e++)c.appendChild(document.createElement(d[e]))}else{e=function(a,b,c){var d=document.createElement("param");d.setAttribute("name",b);d.setAttribute("value",c);a.appendChild(d)};c=document.createElement("object");c.setAttribute("id",this.internal.flash.id);c.setAttribute("data",this.internal.flash.swf);c.setAttribute("type","application/x-shockwave-flash");c.setAttribute("width","1");c.setAttribute("height","1");e(c,"flashvars",d);e(c,"allowscriptaccess","always");e(c,"bgcolor",
39
+this.options.backgroundColor);e(c,"wmode",this.options.wmode)}this.element.append(c);this.internal.flash.jq=b(c)}if(this.html.used){if(this.html.audio.available){this._addHtmlEventListeners(this.htmlElement.audio,this.html.audio);this.element.append(this.htmlElement.audio);this.internal.audio.jq=b("#"+this.internal.audio.id)}if(this.html.video.available){this._addHtmlEventListeners(this.htmlElement.video,this.html.video);this.element.append(this.htmlElement.video);this.internal.video.jq=b("#"+this.internal.video.id);
40
+this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):this.internal.video.jq.css({width:"0px",height:"0px"});this.internal.video.jq.bind("click.jPlayer",function(){a._trigger(b.jPlayer.event.click)})}}this.options.emulateHtml&&this._emulateHtmlBridge();this.html.used&&!this.flash.used&&setTimeout(function(){a.internal.ready=true;a.version.flash="n/a";a._trigger(b.jPlayer.event.repeat);a._trigger(b.jPlayer.event.ready)},100);this._updateNativeVideoControls();
41
+this._updateInterface();this._updateButtons(false);this._updateAutohide();this._updateVolume(this.options.volume);this._updateMute(this.options.muted);this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide();b.jPlayer.prototype.count++},destroy:function(){this.clearMedia();this._removeUiClass();this.css.jq.currentTime.length&&this.css.jq.currentTime.text("");this.css.jq.duration.length&&this.css.jq.duration.text("");b.each(this.css.jq,function(a,b){b.length&&b.unbind(".jPlayer")});this.internal.poster.jq.unbind(".jPlayer");
42
+this.internal.video.jq&&this.internal.video.jq.unbind(".jPlayer");this.options.emulateHtml&&this._destroyHtmlBridge();this.element.removeData("jPlayer");this.element.unbind(".jPlayer");this.element.empty();delete this.instances[this.internal.instance]},enable:function(){},disable:function(){},_testCanPlayType:function(a){try{a.canPlayType(this.format.mp3.codec);return true}catch(b){return false}},_uaBlocklist:function(a){var c=navigator.userAgent.toLowerCase(),d=false;b.each(a,function(a,b){if(b&&
43
+b.test(c)){d=true;return false}});return d},_restrictNativeVideoControls:function(){if(this.require.audio&&this.status.nativeVideoControls){this.status.nativeVideoControls=false;this.status.noFullScreen=true}},_updateNativeVideoControls:function(){if(this.html.video.available&&this.html.used){this.htmlElement.video.controls=this.status.nativeVideoControls;this._updateAutohide();if(this.status.nativeVideoControls&&this.require.video){this.internal.poster.jq.hide();this.internal.video.jq.css({width:this.status.width,
44
+height:this.status.height})}else if(this.status.waitForPlay&&this.status.video){this.internal.poster.jq.show();this.internal.video.jq.css({width:"0px",height:"0px"})}}},_addHtmlEventListeners:function(a,c){var d=this;a.preload=this.options.preload;a.muted=this.options.muted;a.volume=this.options.volume;a.addEventListener("progress",function(){if(c.gate){d._getHtmlStatus(a);d._updateInterface();d._trigger(b.jPlayer.event.progress)}},false);a.addEventListener("timeupdate",function(){if(c.gate){d._getHtmlStatus(a);
45
+d._updateInterface();d._trigger(b.jPlayer.event.timeupdate)}},false);a.addEventListener("durationchange",function(){if(c.gate){d._getHtmlStatus(a);d._updateInterface();d._trigger(b.jPlayer.event.durationchange)}},false);a.addEventListener("play",function(){if(c.gate){d._updateButtons(true);d._html_checkWaitForPlay();d._trigger(b.jPlayer.event.play)}},false);a.addEventListener("playing",function(){if(c.gate){d._updateButtons(true);d._seeked();d._trigger(b.jPlayer.event.playing)}},false);a.addEventListener("pause",
46
+function(){if(c.gate){d._updateButtons(false);d._trigger(b.jPlayer.event.pause)}},false);a.addEventListener("waiting",function(){if(c.gate){d._seeking();d._trigger(b.jPlayer.event.waiting)}},false);a.addEventListener("seeking",function(){if(c.gate){d._seeking();d._trigger(b.jPlayer.event.seeking)}},false);a.addEventListener("seeked",function(){if(c.gate){d._seeked();d._trigger(b.jPlayer.event.seeked)}},false);a.addEventListener("volumechange",function(){if(c.gate){d.options.volume=a.volume;d.options.muted=
47
+a.muted;d._updateMute();d._updateVolume();d._trigger(b.jPlayer.event.volumechange)}},false);a.addEventListener("suspend",function(){if(c.gate){d._seeked();d._trigger(b.jPlayer.event.suspend)}},false);a.addEventListener("ended",function(){if(c.gate){if(!b.jPlayer.browser.webkit)d.htmlElement.media.currentTime=0;d.htmlElement.media.pause();d._updateButtons(false);d._getHtmlStatus(a,true);d._updateInterface();d._trigger(b.jPlayer.event.ended)}},false);a.addEventListener("error",function(){if(c.gate){d._updateButtons(false);
48
+d._seeked();if(d.status.srcSet){clearTimeout(d.internal.htmlDlyCmdId);d.status.waitForLoad=true;d.status.waitForPlay=true;d.status.video&&!d.status.nativeVideoControls&&d.internal.video.jq.css({width:"0px",height:"0px"});d._validString(d.status.media.poster)&&!d.status.nativeVideoControls&&d.internal.poster.jq.show();d.css.jq.videoPlay.length&&d.css.jq.videoPlay.show();d._error({type:b.jPlayer.error.URL,context:d.status.src,message:b.jPlayer.errorMsg.URL,hint:b.jPlayer.errorHint.URL})}}},false);b.each(b.jPlayer.htmlEvent,
49
+function(e,g){a.addEventListener(this,function(){c.gate&&d._trigger(b.jPlayer.event[g])},false)})},_getHtmlStatus:function(a,b){var d=0,e=0,g=0,f=0;if(isFinite(a.duration))this.status.duration=a.duration;d=a.currentTime;e=this.status.duration>0?100*d/this.status.duration:0;if(typeof a.seekable==="object"&&a.seekable.length>0){g=this.status.duration>0?100*a.seekable.end(a.seekable.length-1)/this.status.duration:100;f=this.status.duration>0?100*a.currentTime/a.seekable.end(a.seekable.length-1):0}else{g=
50
+100;f=e}if(b)e=f=d=0;this.status.seekPercent=g;this.status.currentPercentRelative=f;this.status.currentPercentAbsolute=e;this.status.currentTime=d;this.status.readyState=a.readyState;this.status.networkState=a.networkState;this.status.playbackRate=a.playbackRate;this.status.ended=a.ended},_resetStatus:function(){this.status=b.extend({},this.status,b.jPlayer.prototype.status)},_trigger:function(a,c,d){a=b.Event(a);a.jPlayer={};a.jPlayer.version=b.extend({},this.version);a.jPlayer.options=b.extend(true,
51
+{},this.options);a.jPlayer.status=b.extend(true,{},this.status);a.jPlayer.html=b.extend(true,{},this.html);a.jPlayer.flash=b.extend(true,{},this.flash);if(c)a.jPlayer.error=b.extend({},c);if(d)a.jPlayer.warning=b.extend({},d);this.element.trigger(a)},jPlayerFlashEvent:function(a,c){if(a===b.jPlayer.event.ready)if(this.internal.ready){if(this.flash.gate){if(this.status.srcSet){var d=this.status.currentTime,e=this.status.paused;this.setMedia(this.status.media);d>0&&(e?this.pause(d):this.play(d))}this._trigger(b.jPlayer.event.flashreset)}}else{this.internal.ready=
52
+true;this.internal.flash.jq.css({width:"0px",height:"0px"});this.version.flash=c.version;this.version.needFlash!==this.version.flash&&this._error({type:b.jPlayer.error.VERSION,context:this.version.flash,message:b.jPlayer.errorMsg.VERSION+this.version.flash,hint:b.jPlayer.errorHint.VERSION});this._trigger(b.jPlayer.event.repeat);this._trigger(a)}if(this.flash.gate)switch(a){case b.jPlayer.event.progress:this._getFlashStatus(c);this._updateInterface();this._trigger(a);break;case b.jPlayer.event.timeupdate:this._getFlashStatus(c);
53
+this._updateInterface();this._trigger(a);break;case b.jPlayer.event.play:this._seeked();this._updateButtons(true);this._trigger(a);break;case b.jPlayer.event.pause:this._updateButtons(false);this._trigger(a);break;case b.jPlayer.event.ended:this._updateButtons(false);this._trigger(a);break;case b.jPlayer.event.click:this._trigger(a);break;case b.jPlayer.event.error:this.status.waitForLoad=true;this.status.waitForPlay=true;this.status.video&&this.internal.flash.jq.css({width:"0px",height:"0px"});this._validString(this.status.media.poster)&&
54
+this.internal.poster.jq.show();this.css.jq.videoPlay.length&&this.status.video&&this.css.jq.videoPlay.show();this.status.video?this._flash_setVideo(this.status.media):this._flash_setAudio(this.status.media);this._updateButtons(false);this._error({type:b.jPlayer.error.URL,context:c.src,message:b.jPlayer.errorMsg.URL,hint:b.jPlayer.errorHint.URL});break;case b.jPlayer.event.seeking:this._seeking();this._trigger(a);break;case b.jPlayer.event.seeked:this._seeked();this._trigger(a);break;case b.jPlayer.event.ready:break;
55
+default:this._trigger(a)}return false},_getFlashStatus:function(a){this.status.seekPercent=a.seekPercent;this.status.currentPercentRelative=a.currentPercentRelative;this.status.currentPercentAbsolute=a.currentPercentAbsolute;this.status.currentTime=a.currentTime;this.status.duration=a.duration;this.status.readyState=4;this.status.networkState=0;this.status.playbackRate=1;this.status.ended=false},_updateButtons:function(a){if(a!==f){this.status.paused=!a;if(this.css.jq.play.length&&this.css.jq.pause.length)if(a){this.css.jq.play.hide();
56
+this.css.jq.pause.show()}else{this.css.jq.play.show();this.css.jq.pause.hide()}}if(this.css.jq.restoreScreen.length&&this.css.jq.fullScreen.length)if(this.status.noFullScreen){this.css.jq.fullScreen.hide();this.css.jq.restoreScreen.hide()}else if(this.options.fullScreen){this.css.jq.fullScreen.hide();this.css.jq.restoreScreen.show()}else{this.css.jq.fullScreen.show();this.css.jq.restoreScreen.hide()}if(this.css.jq.repeat.length&&this.css.jq.repeatOff.length)if(this.options.loop){this.css.jq.repeat.hide();
57
+this.css.jq.repeatOff.show()}else{this.css.jq.repeat.show();this.css.jq.repeatOff.hide()}},_updateInterface:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.width(this.status.seekPercent+"%");this.css.jq.playBar.length&&this.css.jq.playBar.width(this.status.currentPercentRelative+"%");this.css.jq.currentTime.length&&this.css.jq.currentTime.text(b.jPlayer.convertTime(this.status.currentTime));this.css.jq.duration.length&&this.css.jq.duration.text(b.jPlayer.convertTime(this.status.duration))},
58
+_seeking:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.addClass("jp-seeking-bg")},_seeked:function(){this.css.jq.seekBar.length&&this.css.jq.seekBar.removeClass("jp-seeking-bg")},_resetGate:function(){this.html.audio.gate=false;this.html.video.gate=false;this.flash.gate=false},_resetActive:function(){this.html.active=false;this.flash.active=false},setMedia:function(a){var c=this,d=false,e=this.status.media.poster!==a.poster;this._resetMedia();this._resetGate();this._resetActive();b.each(this.formats,
59
+function(e,f){var i=c.format[f].media==="video";b.each(c.solutions,function(b,e){if(c[e].support[f]&&c._validString(a[f])){var g=e==="html";if(i){if(g){c.html.video.gate=true;c._html_setVideo(a);c.html.active=true}else{c.flash.gate=true;c._flash_setVideo(a);c.flash.active=true}c.css.jq.videoPlay.length&&c.css.jq.videoPlay.show();c.status.video=true}else{if(g){c.html.audio.gate=true;c._html_setAudio(a);c.html.active=true}else{c.flash.gate=true;c._flash_setAudio(a);c.flash.active=true}c.css.jq.videoPlay.length&&
60
+c.css.jq.videoPlay.hide();c.status.video=false}d=true;return false}});if(d)return false});if(d){if((!this.status.nativeVideoControls||!this.html.video.gate)&&this._validString(a.poster))e?this.htmlElement.poster.src=a.poster:this.internal.poster.jq.show();this.status.srcSet=true;this.status.media=b.extend({},a);this._updateButtons(false);this._updateInterface()}else this._error({type:b.jPlayer.error.NO_SUPPORT,context:"{supplied:'"+this.options.supplied+"'}",message:b.jPlayer.errorMsg.NO_SUPPORT,
61
+hint:b.jPlayer.errorHint.NO_SUPPORT})},_resetMedia:function(){this._resetStatus();this._updateButtons(false);this._updateInterface();this._seeked();this.internal.poster.jq.hide();clearTimeout(this.internal.htmlDlyCmdId);this.html.active?this._html_resetMedia():this.flash.active&&this._flash_resetMedia()},clearMedia:function(){this._resetMedia();this.html.active?this._html_clearMedia():this.flash.active&&this._flash_clearMedia();this._resetGate();this._resetActive()},load:function(){this.status.srcSet?
62
+this.html.active?this._html_load():this.flash.active&&this._flash_load():this._urlNotSetError("load")},play:function(a){a=typeof a==="number"?a:NaN;this.status.srcSet?this.html.active?this._html_play(a):this.flash.active&&this._flash_play(a):this._urlNotSetError("play")},videoPlay:function(){this.play()},pause:function(a){a=typeof a==="number"?a:NaN;this.status.srcSet?this.html.active?this._html_pause(a):this.flash.active&&this._flash_pause(a):this._urlNotSetError("pause")},pauseOthers:function(){var a=
63
+this;b.each(this.instances,function(b,d){a.element!==d&&d.data("jPlayer").status.srcSet&&d.jPlayer("pause")})},stop:function(){this.status.srcSet?this.html.active?this._html_pause(0):this.flash.active&&this._flash_pause(0):this._urlNotSetError("stop")},playHead:function(a){a=this._limitValue(a,0,100);this.status.srcSet?this.html.active?this._html_playHead(a):this.flash.active&&this._flash_playHead(a):this._urlNotSetError("playHead")},_muted:function(a){this.options.muted=a;this.html.used&&this._html_mute(a);
64
+this.flash.used&&this._flash_mute(a);if(!this.html.video.gate&&!this.html.audio.gate){this._updateMute(a);this._updateVolume(this.options.volume);this._trigger(b.jPlayer.event.volumechange)}},mute:function(a){a=a===f?true:!!a;this._muted(a)},unmute:function(a){a=a===f?true:!!a;this._muted(!a)},_updateMute:function(a){if(a===f)a=this.options.muted;if(this.css.jq.mute.length&&this.css.jq.unmute.length)if(this.status.noVolume){this.css.jq.mute.hide();this.css.jq.unmute.hide()}else if(a){this.css.jq.mute.hide();
65
+this.css.jq.unmute.show()}else{this.css.jq.mute.show();this.css.jq.unmute.hide()}},volume:function(a){a=this._limitValue(a,0,1);this.options.volume=a;this.html.used&&this._html_volume(a);this.flash.used&&this._flash_volume(a);if(!this.html.video.gate&&!this.html.audio.gate){this._updateVolume(a);this._trigger(b.jPlayer.event.volumechange)}},volumeBar:function(a){if(this.css.jq.volumeBar.length){var b=this.css.jq.volumeBar.offset(),d=a.pageX-b.left,e=this.css.jq.volumeBar.width(),a=this.css.jq.volumeBar.height()-
66
+a.pageY+b.top,b=this.css.jq.volumeBar.height();this.options.verticalVolume?this.volume(a/b):this.volume(d/e)}this.options.muted&&this._muted(false)},volumeBarValue:function(a){this.volumeBar(a)},_updateVolume:function(a){if(a===f)a=this.options.volume;a=this.options.muted?0:a;if(this.status.noVolume){this.css.jq.volumeBar.length&&this.css.jq.volumeBar.hide();this.css.jq.volumeBarValue.length&&this.css.jq.volumeBarValue.hide();this.css.jq.volumeMax.length&&this.css.jq.volumeMax.hide()}else{this.css.jq.volumeBar.length&&
67
+this.css.jq.volumeBar.show();if(this.css.jq.volumeBarValue.length){this.css.jq.volumeBarValue.show();this.css.jq.volumeBarValue[this.options.verticalVolume?"height":"width"](a*100+"%")}this.css.jq.volumeMax.length&&this.css.jq.volumeMax.show()}},volumeMax:function(){this.volume(1);this.options.muted&&this._muted(false)},_cssSelectorAncestor:function(a){var c=this;this.options.cssSelectorAncestor=a;this._removeUiClass();this.ancestorJq=a?b(a):[];a&&this.ancestorJq.length!==1&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,
68
+context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.ancestorJq.length+" found for cssSelectorAncestor.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT});this._addUiClass();b.each(this.options.cssSelector,function(a,b){c._cssSelector(a,b)})},_cssSelector:function(a,c){var d=this;if(typeof c==="string")if(b.jPlayer.prototype.options.cssSelector[a]){this.css.jq[a]&&this.css.jq[a].length&&this.css.jq[a].unbind(".jPlayer");this.options.cssSelector[a]=c;this.css.cs[a]=this.options.cssSelectorAncestor+
69
+" "+c;this.css.jq[a]=c?b(this.css.cs[a]):[];this.css.jq[a].length&&this.css.jq[a].bind("click.jPlayer",function(c){d[a](c);b(this).blur();return false});c&&this.css.jq[a].length!==1&&this._warning({type:b.jPlayer.warning.CSS_SELECTOR_COUNT,context:this.css.cs[a],message:b.jPlayer.warningMsg.CSS_SELECTOR_COUNT+this.css.jq[a].length+" found for "+a+" method.",hint:b.jPlayer.warningHint.CSS_SELECTOR_COUNT})}else this._warning({type:b.jPlayer.warning.CSS_SELECTOR_METHOD,context:a,message:b.jPlayer.warningMsg.CSS_SELECTOR_METHOD,
70
+hint:b.jPlayer.warningHint.CSS_SELECTOR_METHOD});else this._warning({type:b.jPlayer.warning.CSS_SELECTOR_STRING,context:c,message:b.jPlayer.warningMsg.CSS_SELECTOR_STRING,hint:b.jPlayer.warningHint.CSS_SELECTOR_STRING})},seekBar:function(a){if(this.css.jq.seekBar){var b=this.css.jq.seekBar.offset(),a=a.pageX-b.left,b=this.css.jq.seekBar.width();this.playHead(100*a/b)}},playBar:function(a){this.seekBar(a)},repeat:function(){this._loop(true)},repeatOff:function(){this._loop(false)},_loop:function(a){if(this.options.loop!==
71
+a){this.options.loop=a;this._updateButtons();this._trigger(b.jPlayer.event.repeat)}},currentTime:function(){},duration:function(){},gui:function(){},noSolution:function(){},option:function(a,c){var d=a;if(arguments.length===0)return b.extend(true,{},this.options);if(typeof a==="string"){var e=a.split(".");if(c===f){for(var d=b.extend(true,{},this.options),g=0;g<e.length;g++)if(d[e[g]]!==f)d=d[e[g]];else{this._warning({type:b.jPlayer.warning.OPTION_KEY,context:a,message:b.jPlayer.warningMsg.OPTION_KEY,
72
+hint:b.jPlayer.warningHint.OPTION_KEY});return f}return d}for(var g=d={},h=0;h<e.length;h++)if(h<e.length-1){g[e[h]]={};g=g[e[h]]}else g[e[h]]=c}this._setOptions(d);return this},_setOptions:function(a){var c=this;b.each(a,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,c){var d=this;switch(a){case "volume":this.volume(c);break;case "muted":this._muted(c);break;case "cssSelectorAncestor":this._cssSelectorAncestor(c);break;case "cssSelector":b.each(c,function(a,b){d._cssSelector(a,
73
+b)});break;case "fullScreen":if(this.options[a]!==c){this._removeUiClass();this.options[a]=c;this._refreshSize()}break;case "size":!this.options.fullScreen&&this.options[a].cssClass!==c.cssClass&&this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "sizeFull":this.options.fullScreen&&this.options[a].cssClass!==c.cssClass&&this._removeUiClass();this.options[a]=b.extend({},this.options[a],c);this._refreshSize();break;case "autohide":this.options[a]=b.extend({},
74
+this.options[a],c);this._updateAutohide();break;case "loop":this._loop(c);break;case "nativeVideoControls":this.options[a]=b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this._restrictNativeVideoControls();this._updateNativeVideoControls();break;case "noFullScreen":this.options[a]=b.extend({},this.options[a],c);this.status.nativeVideoControls=this._uaBlocklist(this.options.nativeVideoControls);this.status.noFullScreen=this._uaBlocklist(this.options.noFullScreen);
75
+this._restrictNativeVideoControls();this._updateButtons();break;case "noVolume":this.options[a]=b.extend({},this.options[a],c);this.status.noVolume=this._uaBlocklist(this.options.noVolume);this._updateVolume();this._updateMute();break;case "emulateHtml":if(this.options[a]!==c)(this.options[a]=c)?this._emulateHtmlBridge():this._destroyHtmlBridge()}return this},_refreshSize:function(){this._setSize();this._addUiClass();this._updateSize();this._updateButtons();this._updateAutohide();this._trigger(b.jPlayer.event.resize)},
76
+_setSize:function(){if(this.options.fullScreen){this.status.width=this.options.sizeFull.width;this.status.height=this.options.sizeFull.height;this.status.cssClass=this.options.sizeFull.cssClass}else{this.status.width=this.options.size.width;this.status.height=this.options.size.height;this.status.cssClass=this.options.size.cssClass}this.element.css({width:this.status.width,height:this.status.height})},_addUiClass:function(){this.ancestorJq.length&&this.ancestorJq.addClass(this.status.cssClass)},_removeUiClass:function(){this.ancestorJq.length&&
77
+this.ancestorJq.removeClass(this.status.cssClass)},_updateSize:function(){this.internal.poster.jq.css({width:this.status.width,height:this.status.height});!this.status.waitForPlay&&this.html.active&&this.status.video||this.html.video.available&&this.html.used&&this.status.nativeVideoControls?this.internal.video.jq.css({width:this.status.width,height:this.status.height}):!this.status.waitForPlay&&(this.flash.active&&this.status.video)&&this.internal.flash.jq.css({width:this.status.width,height:this.status.height})},
78
+_updateAutohide:function(){var a=this,b=function(){a.css.jq.gui.fadeIn(a.options.autohide.fadeIn,function(){clearTimeout(a.internal.autohideId);a.internal.autohideId=setTimeout(function(){a.css.jq.gui.fadeOut(a.options.autohide.fadeOut)},a.options.autohide.hold)})};if(this.css.jq.gui.length){this.css.jq.gui.stop(true,true);clearTimeout(this.internal.autohideId);this.element.unbind(".jPlayerAutohide");this.css.jq.gui.unbind(".jPlayerAutohide");if(this.status.nativeVideoControls)this.css.jq.gui.hide();
79
+else if(this.options.fullScreen&&this.options.autohide.full||!this.options.fullScreen&&this.options.autohide.restored){this.element.bind("mousemove.jPlayer.jPlayerAutohide",b);this.css.jq.gui.bind("mousemove.jPlayer.jPlayerAutohide",b);this.css.jq.gui.hide()}else this.css.jq.gui.show()}},fullScreen:function(){this._setOption("fullScreen",true)},restoreScreen:function(){this._setOption("fullScreen",false)},_html_initMedia:function(){this.htmlElement.media.src=this.status.src;this.options.preload!==
80
+"none"&&this._html_load();this._trigger(b.jPlayer.event.timeupdate)},_html_setAudio:function(a){var c=this;b.each(this.formats,function(b,e){if(c.html.support[e]&&a[e]){c.status.src=a[e];c.status.format[e]=true;c.status.formatType=e;return false}});this.htmlElement.media=this.htmlElement.audio;this._html_initMedia()},_html_setVideo:function(a){var c=this;b.each(this.formats,function(b,e){if(c.html.support[e]&&a[e]){c.status.src=a[e];c.status.format[e]=true;c.status.formatType=e;return false}});if(this.status.nativeVideoControls)this.htmlElement.video.poster=
81
+this._validString(a.poster)?a.poster:"";this.htmlElement.media=this.htmlElement.video;this._html_initMedia()},_html_resetMedia:function(){if(this.htmlElement.media){this.htmlElement.media.id===this.internal.video.id&&!this.status.nativeVideoControls&&this.internal.video.jq.css({width:"0px",height:"0px"});this.htmlElement.media.pause()}},_html_clearMedia:function(){if(this.htmlElement.media){this.htmlElement.media.src="";this.htmlElement.media.load()}},_html_load:function(){if(this.status.waitForLoad){this.status.waitForLoad=
82
+false;this.htmlElement.media.load()}clearTimeout(this.internal.htmlDlyCmdId)},_html_play:function(a){var b=this;this._html_load();this.htmlElement.media.play();if(!isNaN(a))try{this.htmlElement.media.currentTime=a}catch(d){this.internal.htmlDlyCmdId=setTimeout(function(){b.play(a)},100);return}this._html_checkWaitForPlay()},_html_pause:function(a){var b=this;a>0?this._html_load():clearTimeout(this.internal.htmlDlyCmdId);this.htmlElement.media.pause();if(!isNaN(a))try{this.htmlElement.media.currentTime=
83
+a}catch(d){this.internal.htmlDlyCmdId=setTimeout(function(){b.pause(a)},100);return}a>0&&this._html_checkWaitForPlay()},_html_playHead:function(a){var b=this;this._html_load();try{if(typeof this.htmlElement.media.seekable==="object"&&this.htmlElement.media.seekable.length>0)this.htmlElement.media.currentTime=a*this.htmlElement.media.seekable.end(this.htmlElement.media.seekable.length-1)/100;else if(this.htmlElement.media.duration>0&&!isNaN(this.htmlElement.media.duration))this.htmlElement.media.currentTime=
84
+a*this.htmlElement.media.duration/100;else throw"e";}catch(d){this.internal.htmlDlyCmdId=setTimeout(function(){b.playHead(a)},100);return}this.status.waitForLoad||this._html_checkWaitForPlay()},_html_checkWaitForPlay:function(){if(this.status.waitForPlay){this.status.waitForPlay=false;this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide();if(this.status.video){this.internal.poster.jq.hide();this.internal.video.jq.css({width:this.status.width,height:this.status.height})}}},_html_volume:function(a){if(this.html.audio.available)this.htmlElement.audio.volume=
85
+a;if(this.html.video.available)this.htmlElement.video.volume=a},_html_mute:function(a){if(this.html.audio.available)this.htmlElement.audio.muted=a;if(this.html.video.available)this.htmlElement.video.muted=a},_flash_setAudio:function(a){var c=this;try{b.each(this.formats,function(b,d){if(c.flash.support[d]&&a[d]){switch(d){case "m4a":case "fla":c._getMovie().fl_setAudio_m4a(a[d]);break;case "mp3":c._getMovie().fl_setAudio_mp3(a[d]);break;case "rtmpa":c._getMovie().fl_setAudio_rtmp(a[d])}c.status.src=
86
+a[d];c.status.format[d]=true;c.status.formatType=d;return false}});if(this.options.preload==="auto"){this._flash_load();this.status.waitForLoad=false}}catch(d){this._flashError(d)}},_flash_setVideo:function(a){var c=this;try{b.each(this.formats,function(b,d){if(c.flash.support[d]&&a[d]){switch(d){case "m4v":case "flv":c._getMovie().fl_setVideo_m4v(a[d]);break;case "rtmpv":c._getMovie().fl_setVideo_rtmp(a[d])}c.status.src=a[d];c.status.format[d]=true;c.status.formatType=d;return false}});if(this.options.preload===
87
+"auto"){this._flash_load();this.status.waitForLoad=false}}catch(d){this._flashError(d)}},_flash_resetMedia:function(){this.internal.flash.jq.css({width:"0px",height:"0px"});this._flash_pause(NaN)},_flash_clearMedia:function(){try{this._getMovie().fl_clearMedia()}catch(a){this._flashError(a)}},_flash_load:function(){try{this._getMovie().fl_load()}catch(a){this._flashError(a)}this.status.waitForLoad=false},_flash_play:function(a){try{this._getMovie().fl_play(a)}catch(b){this._flashError(b)}this.status.waitForLoad=
88
+false;this._flash_checkWaitForPlay()},_flash_pause:function(a){try{this._getMovie().fl_pause(a)}catch(b){this._flashError(b)}if(a>0){this.status.waitForLoad=false;this._flash_checkWaitForPlay()}},_flash_playHead:function(a){try{this._getMovie().fl_play_head(a)}catch(b){this._flashError(b)}this.status.waitForLoad||this._flash_checkWaitForPlay()},_flash_checkWaitForPlay:function(){if(this.status.waitForPlay){this.status.waitForPlay=false;this.css.jq.videoPlay.length&&this.css.jq.videoPlay.hide();if(this.status.video){this.internal.poster.jq.hide();
89
+this.internal.flash.jq.css({width:this.status.width,height:this.status.height})}}},_flash_volume:function(a){try{this._getMovie().fl_volume(a)}catch(b){this._flashError(b)}},_flash_mute:function(a){try{this._getMovie().fl_mute(a)}catch(b){this._flashError(b)}},_getMovie:function(){return document[this.internal.flash.id]},_checkForFlash:function(a){var b=false,d;if(window.ActiveXObject)try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+a);b=true}catch(e){}else if(navigator.plugins&&navigator.mimeTypes.length>
90
+0)(d=navigator.plugins["Shockwave Flash"])&&navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/,"$1")>=a&&(b=true);return b},_validString:function(a){return a&&typeof a==="string"},_limitValue:function(a,b,d){return a<b?b:a>d?d:a},_urlNotSetError:function(a){this._error({type:b.jPlayer.error.URL_NOT_SET,context:a,message:b.jPlayer.errorMsg.URL_NOT_SET,hint:b.jPlayer.errorHint.URL_NOT_SET})},_flashError:function(a){var c;c=this.internal.ready?"FLASH_DISABLED":"FLASH";this._error({type:b.jPlayer.error[c],
91
+context:this.internal.flash.swf,message:b.jPlayer.errorMsg[c]+a.message,hint:b.jPlayer.errorHint[c]});this.internal.flash.jq.css({width:"1px",height:"1px"})},_error:function(a){this._trigger(b.jPlayer.event.error,a);this.options.errorAlerts&&this._alert("Error!"+(a.message?"\n\n"+a.message:"")+(a.hint?"\n\n"+a.hint:"")+"\n\nContext: "+a.context)},_warning:function(a){this._trigger(b.jPlayer.event.warning,f,a);this.options.warningAlerts&&this._alert("Warning!"+(a.message?"\n\n"+a.message:"")+(a.hint?
92
+"\n\n"+a.hint:"")+"\n\nContext: "+a.context)},_alert:function(a){alert("jPlayer "+this.version.script+" : id='"+this.internal.self.id+"' : "+a)},_emulateHtmlBridge:function(){var a=this;b.each(b.jPlayer.emulateMethods.split(/\s+/g),function(b,d){a.internal.domNode[d]=function(b){a[d](b)}});b.each(b.jPlayer.event,function(c,d){var e=true;b.each(b.jPlayer.reservedEvent.split(/\s+/g),function(a,b){if(b===c)return e=false});e&&a.element.bind(d+".jPlayer.jPlayerHtml",function(){a._emulateHtmlUpdate();
93
+var b=document.createEvent("Event");b.initEvent(c,false,true);a.internal.domNode.dispatchEvent(b)})})},_emulateHtmlUpdate:function(){var a=this;b.each(b.jPlayer.emulateStatus.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.status[d]});b.each(b.jPlayer.emulateOptions.split(/\s+/g),function(b,d){a.internal.domNode[d]=a.options[d]})},_destroyHtmlBridge:function(){var a=this;this.element.unbind(".jPlayerHtml");b.each((b.jPlayer.emulateMethods+" "+b.jPlayer.emulateStatus+" "+b.jPlayer.emulateOptions).split(/\s+/g),
94
+function(b,d){delete a.internal.domNode[d]})}};b.jPlayer.error={FLASH:"e_flash",FLASH_DISABLED:"e_flash_disabled",NO_SOLUTION:"e_no_solution",NO_SUPPORT:"e_no_support",URL:"e_url",URL_NOT_SET:"e_url_not_set",VERSION:"e_version"};b.jPlayer.errorMsg={FLASH:"jPlayer's Flash fallback is not configured correctly, or a command was issued before the jPlayer Ready event. Details: ",FLASH_DISABLED:"jPlayer's Flash fallback has been disabled by the browser due to the CSS rules you have used. Details: ",NO_SOLUTION:"No solution can be found by jPlayer in this browser. Neither HTML nor Flash can be used.",
95
+NO_SUPPORT:"It is not possible to play any media format provided in setMedia() on this browser using your current options.",URL:"Media URL could not be loaded.",URL_NOT_SET:"Attempt to issue media playback commands, while no media url is set.",VERSION:"jPlayer "+b.jPlayer.prototype.version.script+" needs Jplayer.swf version "+b.jPlayer.prototype.version.needFlash+" but found "};b.jPlayer.errorHint={FLASH:"Check your swfPath option and that Jplayer.swf is there.",FLASH_DISABLED:"Check that you have not display:none; the jPlayer entity or any ancestor.",
96
+NO_SOLUTION:"Review the jPlayer options: support and supplied.",NO_SUPPORT:"Video or audio formats defined in the supplied option are missing.",URL:"Check media URL is valid.",URL_NOT_SET:"Use setMedia() to set the media URL.",VERSION:"Update jPlayer files."};b.jPlayer.warning={CSS_SELECTOR_COUNT:"e_css_selector_count",CSS_SELECTOR_METHOD:"e_css_selector_method",CSS_SELECTOR_STRING:"e_css_selector_string",OPTION_KEY:"e_option_key"};b.jPlayer.warningMsg={CSS_SELECTOR_COUNT:"The number of css selectors found did not equal one: ",
97
+CSS_SELECTOR_METHOD:"The methodName given in jPlayer('cssSelector') is not a valid jPlayer method.",CSS_SELECTOR_STRING:"The methodCssSelector given in jPlayer('cssSelector') is not a String or is empty.",OPTION_KEY:"The option requested in jPlayer('option') is undefined."};b.jPlayer.warningHint={CSS_SELECTOR_COUNT:"Check your css selector and the ancestor.",CSS_SELECTOR_METHOD:"Check your method name.",CSS_SELECTOR_STRING:"Check your css selector is a string.",OPTION_KEY:"Check your option name."}})(jQuery);

+ 551 - 0
web/jplayer/js/jquery.transform2d.js Целия файл

@@ -0,0 +1,551 @@
1
+/*
2
+ * transform: A jQuery cssHooks adding cross-browser 2d transform capabilities to $.fn.css() and $.fn.animate()
3
+ *
4
+ * limitations:
5
+ * - requires jQuery 1.4.3+
6
+ * - Should you use the *translate* property, then your elements need to be absolutely positionned in a relatively positionned wrapper **or it will fail in IE678**.
7
+ * - transformOrigin is not accessible
8
+ *
9
+ * latest version and complete README available on Github:
10
+ * https://github.com/louisremi/jquery.transform.js
11
+ *
12
+ * Copyright 2011 @louis_remi
13
+ * Licensed under the MIT license.
14
+ *
15
+ * This saved you an hour of work?
16
+ * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON
17
+ *
18
+ */
19
+(function( $, window, document, Math, undefined ) {
20
+
21
+/*
22
+ * Feature tests and global variables
23
+ */
24
+var div = document.createElement("div"),
25
+	divStyle = div.style,
26
+	suffix = "Transform",
27
+	testProperties = [
28
+		"O" + suffix,
29
+		"ms" + suffix,
30
+		"Webkit" + suffix,
31
+		"Moz" + suffix
32
+	],
33
+	i = testProperties.length,
34
+	supportProperty,
35
+	supportMatrixFilter,
36
+	supportFloat32Array = "Float32Array" in window,
37
+	propertyHook,
38
+	propertyGet,
39
+	rMatrix = /Matrix([^)]*)/,
40
+	rAffine = /^\s*matrix\(\s*1\s*,\s*0\s*,\s*0\s*,\s*1\s*(?:,\s*0(?:px)?\s*){2}\)\s*$/,
41
+	_transform = "transform",
42
+	_transformOrigin = "transformOrigin",
43
+	_translate = "translate",
44
+	_rotate = "rotate",
45
+	_scale = "scale",
46
+	_skew = "skew",
47
+	_matrix = "matrix";
48
+
49
+// test different vendor prefixes of these properties
50
+while ( i-- ) {
51
+	if ( testProperties[i] in divStyle ) {
52
+		$.support[_transform] = supportProperty = testProperties[i];
53
+		$.support[_transformOrigin] = supportProperty + "Origin";
54
+		continue;
55
+	}
56
+}
57
+// IE678 alternative
58
+if ( !supportProperty ) {
59
+	$.support.matrixFilter = supportMatrixFilter = divStyle.filter === "";
60
+}
61
+
62
+// px isn't the default unit of these properties
63
+$.cssNumber[_transform] = $.cssNumber[_transformOrigin] = true;
64
+
65
+/*
66
+ * fn.css() hooks
67
+ */
68
+if ( supportProperty && supportProperty != _transform ) {
69
+	// Modern browsers can use jQuery.cssProps as a basic hook
70
+	$.cssProps[_transform] = supportProperty;
71
+	$.cssProps[_transformOrigin] = supportProperty + "Origin";
72
+
73
+	// Firefox needs a complete hook because it stuffs matrix with "px"
74
+	if ( supportProperty == "Moz" + suffix ) {
75
+		propertyHook = {
76
+			get: function( elem, computed ) {
77
+				return (computed ?
78
+					// remove "px" from the computed matrix
79
+					$.css( elem, supportProperty ).split("px").join(""):
80
+					elem.style[supportProperty]
81
+				);
82
+			},
83
+			set: function( elem, value ) {
84
+				// add "px" to matrices
85
+				elem.style[supportProperty] = /matrix\([^)p]*\)/.test(value) ?
86
+					value.replace(/matrix((?:[^,]*,){4})([^,]*),([^)]*)/, _matrix+"$1$2px,$3px"):
87
+					value;
88
+			}
89
+		};
90
+	/* Fix two jQuery bugs still present in 1.5.1
91
+	 * - rupper is incompatible with IE9, see http://jqbug.com/8346
92
+	 * - jQuery.css is not really jQuery.cssProps aware, see http://jqbug.com/8402
93
+	 */
94
+	} else if ( /^1\.[0-5](?:\.|$)/.test($.fn.jquery) ) {
95
+		propertyHook = {
96
+			get: function( elem, computed ) {
97
+				return (computed ?
98
+					$.css( elem, supportProperty.replace(/^ms/, "Ms") ):
99
+					elem.style[supportProperty]
100
+				);
101
+			}
102
+		};
103
+	}
104
+	/* TODO: leverage hardware acceleration of 3d transform in Webkit only
105
+	else if ( supportProperty == "Webkit" + suffix && support3dTransform ) {
106
+		propertyHook = {
107
+			set: function( elem, value ) {
108
+				elem.style[supportProperty] = 
109
+					value.replace();
110
+			}
111
+		}
112
+	}*/
113
+
114
+} else if ( supportMatrixFilter ) {
115
+	propertyHook = {
116
+		get: function( elem, computed, asArray ) {
117
+			var elemStyle = ( computed && elem.currentStyle ? elem.currentStyle : elem.style ),
118
+				matrix, data;
119
+
120
+			if ( elemStyle && rMatrix.test( elemStyle.filter ) ) {
121
+				matrix = RegExp.$1.split(",");
122
+				matrix = [
123
+					matrix[0].split("=")[1],
124
+					matrix[2].split("=")[1],
125
+					matrix[1].split("=")[1],
126
+					matrix[3].split("=")[1]
127
+				];
128
+			} else {
129
+				matrix = [1,0,0,1];
130
+			}
131
+
132
+			if ( ! $.cssHooks[_transformOrigin] ) {
133
+				matrix[4] = elemStyle ? parseInt(elemStyle.left, 10) || 0 : 0;
134
+				matrix[5] = elemStyle ? parseInt(elemStyle.top, 10) || 0 : 0;
135
+
136
+			} else {
137
+				data = $._data( elem, "transformTranslate", undefined );
138
+				matrix[4] = data ? data[0] : 0;
139
+				matrix[5] = data ? data[1] : 0;
140
+			}
141
+
142
+			return asArray ? matrix : _matrix+"(" + matrix + ")";
143
+		},
144
+		set: function( elem, value, animate ) {
145
+			var elemStyle = elem.style,
146
+				currentStyle,
147
+				Matrix,
148
+				filter,
149
+				centerOrigin;
150
+
151
+			if ( !animate ) {
152
+				elemStyle.zoom = 1;
153
+			}
154
+
155
+			value = matrix(value);
156
+
157
+			// rotate, scale and skew
158
+			Matrix = [
159
+				"Matrix("+
160
+					"M11="+value[0],
161
+					"M12="+value[2],
162
+					"M21="+value[1],
163
+					"M22="+value[3],
164
+					"SizingMethod='auto expand'"
165
+			].join();
166
+			filter = ( currentStyle = elem.currentStyle ) && currentStyle.filter || elemStyle.filter || "";
167
+
168
+			elemStyle.filter = rMatrix.test(filter) ?
169
+				filter.replace(rMatrix, Matrix) :
170
+				filter + " progid:DXImageTransform.Microsoft." + Matrix + ")";
171
+
172
+			if ( ! $.cssHooks[_transformOrigin] ) {
173
+
174
+				// center the transform origin, from pbakaus's Transformie http://github.com/pbakaus/transformie
175
+				if ( (centerOrigin = $.transform.centerOrigin) ) {
176
+					elemStyle[centerOrigin == "margin" ? "marginLeft" : "left"] = -(elem.offsetWidth/2) + (elem.clientWidth/2) + "px";
177
+					elemStyle[centerOrigin == "margin" ? "marginTop" : "top"] = -(elem.offsetHeight/2) + (elem.clientHeight/2) + "px";
178
+				}
179
+
180
+				// translate
181
+				// We assume that the elements are absolute positionned inside a relative positionned wrapper
182
+				elemStyle.left = value[4] + "px";
183
+				elemStyle.top = value[5] + "px";
184
+
185
+			} else {
186
+				$.cssHooks[_transformOrigin].set( elem, value );
187
+			}
188
+		}
189
+	};
190
+}
191
+// populate jQuery.cssHooks with the appropriate hook if necessary
192
+if ( propertyHook ) {
193
+	$.cssHooks[_transform] = propertyHook;
194
+}
195
+// we need a unique setter for the animation logic
196
+propertyGet = propertyHook && propertyHook.get || $.css;
197
+
198
+/*
199
+ * fn.animate() hooks
200
+ */
201
+$.fx.step.transform = function( fx ) {
202
+	var elem = fx.elem,
203
+		start = fx.start,
204
+		end = fx.end,
205
+		pos = fx.pos,
206
+		transform = "",
207
+		precision = 1E5,
208
+		i, startVal, endVal, unit;
209
+
210
+	// fx.end and fx.start need to be converted to interpolation lists
211
+	if ( !start || typeof start === "string" ) {
212
+
213
+		// the following block can be commented out with jQuery 1.5.1+, see #7912
214
+		if ( !start ) {
215
+			start = propertyGet( elem, supportProperty );
216
+		}
217
+
218
+		// force layout only once per animation
219
+		if ( supportMatrixFilter ) {
220
+			elem.style.zoom = 1;
221
+		}
222
+
223
+		// replace "+=" in relative animations (-= is meaningless with transforms)
224
+		end = end.split("+=").join(start);
225
+
226
+		// parse both transform to generate interpolation list of same length
227
+		$.extend( fx, interpolationList( start, end ) );
228
+		start = fx.start;
229
+		end = fx.end;
230
+	}
231
+
232
+	i = start.length;
233
+
234
+	// interpolate functions of the list one by one
235
+	while ( i-- ) {
236
+		startVal = start[i];
237
+		endVal = end[i];
238
+		unit = +false;
239
+
240
+		switch ( startVal[0] ) {
241
+
242
+			case _translate:
243
+				unit = "px";
244
+			case _scale:
245
+				unit || ( unit = "");
246
+
247
+				transform = startVal[0] + "(" +
248
+					Math.round( (startVal[1][0] + (endVal[1][0] - startVal[1][0]) * pos) * precision ) / precision + unit +","+
249
+					Math.round( (startVal[1][1] + (endVal[1][1] - startVal[1][1]) * pos) * precision ) / precision + unit + ")"+
250
+					transform;
251
+				break;
252
+
253
+			case _skew + "X":
254
+			case _skew + "Y":
255
+			case _rotate:
256
+				transform = startVal[0] + "(" +
257
+					Math.round( (startVal[1] + (endVal[1] - startVal[1]) * pos) * precision ) / precision +"rad)"+
258
+					transform;
259
+				break;
260
+		}
261
+	}
262
+
263
+	fx.origin && ( transform = fx.origin + transform );
264
+
265
+	propertyHook && propertyHook.set ?
266
+		propertyHook.set( elem, transform, +true ):
267
+		elem.style[supportProperty] = transform;
268
+};
269
+
270
+/*
271
+ * Utility functions
272
+ */
273
+
274
+// turns a transform string into its "matrix(A,B,C,D,X,Y)" form (as an array, though)
275
+function matrix( transform ) {
276
+	transform = transform.split(")");
277
+	var
278
+			trim = $.trim
279
+		, i = -1
280
+		// last element of the array is an empty string, get rid of it
281
+		, l = transform.length -1
282
+		, split, prop, val
283
+		, prev = supportFloat32Array ? new Float32Array(6) : []
284
+		, curr = supportFloat32Array ? new Float32Array(6) : []
285
+		, rslt = supportFloat32Array ? new Float32Array(6) : [1,0,0,1,0,0]
286
+		;
287
+
288
+	prev[0] = prev[3] = rslt[0] = rslt[3] = 1;
289
+	prev[1] = prev[2] = prev[4] = prev[5] = 0;
290
+
291
+	// Loop through the transform properties, parse and multiply them
292
+	while ( ++i < l ) {
293
+		split = transform[i].split("(");
294
+		prop = trim(split[0]);
295
+		val = split[1];
296
+		curr[0] = curr[3] = 1;
297
+		curr[1] = curr[2] = curr[4] = curr[5] = 0;
298
+
299
+		switch (prop) {
300
+			case _translate+"X":
301
+				curr[4] = parseInt(val, 10);
302
+				break;
303
+
304
+			case _translate+"Y":
305
+				curr[5] = parseInt(val, 10);
306
+				break;
307
+
308
+			case _translate:
309
+				val = val.split(",");
310
+				curr[4] = parseInt(val[0], 10);
311
+				curr[5] = parseInt(val[1] || 0, 10);
312
+				break;
313
+
314
+			case _rotate:
315
+				val = toRadian(val);
316
+				curr[0] = Math.cos(val);
317
+				curr[1] = Math.sin(val);
318
+				curr[2] = -Math.sin(val);
319
+				curr[3] = Math.cos(val);
320
+				break;
321
+
322
+			case _scale+"X":
323
+				curr[0] = +val;
324
+				break;
325
+
326
+			case _scale+"Y":
327
+				curr[3] = val;
328
+				break;
329
+
330
+			case _scale:
331
+				val = val.split(",");
332
+				curr[0] = val[0];
333
+				curr[3] = val.length>1 ? val[1] : val[0];
334
+				break;
335
+
336
+			case _skew+"X":
337
+				curr[2] = Math.tan(toRadian(val));
338
+				break;
339
+
340
+			case _skew+"Y":
341
+				curr[1] = Math.tan(toRadian(val));
342
+				break;
343
+
344
+			case _matrix:
345
+				val = val.split(",");
346
+				curr[0] = val[0];
347
+				curr[1] = val[1];
348
+				curr[2] = val[2];
349
+				curr[3] = val[3];
350
+				curr[4] = parseInt(val[4], 10);
351
+				curr[5] = parseInt(val[5], 10);
352
+				break;
353
+		}
354
+
355
+		// Matrix product (array in column-major order)
356
+		rslt[0] = prev[0] * curr[0] + prev[2] * curr[1];
357
+		rslt[1] = prev[1] * curr[0] + prev[3] * curr[1];
358
+		rslt[2] = prev[0] * curr[2] + prev[2] * curr[3];
359
+		rslt[3] = prev[1] * curr[2] + prev[3] * curr[3];
360
+		rslt[4] = prev[0] * curr[4] + prev[2] * curr[5] + prev[4];
361
+		rslt[5] = prev[1] * curr[4] + prev[3] * curr[5] + prev[5];
362
+
363
+		prev = [rslt[0],rslt[1],rslt[2],rslt[3],rslt[4],rslt[5]];
364
+	}
365
+	return rslt;
366
+}
367
+
368
+// turns a matrix into its rotate, scale and skew components
369
+// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp
370
+function unmatrix(matrix) {
371
+	var
372
+			scaleX
373
+		, scaleY
374
+		, skew
375
+		, A = matrix[0]
376
+		, B = matrix[1]
377
+		, C = matrix[2]
378
+		, D = matrix[3]
379
+		;
380
+
381
+	// Make sure matrix is not singular
382
+	if ( A * D - B * C ) {
383
+		// step (3)
384
+		scaleX = Math.sqrt( A * A + B * B );
385
+		A /= scaleX;
386
+		B /= scaleX;
387
+		// step (4)
388
+		skew = A * C + B * D;
389
+		C -= A * skew;
390
+		D -= B * skew;
391
+		// step (5)
392
+		scaleY = Math.sqrt( C * C + D * D );
393
+		C /= scaleY;
394
+		D /= scaleY;
395
+		skew /= scaleY;
396
+		// step (6)
397
+		if ( A * D < B * C ) {
398
+			A = -A;
399
+			B = -B;
400
+			skew = -skew;
401
+			scaleX = -scaleX;
402
+		}
403
+
404
+	// matrix is singular and cannot be interpolated
405
+	} else {
406
+		// In this case the elem shouldn't be rendered, hence scale == 0
407
+		scaleX = scaleY = skew = 0;
408
+	}
409
+
410
+	// The recomposition order is very important
411
+	// see http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp#l971
412
+	return [
413
+		[_translate, [+matrix[4], +matrix[5]]],
414
+		[_rotate, Math.atan2(B, A)],
415
+		[_skew + "X", Math.atan(skew)],
416
+		[_scale, [scaleX, scaleY]]
417
+	];
418
+}
419
+
420
+// build the list of transform functions to interpolate
421
+// use the algorithm described at http://dev.w3.org/csswg/css3-2d-transforms/#animation
422
+function interpolationList( start, end ) {
423
+	var list = {
424
+			start: [],
425
+			end: []
426
+		},
427
+		i = -1, l,
428
+		currStart, currEnd, currType;
429
+
430
+	// get rid of affine transform matrix
431
+	( start == "none" || isAffine( start ) ) && ( start = "" );
432
+	( end == "none" || isAffine( end ) ) && ( end = "" );
433
+
434
+	// if end starts with the current computed style, this is a relative animation
435
+	// store computed style as the origin, remove it from start and end
436
+	if ( start && end && !end.indexOf("matrix") && toArray( start ).join() == toArray( end.split(")")[0] ).join() ) {
437
+		list.origin = start;
438
+		start = "";
439
+		end = end.slice( end.indexOf(")") +1 );
440
+	}
441
+
442
+	if ( !start && !end ) { return; }
443
+
444
+	// start or end are affine, or list of transform functions are identical
445
+	// => functions will be interpolated individually
446
+	if ( !start || !end || functionList(start) == functionList(end) ) {
447
+
448
+		start && ( start = start.split(")") ) && ( l = start.length );
449
+		end && ( end = end.split(")") ) && ( l = end.length );
450
+
451
+		while ( ++i < l-1 ) {
452
+			start[i] && ( currStart = start[i].split("(") );
453
+			end[i] && ( currEnd = end[i].split("(") );
454
+			currType = $.trim( ( currStart || currEnd )[0] );
455
+
456
+			append( list.start, parseFunction( currType, currStart ? currStart[1] : 0 ) );
457
+			append( list.end, parseFunction( currType, currEnd ? currEnd[1] : 0 ) );
458
+		}
459
+
460
+	// otherwise, functions will be composed to a single matrix
461
+	} else {
462
+		list.start = unmatrix(matrix(start));
463
+		list.end = unmatrix(matrix(end))
464
+	}
465
+
466
+	return list;
467
+}
468
+
469
+function parseFunction( type, value ) {
470
+	var
471
+		// default value is 1 for scale, 0 otherwise
472
+		defaultValue = +(!type.indexOf(_scale)),
473
+		scaleX,
474
+		// remove X/Y from scaleX/Y & translateX/Y, not from skew
475
+		cat = type.replace( /e[XY]/, "e" );
476
+
477
+	switch ( type ) {
478
+		case _translate+"Y":
479
+		case _scale+"Y":
480
+
481
+			value = [
482
+				defaultValue,
483
+				value ?
484
+					parseFloat( value ):
485
+					defaultValue
486
+			];
487
+			break;
488
+
489
+		case _translate+"X":
490
+		case _translate:
491
+		case _scale+"X":
492
+			scaleX = 1;
493
+		case _scale:
494
+
495
+			value = value ?
496
+				( value = value.split(",") ) &&	[
497
+					parseFloat( value[0] ),
498
+					parseFloat( value.length>1 ? value[1] : type == _scale ? scaleX || value[0] : defaultValue+"" )
499
+				]:
500
+				[defaultValue, defaultValue];
501
+			break;
502
+
503
+		case _skew+"X":
504
+		case _skew+"Y":
505
+		case _rotate:
506
+			value = value ? toRadian( value ) : 0;
507
+			break;
508
+
509
+		case _matrix:
510
+			return unmatrix( value ? toArray(value) : [1,0,0,1,0,0] );
511
+			break;
512
+	}
513
+
514
+	return [[ cat, value ]];
515
+}
516
+
517
+function isAffine( matrix ) {
518
+	return rAffine.test(matrix);
519
+}
520
+
521
+function functionList( transform ) {
522
+	return transform.replace(/(?:\([^)]*\))|\s/g, "");
523
+}
524
+
525
+function append( arr1, arr2, value ) {
526
+	while ( value = arr2.shift() ) {
527
+		arr1.push( value );
528
+	}
529
+}
530
+
531
+// converts an angle string in any unit to a radian Float
532
+function toRadian(value) {
533
+	return ~value.indexOf("deg") ?
534
+		parseInt(value,10) * (Math.PI * 2 / 360):
535
+		~value.indexOf("grad") ?
536
+			parseInt(value,10) * (Math.PI/200):
537
+			parseFloat(value);
538
+}
539
+
540
+// Converts "matrix(A,B,C,D,X,Y)" to [A,B,C,D,X,Y]
541
+function toArray(matrix) {
542
+	// remove the unit of X and Y for Firefox
543
+	matrix = /([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix);
544
+	return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]];
545
+}
546
+
547
+$.transform = {
548
+	centerOrigin: "margin"
549
+};
550
+
551
+})( jQuery, window, document, Math );

+ 2 - 0
web/jplayer/js/mod.csstransforms.min.js Целия файл

@@ -0,0 +1,2 @@
1
+/* Modernizr custom build of 1.7pre: csstransforms */
2
+window.Modernizr=function(a,b,c){function G(){}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return!!E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c&&(!b||b(a[d],j)))return!0}function D(a,b){return(""+a).indexOf(b)!==-1}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="1.7pre",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v,w=function(a){var c=b.createElement("style"),d=b.createElement("div"),e;c.textContent=a+"{#modernizr{height:3px}}",h.appendChild(c),d.id="modernizr",g.appendChild(d),e=d.offsetHeight===3,c.parentNode.removeChild(c),d.parentNode.removeChild(d);return!!e},x=function(){function d(d,e){e=e||b.createElement(a[d]||"div");var f=(d="on"+d)in e;f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=C(e[d],"function"),C(e[d],c)||(e[d]=c),e.removeAttribute(d))),e=null;return f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),y=({}).hasOwnProperty,z;C(y,c)||C(y.call,c)?z=function(a,b){return b in a&&C(a.constructor.prototype[b],c)}:z=function(a,b){return y.call(a,b)},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])};for(var H in r)z(r,H)&&(v=H.toLowerCase(),e[v]=r[H](),u.push((e[v]?"":"no-")+v));e.input||G(),e.crosswindowmessaging=e.postmessage,e.historymanagement=e.history,e.addTest=function(a,b){a=a.toLowerCase();if(!e[a]){b=!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b;return e}},A(""),j=l=null,e._enableHTML5=f,e._version=d,g.className=g.className.replace(/\bno-js\b/,"")+" js "+u.join(" ");return e}(this,this.document)

+ 559 - 0
web/jplayer/js/popcorn.jplayer.js Целия файл

@@ -0,0 +1,559 @@
1
+/*
2
+ * jPlayer Player Plugin for Popcorn JavaScript Library
3
+ * http://www.jplayer.org
4
+ *
5
+ * Copyright (c) 2012 Happyworm Ltd
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ *  - http://www.opensource.org/licenses/mit-license.php
8
+ *  - http://www.gnu.org/copyleft/gpl.html
9
+ *
10
+ * Author: Mark J Panaghiston
11
+ * Version: 1.0.0
12
+ * Date: 13th September 2012
13
+ *
14
+ * For Popcorn Version: 1.3
15
+ * For jPlayer Version: 2.2.0
16
+ * Requires: jQuery 1.3.2+
17
+ * Note: jQuery dependancy cannot be removed since jPlayer 2 is a jQuery plugin. Use of jQuery will be kept to a minimum.
18
+ */
19
+
20
+/* Code verified using http://www.jshint.com/ */
21
+/*jshint asi:false, bitwise:false, boss:false, browser:true, curly:false, debug:false, devel:true, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:false, noarg:true, noempty:false, nonew:true, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false smarttabs:true */
22
+/*global Popcorn:false */
23
+
24
+(function(Popcorn) {
25
+
26
+	var JQUERY_SCRIPT = 'http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js', // Used if jQuery not already present.
27
+	JPLAYER_SCRIPT = 'http://www.jplayer.org/2.2.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present.
28
+	JPLAYER_SWFPATH = 'http://www.jplayer.org/2.2.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object.
29
+	SOLUTION = 'html,flash', // The default solution option.
30
+	DEBUG = false, // Decided to leave the debugging option and console output in for the time being. Overhead is trivial.
31
+	jQueryDownloading = false, // Flag to stop multiple instances from each pulling in jQuery, thus corrupting it.
32
+	jPlayerDownloading = false, // Flag to stop multiple instances from each pulling in jPlayer, thus corrupting it.
33
+	format = { // Duplicate of jPlayer 2.2.0 object, to avoid always requiring jQuery and jPlayer to be loaded before performing the _canPlayType() test.
34
+		mp3: {
35
+			codec: 'audio/mpeg; codecs="mp3"',
36
+			flashCanPlay: true,
37
+			media: 'audio'
38
+		},
39
+		m4a: { // AAC / MP4
40
+			codec: 'audio/mp4; codecs="mp4a.40.2"',
41
+			flashCanPlay: true,
42
+			media: 'audio'
43
+		},
44
+		oga: { // OGG
45
+			codec: 'audio/ogg; codecs="vorbis"',
46
+			flashCanPlay: false,
47
+			media: 'audio'
48
+		},
49
+		wav: { // PCM
50
+			codec: 'audio/wav; codecs="1"',
51
+			flashCanPlay: false,
52
+			media: 'audio'
53
+		},
54
+		webma: { // WEBM
55
+			codec: 'audio/webm; codecs="vorbis"',
56
+			flashCanPlay: false,
57
+			media: 'audio'
58
+		},
59
+		fla: { // FLV / F4A
60
+			codec: 'audio/x-flv',
61
+			flashCanPlay: true,
62
+			media: 'audio'
63
+		},
64
+		rtmpa: { // RTMP AUDIO
65
+			codec: 'audio/rtmp; codecs="rtmp"',
66
+			flashCanPlay: true,
67
+			media: 'audio'
68
+		},
69
+		m4v: { // H.264 / MP4
70
+			codec: 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"',
71
+			flashCanPlay: true,
72
+			media: 'video'
73
+		},
74
+		ogv: { // OGG
75
+			codec: 'video/ogg; codecs="theora, vorbis"',
76
+			flashCanPlay: false,
77
+			media: 'video'
78
+		},
79
+		webmv: { // WEBM
80
+			codec: 'video/webm; codecs="vorbis, vp8"',
81
+			flashCanPlay: false,
82
+			media: 'video'
83
+		},
84
+		flv: { // FLV / F4V
85
+			codec: 'video/x-flv',
86
+			flashCanPlay: true,
87
+			media: 'video'
88
+		},
89
+		rtmpv: { // RTMP VIDEO
90
+			codec: 'video/rtmp; codecs="rtmp"',
91
+			flashCanPlay: true,
92
+			media: 'video'
93
+		}
94
+	},
95
+	isObject = function(val) { // Basic check for Object
96
+		if(val && typeof val === 'object' && val.hasOwnProperty) {
97
+			return true;
98
+		} else {
99
+			return false;
100
+		}
101
+	},
102
+	getMediaType = function(url) { // Function to gleam the media type from the URL
103
+		var mediaType = false;
104
+		if(/\.mp3$/i.test(url)) {
105
+			mediaType = 'mp3';
106
+		} else if(/\.mp4$/i.test(url) || /\.m4v$/i.test(url)) {
107
+			mediaType = 'm4v';
108
+		} else if(/\.m4a$/i.test(url)) {
109
+			mediaType = 'm4a';
110
+		} else if(/\.ogg$/i.test(url) || /\.oga$/i.test(url)) {
111
+			mediaType = 'oga';
112
+		} else if(/\.ogv$/i.test(url)) {
113
+			mediaType = 'ogv';
114
+		} else if(/\.webm$/i.test(url)) {
115
+			mediaType = 'webmv';
116
+		}
117
+		return mediaType;
118
+	},
119
+	getSupplied = function(url) { // Function to generate a supplied option from an src object. ie., When supplied not specified.
120
+		var supplied = '',
121
+		separator = '';
122
+		if(isObject(url)) {
123
+			// Generate supplied option from object's properties. Non-format properties would be ignored by jPlayer. Order is unpredictable.
124
+			for(var prop in url) {
125
+				if(url.hasOwnProperty(prop)) {
126
+					supplied += separator + prop;
127
+					separator = ',';
128
+				}
129
+			}
130
+		}
131
+		if(DEBUG) console.log('getSupplied(): Generated: supplied = "' + supplied + '"');
132
+		return supplied;
133
+	};
134
+
135
+	Popcorn.player( 'jplayer', {
136
+		_canPlayType: function( containerType, url ) {
137
+			// url : Either a String or an Object structured similar a jPlayer media object. ie., As used by setMedia in jPlayer.
138
+			// The url object may also contain a solution and supplied property.
139
+
140
+			// Define the src object structure here!
141
+
142
+			var cType = containerType.toLowerCase(),
143
+			srcObj = {
144
+				media:{},
145
+				options:{}
146
+			},
147
+			rVal = false, // Only a boolean false means it is not supported.
148
+			mediaType;
149
+
150
+			if(cType !== 'video' && cType !== 'audio') {
151
+
152
+				if(typeof url === 'string') {
153
+					// Check it starts with http, so the URL is absolute... Well, it is not a perfect check.
154
+					if(/^http.*/i.test(url)) {
155
+						mediaType = getMediaType(url);
156
+						if(mediaType) {
157
+							srcObj.media[mediaType] = url;
158
+							srcObj.options.solution = SOLUTION;
159
+							srcObj.options.supplied = mediaType;
160
+						}
161
+					}
162
+				} else {
163
+					srcObj = url; // Assume the url is an src object.
164
+				}
165
+
166
+				// Check for Object and appropriate minimum data structure.
167
+				if(isObject(srcObj) && isObject(srcObj.media)) {
168
+
169
+					if(!isObject(srcObj.options)) {
170
+						srcObj.options = {};
171
+					}
172
+
173
+					if(!srcObj.options.solution) {
174
+						srcObj.options.solution = SOLUTION;
175
+					}
176
+
177
+					if(!srcObj.options.supplied) {
178
+						srcObj.options.supplied = getSupplied(srcObj.media);
179
+					}
180
+
181
+					// Figure out how jPlayer will play it.
182
+					// This may not work properly when both audio and video is supplied. ie., A media player. But it should return truethy and jPlayer can figure it out.
183
+					
184
+					var solution = srcObj.options.solution.toLowerCase().split(","), // Create the solution array, with prority based on the order of the solution string.
185
+					supplied = srcObj.options.supplied.toLowerCase().split(","); // Create the supplied formats array, with prority based on the order of the supplied formats string.
186
+
187
+					for(var sol = 0; sol < solution.length; sol++) {
188
+
189
+						var solutionType = solution[sol].replace(/^\s+|\s+$/g, ""), //trim
190
+						checkingHtml = solutionType === 'html',
191
+						checkingFlash = solutionType === 'flash',
192
+						mediaElem;
193
+
194
+						for(var fmt = 0; fmt < supplied.length; fmt++) {
195
+							mediaType = supplied[fmt].replace(/^\s+|\s+$/g, ""); //trim
196
+							if(format[mediaType]) { // Check format is valid.
197
+
198
+								// Create an HTML5 media element for the type of media.
199
+								if(!mediaElem && checkingHtml) {
200
+									mediaElem = document.createElement(format[mediaType].media);
201
+								}
202
+								// See if the HTML5 media element can play the MIME / Codec type.
203
+								// Flash also returns the object if the format is playable, so it is truethy, but that html property is false.
204
+								// This assumes Flash is available, but that should be dealt with by jPlayer if that happens.
205
+								var htmlCanPlay = !!(mediaElem && mediaElem.canPlayType && mediaElem.canPlayType(format[mediaType].codec)),
206
+								htmlWillPlay = htmlCanPlay && checkingHtml,
207
+								flashWillPlay = format[mediaType].flashCanPlay && checkingFlash;
208
+								// The first one found will match what jPlayer uses.
209
+								if(htmlWillPlay || flashWillPlay) {
210
+									rVal = {
211
+										html: htmlWillPlay,
212
+										type: mediaType
213
+									};
214
+									sol = solution.length; // Exit solution loop
215
+									fmt = supplied.length; // Exit supplied loop
216
+								}
217
+							}
218
+						}
219
+					}
220
+				}
221
+			}
222
+			return rVal;
223
+		},
224
+		// _setup: function( options ) { // Warning: options is deprecated.
225
+		_setup: function() {
226
+			var media = this,
227
+			myPlayer, // The jQuery selector of the jPlayer element. Usually a <div>
228
+			jPlayerObj, // The jPlayer data instance. For performance and DRY code.
229
+			mediaType = 'unknown',
230
+			jpMedia = {},
231
+			jpOptions = {},
232
+			ready = false, // Used during init to override the annoying duration dependance in the track event padding during Popcorn's isReady(). ie., We is ready after loadeddata and duration can then be set real value at leisure.
233
+			duration = 0, // For the durationchange event with both HTML5 and Flash solutions. Used with 'ready' to keep control during the Popcorn isReady() via loadeddata event. (Duration=0 is bad.)
234
+			durationchangeId = null, // A timeout ID used with delayed durationchange event. (Because of the duration=NaN fudge to avoid Popcorn track event corruption.)
235
+			canplaythrough = false,
236
+			error = null, // The MediaError object.
237
+
238
+			dispatchDurationChange = function() {
239
+				if(ready) {
240
+					if(DEBUG) console.log('Dispatched event : durationchange : ' + duration);
241
+					media.dispatchEvent('durationchange');
242
+				} else {
243
+					if(DEBUG) console.log('DELAYED EVENT (!ready) : durationchange : ' + duration);
244
+					clearTimeout(durationchangeId); // Stop multiple triggers causing multiple timeouts running in parallel.
245
+					durationchangeId = setTimeout(dispatchDurationChange, 250);
246
+				}
247
+			},
248
+
249
+			jPlayerFlashEventsPatch = function() {
250
+
251
+				/* Events already supported by jPlayer Flash:
252
+				 * loadstart
253
+				 * loadedmetadata (M4A, M4V)
254
+				 * progress
255
+				 * play
256
+				 * pause
257
+				 * seeking
258
+				 * seeked
259
+				 * timeupdate
260
+				 * ended
261
+				 * volumechange
262
+				 * error <- See the custom handler in jPlayerInit()
263
+				 */
264
+
265
+				/* Events patched:
266
+				 * loadeddata
267
+				 * durationchange
268
+				 * canplaythrough
269
+				 * playing
270
+				 */
271
+
272
+				/* Events NOT patched:
273
+				 * suspend
274
+				 * abort
275
+				 * emptied
276
+				 * stalled
277
+				 * loadedmetadata (MP3)
278
+				 * waiting
279
+				 * canplay
280
+				 * ratechange
281
+				 */
282
+
283
+				// Triggering patched events through the jPlayer Object so the events are homogeneous. ie., The contain the event.jPlayer data structure.
284
+
285
+				var checkDuration = function(event) {
286
+					if(event.jPlayer.status.duration !== duration) {
287
+						duration = event.jPlayer.status.duration;
288
+						dispatchDurationChange();
289
+					}
290
+				},
291
+
292
+				checkCanPlayThrough = function(event) {
293
+					if(!canplaythrough && event.jPlayer.status.seekPercent === 100) {
294
+						canplaythrough = true;
295
+						setTimeout(function() {
296
+							if(DEBUG) console.log('Trigger : canplaythrough');
297
+							jPlayerObj._trigger($.jPlayer.event.canplaythrough);
298
+						}, 0);
299
+					}
300
+				};
301
+
302
+				myPlayer.bind($.jPlayer.event.loadstart, function() {
303
+					setTimeout(function() {
304
+						if(DEBUG) console.log('Trigger : loadeddata');
305
+						jPlayerObj._trigger($.jPlayer.event.loadeddata);
306
+					}, 0);
307
+				})
308
+				.bind($.jPlayer.event.progress, function(event) {
309
+					checkDuration(event);
310
+					checkCanPlayThrough(event);
311
+				})
312
+				.bind($.jPlayer.event.timeupdate, function(event) {
313
+					checkDuration(event);
314
+					checkCanPlayThrough(event);
315
+				})
316
+				.bind($.jPlayer.event.play, function() {
317
+					setTimeout(function() {
318
+						if(DEBUG) console.log('Trigger : playing');
319
+						jPlayerObj._trigger($.jPlayer.event.playing);
320
+					}, 0);
321
+				});
322
+
323
+				if(DEBUG) console.log('Created CUSTOM event handlers for FLASH');
324
+			},
325
+
326
+			jPlayerInit = function() {
327
+				(function($) {
328
+
329
+					myPlayer = $('#' +  media.id);
330
+
331
+					if(typeof media.src === 'string') {
332
+						mediaType = getMediaType(media.src);
333
+						jpMedia[mediaType] = media.src;
334
+						jpOptions.supplied = mediaType;
335
+						jpOptions.solution = SOLUTION;
336
+					} else if(isObject(media.src)) {
337
+						jpMedia = isObject(media.src.media) ? media.src.media : {};
338
+						jpOptions = isObject(media.src.options) ? media.src.options : {};
339
+						jpOptions.solution = jpOptions.solution || SOLUTION;
340
+						jpOptions.supplied = jpOptions.supplied || getSupplied(media.src.media);
341
+					}
342
+
343
+					// Allow the swfPath to be set to local server. ie., If the jPlayer Plugin is local and already on the page, then you can also use the local SWF.
344
+					jpOptions.swfPath = jpOptions.swfPath || JPLAYER_SWFPATH;
345
+
346
+					myPlayer.bind($.jPlayer.event.ready, function(event) {
347
+						if(event.jPlayer.flash.used) {
348
+							jPlayerFlashEventsPatch();
349
+						}
350
+						// Set the media andd load it, so that the Flash solution behaves similar to HTML5 solution.
351
+						// This also allows the loadstart event to be used to know jPlayer is ready.
352
+						$(this).jPlayer('setMedia', jpMedia).jPlayer('load');
353
+					});
354
+
355
+					// Do not auto-bubble the reserved events, nor the loadeddata and durationchange event, since the duration must be carefully handled when loadeddata event occurs.
356
+					// See the duration property code for more details. (Ranting.)
357
+
358
+					var reservedEvents = $.jPlayer.reservedEvent + ' loadeddata durationchange',
359
+					reservedEvent = reservedEvents.split(/\s+/g);
360
+
361
+					// Generate event handlers for all the standard HTML5 media events. (Except durationchange)
362
+
363
+					var bindEvent = function(name) {
364
+						myPlayer.bind($.jPlayer.event[name], function(event) {
365
+							if(DEBUG) console.log('Dispatched event: ' + name + (event && event.jPlayer ? ' (' + event.jPlayer.status.currentTime + 's)' : '')); // Must be after dispatch for some reason on Firefox/Opera
366
+							media.dispatchEvent(name);
367
+						});
368
+						if(DEBUG) console.log('Created event handler for: ' + name);
369
+					};
370
+
371
+					for(var eventName in $.jPlayer.event) {
372
+						if($.jPlayer.event.hasOwnProperty(eventName)) {
373
+							var nativeEvent = true;
374
+							for(var iRes in reservedEvent) {
375
+								if(reservedEvent.hasOwnProperty(iRes)) {
376
+									if(reservedEvent[iRes] === eventName) {
377
+										nativeEvent = false;
378
+										break;
379
+									}
380
+								}
381
+							}
382
+							if(nativeEvent) {
383
+								bindEvent(eventName);
384
+							} else {
385
+								if(DEBUG) console.log('Skipped auto event handler creation for: ' + eventName);
386
+							}
387
+						}
388
+					}
389
+
390
+					myPlayer.bind($.jPlayer.event.loadeddata, function(event) {
391
+						if(DEBUG) console.log('Dispatched event: loadeddata' + (event && event.jPlayer ? ' (' + event.jPlayer.status.currentTime + 's)' : ''));
392
+						media.dispatchEvent('loadeddata');
393
+						ready = true;
394
+					});
395
+					if(DEBUG) console.log('Created CUSTOM event handler for: loadeddata');
396
+
397
+					myPlayer.bind($.jPlayer.event.durationchange, function(event) {
398
+						duration = event.jPlayer.status.duration;
399
+						dispatchDurationChange();
400
+					});
401
+					if(DEBUG) console.log('Created CUSTOM event handler for: durationchange');
402
+
403
+					// The error event is a special case. Plus jPlayer error event assumes it is a broken URL. (It could also be a decoder error... Or aborted or a Network error.)
404
+					myPlayer.bind($.jPlayer.event.error, function(event) {
405
+						// Not sure how to handle the error situation. Popcorn does not appear to have the error or error.code property documented here: http://popcornjs.org/popcorn-docs/media-methods/
406
+						// If any error event happens, then something has gone pear shaped.
407
+
408
+						error = event.jPlayer.error; // Saving object pointer, not a copy of the object. Possible garbage collection issue... But the player is dead anyway, so don't care.
409
+
410
+						if(error.type === $.jPlayer.error.URL) {
411
+							error.code = 4; // MEDIA_ERR_SRC_NOT_SUPPORTED since jPlayer makes this assumption. It is the most common error, then the decode error. Never seen either of the other 2 error types occur.
412
+						} else {
413
+							error.code = 0; // It was a jPlayer error, not an HTML5 media error.
414
+						}
415
+
416
+						if(DEBUG) console.log('Dispatched event: error');
417
+						if(DEBUG) console.dir(error);
418
+						media.dispatchEvent('error');
419
+					});
420
+					if(DEBUG) console.log('Created CUSTOM event handler for: error');
421
+
422
+					Popcorn.player.defineProperty( media, 'error', {
423
+						set: function() {
424
+							// Read-only property
425
+							return error;
426
+						},
427
+						get: function() {
428
+							return error;
429
+						}
430
+					});
431
+
432
+					Popcorn.player.defineProperty( media, 'currentTime', {
433
+						set: function( val ) {
434
+							if(jPlayerObj.status.paused) {
435
+								myPlayer.jPlayer('pause', val);
436
+							} else {
437
+								myPlayer.jPlayer('play', val);
438
+							}
439
+							return val;
440
+						},
441
+						get: function() {
442
+							return jPlayerObj.status.currentTime;
443
+						}
444
+					});
445
+
446
+					/* The joy of duration and the loadeddata event isReady() handler
447
+					 * The duration is assumed to be a NaN or a valid duration.
448
+					 * jPlayer uses zero instead of a NaN and this screws up the Popcorn track event start/end arrays padding.
449
+					 * This line here:
450
+					 *  videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
451
+					 * Not sure why it is not simply:
452
+					 *  videoDurationPlus = Number.MAX_VALUE; // Who cares if the padding is close to the real duration?
453
+					 * So if you trigger loadeddata before the duration is correct, the track event padding is screwed up. (It pads the start, not the end... Well, duration+1 = 0+1 = 1s)
454
+					 * That line makes the MP3 Flash fallback difficult to setup. The whole MP3 will need to load before the duration is known.
455
+					 * Planning on using a NaN for duration until a >0 value is found... Except with MP3, where seekPercent must be 100% before setting the duration.
456
+					 * Why not just use a NaN during init... And then correct the duration later?
457
+					 */
458
+
459
+					Popcorn.player.defineProperty( media, 'duration', {
460
+						set: function() {
461
+							// Read-only property
462
+							if(ready) {
463
+								return duration;
464
+							} else {
465
+								return NaN;
466
+							}
467
+						},
468
+						get: function() {
469
+							if(ready) {
470
+								return duration; // Popcorn has initialized, we can now use duration zero or whatever without fear.
471
+							} else {
472
+								return NaN; // Keep the duration a NaN until after loadeddata event has occurred. Otherwise Popcorn track event padding is corrupted.
473
+							}
474
+						}
475
+					});
476
+
477
+					Popcorn.player.defineProperty( media, 'muted', {
478
+						set: function( val ) {
479
+							myPlayer.jPlayer('mute', val);
480
+							return jPlayerObj.options.muted;
481
+						},
482
+						get: function() {
483
+							return jPlayerObj.options.muted;
484
+						}
485
+					});
486
+
487
+					Popcorn.player.defineProperty( media, 'volume', {
488
+						set: function( val ) {
489
+							myPlayer.jPlayer('volume', val);
490
+							return jPlayerObj.options.volume;
491
+						},
492
+						get: function() {
493
+							return jPlayerObj.options.volume;
494
+						}
495
+					});
496
+
497
+					Popcorn.player.defineProperty( media, 'paused', {
498
+						set: function() {
499
+							// Read-only property
500
+							return jPlayerObj.status.paused;
501
+						},
502
+						get: function() {
503
+							return jPlayerObj.status.paused;
504
+						}
505
+					});
506
+
507
+					media.play = function() {
508
+						myPlayer.jPlayer('play');
509
+					};
510
+					media.pause = function() {
511
+						myPlayer.jPlayer('pause');
512
+					};
513
+
514
+					myPlayer.jPlayer(jpOptions); // Instance jPlayer. Note that the options should not have a ready event defined... Kill it by default?
515
+					jPlayerObj = myPlayer.data('jPlayer');
516
+
517
+				}(jQuery));
518
+			},
519
+
520
+			jPlayerCheck = function() {
521
+				if (!jQuery.jPlayer) {
522
+					if (!jPlayerDownloading) {
523
+						jPlayerDownloading = true;
524
+						Popcorn.getScript(JPLAYER_SCRIPT, function() {
525
+							jPlayerDownloading = false;
526
+							jPlayerInit();
527
+						});
528
+					} else {
529
+						setTimeout(jPlayerCheck, 250);
530
+					}
531
+				} else {
532
+					jPlayerInit();
533
+				}
534
+			},
535
+
536
+			jQueryCheck = function() {
537
+				if (!window.jQuery) {
538
+					if (!jQueryDownloading) {
539
+						jQueryDownloading = true;
540
+						Popcorn.getScript(JQUERY_SCRIPT, function() {
541
+							jQueryDownloading = false;
542
+							jPlayerCheck();
543
+						});
544
+					} else {
545
+						setTimeout(jQueryCheck, 250);
546
+					}
547
+				} else {
548
+					jPlayerCheck();
549
+				}
550
+			};
551
+
552
+			jQueryCheck();
553
+		},
554
+		_teardown: function() {
555
+			jQuery('#' +  this.id).jPlayer('destroy');
556
+		}
557
+	});
558
+
559
+}(Popcorn));

Файловите разлики са ограничени, защото са твърде много
+ 2212 - 0
web/jplayer/js/popcorn.js


+ 460 - 0
web/jplayer/js/popcorn.player.js Целия файл

@@ -0,0 +1,460 @@
1
+(function( Popcorn ) {
2
+
3
+  // combines calls of two function calls into one
4
+  var combineFn = function( first, second ) {
5
+
6
+    first = first || Popcorn.nop;
7
+    second = second || Popcorn.nop;
8
+
9
+    return function() {
10
+
11
+      first.apply( this, arguments );
12
+      second.apply( this, arguments );
13
+    };
14
+  };
15
+
16
+  //  ID string matching
17
+  var rIdExp  = /^(#([\w\-\_\.]+))$/;
18
+
19
+  var audioExtensions = "ogg|oga|aac|mp3|wav",
20
+      videoExtensions = "ogg|ogv|mp4|webm",
21
+      mediaExtensions = audioExtensions + "|" + videoExtensions;
22
+
23
+  var audioExtensionRegexp = new RegExp( "^.*\\.(" + audioExtensions + ")($|\\?)" ),
24
+      mediaExtensionRegexp = new RegExp( "^.*\\.(" + mediaExtensions + ")($|\\?)" );
25
+
26
+  Popcorn.player = function( name, player ) {
27
+
28
+    // return early if a player already exists under this name
29
+    if ( Popcorn[ name ] ) {
30
+
31
+      return;
32
+    }
33
+
34
+    player = player || {};
35
+
36
+    var playerFn = function( target, src, options ) {
37
+
38
+      options = options || {};
39
+
40
+      // List of events
41
+      var date = new Date() / 1000,
42
+          baselineTime = date,
43
+          currentTime = 0,
44
+          readyState = 0,
45
+          volume = 1,
46
+          muted = false,
47
+          events = {},
48
+
49
+          // The container div of the resource
50
+          container = typeof target === "string" ? Popcorn.dom.find( target ) : target,
51
+          basePlayer = {},
52
+          timeout,
53
+          popcorn;
54
+
55
+      if ( !Object.prototype.__defineGetter__ ) {
56
+
57
+        basePlayer = container || document.createElement( "div" );
58
+      }
59
+
60
+      // copies a div into the media object
61
+      for( var val in container ) {
62
+
63
+        // don't copy properties if using container as baseplayer
64
+        if ( val in basePlayer ) {
65
+
66
+          continue;
67
+        }
68
+
69
+        if ( typeof container[ val ] === "object" ) {
70
+
71
+          basePlayer[ val ] = container[ val ];
72
+        } else if ( typeof container[ val ] === "function" ) {
73
+
74
+          basePlayer[ val ] = (function( value ) {
75
+
76
+            // this is a stupid ugly kludgy hack in honour of Safari
77
+            // in Safari a NodeList is a function, not an object
78
+            if ( "length" in container[ value ] && !container[ value ].call ) {
79
+
80
+              return container[ value ];
81
+            } else {
82
+
83
+              return function() {
84
+
85
+                return container[ value ].apply( container, arguments );
86
+              };
87
+            }
88
+          }( val ));
89
+        } else {
90
+
91
+          Popcorn.player.defineProperty( basePlayer, val, {
92
+            get: (function( value ) {
93
+
94
+              return function() {
95
+
96
+                return container[ value ];
97
+              };
98
+            }( val )),
99
+            set: Popcorn.nop,
100
+            configurable: true
101
+          });
102
+        }
103
+      }
104
+
105
+      var timeupdate = function() {
106
+
107
+        date = new Date() / 1000;
108
+
109
+        if ( !basePlayer.paused ) {
110
+
111
+          basePlayer.currentTime = basePlayer.currentTime + ( date - baselineTime );
112
+          basePlayer.dispatchEvent( "timeupdate" );
113
+          timeout = setTimeout( timeupdate, 10 );
114
+        }
115
+
116
+        baselineTime = date;
117
+      };
118
+
119
+      basePlayer.play = function() {
120
+
121
+        this.paused = false;
122
+
123
+        if ( basePlayer.readyState >= 4 ) {
124
+
125
+          baselineTime = new Date() / 1000;
126
+          basePlayer.dispatchEvent( "play" );
127
+          timeupdate();
128
+        }
129
+      };
130
+
131
+      basePlayer.pause = function() {
132
+
133
+        this.paused = true;
134
+        basePlayer.dispatchEvent( "pause" );
135
+      };
136
+
137
+      Popcorn.player.defineProperty( basePlayer, "currentTime", {
138
+        get: function() {
139
+
140
+          return currentTime;
141
+        },
142
+        set: function( val ) {
143
+
144
+          // make sure val is a number
145
+          currentTime = +val;
146
+          basePlayer.dispatchEvent( "timeupdate" );
147
+
148
+          return currentTime;
149
+        },
150
+        configurable: true
151
+      });
152
+
153
+      Popcorn.player.defineProperty( basePlayer, "volume", {
154
+        get: function() {
155
+
156
+          return volume;
157
+        },
158
+        set: function( val ) {
159
+
160
+          // make sure val is a number
161
+          volume = +val;
162
+          basePlayer.dispatchEvent( "volumechange" );
163
+          return volume;
164
+        },
165
+        configurable: true
166
+      });
167
+
168
+      Popcorn.player.defineProperty( basePlayer, "muted", {
169
+        get: function() {
170
+
171
+          return muted;
172
+        },
173
+        set: function( val ) {
174
+
175
+          // make sure val is a number
176
+          muted = +val;
177
+          basePlayer.dispatchEvent( "volumechange" );
178
+          return muted;
179
+        },
180
+        configurable: true
181
+      });
182
+
183
+      Popcorn.player.defineProperty( basePlayer, "readyState", {
184
+        get: function() {
185
+
186
+          return readyState;
187
+        },
188
+        set: function( val ) {
189
+
190
+          readyState = val;
191
+          return readyState;
192
+        },
193
+        configurable: true
194
+      });
195
+
196
+      // Adds an event listener to the object
197
+      basePlayer.addEventListener = function( evtName, fn ) {
198
+
199
+        if ( !events[ evtName ] ) {
200
+
201
+          events[ evtName ] = [];
202
+        }
203
+
204
+        events[ evtName ].push( fn );
205
+        return fn;
206
+      };
207
+
208
+      // Removes an event listener from the object
209
+      basePlayer.removeEventListener = function( evtName, fn ) {
210
+
211
+        var i,
212
+            listeners = events[ evtName ];
213
+
214
+        if ( !listeners ){
215
+
216
+          return;
217
+        }
218
+
219
+        // walk backwards so we can safely splice
220
+        for ( i = events[ evtName ].length - 1; i >= 0; i-- ) {
221
+
222
+          if( fn === listeners[ i ] ) {
223
+
224
+            listeners.splice(i, 1);
225
+          }
226
+        }
227
+
228
+        return fn;
229
+      };
230
+
231
+      // Can take event object or simple string
232
+      basePlayer.dispatchEvent = function( oEvent ) {
233
+
234
+        var evt,
235
+            self = this,
236
+            eventInterface,
237
+            eventName = oEvent.type;
238
+
239
+        // A string was passed, create event object
240
+        if ( !eventName ) {
241
+
242
+          eventName = oEvent;
243
+          eventInterface  = Popcorn.events.getInterface( eventName );
244
+
245
+          if ( eventInterface ) {
246
+
247
+            evt = document.createEvent( eventInterface );
248
+            evt.initEvent( eventName, true, true, window, 1 );
249
+          }
250
+        }
251
+
252
+        if ( events[ eventName ] ) {
253
+
254
+          for ( var i = events[ eventName ].length - 1; i >= 0; i-- ) {
255
+
256
+            events[ eventName ][ i ].call( self, evt, self );
257
+          }
258
+        }
259
+      };
260
+
261
+      // Attempt to get src from playerFn parameter
262
+      basePlayer.src = src || "";
263
+      basePlayer.duration = 0;
264
+      basePlayer.paused = true;
265
+      basePlayer.ended = 0;
266
+
267
+      options && options.events && Popcorn.forEach( options.events, function( val, key ) {
268
+
269
+        basePlayer.addEventListener( key, val, false );
270
+      });
271
+
272
+      // true and undefined returns on canPlayType means we should attempt to use it,
273
+      // false means we cannot play this type
274
+      if ( player._canPlayType( container.nodeName, src ) !== false ) {
275
+
276
+        if ( player._setup ) {
277
+
278
+          player._setup.call( basePlayer, options );
279
+        } else {
280
+
281
+          // there is no setup, which means there is nothing to load
282
+          basePlayer.readyState = 4;
283
+          basePlayer.dispatchEvent( "loadedmetadata" );
284
+          basePlayer.dispatchEvent( "loadeddata" );
285
+          basePlayer.dispatchEvent( "canplaythrough" );
286
+        }
287
+      } else {
288
+
289
+        // Asynchronous so that users can catch this event
290
+        setTimeout( function() {
291
+          basePlayer.dispatchEvent( "error" );
292
+        }, 0 );
293
+      }
294
+
295
+      popcorn = new Popcorn.p.init( basePlayer, options );
296
+
297
+      if ( player._teardown ) {
298
+
299
+        popcorn.destroy = combineFn( popcorn.destroy, function() {
300
+
301
+          player._teardown.call( basePlayer, options );
302
+        });
303
+      }
304
+
305
+      return popcorn;
306
+    };
307
+
308
+    playerFn.canPlayType = player._canPlayType = player._canPlayType || Popcorn.nop;
309
+
310
+    Popcorn[ name ] = Popcorn.player.registry[ name ] = playerFn;
311
+  };
312
+
313
+  Popcorn.player.registry = {};
314
+
315
+  Popcorn.player.defineProperty = Object.defineProperty || function( object, description, options ) {
316
+
317
+    object.__defineGetter__( description, options.get || Popcorn.nop );
318
+    object.__defineSetter__( description, options.set || Popcorn.nop );
319
+  };
320
+
321
+  // player queue is to help players queue things like play and pause
322
+  // HTML5 video's play and pause are asynch, but do fire in sequence
323
+  // play() should really mean "requestPlay()" or "queuePlay()" and
324
+  // stash a callback that will play the media resource when it's ready to be played
325
+  Popcorn.player.playerQueue = function() {
326
+
327
+    var _queue = [],
328
+        _running = false;
329
+
330
+    return {
331
+      next: function() {
332
+
333
+        _running = false;
334
+        _queue.shift();
335
+        _queue[ 0 ] && _queue[ 0 ]();
336
+      },
337
+      add: function( callback ) {
338
+
339
+        _queue.push(function() {
340
+
341
+          _running = true;
342
+          callback && callback();
343
+        });
344
+
345
+        // if there is only one item on the queue, start it
346
+        !_running && _queue[ 0 ]();
347
+      }
348
+    };
349
+  };
350
+
351
+  // smart will attempt to find you a match, if it does not find a match,
352
+  // it will attempt to create a video element with the source,
353
+  // if that failed, it will throw.
354
+  Popcorn.smart = function( target, src, options ) {
355
+    var playerType,
356
+        elementTypes = [ "AUDIO", "VIDEO" ],
357
+        sourceNode,
358
+        firstSrc,
359
+        node = Popcorn.dom.find( target ),
360
+        i, srcResult,
361
+        canPlayTypeTester = document.createElement( "video" ),
362
+        canPlayTypes = {
363
+          "ogg": "video/ogg",
364
+          "ogv": "video/ogg",
365
+          "oga": "audio/ogg",
366
+          "webm": "video/webm",
367
+          "mp4": "video/mp4",
368
+          "mp3": "audio/mp3"
369
+        };
370
+
371
+    var canPlayType = function( type ) {
372
+
373
+      return canPlayTypeTester.canPlayType( canPlayTypes[ type ] );
374
+    };
375
+
376
+    var canPlaySrc = function( src ) {
377
+
378
+      srcResult = mediaExtensionRegexp.exec( src );
379
+
380
+      if ( !srcResult || !srcResult[ 1 ] ) {
381
+        return false;
382
+      }
383
+
384
+      return canPlayType( srcResult[ 1 ] );
385
+    };
386
+
387
+    if ( !node ) {
388
+
389
+      Popcorn.error( "Specified target " + target + " was not found." );
390
+      return;
391
+    }
392
+
393
+    // For when no src is defined.
394
+    // Usually this is a video element with a src already on it.
395
+    if ( elementTypes.indexOf( node.nodeName ) > -1 && !src ) {
396
+
397
+      if ( typeof src === "object" ) {
398
+
399
+        options = src;
400
+        src = undefined;
401
+      }
402
+
403
+      return Popcorn( node, options );
404
+    }
405
+
406
+    // if our src is not an array, create an array of one.	
407
+    if ( typeof( src ) === "string" ) {
408
+
409
+      src = [ src ];
410
+    }
411
+
412
+    // go through each src, and find the first playable.
413
+    // this only covers player sources popcorn knows of,
414
+    // and not things like a youtube src that is private.
415
+    // it will still consider a private youtube video to be playable.
416
+    for ( i = 0, srcLength = src.length; i < srcLength; i++ ) {
417
+
418
+      // src is a playable HTML5 video, we don't need to check custom players.
419
+      if ( canPlaySrc( src[ i ] ) ) {
420
+
421
+        src = src[ i ];
422
+        break;
423
+      }
424
+
425
+      // for now we loop through and use the first valid player we find.
426
+      for ( var key in Popcorn.player.registry ) {
427
+
428
+        if ( Popcorn.player.registry.hasOwnProperty( key ) ) {
429
+
430
+          if ( Popcorn.player.registry[ key ].canPlayType( node.nodeName, src[ i ] ) ) {
431
+
432
+            // Popcorn.smart( player, src, /* options */ )
433
+            return Popcorn[ key ]( node, src[ i ], options );
434
+          }
435
+        }
436
+      }
437
+    }
438
+
439
+    // Popcorn.smart( div, src, /* options */ )
440
+    // attempting to create a video in a container
441
+    if ( elementTypes.indexOf( node.nodeName ) === -1 ) {
442
+
443
+      firstSrc = typeof( src ) === "string" ? src : src.length ? src[ 0 ] : src;
444
+
445
+      target = document.createElement( !!audioExtensionRegexp.exec( firstSrc ) ? elementTypes[ 0 ] : elementTypes[ 1 ] );
446
+
447
+      // Controls are defaulted to being present
448
+      target.controls = true;
449
+
450
+      node.appendChild( target );
451
+      node = target;
452
+    }
453
+
454
+    options && options.events && options.events.error && node.addEventListener( "error", options.events.error, false );
455
+    node.src = src;
456
+
457
+    return Popcorn( node, options );
458
+
459
+  };
460
+})( Popcorn );

+ 143 - 0
web/jplayer/js/popcorn.subtitle.js Целия файл

@@ -0,0 +1,143 @@
1
+// PLUGIN: Subtitle
2
+
3
+(function ( Popcorn ) {
4
+
5
+  var i = 0,
6
+      createDefaultContainer = function( context, id ) {
7
+
8
+        var ctxContainer = context.container = document.createElement( "div" ),
9
+            style = ctxContainer.style,
10
+            media = context.media;
11
+
12
+        var updatePosition = function() {
13
+          var position = context.position();
14
+          // the video element must have height and width defined
15
+          style.fontSize = "18px";
16
+          style.width = media.offsetWidth + "px";
17
+          style.top = position.top  + media.offsetHeight - ctxContainer.offsetHeight - 40 + "px";
18
+          style.left = position.left + "px";
19
+
20
+          setTimeout( updatePosition, 10 );
21
+        };
22
+
23
+        ctxContainer.id = id || Popcorn.guid();
24
+        style.position = "absolute";
25
+        style.color = "white";
26
+        style.textShadow = "black 2px 2px 6px";
27
+        style.fontWeight = "bold";
28
+        style.textAlign = "center";
29
+
30
+        updatePosition();
31
+
32
+        context.media.parentNode.appendChild( ctxContainer );
33
+
34
+        return ctxContainer;
35
+      };
36
+
37
+  /**
38
+   * Subtitle popcorn plug-in
39
+   * Displays a subtitle over the video, or in the target div
40
+   * Options parameter will need a start, and end.
41
+   * Optional parameters are target and text.
42
+   * Start is the time that you want this plug-in to execute
43
+   * End is the time that you want this plug-in to stop executing
44
+   * Target is the id of the document element that the content is
45
+   *  appended to, this target element must exist on the DOM
46
+   * Text is the text of the subtitle you want to display.
47
+   *
48
+   * @param {Object} options
49
+   *
50
+   * Example:
51
+     var p = Popcorn('#video')
52
+        .subtitle({
53
+          start:            5,                 // seconds, mandatory
54
+          end:              15,                // seconds, mandatory
55
+          text:             'Hellow world',    // optional
56
+          target:           'subtitlediv',     // optional
57
+        } )
58
+   *
59
+   */
60
+
61
+  Popcorn.plugin( "subtitle" , {
62
+
63
+      manifest: {
64
+        about: {
65
+          name: "Popcorn Subtitle Plugin",
66
+          version: "0.1",
67
+          author: "Scott Downe",
68
+          website: "http://scottdowne.wordpress.com/"
69
+        },
70
+        options: {
71
+          start: {
72
+            elem: "input",
73
+            type: "text",
74
+            label: "Start"
75
+          },
76
+          end: {
77
+            elem: "input",
78
+            type: "text",
79
+            label: "End"
80
+          },
81
+          target: "subtitle-container",
82
+          text: {
83
+            elem: "input",
84
+            type: "text",
85
+            label: "Text"
86
+          }
87
+        }
88
+      },
89
+
90
+      _setup: function( options ) {
91
+        var newdiv = document.createElement( "div" );
92
+
93
+        newdiv.id = "subtitle-" + i++;
94
+        newdiv.style.display = "none";
95
+
96
+        // Creates a div for all subtitles to use
97
+        ( !this.container && ( !options.target || options.target === "subtitle-container" ) ) &&
98
+          createDefaultContainer( this );
99
+
100
+        // if a target is specified, use that
101
+        if ( options.target && options.target !== "subtitle-container" ) {
102
+          // In case the target doesn't exist in the DOM
103
+          options.container = document.getElementById( options.target ) || createDefaultContainer( this, options.target );
104
+        } else {
105
+          // use shared default container
106
+          options.container = this.container;
107
+        }
108
+
109
+        document.getElementById( options.container.id ) && document.getElementById( options.container.id ).appendChild( newdiv );
110
+        options.innerContainer = newdiv;
111
+
112
+        options.showSubtitle = function() {
113
+          options.innerContainer.innerHTML = options.text || "";
114
+        };
115
+      },
116
+      /**
117
+       * @member subtitle
118
+       * The start function will be executed when the currentTime
119
+       * of the video  reaches the start time provided by the
120
+       * options variable
121
+       */
122
+      start: function( event, options ){
123
+        options.innerContainer.style.display = "inline";
124
+        options.showSubtitle( options, options.text );
125
+      },
126
+      /**
127
+       * @member subtitle
128
+       * The end function will be executed when the currentTime
129
+       * of the video  reaches the end time provided by the
130
+       * options variable
131
+       */
132
+      end: function( event, options ) {
133
+        options.innerContainer.style.display = "none";
134
+        options.innerContainer.innerHTML = "";
135
+      },
136
+
137
+      _teardown: function ( options ) {
138
+        options.container.removeChild( options.innerContainer );
139
+      }
140
+
141
+  });
142
+
143
+})( Popcorn );

+ 640 - 0
web/jplayer/skin/blue.monday/jplayer.blue.monday.css Целия файл

@@ -0,0 +1,640 @@
1
+/*
2
+ * Skin for jPlayer Plugin (jQuery JavaScript Library)
3
+ * http://www.jplayer.org
4
+ *
5
+ * Skin Name: Blue Monday
6
+ *
7
+ * Copyright (c) 2010-2012 Happyworm Ltd
8
+ * Dual licensed under the MIT and GPL licenses.
9
+ *  - http://www.opensource.org/licenses/mit-license.php
10
+ *  - http://www.gnu.org/copyleft/gpl.html
11
+ *
12
+ * Author: Silvia Benvenuti
13
+ * Skin Version: 4.2 (jPlayer 2.2.0)
14
+ * Date: 22nd October 2012
15
+ */
16
+
17
+div.jp-audio,
18
+div.jp-audio-stream,
19
+div.jp-video {
20
+
21
+	/* Edit the font-size to counteract inherited font sizing.
22
+	 * Eg. 1.25em = 1 / 0.8em
23
+	 */
24
+
25
+	font-size:1.25em; /* 1.25em for testing in site pages */ /* No parent CSS that can effect the size in the demos ZIP */
26
+
27
+	font-family:Verdana, Arial, sans-serif;
28
+	line-height:1.6;
29
+	color: #666;
30
+	/*border:1px solid #009be3;*/
31
+	background-color:#eee;
32
+}
33
+div.jp-audio {
34
+	width:500px;
35
+}
36
+div.jp-audio-stream {
37
+	width:182px;
38
+}
39
+div.jp-video-270p {
40
+	width:480px;
41
+}
42
+div.jp-video-360p {
43
+	width:640px;
44
+}
45
+div.jp-video-full {
46
+	/* Rules for IE6 (full-screen) */
47
+	width:480px;
48
+	height:270px;
49
+	/* Rules for IE7 (full-screen) - Otherwise the relative container causes other page items that are not position:static (default) to appear over the video/gui. */
50
+	position:static !important; position:relative
51
+}
52
+
53
+/* The z-index rule is defined in this manner to enable Popcorn plugins that add overlays to video area. EG. Subtitles. */
54
+div.jp-video-full div div {
55
+	z-index:1000;
56
+}
57
+
58
+div.jp-video-full div.jp-jplayer {
59
+	top: 0;
60
+	left: 0;
61
+	position: fixed !important; position: relative; /* Rules for IE6 (full-screen) */
62
+	overflow: hidden;
63
+}
64
+
65
+div.jp-video-full div.jp-gui {
66
+	position: fixed !important; position: static; /* Rules for IE6 (full-screen) */
67
+	top: 0;
68
+	left: 0;
69
+	width:100%;
70
+	height:100%;
71
+	z-index:1001; /* 1 layer above the others. */
72
+}
73
+
74
+div.jp-video-full div.jp-interface {
75
+	position: absolute !important; position: relative; /* Rules for IE6 (full-screen) */
76
+	bottom: 0;
77
+	left: 0;
78
+}
79
+
80
+div.jp-interface {
81
+	position: relative;
82
+	background-color:#eee;
83
+	width:100%;
84
+}
85
+
86
+div.jp-audio div.jp-type-single div.jp-interface {
87
+	height:80px;
88
+}
89
+div.jp-audio div.jp-type-playlist div.jp-interface {
90
+	height:80px;
91
+}
92
+
93
+div.jp-audio-stream div.jp-type-single div.jp-interface {
94
+	height:80px;
95
+}
96
+
97
+div.jp-video div.jp-interface {
98
+	/*border-top:1px solid #009be3;*/
99
+}
100
+
101
+/* @group CONTROLS */
102
+
103
+div.jp-controls-holder {
104
+	clear: both;
105
+	width:440px;
106
+	margin:0 auto;
107
+	position: relative;
108
+	overflow:hidden;
109
+	top:-8px; /* This negative value depends on the size of the text in jp-currentTime and jp-duration */
110
+}
111
+
112
+div.jp-interface ul.jp-controls {
113
+	list-style-type:none;
114
+	margin:0;
115
+	padding: 0;
116
+	overflow:hidden;
117
+}
118
+
119
+div.jp-audio ul.jp-controls {
120
+	width: 380px;
121
+	padding:20px 20px 0 20px;
122
+}
123
+
124
+div.jp-audio-stream ul.jp-controls {
125
+	width: 142px;
126
+	padding:20px 20px 0 20px;
127
+}
128
+
129
+div.jp-video div.jp-type-single ul.jp-controls {
130
+	width: 78px;
131
+	margin-left: 200px;
132
+}
133
+
134
+div.jp-video div.jp-type-playlist ul.jp-controls {
135
+	width: 134px;
136
+	margin-left: 172px;
137
+}
138
+div.jp-video ul.jp-controls,
139
+div.jp-interface ul.jp-controls li {
140
+	display:inline;
141
+	float: left;
142
+}
143
+
144
+div.jp-interface ul.jp-controls a {
145
+	display:block;
146
+	overflow:hidden;
147
+	text-indent:-9999px;
148
+}
149
+a.jp-play,
150
+a.jp-pause {
151
+	width:40px;
152
+	height:40px;
153
+}
154
+
155
+a.jp-play {
156
+	background: url("jplayer.blue.monday.jpg") 0 0 no-repeat;
157
+}
158
+a.jp-play:hover {
159
+	background: url("jplayer.blue.monday.jpg") -41px 0 no-repeat;
160
+}
161
+a.jp-pause {
162
+	background: url("jplayer.blue.monday.jpg") 0 -42px no-repeat;
163
+	display: none;
164
+}
165
+a.jp-pause:hover {
166
+	background: url("jplayer.blue.monday.jpg") -41px -42px no-repeat;
167
+}
168
+
169
+a.jp-stop, a.jp-previous, a.jp-next {
170
+	width:28px;
171
+	height:28px;
172
+	margin-top:6px;
173
+}
174
+
175
+a.jp-stop {
176
+	background: url("jplayer.blue.monday.jpg") 0 -83px no-repeat;
177
+	margin-left:10px;
178
+}
179
+
180
+a.jp-stop:hover {
181
+	background: url("jplayer.blue.monday.jpg") -29px -83px no-repeat;
182
+}
183
+
184
+a.jp-previous {
185
+	background: url("jplayer.blue.monday.jpg") 0 -112px no-repeat;
186
+}
187
+a.jp-previous:hover {
188
+	background: url("jplayer.blue.monday.jpg") -29px -112px no-repeat;
189
+}
190
+
191
+a.jp-next {
192
+	background: url("jplayer.blue.monday.jpg") 0 -141px no-repeat;
193
+}
194
+a.jp-next:hover {
195
+	background: url("jplayer.blue.monday.jpg") -29px -141px no-repeat;
196
+}
197
+
198
+/* @end */
199
+
200
+/* @group progress bar */
201
+
202
+div.jp-progress {
203
+	overflow:hidden;
204
+	background-color: #ddd;
205
+}
206
+div.jp-audio div.jp-progress {
207
+	position: absolute;
208
+	top:32px;
209
+	height:15px;
210
+}
211
+div.jp-audio div.jp-type-single div.jp-progress {
212
+	left:110px;
213
+	width:186px;
214
+}
215
+div.jp-audio div.jp-type-playlist div.jp-progress {
216
+	left:166px;
217
+	width:130px;
218
+}
219
+div.jp-video div.jp-progress {
220
+	top:0px;
221
+	left:0px;
222
+	width:100%;
223
+	height:10px;
224
+}
225
+div.jp-seek-bar {
226
+	background: url("jplayer.blue.monday.jpg") 0 -202px repeat-x;
227
+	width:0px;
228
+	height:100%;
229
+	cursor: pointer;
230
+}
231
+div.jp-play-bar {
232
+	background: url("jplayer.blue.monday.jpg") 0 -218px repeat-x ;
233
+	width:0px;
234
+	height:100%;
235
+}
236
+
237
+/* The seeking class is added/removed inside jPlayer */
238
+div.jp-seeking-bg {
239
+	background: url("jplayer.blue.monday.seeking.gif");
240
+}
241
+
242
+/* @end */
243
+
244
+/* @group volume controls */
245
+
246
+
247
+a.jp-mute,
248
+a.jp-unmute,
249
+a.jp-volume-max {
250
+	width:18px;
251
+	height:15px;
252
+	margin-top:12px;
253
+}
254
+
255
+div.jp-audio div.jp-type-single a.jp-mute,
256
+div.jp-audio div.jp-type-single a.jp-unmute {
257
+	margin-left: 210px;	
258
+}
259
+div.jp-audio div.jp-type-playlist a.jp-mute,
260
+div.jp-audio div.jp-type-playlist a.jp-unmute {
261
+	margin-left: 154px;
262
+}
263
+
264
+div.jp-audio-stream div.jp-type-single a.jp-mute,
265
+div.jp-audio-stream div.jp-type-single a.jp-unmute {
266
+	margin-left:10px;
267
+}
268
+
269
+div.jp-audio a.jp-volume-max,
270
+div.jp-audio-stream a.jp-volume-max {
271
+	margin-left: 56px;	
272
+}
273
+
274
+div.jp-video a.jp-mute,
275
+div.jp-video a.jp-unmute,
276
+div.jp-video a.jp-volume-max {
277
+	position: absolute;
278
+	top:12px;
279
+	margin-top:0;
280
+}
281
+
282
+div.jp-video a.jp-mute,
283
+div.jp-video a.jp-unmute {
284
+	left: 50px;
285
+}
286
+
287
+div.jp-video a.jp-volume-max {
288
+	left: 134px;
289
+}
290
+
291
+a.jp-mute {
292
+	background: url("jplayer.blue.monday.jpg") 0 -170px no-repeat;
293
+}
294
+a.jp-mute:hover {
295
+	background: url("jplayer.blue.monday.jpg") -19px -170px no-repeat;
296
+}
297
+a.jp-unmute {
298
+	background: url("jplayer.blue.monday.jpg") -60px -170px no-repeat;
299
+	display: none;
300
+}
301
+a.jp-unmute:hover {
302
+	background: url("jplayer.blue.monday.jpg") -79px -170px no-repeat;
303
+}
304
+a.jp-volume-max {
305
+	background: url("jplayer.blue.monday.jpg") 0 -186px no-repeat;
306
+}
307
+a.jp-volume-max:hover {
308
+	background: url("jplayer.blue.monday.jpg") -19px -186px no-repeat;
309
+}
310
+
311
+div.jp-volume-bar {
312
+	position: absolute;
313
+	overflow:hidden;
314
+	background: url("jplayer.blue.monday.jpg") 0 -250px repeat-x;
315
+	width:46px;
316
+	height:5px;
317
+	cursor: pointer;
318
+}
319
+div.jp-audio div.jp-volume-bar {
320
+	top:37px;
321
+	left:330px;
322
+}
323
+div.jp-audio-stream div.jp-volume-bar {
324
+	top:37px;
325
+	left:92px;
326
+}
327
+div.jp-video div.jp-volume-bar {
328
+	top:17px;
329
+	left:72px;
330
+}
331
+div.jp-volume-bar-value {
332
+	background: url("jplayer.blue.monday.jpg") 0 -256px repeat-x;
333
+	width:0px;
334
+	height:5px;
335
+}
336
+
337
+/* @end */
338
+
339
+/* @group current time and duration */
340
+
341
+div.jp-audio div.jp-time-holder {
342
+	position:absolute;
343
+	top:50px;
344
+}
345
+div.jp-audio div.jp-type-single div.jp-time-holder {
346
+	left:110px;
347
+	width:186px;
348
+}
349
+div.jp-audio div.jp-type-playlist div.jp-time-holder {
350
+	left:166px;
351
+	width:130px;
352
+}
353
+
354
+div.jp-current-time,
355
+div.jp-duration {
356
+	width:60px;
357
+	font-size:.64em;
358
+	font-style:oblique;
359
+}
360
+div.jp-current-time {
361
+	float: left;
362
+	display:inline;
363
+}
364
+div.jp-duration {
365
+	float: right;
366
+	display:inline;
367
+	text-align: right;
368
+}
369
+
370
+div.jp-video div.jp-current-time {
371
+	margin-left:20px;
372
+}
373
+div.jp-video div.jp-duration {
374
+	margin-right:20px;
375
+}
376
+
377
+/* @end */
378
+
379
+/* @group playlist */
380
+
381
+div.jp-title {
382
+	font-weight:bold;
383
+	text-align:center;
384
+}
385
+
386
+div.jp-title,
387
+div.jp-playlist {
388
+	width:100%;
389
+	background-color:#ccc;
390
+	/*border-top:1px solid #009be3;*/
391
+}
392
+div.jp-type-single div.jp-title,
393
+div.jp-type-playlist div.jp-title,
394
+div.jp-type-single div.jp-playlist {
395
+	border-top:none;
396
+}
397
+div.jp-title ul,
398
+div.jp-playlist ul {
399
+	list-style-type:none;
400
+	margin:0;
401
+	padding:0 20px;
402
+	font-size:.72em;
403
+}
404
+
405
+div.jp-title li {
406
+	padding:5px 0;
407
+	font-weight:bold;
408
+}
409
+div.jp-playlist li {
410
+	padding:5px 0 4px 20px;
411
+	/*border-bottom:1px solid #eee;*/
412
+}
413
+
414
+div.jp-playlist li div {
415
+	display:inline;
416
+}
417
+
418
+/* Note that the first-child (IE6) and last-child (IE6/7/8) selectors do not work on IE */
419
+
420
+div.jp-type-playlist div.jp-playlist li:last-child {
421
+	padding:5px 0 5px 20px;
422
+	border-bottom:none;
423
+}
424
+div.jp-type-playlist div.jp-playlist li.jp-playlist-current {
425
+	list-style-type:square;
426
+	list-style-position:inside;
427
+	padding-left:7px;
428
+}
429
+div.jp-type-playlist div.jp-playlist a {
430
+	color: #333;
431
+	text-decoration: none;
432
+}
433
+div.jp-type-playlist div.jp-playlist a:hover {
434
+	color:#0d88c1;
435
+}
436
+div.jp-type-playlist div.jp-playlist a.jp-playlist-current {
437
+	color:#0d88c1;
438
+}
439
+
440
+div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove {
441
+	float:right;
442
+	display:inline;
443
+	text-align:right;
444
+	margin-right:10px;
445
+	font-weight:bold;
446
+	color:#666;
447
+}
448
+div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove:hover {
449
+	color:#0d88c1;
450
+}
451
+div.jp-type-playlist div.jp-playlist span.jp-free-media {
452
+	float:right;
453
+	display:inline;
454
+	text-align:right;
455
+	margin-right:10px;
456
+}
457
+div.jp-type-playlist div.jp-playlist span.jp-free-media a{
458
+	color:#666;
459
+}
460
+div.jp-type-playlist div.jp-playlist span.jp-free-media a:hover{
461
+	color:#0d88c1;
462
+}
463
+span.jp-artist {
464
+	font-size:.8em;
465
+	color:#666;
466
+}
467
+
468
+/* @end */
469
+
470
+div.jp-video-play {
471
+	width:100%;
472
+	overflow:hidden; /* Important for nested negative margins to work in modern browsers */
473
+	cursor:pointer;
474
+	background-color:rgba(0,0,0,0); /* Makes IE9 work with the active area over the whole video area. IE6/7/8 only have the button as active area. */
475
+}
476
+div.jp-video-270p div.jp-video-play {
477
+	margin-top:-270px;
478
+	height:270px;
479
+}
480
+div.jp-video-360p div.jp-video-play {
481
+	margin-top:-360px;
482
+	height:360px;
483
+}
484
+div.jp-video-full div.jp-video-play {
485
+	height:100%;
486
+}
487
+a.jp-video-play-icon {
488
+	position:relative;
489
+	display:block;
490
+	width: 112px;
491
+	height: 100px;
492
+
493
+	margin-left:-56px;
494
+	margin-top:-50px;
495
+	left:50%;
496
+	top:50%;
497
+
498
+	background: url("jplayer.blue.monday.video.play.png") 0 0 no-repeat;
499
+	text-indent:-9999px;
500
+}
501
+div.jp-video-play:hover a.jp-video-play-icon {
502
+	background: url("jplayer.blue.monday.video.play.png") 0 -100px no-repeat;
503
+}
504
+
505
+
506
+
507
+
508
+
509
+div.jp-jplayer audio,
510
+div.jp-jplayer {
511
+	width:0px;
512
+	height:0px;
513
+}
514
+
515
+div.jp-jplayer {
516
+	background-color: #000000;
517
+}
518
+
519
+
520
+
521
+
522
+
523
+/* @group TOGGLES */
524
+
525
+/* The audio toggles are nested inside jp-time-holder */
526
+
527
+ul.jp-toggles {
528
+	list-style-type:none;
529
+	padding:0;
530
+	margin:0 auto;
531
+	overflow:hidden;
532
+}
533
+
534
+div.jp-audio .jp-type-single ul.jp-toggles {
535
+	width:25px;
536
+}
537
+div.jp-audio .jp-type-playlist ul.jp-toggles {
538
+	width:55px;
539
+	margin: 0;
540
+	position: absolute;
541
+	left: 325px;
542
+	top: 50px;
543
+}
544
+
545
+div.jp-video ul.jp-toggles {
546
+	margin-top:10px;
547
+	width:100px;
548
+}
549
+
550
+ul.jp-toggles li {
551
+	display:block;
552
+	float:right;
553
+}
554
+
555
+ul.jp-toggles li a {
556
+	display:block;
557
+	width:25px;
558
+	height:18px;
559
+	text-indent:-9999px;
560
+	line-height:100%; /* need this for IE6 */
561
+}
562
+
563
+a.jp-full-screen {
564
+	background: url("jplayer.blue.monday.jpg") 0 -310px no-repeat;
565
+	margin-left: 20px;
566
+}
567
+
568
+a.jp-full-screen:hover {
569
+	background: url("jplayer.blue.monday.jpg") -30px -310px no-repeat;
570
+}
571
+
572
+a.jp-restore-screen {
573
+	background: url("jplayer.blue.monday.jpg") -60px -310px no-repeat;
574
+	margin-left: 20px;
575
+}
576
+
577
+a.jp-restore-screen:hover {
578
+	background: url("jplayer.blue.monday.jpg") -90px -310px no-repeat;
579
+}
580
+
581
+a.jp-repeat {
582
+	background: url("jplayer.blue.monday.jpg") 0 -290px no-repeat;
583
+}
584
+
585
+a.jp-repeat:hover {
586
+	background: url("jplayer.blue.monday.jpg") -30px -290px no-repeat;
587
+}
588
+
589
+a.jp-repeat-off {
590
+	background: url("jplayer.blue.monday.jpg") -60px -290px no-repeat;
591
+}
592
+
593
+a.jp-repeat-off:hover {
594
+	background: url("jplayer.blue.monday.jpg") -90px -290px no-repeat;
595
+}
596
+
597
+a.jp-shuffle {
598
+	background: url("jplayer.blue.monday.jpg") 0 -270px no-repeat;
599
+	margin-left: 5px;
600
+}
601
+
602
+a.jp-shuffle:hover {
603
+	background: url("jplayer.blue.monday.jpg") -30px -270px no-repeat;
604
+}
605
+
606
+a.jp-shuffle-off {
607
+	background: url("jplayer.blue.monday.jpg") -60px -270px no-repeat;
608
+	margin-left: 5px;
609
+}
610
+
611
+a.jp-shuffle-off:hover {
612
+	background: url("jplayer.blue.monday.jpg") -90px -270px no-repeat;
613
+}
614
+
615
+
616
+/* @end */
617
+
618
+/* @group NO SOLUTION error feedback */
619
+
620
+.jp-no-solution {
621
+	padding:5px;
622
+	font-size:.8em;
623
+	background-color:#eee;
624
+	border:2px solid #009be3;
625
+	color:#000;
626
+	display:none;
627
+}
628
+
629
+.jp-no-solution a {
630
+	color:#000;
631
+}
632
+
633
+.jp-no-solution span {
634
+	font-size:1em;
635
+	display:block;
636
+	text-align:center;
637
+	font-weight:bold;
638
+}
639
+
640
+/* @end */

BIN
web/jplayer/skin/blue.monday/jplayer.blue.monday.jpg Целия файл


BIN
web/jplayer/skin/blue.monday/jplayer.blue.monday.seeking.gif Целия файл


BIN
web/jplayer/skin/blue.monday/jplayer.blue.monday.video.play.png Целия файл


BIN
web/jplayer/skin/circle.skin/bgr.jpg Целия файл


BIN
web/jplayer/skin/circle.skin/buffer.png Целия файл


+ 133 - 0
web/jplayer/skin/circle.skin/circle.player.css Целия файл

@@ -0,0 +1,133 @@
1
+/*
2
+ * Project: CirclePlayer
3
+ * http://www.jplayer.org
4
+ *
5
+ * Copyright (c) 2012 Happyworm Ltd
6
+ *
7
+ * Author: Silvia Benvenuti
8
+ * Edited by: Mark J Panaghiston
9
+ * Date: 2nd October 2012
10
+ * Artwork inspired by: http://forrst.com/posts/Untitled-CJz
11
+ */
12
+
13
+.cp-container {
14
+	position:relative;
15
+	width:104px; /* 200 - (2 * 48) */
16
+	height:104px;
17
+	background:url("bgr.jpg") 0 0 no-repeat;
18
+	padding:48px;
19
+	-webkit-tap-highlight-color:rgba(0,0,0,0);
20
+}
21
+
22
+.cp-container :focus {
23
+	border:none;
24
+	outline:0;
25
+}
26
+
27
+.cp-buffer-1,
28
+.cp-buffer-2,
29
+.cp-progress-1,
30
+.cp-progress-2 {
31
+	position:absolute;
32
+	top:0;
33
+	left:0;
34
+	width:104px;
35
+	height:104px;
36
+	clip:rect(0px,52px,104px,0px);
37
+
38
+	-moz-border-radius:52px;
39
+	-webkit-border-radius:52px;
40
+	border-radius:52px;
41
+}
42
+
43
+.cp-buffer-1,
44
+.cp-buffer-2 {
45
+	background:url("buffer.png") 0 0 no-repeat;
46
+}
47
+
48
+
49
+/* FALLBACK for .progress
50
+ * (24 steps starting from 1hr filled progress, Decrease second value by 104px for next step)
51
+ * (It needs the container selector to work. Or use div)
52
+ */
53
+
54
+.cp-container .cp-fallback {
55
+	background:url("progress_sprite.jpg") no-repeat;
56
+	background-position:0 104px; 
57
+}
58
+
59
+.cp-progress-1,
60
+.cp-progress-2 {
61
+	background:url("progress.png") 0 0 no-repeat;
62
+}
63
+
64
+.cp-buffer-holder,
65
+.cp-progress-holder,
66
+.cp-circle-control {
67
+	position:absolute;
68
+	width:104px;
69
+	height:104px;
70
+} 
71
+
72
+.cp-circle-control {
73
+	cursor:pointer;
74
+}
75
+
76
+.cp-buffer-holder,
77
+.cp-progress-holder {
78
+	clip:rect(0px,104px,104px,52px);
79
+	display:none;
80
+}
81
+
82
+
83
+/* This is needed when progress is greater than 50% or for fallback */
84
+
85
+.cp-buffer-holder.cp-gt50,
86
+.cp-progress-holder.cp-gt50,
87
+.cp-progress-1.cp-fallback{
88
+	clip:rect(auto, auto, auto, auto);
89
+}
90
+
91
+.cp-controls {
92
+	margin:0;
93
+	padding:26px;
94
+}
95
+
96
+.cp-controls li{
97
+	list-style-type:none;
98
+	display:block;
99
+
100
+	/*IE Fix*/
101
+	position:absolute;
102
+}
103
+
104
+.cp-controls li a{
105
+	position:relative;
106
+	display:block;
107
+	width:50px;
108
+	height:50px;
109
+	text-indent:-9999px;
110
+	z-index:1;
111
+	cursor:pointer;
112
+}
113
+
114
+.cp-controls .cp-play {
115
+	background:url("controls.jpg") 0 0 no-repeat;
116
+}
117
+
118
+.cp-controls .cp-play:hover {
119
+	background:url("controls.jpg") -50px 0 no-repeat;
120
+}
121
+
122
+.cp-controls .cp-pause {
123
+	background:url("controls.jpg") 0 -50px no-repeat;
124
+}
125
+
126
+.cp-controls .cp-pause:hover {
127
+	background:url("controls.jpg") -50px -50px no-repeat;
128
+}
129
+
130
+.cp-jplayer {
131
+	width:0;
132
+	height:0;
133
+}

BIN
web/jplayer/skin/circle.skin/controls.jpg Целия файл


BIN
web/jplayer/skin/circle.skin/progress.png Целия файл


BIN
web/jplayer/skin/circle.skin/progress_sprite.jpg Целия файл


+ 670 - 0
web/jplayer/skin/pink.flag/jplayer.pink.flag.css Целия файл

@@ -0,0 +1,670 @@
1
+/*
2
+ * Skin for jPlayer Plugin (jQuery JavaScript Library)
3
+ * http://www.jplayer.org
4
+ *
5
+ * Skin Name: Pink Flag
6
+ *
7
+ * Copyright (c) 2012 Happyworm Ltd
8
+ * Dual licensed under the MIT and GPL licenses.
9
+ *  - http://www.opensource.org/licenses/mit-license.php
10
+ *  - http://www.gnu.org/copyleft/gpl.html
11
+ *
12
+ * Author: Silvia Benvenuti
13
+ * Skin Version: 1.2 (jPlayer 2.2.0)
14
+ * Date: 22nd October 2012
15
+ */
16
+
17
+div.jp-audio,
18
+div.jp-audio-stream,
19
+div.jp-video {
20
+
21
+	/* Edit the font-size to counteract inherited font sizing.
22
+	 * Eg. 1.25em = 1 / 0.8em
23
+	 */
24
+
25
+	font-size:1.25em; /* 1.25em for testing in site pages */ /* No parent CSS that can effect the size in the demos ZIP */
26
+
27
+	font-family:Verdana, Arial, sans-serif;
28
+	line-height:1.6;
29
+	color: #fff;
30
+	border-top:1px solid #554461;
31
+	border-left:1px solid #554461;
32
+	border-right:1px solid #180a1f;
33
+	border-bottom:1px solid #180a1f;
34
+	background-color:#3a2a45;
35
+}
36
+div.jp-audio {
37
+	width:201px;
38
+	padding:20px;
39
+}
40
+
41
+div.jp-audio-stream {
42
+	width:101px;
43
+	padding:20px 20px 10px 20px;
44
+}
45
+
46
+div.jp-video-270p {
47
+	width:480px;
48
+}
49
+div.jp-video-360p {
50
+	width:640px;
51
+}
52
+div.jp-video-full {
53
+	/* Rules for IE6 (full-screen) */
54
+	width:480px;
55
+	height:270px;
56
+	/* Rules for IE7 (full-screen) - Otherwise the relative container causes other page items that are not position:static (default) to appear over the video/gui. */
57
+	position:static !important; position:relative;
58
+}
59
+
60
+/* The z-index rule is defined in this manner to enable Popcorn plugins that add overlays to video area. EG. Subtitles. */
61
+div.jp-video-full div div {
62
+	z-index:1000;
63
+}
64
+
65
+div.jp-video-full div.jp-jplayer {
66
+	top: 0;
67
+	left: 0;
68
+	position: fixed !important; position: relative; /* Rules for IE6 (full-screen) */
69
+	overflow: hidden;
70
+}
71
+
72
+div.jp-video-full div.jp-gui {
73
+	position: fixed !important; position: static; /* Rules for IE6 (full-screen) */
74
+	top: 0;
75
+	left: 0;
76
+	width:100%;
77
+	height:100%;
78
+	z-index:1001; /* 1 layer above the others. */
79
+}
80
+div.jp-video-full div.jp-interface {
81
+	position: absolute !important; position: relative; /* Rules for IE6 (full-screen) */
82
+	bottom: 0;
83
+	left: 0;
84
+}
85
+
86
+div.jp-interface {
87
+	position: relative;
88
+	width:100%;
89
+	background-color:#3a2a45; /* Required for the full screen */
90
+}
91
+
92
+
93
+div.jp-audio .jp-interface {
94
+	height: 80px;
95
+	padding-top:30px;
96
+}
97
+
98
+div.jp-audio-stream .jp-interface {
99
+	height: 50px;
100
+	padding-top:30px;
101
+}
102
+
103
+/* @group CONTROLS */
104
+
105
+div.jp-controls-holder {
106
+	clear: both;
107
+	width:440px;
108
+	margin:0 auto 10px auto;
109
+	position: relative;
110
+	overflow:hidden;
111
+}
112
+
113
+div.jp-interface ul.jp-controls {
114
+	background: url("jplayer.pink.flag.jpg") 0 0 no-repeat;
115
+	list-style-type:none;
116
+	padding: 1px 0 2px 1px;
117
+	overflow:hidden;
118
+	width: 201px;
119
+	height: 34px;
120
+}
121
+
122
+div.jp-audio ul.jp-controls,
123
+div.jp-audio-stream ul.jp-controls {
124
+	margin:0 auto;
125
+}
126
+
127
+div.jp-audio-stream ul.jp-controls {
128
+	width: 100px;
129
+}
130
+
131
+div.jp-video ul.jp-controls {
132
+	margin:0 0 0 115px;
133
+	float:left;
134
+	display:inline; /* need this to fix IE6 double margin */
135
+}
136
+
137
+div.jp-interface ul.jp-controls li {
138
+	display:inline;
139
+	float: left;
140
+}
141
+div.jp-interface ul.jp-controls a {
142
+	display:block;
143
+	overflow:hidden;
144
+	text-indent:-9999px;
145
+	height: 34px;
146
+	margin: 0 1px 2px 0;
147
+	padding: 0;
148
+}
149
+
150
+
151
+/* @group single player controls */
152
+
153
+div.jp-type-single  .jp-controls li a{
154
+	width: 99px;
155
+}
156
+
157
+div.jp-type-single  .jp-play {
158
+	background: url("jplayer.pink.flag.jpg") 0px -40px no-repeat;
159
+}
160
+
161
+div.jp-type-single  .jp-play:hover {
162
+	background: url("jplayer.pink.flag.jpg") -100px -40px no-repeat;
163
+}
164
+
165
+div.jp-type-single  .jp-pause {
166
+	background: url("jplayer.pink.flag.jpg") 0px -120px no-repeat;
167
+}
168
+
169
+div.jp-type-single  .jp-pause:hover {
170
+	background: url("jplayer.pink.flag.jpg") -100px -120px no-repeat;
171
+}
172
+
173
+/* The right border is normally in the ul background image. */
174
+div.jp-audio-stream .jp-play,
175
+div.jp-audio-stream .jp-pause {
176
+	border-right:1px solid #180920;
177
+}
178
+
179
+div.jp-type-single  .jp-stop {
180
+	background: url("jplayer.pink.flag.jpg") 0px -80px no-repeat;
181
+}
182
+
183
+div.jp-type-single  .jp-stop:hover {
184
+	background: url("jplayer.pink.flag.jpg") -100px -80px no-repeat;
185
+}
186
+
187
+/* @end */
188
+
189
+/* @group playlist player controls */
190
+
191
+div.jp-type-playlist .jp-controls li a{
192
+	width: 49px;
193
+}
194
+
195
+div.jp-type-playlist .jp-play {
196
+	background: url("jplayer.pink.flag.jpg") -24px -40px no-repeat;
197
+}
198
+
199
+div.jp-type-playlist .jp-play:hover {
200
+	background: url("jplayer.pink.flag.jpg") -124px -40px no-repeat;
201
+}
202
+
203
+div.jp-type-playlist .jp-pause {
204
+	background: url("jplayer.pink.flag.jpg") -24px -120px no-repeat;
205
+}
206
+
207
+div.jp-type-playlist .jp-pause:hover {
208
+	background: url("jplayer.pink.flag.jpg") -124px -120px no-repeat;
209
+}
210
+
211
+div.jp-type-playlist .jp-stop {
212
+	background: url("jplayer.pink.flag.jpg") -24px -80px no-repeat;
213
+}
214
+
215
+div.jp-type-playlist .jp-stop:hover {
216
+	background: url("jplayer.pink.flag.jpg") -124px -80px no-repeat;
217
+}
218
+
219
+div.jp-type-playlist .jp-previous {
220
+	background: url("jplayer.pink.flag.jpg") -24px -200px no-repeat;
221
+}
222
+
223
+div.jp-type-playlist .jp-previous:hover {
224
+	background: url("jplayer.pink.flag.jpg") -124px -200px no-repeat;
225
+}
226
+
227
+div.jp-type-playlist .jp-next {
228
+	background: url("jplayer.pink.flag.jpg") -24px -160px no-repeat;
229
+}
230
+
231
+div.jp-type-playlist .jp-next:hover {
232
+	background: url("jplayer.pink.flag.jpg") -124px -160px no-repeat;
233
+}
234
+
235
+/* @end */
236
+
237
+/* @end */
238
+
239
+
240
+
241
+
242
+/* @group TOGGLES */
243
+
244
+ul.jp-toggles {
245
+	list-style-type:none;
246
+	padding:0;
247
+	margin:0 auto;
248
+	overflow:hidden;
249
+}
250
+
251
+div.jp-audio ul.jp-toggles {
252
+	width:55px;
253
+}
254
+
255
+div.jp-audio .jp-type-single ul.jp-toggles {
256
+	width:25px;
257
+}
258
+
259
+div.jp-video ul.jp-toggles {
260
+	width:100px;
261
+	margin-top: 10px;
262
+}
263
+
264
+ul.jp-toggles li{
265
+	display:block;
266
+	float:right;
267
+}
268
+
269
+ul.jp-toggles li a{
270
+	display:block;
271
+	width:25px;
272
+	height:18px;
273
+	text-indent:-9999px;
274
+	line-height:100%; /* need this for IE6 */
275
+}
276
+
277
+.jp-full-screen {
278
+	background: url("jplayer.pink.flag.jpg") 0 -420px no-repeat;
279
+	margin-left: 20px;
280
+}
281
+
282
+.jp-full-screen:hover {
283
+	background: url("jplayer.pink.flag.jpg") -30px -420px no-repeat;
284
+}
285
+
286
+.jp-restore-screen {
287
+	background: url("jplayer.pink.flag.jpg") -60px -420px no-repeat;
288
+	margin-left: 20px;
289
+}
290
+
291
+.jp-restore-screen:hover {
292
+	background: url("jplayer.pink.flag.jpg") -90px -420px no-repeat;
293
+}
294
+
295
+.jp-repeat {
296
+	background: url("jplayer.pink.flag.jpg") 0 -440px no-repeat;
297
+}
298
+
299
+.jp-repeat:hover {
300
+	background: url("jplayer.pink.flag.jpg") -30px -440px no-repeat;
301
+}
302
+
303
+.jp-repeat-off {
304
+	background: url("jplayer.pink.flag.jpg") -60px -440px no-repeat;
305
+}
306
+
307
+.jp-repeat-off:hover {
308
+	background: url("jplayer.pink.flag.jpg") -90px -440px no-repeat;
309
+}
310
+
311
+.jp-shuffle {
312
+	background: url("jplayer.pink.flag.jpg") 0 -460px no-repeat;
313
+	margin-left: 5px;
314
+}
315
+
316
+.jp-shuffle:hover {
317
+	background: url("jplayer.pink.flag.jpg") -30px -460px no-repeat;
318
+}
319
+
320
+.jp-shuffle-off {
321
+	background: url("jplayer.pink.flag.jpg") -60px -460px no-repeat;
322
+	margin-left: 5px;
323
+}
324
+
325
+.jp-shuffle-off:hover {
326
+	background: url("jplayer.pink.flag.jpg") -90px -460px no-repeat;
327
+}
328
+
329
+
330
+/* @end */
331
+
332
+/* @group progress bar */
333
+
334
+/* The seeking class is added/removed inside jPlayer */
335
+div.jp-seeking-bg {
336
+	background: url("jplayer.pink.flag.seeking.gif");
337
+}
338
+
339
+.jp-progress {
340
+	background: url("jplayer.pink.flag.jpg") 0px -240px no-repeat;
341
+	width: 197px;
342
+	height: 13px;
343
+	padding: 0 2px 2px 2px;
344
+	margin-bottom: 4px;
345
+	overflow:hidden;
346
+}
347
+
348
+div.jp-video .jp-progress {
349
+	border-top:1px solid #180a1f;
350
+	border-bottom: 1px solid #554560;
351
+	width:100%;
352
+	background-image: none;
353
+	padding: 0;
354
+}
355
+
356
+.jp-seek-bar {
357
+	background: url("jplayer.pink.flag.jpg") 0px -260px repeat-x;
358
+	width:0px;
359
+	height: 100%;
360
+	overflow:hidden;
361
+	cursor:pointer;
362
+}
363
+
364
+.jp-play-bar {
365
+	background: url("jplayer.pink.flag.jpg") 0px -280px repeat-x;
366
+	width:0px;
367
+	height: 100%;
368
+	overflow:hidden;
369
+}
370
+
371
+
372
+/* @end */
373
+
374
+/* @group volume controls */
375
+
376
+div.jp-interface ul.jp-controls a.jp-mute,
377
+div.jp-interface ul.jp-controls a.jp-unmute,
378
+div.jp-interface ul.jp-controls a.jp-volume-max {
379
+	background: url("jplayer.pink.flag.jpg") 0px -330px no-repeat;
380
+	position: absolute;
381
+	width: 16px;
382
+	height: 11px;
383
+}
384
+
385
+div.jp-audio ul.jp-controls a.jp-mute,
386
+div.jp-audio ul.jp-controls a.jp-unmute,
387
+div.jp-audio-stream ul.jp-controls a.jp-mute,
388
+div.jp-audio-stream ul.jp-controls a.jp-unmute {
389
+	top:-6px;
390
+	left: 0;
391
+}
392
+
393
+div.jp-audio ul.jp-controls a.jp-volume-max,
394
+div.jp-audio-stream ul.jp-controls a.jp-volume-max {
395
+	top:-6px;
396
+	right: 0;
397
+}
398
+
399
+
400
+div.jp-video ul.jp-controls a.jp-mute,
401
+div.jp-video ul.jp-controls a.jp-unmute {
402
+	left: 0;
403
+	top:14px;
404
+}
405
+
406
+div.jp-video ul.jp-controls a.jp-volume-max {
407
+	left: 84px;
408
+	top:14px;
409
+}
410
+
411
+div.jp-interface ul.jp-controls a.jp-mute:hover {
412
+	background: url("jplayer.pink.flag.jpg") -25px -330px no-repeat;
413
+}
414
+
415
+div.jp-interface ul.jp-controls a.jp-unmute {
416
+	background: url("jplayer.pink.flag.jpg") -60px -330px no-repeat;
417
+}
418
+
419
+div.jp-interface ul.jp-controls a.jp-unmute:hover {
420
+	background: url("jplayer.pink.flag.jpg") -85px -330px no-repeat;
421
+}
422
+
423
+div.jp-interface ul.jp-controls a.jp-volume-max {
424
+	background: url("jplayer.pink.flag.jpg") 0px -350px no-repeat;
425
+}
426
+
427
+div.jp-interface ul.jp-controls a.jp-volume-max:hover {
428
+	background: url("jplayer.pink.flag.jpg") -25px -350px no-repeat;
429
+}
430
+
431
+.jp-volume-bar {
432
+	background: url("jplayer.pink.flag.jpg") 0px -300px repeat-x;
433
+	position: absolute;
434
+	width: 197px;
435
+	height: 4px;
436
+	padding: 2px 2px 1px 2px;
437
+	overflow: hidden;
438
+}
439
+
440
+.jp-volume-bar:hover {
441
+	cursor:  pointer;
442
+}
443
+
444
+
445
+div.jp-audio .jp-interface .jp-volume-bar,
446
+div.jp-audio-stream .jp-interface .jp-volume-bar {
447
+	top:10px;
448
+	left: 0;
449
+}
450
+
451
+div.jp-audio-stream .jp-interface .jp-volume-bar {
452
+	width: 97px;
453
+	border-right:1px solid #180920;
454
+	padding-right:1px;
455
+}
456
+
457
+div.jp-video .jp-volume-bar {
458
+	top: 0;
459
+	left: 0;
460
+	width:95px;
461
+	border-right:1px solid #180920;
462
+	padding-right:1px;
463
+	margin-top: 30px;
464
+}
465
+
466
+.jp-volume-bar-value {
467
+	background: url("jplayer.pink.flag.jpg") 0px -320px repeat-x;
468
+	height: 4px;
469
+}
470
+
471
+/* @end */
472
+
473
+/* @group current time and duration */
474
+
475
+.jp-current-time, .jp-duration {
476
+	width:70px;
477
+	font-size:.5em;
478
+	color: #8c7a99;
479
+}
480
+
481
+.jp-current-time {
482
+	float: left;
483
+}
484
+
485
+.jp-duration {
486
+	float: right;
487
+	text-align:right;
488
+}
489
+
490
+.jp-video .jp-current-time {
491
+	padding-left:20px;
492
+}
493
+
494
+.jp-video .jp-duration {
495
+	padding-right:20px;
496
+}
497
+
498
+/* @end */
499
+
500
+/* @group playlist */
501
+
502
+.jp-title ul,
503
+.jp-playlist ul {
504
+	list-style-type:none;	
505
+	font-size:.7em;
506
+	margin: 0;
507
+	padding: 0;
508
+}
509
+
510
+.jp-video .jp-title ul {
511
+	margin: 0 20px 10px;
512
+}
513
+
514
+.jp-video .jp-playlist ul {
515
+	margin: 0 20px;
516
+}
517
+
518
+.jp-title li,
519
+.jp-playlist li {
520
+	position: relative;
521
+	padding: 2px 0;
522
+	border-top:1px solid #554461;
523
+	border-bottom:1px solid #180a1f;
524
+	overflow: hidden;
525
+}
526
+
527
+.jp-title li{
528
+	border-bottom:none;
529
+	border-top:none;
530
+	padding:0;
531
+	text-align:center;
532
+}
533
+
534
+/* Note that the first-child (IE6) and last-child (IE6/7/8) selectors do not work on IE */
535
+
536
+div.jp-type-playlist div.jp-playlist li:first-child {
537
+	border-top:none;
538
+	padding-top:3px;
539
+}
540
+
541
+div.jp-type-playlist div.jp-playlist li:last-child {
542
+	border-bottom:none;
543
+	padding-bottom:3px;
544
+}
545
+
546
+div.jp-type-playlist div.jp-playlist a {
547
+	color: #fff;
548
+	text-decoration:none;
549
+}
550
+
551
+div.jp-type-playlist div.jp-playlist a:hover {
552
+	color: #e892e9;
553
+}
554
+
555
+div.jp-type-playlist div.jp-playlist li.jp-playlist-current {
556
+	background-color: #26102e;
557
+	margin: 0 -20px;
558
+	padding: 2px 20px;
559
+	border-top: 1px solid #26102e;
560
+	border-bottom: 1px solid #26102e;
561
+}
562
+
563
+div.jp-type-playlist div.jp-playlist li.jp-playlist-current a{
564
+	color: #e892e9;
565
+}
566
+
567
+div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove {
568
+	float:right;
569
+	display:inline;
570
+	text-align:right;
571
+	margin-left:10px;
572
+	font-weight:bold;
573
+	color:#8C7A99;
574
+}
575
+div.jp-type-playlist div.jp-playlist a.jp-playlist-item-remove:hover {
576
+	color:#E892E9;
577
+}
578
+
579
+div.jp-type-playlist div.jp-playlist span.jp-free-media {
580
+	float: right;
581
+	display:inline;
582
+	text-align:right;
583
+	color:#8C7A99;
584
+}
585
+
586
+div.jp-type-playlist div.jp-playlist span.jp-free-media a{
587
+	color:#8C7A99;
588
+}
589
+
590
+div.jp-type-playlist div.jp-playlist span.jp-free-media a:hover{
591
+	color:#E892E9;
592
+}
593
+span.jp-artist {
594
+	font-size:.8em;
595
+	color:#8C7A99;
596
+}
597
+
598
+/* @end */
599
+
600
+
601
+div.jp-video div.jp-video-play {
602
+	width:100%;
603
+	overflow:hidden; /* Important for nested negative margins to work in modern browsers */
604
+	cursor:pointer;
605
+}
606
+div.jp-video-270p div.jp-video-play {
607
+	margin-top:-270px;
608
+	height:270px;
609
+}
610
+div.jp-video-360p div.jp-video-play {
611
+	margin-top:-360px;
612
+	height:360px;
613
+}
614
+div.jp-video-full div.jp-video-play {
615
+	height:100%;
616
+}
617
+a.jp-video-play-icon {
618
+	position:relative;
619
+	display:block;
620
+	width: 112px;
621
+	height: 100px;
622
+
623
+	margin-left:-56px;
624
+	margin-top:-50px;
625
+	left:50%;
626
+	top:50%;
627
+
628
+	background: url("jplayer.pink.flag.video.play.png") 0 0 no-repeat;
629
+	text-indent:-9999px;
630
+}
631
+div.jp-video-play:hover a.jp-video-play-icon {
632
+	background: url("jplayer.pink.flag.video.play.png") 0 -100px no-repeat;
633
+}
634
+
635
+
636
+div.jp-jplayer audio,
637
+div.jp-jplayer {
638
+	width:0px;
639
+	height:0px;
640
+}
641
+
642
+div.jp-jplayer {
643
+	background-color: #000000;
644
+}
645
+
646
+/* @group NO SOLUTION error feedback */
647
+
648
+.jp-no-solution {
649
+	padding:5px;
650
+	font-size:.8em;
651
+	background-color:#3a2a45;
652
+	border-top:2px solid #554461;
653
+	border-left:2px solid #554461;
654
+	border-right:2px solid #180a1f;
655
+	border-bottom:2px solid #180a1f;
656
+	color:#FFF;
657
+	display:none;
658
+}
659
+
660
+.jp-no-solution a {
661
+	color:#FFF;
662
+}
663
+
664
+.jp-no-solution span {
665
+	font-size:1em;
666
+	display:block;
667
+	text-align:center;
668
+	font-weight:bold;
669
+}
670
+/* @end */

BIN
web/jplayer/skin/pink.flag/jplayer.pink.flag.jpg Целия файл


BIN
web/jplayer/skin/pink.flag/jplayer.pink.flag.seeking.gif Целия файл


BIN
web/jplayer/skin/pink.flag/jplayer.pink.flag.video.play.png Целия файл


+ 0 - 0
web/js/jquery-1.8.2.dev.js Целия файл


+ 0 - 0
web/js/jquery-1.8.2.prod.js Целия файл


+ 0 - 0
web/js/swfobject.js Целия файл