1
0
mirror of https://github.com/videojs/video.js.git synced 2024-12-27 02:43:45 +02:00

+ vjs.Html5.{patchCanPlayType,unpatchCanPlayType}

patchCanPlayType is called on load.
It patched video#canPlayType if needed.
unpatchCanPlayType will revert the patch and return the patch function.
There are also corresponding tests that test patchCanPlayType,
unpatchCanPlayType and also whether the patch functions themselves work
correctly.
This commit is contained in:
Gary Katsevman 2014-03-17 20:47:47 -04:00
parent 252ad3f466
commit 5381f70d1c
2 changed files with 98 additions and 24 deletions

View File

@ -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' : '';
};
}

View File

@ -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;
});