1 /** The minplayer namespace. */
  2 var minplayer = minplayer || {};
  3 
  4 /** All the media player implementations */
  5 minplayer.players = minplayer.players || {};
  6 
  7 /**
  8  * @constructor
  9  * @extends minplayer.players.base
 10  * @class The vimeo media player.
 11  *
 12  * @param {object} context The jQuery context.
 13  * @param {object} options This components options.
 14  * @param {object} queue The event queue to pass events around.
 15  */
 16 minplayer.players.vimeo = function(context, options, queue) {
 17 
 18   // Derive from players base.
 19   minplayer.players.base.call(this, context, options, queue);
 20 };
 21 
 22 /** Derive from minplayer.players.base. */
 23 minplayer.players.vimeo.prototype = new minplayer.players.base();
 24 
 25 /** Reset the constructor. */
 26 minplayer.players.vimeo.prototype.constructor = minplayer.players.vimeo;
 27 
 28 /**
 29  * @see minplayer.plugin.construct
 30  * @this minplayer.players.vimeo
 31  */
 32 minplayer.players.vimeo.prototype.construct = function() {
 33 
 34   // Call the players.flash constructor.
 35   minplayer.players.base.prototype.construct.call(this);
 36 
 37   // Set the plugin name within the options.
 38   this.options.pluginName = 'vimeo';
 39 };
 40 
 41 /**
 42  * @see minplayer.players.base#getPriority
 43  * @return {number} The priority of this media player.
 44  */
 45 minplayer.players.vimeo.getPriority = function() {
 46   return 10;
 47 };
 48 
 49 /**
 50  * @see minplayer.players.base#canPlay
 51  * @return {boolean} If this player can play this media type.
 52  */
 53 minplayer.players.vimeo.canPlay = function(file) {
 54 
 55   // Check for the mimetype for vimeo.
 56   if (file.mimetype === 'video/vimeo') {
 57     return true;
 58   }
 59 
 60   // If the path is a vimeo path, then return true.
 61   return (file.path.search(/^http(s)?\:\/\/(www\.)?vimeo\.com/i) === 0);
 62 };
 63 
 64 /**
 65  * Determines if the player should show the playloader.
 66  *
 67  * @param {string} preview The preview image.
 68  * @return {bool} If this player implements its own playLoader.
 69  */
 70 minplayer.players.vimeo.prototype.hasPlayLoader = function(preview) {
 71   return minplayer.hasTouch || !preview;
 72 };
 73 
 74 /**
 75  * Determines if the player should show the playloader.
 76  *
 77  * @return {bool} If this player implements its own playLoader.
 78  */
 79 minplayer.players.vimeo.prototype.hasController = function() {
 80   return minplayer.hasTouch;
 81 };
 82 
 83 /**
 84  * Return the ID for a provided media file.
 85  *
 86  * @param {object} file A {@link minplayer.file} object.
 87  * @return {string} The ID for the provided media.
 88  */
 89 minplayer.players.vimeo.getMediaId = function(file) {
 90   var regex = /^http[s]?\:\/\/(www\.)?vimeo\.com\/(\?v\=)?([0-9]+)/i;
 91   if (file.path.search(regex) === 0) {
 92     return file.path.match(regex)[3];
 93   }
 94   else {
 95     return file.path;
 96   }
 97 };
 98 
 99 /**
100  * Returns a preview image for this media player.
101  *
102  * @param {object} file A {@link minplayer.file} object.
103  * @param {string} type The type of image.
104  * @param {function} callback Called when the image is retrieved.
105  */
106 minplayer.players.vimeo.getImage = function(file, type, callback) {
107   jQuery.ajax({
108     url: 'http://vimeo.com/api/v2/video/' + file.id + '.json',
109     dataType: 'jsonp',
110     success: function(data) {
111       callback(data[0].thumbnail_large);
112     }
113   });
114 };
115 
116 /**
117  * @see minplayer.players.base#reset
118  */
119 minplayer.players.vimeo.prototype.reset = function() {
120 
121   // Reset the flash variables..
122   minplayer.players.base.prototype.reset.call(this);
123 };
124 
125 /**
126  * @see minplayer.players.base#create
127  * @return {object} The media player entity.
128  */
129 minplayer.players.vimeo.prototype.create = function() {
130   minplayer.players.base.prototype.create.call(this);
131 
132   // Insert the Vimeo Froogaloop player.
133   var tag = document.createElement('script');
134   tag.src = 'http://a.vimeocdn.com/js/froogaloop2.min.js';
135   var firstScriptTag = document.getElementsByTagName('script')[0];
136   firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
137 
138   // Create the iframe for this player.
139   var iframe = document.createElement('iframe');
140   iframe.setAttribute('id', this.options.id + '-player');
141   iframe.setAttribute('type', 'text/html');
142   iframe.setAttribute('width', '100%');
143   iframe.setAttribute('height', '100%');
144   iframe.setAttribute('frameborder', '0');
145   jQuery(iframe).addClass('vimeo-player');
146 
147   // Get the source.
148   var src = 'http://player.vimeo.com/video/';
149   src += this.mediaFile.id + '?';
150 
151   // Add the parameters to the src.
152   src += jQuery.param({
153     'wmode': 'opaque',
154     'api': 1,
155     'player_id': this.options.id + '-player',
156     'title': 0,
157     'byline': 0,
158     'portrait': 0,
159     'autoplay': this.options.autoplay,
160     'loop': this.options.loop
161   });
162 
163   // Set the source of the iframe.
164   iframe.setAttribute('src', src);
165 
166   // Now register this player when the froogaloop code is loaded.
167   this.poll((function(player) {
168     return function() {
169       if (window.Froogaloop) {
170         player.player = window.Froogaloop(iframe);
171         var playerTimeout = 0;
172         player.player.addEvent('ready', function() {
173           clearTimeout(playerTimeout);
174           player.onReady();
175           player.onError('');
176         });
177         playerTimeout = setTimeout(function() {
178           player.onReady();
179           player.onError('Unable to play video.');
180         }, 2000);
181       }
182       return !window.Froogaloop;
183     };
184   })(this), 200);
185 
186   // Trigger that the load has started.
187   this.trigger('loadstart');
188 
189   // Return the player.
190   return iframe;
191 };
192 
193 /**
194  * @see minplayer.players.base#onReady
195  */
196 minplayer.players.vimeo.prototype.onReady = function(player_id) {
197 
198   // Add the other listeners.
199   this.player.addEvent('loadProgress', (function(player) {
200     return function(progress) {
201       player.duration.set(parseFloat(progress.duration));
202       player.bytesLoaded.set(progress.bytesLoaded);
203       player.bytesTotal.set(progress.bytesTotal);
204     };
205   })(this));
206 
207   this.player.addEvent('playProgress', (function(player) {
208     return function(progress) {
209       player.duration.set(parseFloat(progress.duration));
210       player.currentTime.set(parseFloat(progress.seconds));
211     };
212   })(this));
213 
214   this.player.addEvent('play', (function(player) {
215     return function() {
216       player.onPlaying();
217     };
218   })(this));
219 
220   this.player.addEvent('pause', (function(player) {
221     return function() {
222       player.onPaused();
223     };
224   })(this));
225 
226   this.player.addEvent('finish', (function(player) {
227     return function() {
228       player.onComplete();
229     };
230   })(this));
231 
232   minplayer.players.base.prototype.onReady.call(this);
233   this.onLoaded();
234 };
235 
236 /**
237  * Clears the media player.
238  */
239 minplayer.players.vimeo.prototype.clear = function() {
240   if (this.player) {
241     this.player.api('unload');
242   }
243   minplayer.players.base.prototype.clear.call(this);
244 };
245 
246 /**
247  * @see minplayer.players.base#load
248  * @return {boolean} If this action was performed.
249  */
250 minplayer.players.vimeo.prototype.load = function(file) {
251   if (minplayer.players.base.prototype.load.call(this, file)) {
252     this.construct();
253     return true;
254   }
255   return false;
256 };
257 
258 /**
259  * @see minplayer.players.base#play
260  * @return {boolean} If this action was performed.
261  */
262 minplayer.players.vimeo.prototype.play = function() {
263   if (minplayer.players.base.prototype.play.call(this)) {
264     this.player.api('play');
265     return true;
266   }
267 
268   return false;
269 };
270 
271 /**
272  * @see minplayer.players.base#pause
273  * @return {boolean} If this action was performed.
274  */
275 minplayer.players.vimeo.prototype.pause = function() {
276   if (minplayer.players.base.prototype.pause.call(this)) {
277     this.player.api('pause');
278     return true;
279   }
280 
281   return false;
282 };
283 
284 /**
285  * @see minplayer.players.base#stop
286  * @return {boolean} If this action was performed.
287  */
288 minplayer.players.vimeo.prototype.stop = function() {
289   if (minplayer.players.base.prototype.stop.call(this)) {
290     this.player.api('unload');
291     return true;
292   }
293 
294   return false;
295 };
296 
297 /**
298  * @see minplayer.players.base#seek
299  * @return {boolean} If this action was performed.
300  */
301 minplayer.players.vimeo.prototype.seek = function(pos) {
302   if (minplayer.players.base.prototype.seek.call(this, pos)) {
303     this.player.api('seekTo', pos);
304     return true;
305   }
306 
307   return false;
308 };
309 
310 /**
311  * @see minplayer.players.base#setVolume
312  * @return {boolean} If this action was performed.
313  */
314 minplayer.players.vimeo.prototype.setVolume = function(vol) {
315   if (minplayer.players.base.prototype.setVolume.call(this, vol)) {
316     this.volume.set(vol);
317     this.player.api('setVolume', vol);
318     return true;
319   }
320 
321   return false;
322 };
323 
324 /**
325  * @see minplayer.players.base#getVolume
326  */
327 minplayer.players.vimeo.prototype.getVolume = function(callback) {
328   this.player.api('getVolume', function(vol) {
329     callback(vol);
330   });
331 };
332 
333 /**
334  * @see minplayer.players.base#getDuration.
335  */
336 minplayer.players.vimeo.prototype.getDuration = function(callback) {
337   if (this.isReady()) {
338     if (this.duration.value) {
339       callback(this.duration.value);
340     }
341     else {
342       this.player.api('getDuration', function(duration) {
343         callback(duration);
344       });
345     }
346   }
347 };
348