1 // ==========================================================================
  2 // Project:   SproutCore - JavaScript Application Framework
  3 // Copyright: ©2012 Michael Krotscheck and contributors.
  4 // License:   Licensed under MIT license (see license.js)
  5 // ==========================================================================
  6 
  7 /**
  8  * @class
  9  * 
 10  * An easy-to-reference list of media capabilities which the current running
 11  * browser supports such as HTML5 and Plugin detection. It is modeled after
 12  * Flash Player's browser capabilities class, with all the non-media related
 13  * properties removed. Rather than performing specific browser checks, we
 14  * instead test by creating some basic DOM elements. It's both more reliable and
 15  * easier to maintain than browser version checks.
 16  * 
 17  * To see whether your target browser will support what you're trying to do,
 18  * check http://caniuse.com/
 19  * 
 20  * @see http://caniuse.com/
 21  * @since SproutCore 1.8.1
 22  * @author Michael Krotscheck
 23  */
 24 SC.mediaCapabilities = SC.Object.create({});
 25 
 26 /**
 27  * Automatic detection of various browser media capabilities.
 28  */
 29 (function() {
 30   /**
 31    * Specifies whether the browser supports the HTML5 <audio> tag.
 32    * 
 33    * @name SC.mediaCapabilities.isHTML5AudioSupported
 34    * @type Boolean
 35    */
 36   SC.mediaCapabilities.isHTML5AudioSupported = NO;
 37   try {
 38     // Firefox 3.6 doesn't support the W3C API. Disable support.
 39     if(SC.browser.isMozilla && SC.browser.compare(SC.browser.mozilla, "3.6") <= 0) {
 40       throw new Error('Browser not supported');
 41     }
 42     
 43     var doc = document.createElement('audio');
 44     var isAudioSupported = !!doc.canPlayType;
 45     delete doc;
 46     SC.mediaCapabilities.isHTML5AudioSupported = isAudioSupported;
 47     
 48   } catch(e) {
 49   }
 50   
 51   /**
 52    * Specifies whether the browser supports the HTML5 <video> tag.
 53    * 
 54    * @name SC.mediaCapabilities.isHTML5AudioSupported
 55    * @type Boolean
 56    */
 57   SC.mediaCapabilities.isHTML5VideoSupported = NO;
 58   try {
 59     // Firefox 3.6 doesn't support the W3C API. Disable support.
 60     if(SC.browser.isMozilla && SC.browser.compare(SC.browser.mozilla, "3.6") <= 0) {
 61       throw new Error('Browser not supported');
 62     }
 63     
 64     var doc = document.createElement('video');
 65     var isVideoSupported = !!doc.canPlayType;
 66     delete doc;
 67     SC.mediaCapabilities.isHTML5VideoSupported = isVideoSupported;
 68   } catch(e) {
 69   }
 70   
 71   /**
 72    * Specifies whether the browser supports the Adobe Flash plugin.
 73    * 
 74    * @name SC.mediaCapabilities.isHTML5AudioSupported
 75    * @type Boolean
 76    */
 77   SC.mediaCapabilities.isFlashSupported = NO;
 78   // Non-IE detection
 79   if(navigator.plugins) {
 80     for( var i = 0; i < navigator.plugins.length; i++) {
 81       if(navigator.plugins[i].name.indexOf("Shockwave Flash") >= 0) {
 82         SC.mediaCapabilities.isFlashSupported = YES;
 83       }
 84     }
 85   }
 86   // IE ActiveX detection
 87   if(window.ActiveXObject) {
 88     try {
 89       var control = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
 90       delete control;
 91       SC.mediaCapabilities.isFlashSupported = YES;
 92     } catch(e) {
 93       // Do nothing- The ActiveX object isn't available.
 94     }
 95   }
 96   
 97   /**
 98    * Specifies whether the browser supports quicktime media playback.
 99    * 
100    * @type Boolean
101    */
102   SC.mediaCapabilities.isQuicktimeSupported = NO;
103   
104   // Non-IE detection
105   if(navigator.plugins) {
106     for( var i = 0; i < navigator.plugins.length; i++) {
107       if(navigator.plugins[i].name.indexOf("QuickTime") >= 0) {
108         SC.mediaCapabilities.isQuicktimeSupported = YES;
109       }
110     }
111   }
112   // IE ActiveX detection
113   if(window.ActiveXObject) {
114     var control = null;
115     try {
116       control = new ActiveXObject('QuickTime.QuickTime');
117       delete control;
118       SC.mediaCapabilities.isQuicktimeSupported = YES;
119     } catch(e) {
120       // Do nothing- the ActiveX object isn't available.
121     }
122     
123     try {
124       // This generates a user prompt in Internet Explorer 7
125       control = new ActiveXObject('QuickTimeCheckObject.QuickTimeCheck');
126       delete control;
127       SC.mediaCapabilities.isQuicktimeSupported = YES;
128     } catch(e) {
129       // Do nothing- The ActiveX object isn't available.
130     }
131   }
132   
133   /**
134    * Specifies whether the browser supports the HTML5 getUserMedia/Stream API.
135    * 
136    * NOTE: As of February 2012, this feature is still in Draft status and is
137    * likely to change frequently. It's included here for the sake of
138    * completeness, however concrete implementations don't yet exist.
139    * 
140    * @name SC.mediaCapabilities.isHTML5StreamApiSupported
141    * @type Boolean
142    */
143   SC.mediaCapabilities.isHTML5StreamApiSupported = !!navigator.getUserMedia;
144   
145   /**
146    * Specifies whether the browser supports audio recording via the HTML5 stream
147    * API or the Adobe Flash plugin.
148    * 
149    * @name SC.mediaCapabilities.hasMicrophone
150    * @type Boolean
151    */
152   SC.mediaCapabilities.hasMicrophone = SC.mediaCapabilities.isHTML5StreamApiSupported || SC.mediaCapabilities.isFlashSupported;
153   
154   /**
155    * Specifies whether the browser supports video recording via the HTML5 stream
156    * API or the Adobe Flash Plugin.
157    * 
158    * @name SC.mediaCapabilities.hasMicrophone
159    * @type Boolean
160    */
161   SC.mediaCapabilities.hasVideoCamera = SC.mediaCapabilities.isHTML5StreamApiSupported || SC.mediaCapabilities.isFlashSupported;
162   
163   /**
164    * Specifies whether the browser has audio playback capabilities.
165    * 
166    * @name SC.mediaCapabilities.hasAudioPlayback
167    * @type Boolean
168    */
169   SC.mediaCapabilities.hasAudioPlayback = SC.mediaCapabilities.isHTML5AudioSupported || SC.mediaCapabilities.isQuicktimeSupported || SC.mediaCapabilities.isFlashSupported;
170   
171   /**
172    * Specifies whether the browser has video playback capabilities.
173    * 
174    * @name SC.mediaCapabilities.hasVideoPlayback
175    * @type Boolean
176    */
177   SC.mediaCapabilities.hasVideoPlayback = SC.mediaCapabilities.isHTML5VideoSupported || SC.mediaCapabilities.isQuicktimeSupported || SC.mediaCapabilities.isFlashSupported;
178   
179   /**
180    * Specifies whether the browser supports Ogg Vorbis.
181    * 
182    * @name SC.mediaCapabilities.isOggSupported
183    * @type Boolean
184    */
185   SC.mediaCapabilities.isOggSupported = SC.mediaCapabilities.hasVideoPlayback && (SC.browser.isMozilla || SC.browser.isChrome || SC.browser.isOpera);
186   
187   /**
188    * Specifies whether the browser supports the WebM/VP8 Video format.
189    * 
190    * @name SC.mediaCapabilities.isWebMSupported
191    * @type Boolean
192    */
193   SC.mediaCapabilities.isWebMSupported = SC.mediaCapabilities.hasVideoPlayback && (SC.browser.isMozilla || SC.browser.isChrome || SC.browser.isOpera);
194   
195   /**
196    * Specifies whether the browser supports the Adobe FLV compression format.
197    * 
198    * @name isFLVSupported
199    * @type Boolean
200    */
201   SC.mediaCapabilities.isFLVSupported = SC.mediaCapabilities.isFlashSupported;
202   
203   /**
204    * Specifies whether the browser supports the MPEG-4/H.264 Video format
205    * 
206    * @name isMP4Supported
207    * @type Boolean
208    */
209   SC.mediaCapabilities.isMP4Supported = SC.mediaCapabilities.hasVideoPlayback && (SC.browser.isIE || SC.browser.isChrome || SC.browser.isSafari);
210   
211 })();
212