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.display
 10  * @class The base media player class where all media players derive from.
 11  *
 12  * @param {object} context The jQuery context.
 13  * @param {object} options This components options.
 14  */
 15 minplayer.players.base = function(context, options) {
 16 
 17   // Derive from display
 18   minplayer.display.call(this, 'media', context, options);
 19 };
 20 
 21 /** Derive from minplayer.display. */
 22 minplayer.players.base.prototype = new minplayer.display();
 23 
 24 /** Reset the constructor. */
 25 minplayer.players.base.prototype.constructor = minplayer.players.base;
 26 
 27 /**
 28  * Get the priority of this media player.
 29  *
 30  * @return {number} The priority of this media player.
 31  */
 32 minplayer.players.base.getPriority = function() {
 33   return 0;
 34 };
 35 
 36 /**
 37  * Returns the ID for the media being played.
 38  *
 39  * @param {object} file A {@link minplayer.file} object.
 40  * @return {string} The ID for the provided media.
 41  */
 42 minplayer.players.base.getMediaId = function(file) {
 43   return '';
 44 };
 45 
 46 /**
 47  * Determine if we can play the media file.
 48  *
 49  * @param {object} file A {@link minplayer.file} object.
 50  * @return {boolean} If this player can play this media type.
 51  */
 52 minplayer.players.base.canPlay = function(file) {
 53   return false;
 54 };
 55 
 56 /**
 57  * @see minplayer.plugin.construct
 58  * @this minplayer.players.base
 59  */
 60 minplayer.players.base.prototype.construct = function() {
 61 
 62   // Call the media display constructor.
 63   minplayer.display.prototype.construct.call(this);
 64 
 65   // Reset the variables to initial state.
 66   this.reset();
 67 
 68   /** The currently loaded media file. */
 69   this.mediaFile = this.options.file;
 70 
 71   // Get the player display object.
 72   if (!this.playerFound()) {
 73 
 74     // Remove the media element if found
 75     if (this.elements.media) {
 76       this.elements.media.remove();
 77     }
 78 
 79     // Create a new media player element.
 80     this.display.html(this.create());
 81   }
 82 
 83   // Get the player object...
 84   this.player = this.getPlayer();
 85 };
 86 
 87 /**
 88  * @see minplayer.plugin.destroy.
 89  */
 90 minplayer.players.base.prototype.destroy = function() {
 91   minplayer.plugin.prototype.destroy.call(this);
 92 
 93   // Reset the player.
 94   this.reset();
 95 };
 96 
 97 /**
 98  * Clears all the intervals.
 99  */
