diff --git a/src/js/media/html5.js b/src/js/media/html5.js
index f4e586762..54a4bfc2e 100644
--- a/src/js/media/html5.js
+++ b/src/js/media/html5.js
@@ -266,6 +266,55 @@ vjs.Html5.canControlVolume = function(){
return volume !== vjs.TEST_VID.volume;
};
+// HTML5 Feature detection and Device Fixes --------------------------------- //
+(function() {
+ var canPlayType,
+ mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl$/i,
+ mp4RE = /^video\/mp4$/i;
+
+ vjs.Html5.patchCanPlayType = function() {
+ // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
+ if (vjs.ANDROID_VERSION >= 4.0) {
+ if (!canPlayType) {
+ canPlayType = HTMLVideoElement.prototype.canPlayType;
+ }
+
+ HTMLVideoElement.prototype.canPlayType = function(type) {
+ if (type && mpegurlRE.test(type)) {
+ return "maybe";
+ }
+ return canPlayType.call(this, type);
+ };
+ }
+
+ // Override Android 2.2 and less canPlayType method which is broken
+ if (vjs.IS_OLD_ANDROID) {
+ if (!canPlayType) {
+ canPlayType = HTMLVideoElement.prototype.canPlayType;
+ }
+
+ HTMLVideoElement.prototype.canPlayType = function(type){
+ if (type && mp4RE.test(type)) {
+ return "maybe";
+ }
+ return canPlayType.call(this, type);
+ };
+ }
+ };
+
+ vjs.Html5.unpatchCanPlayType = function() {
+ var r = canPlayType;
+ if (canPlayType) {
+ HTMLVideoElement.prototype.canPlayType = canPlayType;
+ canPlayType = null;
+ return r;
+ }
+ };
+
+ // by default, patch the video element
+ vjs.Html5.patchCanPlayType();
+})();
+
// List of all HTML5 events (various uses).
vjs.Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(',');
@@ -300,27 +349,3 @@ vjs.Html5.disposeMediaElement = function(el){
})();
}
};
-
-// HTML5 Feature detection and Device Fixes --------------------------------- //
-
-// Android 4.0 and above can play HLS to some extent but it reports being unable to do so
-if (vjs.ANDROID_VERSION >= 4.0) {
- (function() {
- var canPlayType = HTMLVideoElement.prototype.canPlayType,
- mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl$/i;
-
- HTMLVideoElement.prototype.canPlayType = function(type) {
- if (type && mpegurlRE.test(type)) {
- return "maybe";
- }
- return canPlayType.call(video.constructor.prototype, type);
- }
- })();
-}
-
- // Override Android 2.2 and less canPlayType method which is broken
-if (vjs.IS_OLD_ANDROID) {
- document.createElement('video').constructor.prototype.canPlayType = function(type){
- return (type && type.toLowerCase().indexOf('video/mp4') != -1) ? 'maybe' : '';
- };
-}
diff --git a/test/unit/media.html5.js b/test/unit/media.html5.js
index e38777ea0..d828a5aa2 100644
--- a/test/unit/media.html5.js
+++ b/test/unit/media.html5.js
@@ -1,5 +1,7 @@
module('HTML5');
+var oldAndroidVersion;
+
test('should detect whether the volume can be changed', function(){
var testVid, ConstVolumeVideo;
if (!{}['__defineSetter__']) {
@@ -38,3 +40,50 @@ test('should re-link the player if the tech is moved', function(){
strictEqual(player, tech.el()['player']);
});
+
+test('patchCanPlayType patches canplaytype with our function, conditionally', function() {
+ var oldAV = vjs.ANDROID_VERSION,
+ video = document.createElement('video'),
+ canPlayType = HTMLVideoElement.prototype.canPlayType,
+ patchCanPlayType,
+ unpatchedCanPlayType;
+
+ vjs.ANDROID_VERSION = 4.0
+ vjs.Html5.patchCanPlayType();
+
+ notStrictEqual(video.canPlayType, canPlayType, 'original canPlayType and patched canPlayType should not be equal');
+
+ patchCanPlayType = video.canPlayType;
+ unpatchedCanPlayType = vjs.Html5.unpatchCanPlayType();
+
+ strictEqual(video.canPlayType, HTMLVideoElement.prototype.canPlayType, 'original canPlayType and unpatched canPlayType should be equal');
+
+ vjs.ANDROID_VERSION = oldAV;
+});
+
+test('should return maybe for HLS urls on Android 4.0 or above', function() {
+ var oldAV = vjs.ANDROID_VERSION,
+ video = document.createElement('video');
+
+ vjs.ANDROID_VERSION = 4.0
+ vjs.Html5.patchCanPlayType();
+
+ strictEqual(video.canPlayType('application/x-mpegurl'), "maybe", "android version 4.0 or above should be a maybe for x-mpegurl");
+ strictEqual(video.canPlayType('application/x-mpegURL'), "maybe", "android version 4.0 or above should be a maybe for x-mpegURL");
+ strictEqual(video.canPlayType('application/vnd.apple.mpegurl'), "maybe", "android version 4.0 or above should be a maybe for vnd.apple.mpegurl");
+ strictEqual(video.canPlayType('application/vnd.apple.mpegURL'), "maybe", "android version 4.0 or above should be a maybe for vnd.apple.mpegurl");
+
+ vjs.ANDROID_VERSION = oldAV;
+});
+
+test('should return a maybe for mp4 on OLD ANDROID', function() {
+ var isOldAndroid = vjs.IS_OLD_ANDROID,
+ video = document.createElement('video');
+
+ vjs.IS_OLD_ANDROID = true;
+ vjs.Html5.patchCanPlayType();
+
+ strictEqual(video.canPlayType('video/mp4'), 'maybe', 'old android should return a maybe for video/mp4');
+
+ vjs.IS_OLD_ANDROID = isOldAndroid;
+});