1 /** The minplayer namespace. */
  2 var minplayer = minplayer || {};
  3 
  4 /**
  5  * @constructor
  6  * @class A wrapper class used to provide all the data necessary to control an
  7  * individual file within this media player.
  8  *
  9  * @param {object} file A media file object with minimal required information.
 10  */
 11 minplayer.file = function(file) {
 12 
 13   // If there isn't a file provided, then just return null.
 14   if (!file) {
 15     return null;
 16   }
 17 
 18   file = (typeof file === 'string') ? {path: file} : file;
 19 
 20   // If we already are a minplayer file, then just return this file.
 21   if (file.hasOwnProperty('isMinPlayerFile')) {
 22     return file;
 23   }
 24 
 25   this.isMinPlayerFile = true;
 26   this.duration = file.duration || 0;
 27   this.bytesTotal = file.bytesTotal || 0;
 28   this.quality = file.quality || 0;
 29   this.stream = file.stream || '';
 30   this.path = file.path || '';
 31   this.codecs = file.codecs || '';
 32 
 33   // These should be provided, but just in case...
 34   this.extension = file.extension || this.getFileExtension();
 35   this.mimetype = file.mimetype || file.filemime || this.getMimeType();
 36   this.type = file.type || this.getType();
 37 
 38   // Fail safe to try and guess the mimetype and media type.
 39   if (!this.type) {
 40     this.mimetype = this.getMimeType();
 41     this.type = this.getType();
 42   }
 43 
 44   // Get the player.
 45   this.player = minplayer.player || file.player || this.getBestPlayer();
 46   this.priority = file.priority || this.getPriority();
 47   this.id = file.id || this.getId();
 48   if (!this.path) {
 49     this.path = this.id;
 50   }
 51 };
 52 
 53 /** Used to force the player for all media. */
 54 minplayer.player = '';
 55 
 56 /**
 57  * Returns the best player for the job.
 58  *
 59  * @return {string} The best player to play the media file.
 60  */
 61 minplayer.file.prototype.getBestPlayer = function() {
 62   var bestplayer = null, bestpriority = 0;
 63   jQuery.each(minplayer.players, (function(file) {
 64     return function(name, player) {
 65       var priority = player.getPriority(file);
 66       if (player.canPlay(file) && (priority > bestpriority)) {
 67         bestplayer = name;
 68         bestpriority = priority;
 69       }
 70     };
 71   })(this));
 72   return bestplayer;
 73 };
 74 
 75 /**
 76  * The priority of this file is determined by the priority of the best
 77  * player multiplied by the priority of the mimetype.
 78  *
 79  * @return {integer} The priority of the media file.
 80  */
 81 minplayer.file.prototype.getPriority = function() {
 82   var priority = 1;
 83   if (this.player) {
 84     priority = minplayer.players[this.player].getPriority(this);
 85   }
 86   switch (this.mimetype) {
 87     case 'video/x-webm':
 88     case 'video/webm':
 89     case 'application/octet-stream':
 90     case 'application/vnd.apple.mpegurl':
 91       return priority * 10;
 92     case 'video/mp4':
 93     case 'audio/mp4':
 94     case 'audio/mpeg':
 95       return priority * 9;
 96     case 'video/ogg':
 97     case 'audio/ogg':
 98     case 'video/quicktime':
 99       return priority * 8;
100     default:
101       return priority * 5;
102   }
103 };
104 
105 /**
106  * Returns the file extension of the file path.
107  *
108  * @return {string} The file extension.
109  */
110 minplayer.file.prototype.getFileExtension = function() {
111   return this.path.substring(this.path.lastIndexOf('.') + 1).toLowerCase();
112 };
113 
114 /**
115  * Returns the proper mimetype based off of the extension.
116  *
117  * @return {string} The mimetype of the file based off of extension.
118  */
119 minplayer.file.prototype.getMimeType = function() {
120   switch (this.extension) {
121     case 'mp4': case 'm4v': case 'flv': case 'f4v':
122       return 'video/mp4';
123     case 'm3u8':
124       return 'application/vnd.apple.mpegurl';
125     case'webm':
126       return 'video/webm';
127     case 'ogg': case 'ogv':
128       return 'video/ogg';
129     case '3g2':
130       return 'video/3gpp2';
131     case '3gpp':
132     case '3gp':
133       return 'video/3gpp';
134     case 'mov':
135       return 'video/quicktime';
136     case'swf':
137       return 'application/x-shockwave-flash';
138     case 'oga':
139       return 'audio/ogg';
140     case 'mp3':
141       return 'audio/mpeg';
142     case 'm4a': case 'f4a':
143       return 'audio/mp4';
144     case 'aac':
145       return 'audio/aac';
146     case 'wav':
147       return 'audio/vnd.wave';
148     case 'wma':
149       return 'audio/x-ms-wma';
150     default:
151       return 'unknown';
152   }
153 };
154 
155 /**
156  * The type of media this is: video or audio.
157  *
158  * @return {string} "video" or "audio" based on what the type of media this
159  * is.
160  */
161 minplayer.file.prototype.getType = function() {
162   var type = this.mimetype.match(/([^\/]+)(\/)/);
163   type = (type && (type.length > 1)) ? type[1] : '';
164   if (type === 'video') {
165     return 'video';
166   }
167   if (type === 'audio') {
168     return 'audio';
169   }
170   switch (this.mimetype) {
171     case 'application/octet-stream':
172     case 'application/x-shockwave-flash':
173     case 'application/vnd.apple.mpegurl':
174       return 'video';
175   }
176   return '';
177 };
178 
179 /**
180  * Returns the ID for this media file.
181  *
182  * @return {string} The id for this media file which is provided by the player.
183  */
184 minplayer.file.prototype.getId = function() {
185   var player = minplayer.players[this.player];
186   return (player && player.getMediaId) ? player.getMediaId(this) : '';
187 };
188