100 minplayer.players.base.prototype.clearIntervals = function() {
101   // Stop the intervals.
102   this.playInterval = false;
103   this.progressInterval = false;
104 };
105 
106 /**
107  * Resets all variables.
108  */
109 minplayer.players.base.prototype.reset = function() {
110 
111   // Reset the ready flag.
112   this.playerReady = false;
113 
114   // The duration of the player.
115   this.duration = new minplayer.async();
116 
117   // The current play time of the player.
118   this.currentTime = new minplayer.async();
119 
120   // The amount of bytes loaded in the player.
121   this.bytesLoaded = new minplayer.async();
122 
123   // The total amount of bytes for the media.
124   this.bytesTotal = new minplayer.async();
125 
126   // The bytes that the download started with.
127   this.bytesStart = new minplayer.async();
128 
129   // The current volume of the player.
130   this.volume = new minplayer.async();
131 
132   // Stop the intervals.
133   this.clearIntervals();
134 
135   // If the player exists, then unbind all events.
136   if (this.player) {
137     jQuery(this.player).unbind();
138   }
139 };
140 
141 /**
142  * Create a polling timer.
143  * @param {function} callback The function to call when you poll.
144  */
145 minplayer.players.base.prototype.poll = function(callback) {
146   var _this = this;
147   setTimeout(function later() {
148     if (callback.call(_this)) {
149       setTimeout(later, 1000);
150     }
151   }, 1000);
152 };
153 
154 /**
155  * Called when the player is ready to recieve events and commands.
156  */
157 minplayer.players.base.prototype.onReady = function() {
158   // Store the this pointer.
159   var _this = this;
160 
161   // Set the ready flag.
162   this.playerReady = true;
163 
164   // Set the volume to the default.
165   this.setVolume(this.options.volume / 100);
166 
167   // Setup the progress interval.
168   this.progressInterval = true;
169 
170   // Create a poll to get the progress.
171   this.poll(function() {
172 
173     // Only do this if the play interval is set.
174     if (_this.progressInterval) {
175 
176       // Get the bytes loaded asynchronously.
177       _this.getBytesLoaded(function(bytesLoaded) {
178 
179         // Get the bytes total asynchronously.
180         _this.getBytesTotal(function(bytesTotal) {
181 
182           // Trigger an event about the progress.
183           if (bytesLoaded || bytesTotal) {
184 
185             // Get the bytes start, but don't require it.
186             var bytesStart = 0;
187             _this.getBytesStart(function(val) {
188               bytesStart = val;
189             });
190 
191             // Trigger a progress event.
192             _this.trigger('progress', {
193               loaded: bytesLoaded,
194               total: bytesTotal,
195               start: bytesStart
196             });
197           }
198         });
199       });
200     }
201 
202     return _this.progressInterval;
203   });
204 
205   // We are now ready.
206   this.ready();
207 
208   // Trigger that the load has started.
209   this.trigger('loadstart');
210 };
211 
212 /**
213  * Should be called when the media is playing.
214  */
215 minplayer.players.base.prototype.onPlaying = function() {
216   // Store the this pointer.
217   var _this = this;
218 
219   // Trigger an event that we are playing.
220   this.trigger('playing');
221 
222   // Set the playInterval to true.
223   this.playInterval = true;
224 
225   // Create a poll to get the timeupate.
226   this.poll(function() {
227 
228     // Only do this if the play interval is set.
229     if (_this.playInterval) {
230 
231       // Get the current time asyncrhonously.
232       _this.getCurrentTime(function(currentTime) {
233 
234         // Get the duration asynchronously.
235         _this.getDuration(function(duration) {
236 
237           // Convert these to floats.
238           currentTime = parseFloat(currentTime);
239           duration = parseFloat(duration);
240 
241           // Trigger an event about the progress.
242           if (currentTime || duration) {
243 
244             // Trigger an update event.
245             _this.trigger('timeupdate', {
246               currentTime: currentTime,
247               duration: duration
248             });
249           }
250         });
251       });
252     }
253 
254     return _this.playInterval;
255   });
256 };
257 
258 /**
259  * Should be called when the media is paused.
260  */
261 minplayer.players.base.prototype.onPaused = function() {
262 
263   // Trigger an event that we are paused.
264   this.trigger('pause');
265 
266   // Stop the play interval.
267   this.playInterval = false;
268 };
269 
270 /**
271  * Should be called when the media is complete.
272  */
273 minplayer.players.base.prototype.onComplete = function() {
274   // Stop the intervals.
275   this.clearIntervals();
276   this.trigger('ended');
277 };
278 
279 /**
280  * Should be called when the media is done loading.
281  */
282 minplayer.players.base.prototype.onLoaded = function() {
283   this.trigger('loadeddata');
284 };
285 
286 /**
287  * Should be called when the player is waiting.
288  */
289 minplayer.players.base.prototype.onWaiting = function() {
290   this.trigger('waiting');
291 };
292 
293 /**
294  * Called when an error occurs.
295  *
296  * @param {string} errorCode The error that was triggered.
297  */
298 minplayer.players.base.prototype.onError = function(errorCode) {
299   this.trigger('error', errorCode);
300 };
301 
302 /**
303  * @see minplayer.players.base#isReady
304  * @return {boolean} Checks to see if the Flash is ready.
305  */
306 minplayer.players.base.prototype.isReady = function() {
307 
308   // Return that the player is set and the ready flag is good.
309   return (this.player && this.playerReady);
310 };
311 
312 /**
313  * Determines if the player should show the playloader.
314  *
315  * @return {bool} If this player implements its own playLoader.
316  */
317 minplayer.players.base.prototype.hasPlayLoader = function() {
318   return false;
319 };
320 
321 /**
322  * Returns if the media player is already within the DOM.
323  *
324  * @return {boolean} TRUE - if the player is in the DOM, FALSE otherwise.
325  */
326 minplayer.players.base.prototype.playerFound = function() {
327   return false;
328 };
329 
330 /**
331  * Creates the media player and inserts it in the DOM.
332  *
333  * @return {object} The media player entity.
334  */
335 minplayer.players.base.prototype.create = function() {
336   this.reset();
337   return null;
338 };
339 
340 /**
341  * Returns the media player object.
342  *
343  * @return {object} The media player object.
344  */
345 minplayer.players.base.prototype.getPlayer = function() {
346   return this.player;
347 };
348 
349 /**
350  * Loads a new media player.
351  *
352  * @param {object} file A {@link minplayer.file} object.
353  */
354 minplayer.players.base.prototype.load = function(file) {
355 
356   // Store the media file for future lookup.
357   if (file) {
358     this.reset();
359     this.mediaFile = file;
360   }
361 };
362 
363 /**
364  * Play the loaded media file.
365  */
366 minplayer.players.base.prototype.play = function() {
367 };
368 
369 /**
370  * Pause the loaded media file.
371  */
372 minplayer.players.base.prototype.pause = function() {
373 };
374 
375 /**
376  * Stop the loaded media file.
377  */
378 minplayer.players.base.prototype.stop = function() {
379   // Stop the intervals.
380   this.clearIntervals();
381 };
382 
383 /**
384  * Seek the loaded media.
385  *
386  * @param {number} pos The position to seek the minplayer. 0 to 1.
387  */
388 minplayer.players.base.prototype.seek = function(pos) {
389 
390 };
391 
392 /**
393  * Set the volume of the loaded minplayer.
394  *
395  * @param {number} vol The volume to set the media. 0 to 1.
396  */
397 minplayer.players.base.prototype.setVolume = function(vol) {
398   this.trigger('volumeupdate', vol);
399 };
400 
401 /**
402  * Get the volume from the loaded media.
403  *
404  * @param {function} callback Called when the volume is determined.
405  * @return {number} The volume of the media; 0 to 1.
406  */
407 minplayer.players.base.prototype.getVolume = function(callback) {
408   return this.volume.get(callback);
409 };
410 
411 /**
412  * Get the current time for the media being played.
413  *
414  * @param {function} callback Called when the time is determined.
415  * @return {number} The volume of the media; 0 to 1.
416  */
417 minplayer.players.base.prototype.getCurrentTime = function(callback) {
418   return this.currentTime.get(callback);
419 };
420 
421 /**
422  * Return the duration of the loaded media.
423  *
424  * @param {function} callback Called when the duration is determined.
425  * @return {number} The duration of the loaded media.
426  */
427 minplayer.players.base.prototype.getDuration = function(callback) {
428   return this.duration.get(callback);
429 };
430 
431 /**
432  * Return the start bytes for the loaded media.
433  *
434  * @param {function} callback Called when the start bytes is determined.
435  * @return {int} The bytes that were started.
436  */
437 minplayer.players.base.prototype.getBytesStart = function(callback) {
438   return this.bytesStart.get(callback);
439 };
440 
441 /**
442  * Return the bytes of media loaded.
443  *
444  * @param {function} callback Called when the bytes loaded is determined.
445  * @return {int} The amount of bytes loaded.
446  */
447 minplayer.players.base.prototype.getBytesLoaded = function(callback) {
448   return this.bytesLoaded.get(callback);
449 };
450 
451 /**
452  * Return the total amount of bytes.
453  *
454  * @param {function} callback Called when the bytes total is determined.
455  * @return {int} The total amount of bytes for this media.
456  */
457 minplayer.players.base.prototype.getBytesTotal = function(callback) {
458   return this.bytesTotal.get(callback);
459 };
460 
461