1 /*jshint maxlen:90 */
  2 
  3 /** The minplayer namespace. */
  4 var minplayer = minplayer || {};
  5 
  6 /** All the media player implementations */
  7 minplayer.players = minplayer.players || {};
  8 
  9 /**
 10  * @constructor
 11  * @extends minplayer.players.base
 12  * @class The Dailymotion media player.
 13  *
 14  * @param {object} context The jQuery context.
 15  * @param {object} options This components options.
 16  * @param {object} queue The event queue to pass events around.
 17  */
 18 minplayer.players.dailymotion = function(context, options, queue) {
 19 
 20   /** The quality of the Dailymotion stream. */
 21   this.quality = 'default';
 22 
 23   // Derive from players base.
 24   minplayer.players.base.call(this, context, options, queue);
 25 };
 26 
 27 /** Derive from minplayer.players.base. */
 28 minplayer.players.dailymotion.prototype = new minplayer.players.base();
 29 
 30 /** Reset the constructor. */
 31 minplayer.players.dailymotion.prototype.constructor = minplayer.players.dailymotion;
 32 
 33 /**
 34  * @see minplayer.plugin.construct
 35  * @this minplayer.players.dailymotion
 36  */
 37 minplayer.players.dailymotion.prototype.construct = function() {
 38 
 39   // Call the players.flash constructor.
 40   minplayer.players.base.prototype.construct.call(this);
 41 
 42   // Set the plugin name within the options.
 43   this.options.pluginName = 'dailymotion';
 44 };
 45 
 46 /**
 47  * @see minplayer.players.base#getPriority
 48  * @param {object} file A {@link minplayer.file} object.
 49  * @return {number} The priority of this media player.
 50  */
 51 minplayer.players.dailymotion.getPriority = function(file) {
 52   return 10;
 53 };
 54 
 55 /**
 56  * @see minplayer.players.base#canPlay
 57  *
 58  * @param {object} file A {@link minplayer.file} object.
 59  * @return {boolean} If this player can play this media type.
 60  */
 61 minplayer.players.dailymotion.canPlay = function(file) {
 62 
 63   // Check for the mimetype for dailymotion.
 64   if (file.mimetype === 'video/dailymotion') {
 65     return true;
 66   }
 67 
 68   // If the path is a Dailymotion path, then return true.
 69   var regex = /^http(s)?\:\/\/(www\.)?(dailymotion\.com)/i;
 70   return (file.path.search(regex) === 0);
 71 };
 72 
 73 /**
 74  * Return the ID for a provided media file.
 75  *
 76  * @param {object} file A {@link minplayer.file} object.
 77  * @return {string} The ID for the provided media.
 78  */
 79 minplayer.players.dailymotion.getMediaId = function(file) {
 80   var regex = '^http[s]?\\:\\/\\/(www\\.)?';
 81   regex += '(dailymotion\\.com\\/video/)';
 82   regex += '([a-z0-9\\-]+)';
 83   regex += '_*';
 84   var reg = RegExp(regex, 'i');
 85 
 86   // Locate the media id.
 87   if (file.path.search(reg) === 0) {
 88     return file.path.match(reg)[3];
 89   }
 90   else {
 91     return file.path;
 92   }
 93 };
 94 
 95 /**
 96  * Returns a preview image for this media player.
 97  *
 98  * @param {object} file A {@link minplayer.file} object.
 99  * @param {string} type The type of image.
100  * @param {function} callback Called when the image is retrieved.
101  */
102 minplayer.players.dailymotion.getImage = function(file, type, callback) {
103   callback('http://www.dailymotion.com/thumbnail/video/' + file.id);
104 };
105 
106 /**
107  * Parse a single playlist node.
108  *
109  * @param {object} item The dailymotion item.
110  * @return {object} The mediafront node.
111  */
112 minplayer.players.dailymotion.parseNode = function(item) {
113   return {
114     title: node.title,
115     description: node.description,
116     mediafiles: {
117       image: {
118         'thumbnail': {
119           path: node.thumbnail_small_url
120         },
121         'image': {
122           path: node.thumbnail_url
123         }
124       },
125       media: {
126         'media': {
127           player: 'dailymotion',
128           id: node.id
129         }
130       }
131     }
132   };
133 };
134 
135 /**
136  * Returns information about this dailymotion video.
137  *
138  * @param {object} file The file to load.
139  * @param {function} callback Called when the node is loaded.
140  */
141 minplayer.players.dailymotion.getNode = function(file, callback) {
142 
143   var url = 'https://api.dailymotion.com/video/' + file.id;
144   url += '?fields=title,id,description,thumbnail_small_url,thumbnail_url';
145   jQuery.get(url, function(data) {
146     callback(minplayer.players.dailymotion.parseNode(data.data));
147   }, 'jsonp');
148 };
149 
150 /**
151  * Called when an API is loaded and ready.
152  *
153  * @param {string} event The onReady event that was triggered.
154  */
155 minplayer.players.dailymotion.prototype.onReady = function(event) {
156   minplayer.players.base.prototype.onReady.call(this);
157   if (!this.options.autoplay) {
158     this.pause();
159   }
160   this.onLoaded();
161 };
162 
163 /**
164  * Checks to see if this player can be found.
165  * @return {bool} TRUE - Player is found, FALSE - otherwise.
166  */
167 minplayer.players.dailymotion.prototype.playerFound = function() {
168   return (this.display.find(this.mediaFile.type).length > 0);
169 };
170 
171 /**
172  * Called when the player quality changes.
173  *
174  * @param {string} newQuality The new quality for the change.
175  */
176 minplayer.players.dailymotion.prototype.onQualityChange = function(newQuality) {
177   this.quality = newQuality.data;
178 };
179 
180 /**
181  * Determines if the player should show the playloader.
182  *
183  * @param {string} preview The preview image.
184  * @return {bool} If this player implements its own playLoader.
185  */
186 minplayer.players.dailymotion.prototype.hasPlayLoader = function(preview) {
187   return minplayer.hasTouch || !preview;
188 };
189 
190 /**
191  * Determines if the player should show the controller.
192  *
193  * @return {bool} If this player implements its own playLoader.
194  */
195 minplayer.players.dailymotion.prototype.hasController = function() {
196   return minplayer.isIDevice;
197 };
198 
199 /**
200  * @see minplayer.players.base#create
201  * @return {object} The media player entity.
202  */
203 minplayer.players.dailymotion.prototype.createPlayer = function() {
204   minplayer.players.base.prototype.createPlayer.call(this);
205 
206   // Insert the Dailymotion iframe API player.
207   var dailymotion_script = document.location.protocol;
208   dailymotion_script += '//api.dmcdn.net/all.js';
209   if (jQuery('script[src="' + dailymotion_script + '"]').length === 0) {
210     var tag = document.createElement('script');
211     tag.src = dailymotion_script;
212     var firstScriptTag = document.getElementsByTagName('script')[0];
213     firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
214   }
215 
216   // Get the player ID.
217   this.playerId = this.options.id + '-player';
218 
219   // Poll until the Dailymotion API is ready.
220   this.poll(this.options.id + '_dailymotion', (function(player) {
221     return function() {
222       var ready = jQuery('#' + player.playerId).length > 0;
223       ready = ready && ('DM' in window);
224       ready = ready && (typeof DM.player === 'function');
225       if (ready) {
226         // Determine the origin of this script.
227         jQuery('#' + player.playerId).addClass('dailymotion-player');
228 
229         var params = {};
230         params = {
231           id: player.playerId,
232           api: minplayer.isIDevice ? 0 : 1,
233           wmode: 'opaque',
234           controls: minplayer.isAndroid ? 1 : 0,
235           related: 0,
236           info: 0,
237           logo: 0
238         };
239 
240 
241         // Create the player.
242         player.player = new DM.player(player.playerId, {
243           video: player.mediaFile.id,
244           height: '100%',
245           width: '100%',
246           frameborder: 0,
247           params: params
248         });
249 
250         player.player.addEventListener('apiready', function() {
251           player.onReady(player);
252         });
253         player.player.addEventListener('ended', function() {
254           player.onComplete(player);
255         });
256         player.player.addEventListener('playing', function() {
257           player.onPlaying(player);
258         });
259         player.player.addEventListener('progress', function() {
260           player.onWaiting(player);
261         });
262         player.player.addEventListener('pause', function() {
263           player.onPaused(player);
264         });
265         player.player.addEventListener('error', function() {
266           player.onError(player);
267         });
268       }
269       return !ready;
270     };
271   })(this), 200);
272 
273   // Return the player.
274   return jQuery(document.createElement('div')).attr({
275     id: this.playerId
276   });
277 };
278 
279 /**
280  * @see minplayer.players.base#load
281  */
282 minplayer.players.dailymotion.prototype.load = function(file, callback) {
283   minplayer.players.base.prototype.load.call(this, file, function() {
284     this.player.load(file.id);
285     if (callback) {
286       callback.call(this);
287     }
288   });
289 };
290 
291 /**
292  * @see minplayer.players.base#play
293  */
294 minplayer.players.dailymotion.prototype.play = function(callback) {
295   minplayer.players.base.prototype.play.call(this, function() {
296     this.onWaiting();
297     this.player.play();
298     if (callback) {
299       callback.call(this);
300     }
301   });
302 };
303 
304 /**
305  * @see minplayer.players.base#pause
306  */
307 minplayer.players.dailymotion.prototype.pause = function(callback) {
308   minplayer.players.base.prototype.pause.call(this, function() {
309     if (this.loaded) {
310       this.player.pause();
311       if (callback) {
312         callback.call(this);
313       }
314     }
315   });
316 };
317 
318 /**
319  * @see minplayer.players.base#stop
320  */
321 minplayer.players.dailymotion.prototype.stop = function(callback) {
322   minplayer.players.base.prototype.stop.call(this, function() {
323     this.player.pause();
324     if (callback) {
325       callback.call(this);
326     }
327   });
328 };
329 
330 /**
331  * @see minplayer.players.base#_seek
332  */
333 minplayer.players.dailymotion.prototype._seek = function(pos) {
334   this.onWaiting();
335   this.player.seek(pos);
336 };
337 
338 /**
339  * @see minplayer.players.base#setVolume
340  */
341 minplayer.players.dailymotion.prototype.setVolume = function(vol, callback) {
342   minplayer.players.base.prototype.setVolume.call(this, vol, function() {
343     if (this.loaded) {
344       this.player.setVolume(vol);
345       if (callback !== undefined) {
346         callback.call(this);
347       }
348     }
349   });
350 
351 };
352 
353 /**
354  * @see minplayer.players.base#_getVolume
355  */
356 minplayer.players.dailymotion.prototype._getVolume = function(callback) {
357   callback(this.player.volume);
358 };
359 
360 /**
361  * @see minplayer.players.base#_getDuration.
362  */
363 minplayer.players.dailymotion.prototype._getDuration = function(callback) {
364   callback(this.player.duration);
365 };
366 
367 /**
368  * @see minplayer.players.base#_getCurrentTime
369  */
370 minplayer.players.dailymotion.prototype._getCurrentTime = function(callback) {
371   callback(this.player.currentTime);
372 };
373